instruction * instruction_alloc( const char *name, int len, const char *val ) { instruction *i; if (!name || !val) return NULL; i = malloc( sizeof *i ); if (!i) return NULL; if (strlen( name ) > MAXLEN_INSTRUCTION) printf( _("Warning: Instruction name too long\n") ); strncpy( i->name, name, MAXLEN_INSTRUCTION ); i->name[MAXLEN_INSTRUCTION] = '\0'; i->value = register_alloc( len ); if (!i->value) { free( i ); return NULL; } i->out = register_alloc( len ); if (!i->out) { free( i->value ); free( i ); return NULL; } register_init( i->value, val ); i->data_register = NULL; i->next = NULL; return i; }
void discovery( chain_t *chain ) { int irlen; tap_register *ir; tap_register *irz; /* detecting IR size */ jtag_reset( chain ); printf( _("Detecting IR length ... ") ); fflush( stdout ); tap_capture_ir( chain ); irlen = detect_register_size( chain ); printf( _("%d\n"), irlen ); if (irlen < 1) { printf( _("Error: Invalid IR length!\n") ); return; } /* all 1 is BYPASS in all parts, so DR length gives number of parts */ ir = register_fill( register_alloc( irlen ), 1 ); irz = register_duplicate( ir ); if (!ir || !irz) { register_free( ir ); register_free( irz ); printf( _("Error: Out of memory!\n") ); return; } for (;;) { int rs; jtag_reset( chain ); tap_capture_ir( chain ); tap_shift_register( chain, ir, NULL, 1 ); printf( _("Detecting DR length for IR %s ... "), register_get_string( ir ) ); fflush( stdout ); tap_capture_dr( chain ); rs = detect_register_size( chain ); printf( _("%d\n"), rs ); register_inc( ir ); if (register_compare( ir, irz ) == 0) break; } register_free( ir ); register_free( irz ); }
data_register * data_register_alloc( const char *name, int len ) { data_register *dr; if (!name) return NULL; dr = malloc( sizeof *dr ); if (!dr) return NULL; if (strlen( name ) > MAXLEN_DATA_REGISTER) printf( _("Warning: Data register name too long\n") ); strncpy( dr->name, name, MAXLEN_DATA_REGISTER ); dr->name[MAXLEN_DATA_REGISTER] = '\0'; if (len>0) { dr->in = register_alloc( len ); dr->out = register_alloc( len ); } else { dr->in = register_alloc( 1 ); dr->out = register_alloc( 1 ); } if (!dr->in || !dr->out) { free( dr->in ); free( dr->out ); free( dr->name ); free( dr ); return NULL; } dr->next = NULL; return dr; }
void expr_codegen(struct expr *e, FILE *file) { int string_count = 0, found = 0, count = 1; struct string_node *sn; char* string_label = (char*)malloc(9); char* label_name = (char*)malloc(9); struct expr *temp_ptr; if(!e) return; switch(e->kind) { case EXPR_LIST: break; case EXPR_ASSIGNMENT: expr_codegen(e->right, file); fprintf(file, "\tMOV %s, %s\t\t# Assignment\n", register_name(e->right->reg), symbol_code(e->left->symbol)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_OR: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tOR %s, %s\n", register_name(e->left->reg), register_name(e->right->reg)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_AND: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tAND %s, %s\n", register_name(e->left->reg), register_name(e->right->reg)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_LT: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); sprintf(label_name, "done_%d", labelNum); fprintf(file, "\tJG %s\n", label_name); fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg)); fprintf(file, "%s:\n", label_name); e->reg = e->right->reg; register_free(e->left->reg); labelNum++; break; case EXPR_GT: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); sprintf(label_name, "done_%d", labelNum); fprintf(file, "\tJL %s\n", label_name); fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg)); fprintf(file, "%s:\n", label_name); e->reg = e->right->reg; register_free(e->left->reg); labelNum++; break; case EXPR_LE: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); sprintf(label_name, "done_%d", labelNum); fprintf(file, "\tJGE %s\n", label_name); fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg)); fprintf(file, "%s:\n", label_name); e->reg = e->right->reg; register_free(e->left->reg); labelNum++; break; case EXPR_GE: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); sprintf(label_name, "done_%d", labelNum); fprintf(file, "\tJLE %s\n", label_name); fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg)); fprintf(file, "%s:\n", label_name); e->reg = e->right->reg; register_free(e->left->reg); labelNum++; break; case EXPR_NOT_EQUALS: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); sprintf(label_name, "done_%d", labelNum); fprintf(file, "\tJNE %s\n", label_name); fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg)); fprintf(file, "%s:\n", label_name); e->reg = e->right->reg; register_free(e->left->reg); labelNum++; break; case EXPR_EQUALS: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tCMP %s, %s\t\t\n", register_name(e->left->reg), register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); fprintf(file, "\tMOV $1, %s\n", register_name(e->right->reg)); sprintf(label_name, "done_%d", labelNum); fprintf(file, "\tJE %s\n", label_name); fprintf(file, "\tMOV $0, %s\n", register_name(e->right->reg)); fprintf(file, "%s:\n", label_name); e->reg = e->right->reg; register_free(e->left->reg); labelNum++; break; case EXPR_ADD: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tADD %s, %s\n", register_name(e->left->reg), register_name(e->right->reg)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_MINUS: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tSUB %s, %s\n", register_name(e->right->reg), register_name(e->left->reg)); e->reg = e->left->reg; register_free(e->right->reg); break; case EXPR_TIMES: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tMOV %s, %rax\t\t#Move left value into rax to prepare for multiplying\n", register_name(e->left->reg)); fprintf(file, "\tIMUL %s\t\t# Multiply %rax by the value in %s\n", register_name(e->right->reg), register_name(e->right->reg)); fprintf(file, "\tMOV %rax, %s\t\t# Move multiplied result back to non-scratch register\n", register_name(e->right->reg)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_DIVIDES: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tMOVQ %s, %rax\t\t#Move left value into rax to prepare for dividing\n", register_name(e->left->reg)); fprintf(file, "\tCQTO\n"); fprintf(file, "\tIDIVQ %s\t\t\t# Divide %rax by the value in %s\n", register_name(e->right->reg), register_name(e->right->reg)); fprintf(file, "\tMOVQ %rax, %s\t\t# Move divided result back to non-scratch register\n", register_name(e->right->reg)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_MOD: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tMOVQ %s, %rax\t\t#Move left value into rax to prepare for dividing\n", register_name(e->left->reg)); fprintf(file, "\tCQTO\n"); fprintf(file, "\tIDIVQ %s\t\t\t# Divide %rax by the value in %s\n", register_name(e->right->reg), register_name(e->right->reg)); fprintf(file, "\tMOVQ %rdx, %s\t\t# Move remainder back to non-scratch register\n", register_name(e->right->reg)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_POWER: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\tMOV %s, %rdi\t\t# Move first argument for base of power\n", register_name(e->left->reg)); fprintf(file, "\tMOV %s, %rsi\t\t# Move second argument for exponent\n", register_name(e->right->reg)); fprintf(file, "\n\tPUSHQ %r10\n"); fprintf(file, "\tPUSHQ %r11\n"); fprintf(file, "\n\tCALL integer_power\n\n"); fprintf(file, "\tPOPQ %r11\n"); fprintf(file, "\tPOPQ %r10\n"); fprintf(file, "\tMOV %rax, %s\t\t# Move result of integer_power into register\n", register_name(e->right->reg)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_NEGATIVE: expr_codegen(e->right, file); fprintf(file, "\tNEG %s\t\t# Negate the value\n", register_name(e->right->reg)); e->reg = e->right->reg; break; case EXPR_NOT: expr_codegen(e->right, file); fprintf(file, "\tSUB $1, %s\t\t# Negate the boolean\n", register_name(e->right->reg)); e->reg = e->right->reg; break; case EXPR_PRE_INCREMENT: expr_codegen(e->right, file); fprintf(file, "\tINC %s\n", register_name(e->right->reg)); fprintf(file, "\tMOV %s, %s\n", register_name(e->right->reg), symbol_code(e->right->symbol)); e->reg = e->right->reg; break; case EXPR_PRE_DECREMENT: expr_codegen(e->right, file); fprintf(file, "\tDEC %s\n", register_name(e->right->reg)); fprintf(file, "\tMOV %s, %s\n", register_name(e->right->reg), symbol_code(e->right->symbol)); e->reg = e->right->reg; break; case EXPR_POST_INCREMENT: // TODO: Delay incrementing expr_codegen(e->left, file); fprintf(file, "\tINC %s\n", register_name(e->left->reg)); fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), symbol_code(e->left->symbol)); e->reg = e->left->reg; break; case EXPR_POST_DECREMENT: expr_codegen(e->left, file); fprintf(file, "\tDEC %s\n", register_name(e->left->reg)); fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), symbol_code(e->left->symbol)); e->reg = e->left->reg; break; case EXPR_FUNCTION: // setup function args fprintf(file, "\tMOV $0, %rax\n"); temp_ptr = e->right; while(temp_ptr) { if(count > 6) { printf("You may only supple 6 arguments to a function\n"); exit(1); } expr_codegen(temp_ptr->left, file); fprintf(file, "\tMOV %s, %s\n", register_name(temp_ptr->left->reg), num_to_arg(count++)); temp_ptr = temp_ptr->right; } // call function fprintf(file, "\n\tPUSH %r10\n"); fprintf(file, "\tPUSH %r11\n"); fprintf(file, "\n\tCALL %s\n\n", e->left->name); fprintf(file, "\tPOP %r11\n"); fprintf(file, "\tPOP %r10\n"); e->reg = register_alloc(); fprintf(file, "\tMOV %rax, %s\n", register_name(e->reg)); break; case EXPR_BOOLEAN: e->reg = register_alloc(); fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg)); break; case EXPR_INT: e->reg = register_alloc(); fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg)); break; case EXPR_CHAR: e->reg = register_alloc(); fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg)); break; case EXPR_STRING: e->reg = register_alloc(); // find the string sn = string_head; while(sn) { if(!strcmp(sn->text, e->string_literal)) { // string found found = 1; sprintf(string_label, "LC%d", string_count); e->reg = register_alloc(); fprintf(file, "\tMOV $%s, %s\t\t# Move string into register\n", string_label, register_name(e->reg)); break; } string_count++; sn = sn->next; } if(!found) { printf("Could not find string %s in data\n", e->string_literal); exit(1); } break; case EXPR_NAME: e->reg = register_alloc(); fprintf(file, "\tMOV %s, %s\n", symbol_code(e->symbol), register_name(e->reg)); break; case EXPR_ARRAY: break; case EXPR_ARRAY_LITERAL: break; } }
int detect_register_size( chain_t *chain ) { int len; tap_register *rz; tap_register *rout; tap_register *rpat; /* This seems to be a good place to check if TDO changes at all */ int tdo, tdo_stuck = -2; for (len = 1; len <= MAX_REGISTER_LENGTH; len++) { int p; int ok = 0; rz = register_fill( register_alloc( len ), 0 ); rout = register_alloc( DETECT_PATTERN_SIZE + len ); rpat = register_inc( register_fill( register_alloc( DETECT_PATTERN_SIZE + len ), 0 ) ); for (p = 1; p < (1 << DETECT_PATTERN_SIZE); p++) { int i; const char *s; ok = 0; s = register_get_string( rpat ); while (*s) s++; for (i = 0; i < TEST_COUNT; i++) { tap_shift_register( chain, rz, NULL, 0 ); tap_shift_register( chain, rpat, rout, 0 ); #ifdef VERY_LOW_LEVEL_DEBUG printf(">>> %s\n", register_get_string(rz)); printf(" + %s\n", register_get_string(rpat)); #endif tdo = register_all_bits_same_value(rout); if(tdo_stuck == -2) tdo_stuck = tdo; if(tdo_stuck != tdo) tdo_stuck = -1; register_shift_right( rout, len ); if (register_compare( rpat, rout ) == 0) ok++; #ifdef VERY_LOW_LEVEL_DEBUG printf(" = %s => %d\n", register_get_string(rout), ok); #endif } if (100 * ok / TEST_COUNT < TEST_THRESHOLD) { ok = 0; break; } register_inc( rpat ); } register_free( rz ); register_free( rout ); register_free( rpat ); if (ok) return len; } if(tdo_stuck >= 0) { printf(_("Warning: TDO seems to be stuck at %d\n"), tdo_stuck); } return -1; }
void compare(struct expr *e, FILE *file) { expr_codegen(e->left, file); expr_codegen(e->right, file); e->reg = register_alloc(); if(expr_typecheck(e->left)->kind==TYPE_STRING && expr_typecheck(e->right)->kind==TYPE_STRING){ fprintf(file, "\n\t#String comparison\n"); const char *left; const char *right; //get the correct string for left if(e->left->kind==EXPR_STRING_LITERAL) left = e->left->string_literal; else if(e->left->kind==EXPR_IDENT) left = e->left->symbol->string_literal; //get the correct string for right if(e->right->kind==EXPR_STRING_LITERAL) right = e->right->string_literal; else if(e->right->kind==EXPR_IDENT) right = e->right->symbol->string_literal; //compare the strings int result = strcmp(left, right); if(e->kind == EXPR_EQ){ if(result){ fprintf(file, "\tMOV $0, %s\n", register_name(e->reg)); } else { fprintf(file, "\tMOV $1, %s\n", register_name(e->reg)); } } else if(e->kind == EXPR_NE){ if(result){ fprintf(file, "\tMOV $1, %s\n", register_name(e->reg)); } else { fprintf(file, "\tMOV $0, %s\n", register_name(e->reg)); } } } else { fprintf(file, "\n\t#Comparison\n"); fprintf(file, "\tCMP %s, %s\n", register_name(e->right->reg), register_name(e->left->reg)); register_free(e->left->reg); register_free(e->right->reg); char *jump = malloc(4); switch(e->kind){ case EXPR_GE: strcpy(jump, "JGE"); break; case EXPR_LE: strcpy(jump, "JLE"); break; case EXPR_GT: strcpy(jump, "JG"); break; case EXPR_LT: strcpy(jump, "JL"); break; case EXPR_EQ: strcpy(jump, "JE"); break; case EXPR_NE: strcpy(jump, "JNE"); break; } int label_true = label_count++; int label_false = label_count++; fprintf(file, "\t%s L%d\n", jump, label_true); fprintf(file, "\tMOV $0, %s\n", register_name(e->reg)); fprintf(file, "\tJMP L%d\n", label_false); fprintf(file, "L%d:\n", label_true); fprintf(file, "\tMOV $1, %s\n", register_name(e->reg)); fprintf(file, "L%d:\n", label_false); free(jump); } }
//Generates code and writes it to a file void expr_codegen(struct expr *e, FILE *file) { if(!e) return; struct expr *e2; switch(e->kind) { case EXPR_ASSIGNMENT: fprintf(file, "\n\t#Assignment of %s %d right value\n", e->left->symbol->name, e->left->symbol->which); expr_codegen(e->right, file); fprintf(file, "\n\t#Assignment assign to %s %d\n", e->left->symbol->name, e->left->symbol->which); fprintf(file, "\tMOV %s, %s\n", register_name(e->right->reg), symbol_code(e->left->symbol)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_GE: //all of these go to the compare function case EXPR_LE: case EXPR_GT: case EXPR_LT: case EXPR_EQ: case EXPR_NE: compare(e, file); break; case EXPR_ADD: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\n\t#Addition\n"); fprintf(file, "\tADD %s, %s\n", register_name(e->left->reg), register_name(e->right->reg)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_SUB: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\n\t#Subtraction\n"); fprintf(file, "\tSUB %s, %s\n", register_name(e->right->reg), register_name(e->left->reg)); e->reg = e->left->reg; register_free(e->right->reg); break; case EXPR_MUL: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\n\t#Multiplication\n"); fprintf(file, "\tMOV %s, %%rax\n", register_name(e->left->reg)); fprintf(file, "\tIMUL %s\n", register_name(e->right->reg)); fprintf(file, "\tMOV %%rax, %s\n", register_name(e->right->reg)); register_free(e->left->reg); e->reg = e->right->reg; break; case EXPR_DIV: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\n\t#Division\n"); fprintf(file, "\tMOV %s, %%rax\n", register_name(e->left->reg)); fprintf(file, "\tCQO\n"); fprintf(file, "\tIDIV %s\n", register_name(e->right->reg)); fprintf(file, "\tMOV %%rax, %s\n", register_name(e->right->reg)); register_free(e->left->reg); e->reg = e->right->reg; break; case EXPR_MOD: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\n\t#Modulus\n"); fprintf(file, "\tMOV %s, %%rax\n", register_name(e->left->reg)); fprintf(file, "\tCQO\n"); fprintf(file, "\tIDIV %s\n", register_name(e->right->reg)); fprintf(file, "\tMOV %%rdx, %s\n", register_name(e->right->reg)); register_free(e->left->reg); e->reg = e->right->reg; break; case EXPR_POW: expr_codegen(e->left, file); expr_codegen(e->right, file); int label_start = label_count++; int label_end = label_count++; fprintf(file, "\n\t#Exponent function\n"); fprintf(file, "\tMOV $1, %%rax\n"); fprintf(file, "L%d:\n", label_start); fprintf(file, "\tCMP $0, %s\n", register_name(e->right->reg)); fprintf(file, "\tJE L%d\n", label_end); fprintf(file, "\tSUB $1, %s\n", register_name(e->right->reg)); fprintf(file, "\tMUL %s\n", register_name(e->left->reg)); fprintf(file, "\tJMP L%d\n", label_start); fprintf(file, "L%d:\n", label_end); register_free(e->left->reg); register_free(e->right->reg); e->reg = register_alloc(); fprintf(file, "\tMOV %%rax, %s\n", register_name(e->reg)); break; case EXPR_LOGICAL_NOT: expr_codegen(e->right, file); fprintf(file, "\n\t#Logical Not\n"); e->reg = e->right->reg; fprintf(file, "\tCMPQ $0, %s\n", register_name(e->reg)); fprintf(file, "\tJNE L%d\n", label_count); fprintf(file, "\tMOV $1, %s\n", register_name(e->reg)); fprintf(file, "\tJMP L%d\n", label_count+1); fprintf(file, "L%d:\n", label_count++); fprintf(file, "\tMOV $0, %s\n", register_name(e->reg)); fprintf(file, "L%d:\n", label_count++); break; case EXPR_LOGICAL_AND: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\n\t#Logical And\n"); fprintf(file, "\tAND %s, %s\n", register_name(e->left->reg), register_name(e->right->reg)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_LOGICAL_OR: expr_codegen(e->left, file); expr_codegen(e->right, file); fprintf(file, "\n\t#Logical Or\n"); fprintf(file, "\tOR %s, %s\n", register_name(e->left->reg), register_name(e->right->reg)); e->reg = e->right->reg; register_free(e->left->reg); break; case EXPR_POSTFIX_PLUS: expr_codegen(e->left, file); fprintf(file, "\n\t#Increment\n"); e->reg = register_alloc(); fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), register_name(e->reg)); fprintf(file, "\tADD $1, %s\n", register_name(e->left->reg)); fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), symbol_code(e->left->symbol)); register_free(e->left->reg); break; case EXPR_POSTFIX_MINUS: expr_codegen(e->left, file); fprintf(file, "\n\t#Increment\n"); e->reg = register_alloc(); fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), register_name(e->reg)); fprintf(file, "\tSUB $1, %s\n", register_name(e->left->reg)); fprintf(file, "\tMOV %s, %s\n", register_name(e->left->reg), symbol_code(e->left->symbol)); register_free(e->left->reg); break; case EXPR_IDENT: fprintf(file, "\n\t#Identifier %d %s\n", e->symbol->which, e->symbol->name); e->reg = register_alloc(); if(e->symbol->type->kind == TYPE_STRING && e->symbol->kind == SCOPE_GLOBAL){ fprintf(file, "\tLEA %s, %s\n", symbol_code(e->symbol), register_name(e->reg)); } else { fprintf(file, "\tMOV %s, %s\n", symbol_code(e->symbol), register_name(e->reg)); } break; case EXPR_INTEGER_LITERAL: //comment label fprintf(file, "\n\t#Integer literal %d\n", e->literal_value); e->reg = register_alloc(); fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg)); break; case EXPR_STRING_LITERAL: //comment label fprintf(file, "\n\t#String literal %s\n", e->string_literal); e->reg = register_alloc(); fprintf(file, ".data\nSTR%d: \n.string \"%s\"\n.text\n", string_number, e->string_literal); fprintf(file, "\tLEA STR%d, %s\n", string_number++, register_name(e->reg)); break; case EXPR_CHAR_LITERAL: fprintf(file, "\n\t#Char literal %c\n", e->literal_value); e->reg = register_alloc(); fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg)); break; case EXPR_TRUE: fprintf(file, "\n\t#True\n"); e->reg = register_alloc(); fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg)); break; case EXPR_FALSE: fprintf(file, "\n\t#False\n"); e->reg = register_alloc(); fprintf(file, "\tMOV $%d, %s\n", e->literal_value, register_name(e->reg)); register_free(e->reg); break; case EXPR_FCALL: if(function_params(e) >= 6) fcall_error(); e->reg = register_alloc(); fprintf(file, "\n\t#Calling function %s\n", e->left->name); if(!e->right){ /* do nothing for no params */ } else if(e->right->kind != EXPR_COMMA){ //this means single argument expr_codegen(e->right, file); fprintf(file, "\n\t#Move Only Argument\n"); fprintf(file, "\tMOV %s, %%rdi\n", register_name(e->right->reg)); register_free(e->right->reg); } else { //multiple parameters struct expr *param = e->right; int param_number = 0; while(param->kind == EXPR_COMMA){ expr_codegen(param->left, file); fprintf(file, "\n\t#Move Argument %d\n", param_number); fprintf(file, "\tMOV %s, ", register_name(param->left->reg)); register_free(param->left->reg); switch(param_number++){ case 0: fprintf(file, "%%rdi"); break; case 1: fprintf(file, "%%rsi"); break; case 2: fprintf(file, "%%rdx"); break; case 3: fprintf(file, "%%rcx"); break; case 4: fprintf(file, "%%r8"); break; case 5: fprintf(file, "%%r9"); break; } fprintf(file, "\n"); param = param->right; } expr_codegen(param, file); fprintf(file, "\n\t#Move Argument %d\n", param_number); fprintf(file, "\tMOV %s, ", register_name(param->reg)); switch(param_number++){ case 0: fprintf(file, "%%rdi"); break; case 1: fprintf(file, "%%rsi"); break; case 2: fprintf(file, "%%rdx"); break; case 3: fprintf(file, "%%rcx"); break; case 4: fprintf(file, "%%r8"); break; case 5: fprintf(file, "%%r9"); break; } fprintf(file, "\n"); register_free(param->reg); } fprintf(file, "\tPUSH %%r10\n"); fprintf(file, "\tPUSH %%r11\n"); fprintf(file, "\n\tCALL %s\n\n", e->left->name); fprintf(file, "\tPOP %%r11\n"); fprintf(file, "\tPOP %%r10\n"); fprintf(file, "\tMOV %%rax, %s\n", register_name(e->reg)); break; case EXPR_PARENS: expr_codegen(e->right, file); e->reg = e->right->reg; break; case EXPR_ARRCALL: //These 4 have to do with arrays case EXPR_ARRINDEX: //We are not implementing arrays for codegen case EXPR_BLOCK: case EXPR_BLOCK_COMMA: array_error(); break; } }
void* operator new[] (size_t size) { return register_alloc(size); }