void code_compare(FILE *file, RegDesc *registers, char *op, Symbol *result, Symbol *operand1, Symbol *operand2) { debug("%s = %s %s %s", result->name, op, operand1->name, operand2->name); int dest_reg = get_result_register(file, registers, operand1); int source_reg = get_argument_register(file, registers, operand2, dest_reg); debug("Code Compare Dest: %d Source: %d", dest_reg, source_reg); //Compare code_instruction(file, COMPARE, registers[source_reg].name, registers[dest_reg].name); //code_instruction(file, COMPARE, registers[dest_reg].name, registers[source_reg].name); //Get the low bytes char *low = make_low(registers[dest_reg].name); //Get the value code_instruction(file, op, low, NULL); //Now clear remaining bytes code_instruction(file, "movzbl", low, registers[dest_reg].name); //Update clear_register(registers, dest_reg); insert_register(registers, dest_reg, result, TRUE); }
//Here we should make the call, and if we are saving the result, tell the regdesc that void code_call(FILE *file, RegDesc *registers, Symbol *function, Symbol *result) { code_spill_all(file, registers); clear_registers(registers); if (function->external != NULL) { //If this is printf, push the appropriate string if (strcmp(function->external, "printf") == 0) { arg_count++; code_instruction(file, PUSH, "$.LC0", NULL); } //This an external call, so drop the instruction using the linked name code_instruction(file, CALL, function->external, NULL); } else { //This is an internal routine //Therefore, we need to set up the static link int caller_nested = current_scope->symbols->nested; int callee_nested = function->symbols->nested; debug("Static Linking - Caller: %d to Callee: %d", caller_nested, callee_nested); if (caller_nested < callee_nested) { //This is one hop, so we can Load address code_instruction(file, LOAD_ADDRESS, CURRENT_STATIC_LINK, EAX); code_instruction(file, MOVE, EAX, NEXT_STATIC_LINK); } else { code_instruction(file, MOVE, CURRENT_STATIC_LINK, EDI); int i; int hops = caller_nested - callee_nested + 1; for (i = 0; i < hops - 1; i++) code_instruction(file, MOVE, make_relative_address(0, EDI), EDI); code_instruction(file, MOVE, EDI, NEXT_STATIC_LINK); } code_instruction(file, CALL, function->name, NULL); } //Clean up the stack if (arg_count > 0) { code_instruction(file, ADD, make_integer(arg_count * 4), ESP); arg_count = 0; } if (result != NULL) { //Return values are put in eax insert_register(registers, REG_EAX, result, TRUE); } }
void code_unary(FILE *file, RegDesc *registers, char *op, Symbol *result, Symbol *operand) { int dest_reg = get_result_register(file, registers, operand); debug("Code Unary %s Dest: %d", op, dest_reg); code_instruction(file, op, registers[dest_reg].name, NULL); clear_register(registers, dest_reg); insert_register(registers, dest_reg, result, TRUE); }
// result = operand1 op operand2 void code_binary(FILE *file, RegDesc *registers, char *op, Symbol *result, Symbol *operand1, Symbol *operand2) { int dest_reg; if ((strcmp(op, ATT_MOD) == 0) || (strcmp(op, MULTIPLY) == 0) || (strcmp(op, DIVIDE) == 0)) { //Spill eax code_spill_reg(file, registers, REG_EAX); //Set destination dest_reg = REG_EAX; clear_register(registers, dest_reg); code_load_reg(file, registers, REG_EAX, operand1); insert_register(registers, dest_reg, operand1, FALSE); if ((strcmp(op, ATT_MOD) == 0) || (strcmp(op, DIVIDE) == 0)) code_instruction(file, QUADWORD, NULL, NULL); } else { dest_reg = get_result_register(file, registers, operand1); } int source_reg = get_argument_register(file, registers, operand2, dest_reg); debug("Code Binary %s Dest: %d Source: %d", op, dest_reg, source_reg); if (strcmp(op, ATT_MOD) == 0) { code_instruction(file, DIVIDE, registers[source_reg].name, registers[dest_reg].name); clear_register(registers, REG_EDX); insert_register(registers, REG_EDX, result, TRUE); } else { code_instruction(file, op, registers[source_reg].name, registers[dest_reg].name); clear_register(registers, dest_reg); insert_register(registers, dest_reg, result, TRUE); } }
void code_copy(FILE *file, RegDesc *registers, Symbol *result, Symbol *operand1) { int source = get_result_register(file, registers, operand1); insert_register(registers, source, result, TRUE); if (result->is_array_element == TRUE) { code_spill_reg(file, registers, source); } debug("Copied %s to %s Array %d", operand1->name, result->name, result->is_array_element); }
static void convert_ident_tokens() { token_list *tok = tl; /* Step 1: Build trie */ /* Instructions */ insert_token("abs", token_abs); insert_token("add", token_add); insert_token("and", token_and); insert_token("arccos", token_arccos); insert_token("arcsin", token_arcsin); insert_token("arctan", token_arctan); insert_token("beep", token_beep); insert_token("call", token_call); insert_token("chs", token_chs); insert_token("cos", token_cos); insert_token("debug", token_debug); insert_token("dist", token_dist); insert_token("div", token_div); insert_token("drop", token_drop); insert_token("dropall", token_dropall); insert_token("dup", token_dup); insert_token("end", token_end); insert_token("eq", token_eq); insert_token("gt", token_gt); insert_token("icon", token_icon); insert_token("if", token_if); insert_token("ife", token_ife); insert_token("ifeg", token_ifeg); insert_token("ifg", token_ifg); insert_token("jump", token_jump); insert_token("lt", token_lt); insert_token("max", token_max); insert_token("min", token_min); insert_token("mod", token_mod); insert_token("mov", token_mov); insert_token("mul", token_mul); insert_token("ne", token_ne); insert_token("nop", token_nop); insert_token("not", token_not); insert_token("or", token_or); insert_token("peek", token_peek); insert_token("pop", token_pop); insert_token("print", token_print); insert_token("push", token_push); insert_token("random", token_random); insert_token("recall", token_recall); insert_token("return", token_return); insert_token("roll", token_roll); insert_token("setparam", token_setparam); insert_token("sin", token_sin); insert_token("sound", token_sound); insert_token("sqrt", token_sqrt); insert_token("store", token_store); insert_token("sub", token_sub); insert_token("swap", token_swap); insert_token("sync", token_sync); insert_token("tan", token_tan); insert_token("test", token_test); insert_token("vrecall", token_vrecall); insert_token("vstore", token_vstore); insert_token("xor", token_xor); /* Registers */ insert_register("aim", reg_aim); insert_register("bullet", reg_bullet); insert_register("channel", reg_channel); insert_register("chronon", reg_chronon); insert_register("collision", reg_collision); insert_register("damage", reg_damage); insert_register("energy", reg_energy); insert_register("fire", reg_fire); insert_register("friend", reg_friend); insert_register("hellbore", reg_hellbore); insert_register("history", reg_history); insert_register("id", reg_id); insert_register("kills", reg_kills); insert_register("look", reg_look); insert_register("mine", reg_mine); insert_register("missile", reg_missile); insert_register("movex", reg_movex); insert_register("movey", reg_movey); insert_register("nuke", reg_nuke); insert_register("probe", reg_probe); insert_register("radar", reg_radar); insert_register("range", reg_range); insert_register("robots", reg_robots); insert_register("scan", reg_scan); insert_register("shield", reg_shield); insert_register("signal", reg_signal); insert_register("speedx", reg_speedx); insert_register("speedy", reg_speedy); insert_register("stunner", reg_stunner); insert_register("teammates", reg_teammates); insert_register("wall", reg_wall); insert_register("x", reg_x); insert_register("y", reg_y); /* Step 2: Convert tokens */ while( tok != NULL ) { if( tok->t == token_ident ) { if( !convert_ident_token(tok) ) { if( !reg_check(tok) ) { /* Default to label */ tok->t = token_label; } } } tok = tok->next; } }