void emit_jle( assembler_buffer_t * buf, label_t * lab) { emit_jcc(buf, lab, LE); }
void emit_jne( assembler_buffer_t * buf, label_t * lab) { emit_jcc(buf, lab, NEQ); }
static void x86_emit_inst(Inst* inst, int* pc2addr, int rodata_addr) { switch (inst->op) { case MOV: emit_mov(inst->dst.reg, &inst->src); break; case ADD: if (inst->src.type == REG) { emit_1(0x01); emit_reg2(inst->dst.reg, inst->src.reg); } else { emit_2(0x81, 0xc0 + REGNO[inst->dst.reg]); emit_le(inst->src.imm); } emit_2(0x81, 0xe0 + REGNO[inst->dst.reg]); emit_le(0xffffff); break; case SUB: if (inst->src.type == REG) { emit_1(0x29); emit_reg2(inst->dst.reg, inst->src.reg); } else { emit_2(0x81, 0xe8 + REGNO[inst->dst.reg]); emit_le(inst->src.imm); } emit_2(0x81, 0xe0 + REGNO[inst->dst.reg]); emit_le(0xffffff); break; case LOAD: emit_1(0x8b); goto store_load_common; case STORE: emit_1(0x89); store_load_common: if (inst->src.type == REG) { emit_2(4 + (REGNO[inst->dst.reg] * 8), 0x86 + (REGNO[inst->src.reg] * 8)); } else { emit_1(0x86 + (REGNO[inst->dst.reg] * 8)); emit_le(inst->src.imm * 4); } break; case PUTC: // push EDI emit_1(0x57); emit_mov(EDI, &inst->src); // push EAX, ECX, EDX, EBX, EDI emit_5(0x50, 0x51, 0x52, 0x53, 0x57); emit_mov_imm(B, 1); // stdout emit_mov_reg(C, ESP); emit_mov_imm(D, 1); emit_mov_imm(A, 4); // write emit_int80(); // pop EDI, EBX, EDX, ECX, EAX emit_5(0x5f, 0x5b, 0x5a, 0x59, 0x58); // pop EDI emit_1(0x5f); break; case GETC: // push EDI emit_1(0x57); // push EAX, ECX, EDX, EBX emit_4(0x50, 0x51, 0x52, 0x53); // push 0 emit_2(0x6a, 0x00); emit_mov_imm(B, 0); // stdin emit_mov_reg(C, ESP); emit_mov_imm(D, 1); emit_mov_imm(A, 3); // read emit_int80(); // pop EDI emit_1(0x5f); emit_mov_imm(B, 0); // cmp EAX, 1 emit_3(0x83, 0xf8, 0x01); // cmovnz EDI, EBX emit_3(0x0f, 0x45, 0xfb); // pop EBX, EDX, ECX, EAX emit_4(0x5b, 0x5a, 0x59, 0x58); emit_mov_reg(inst->dst.reg, EDI); // pop EDI emit_1(0x5f); break; case EXIT: emit_mov_imm(B, 0); emit_mov_imm(A, 1); // exit emit_int80(); break; case DUMP: break; case EQ: emit_setcc(inst, 0x94); break; case NE: emit_setcc(inst, 0x95); break; case LT: emit_setcc(inst, 0x9c); break; case GT: emit_setcc(inst, 0x9f); break; case LE: emit_setcc(inst, 0x9e); break; case GE: emit_setcc(inst, 0x9d); break; case JEQ: emit_jcc(inst, 0x75, pc2addr, rodata_addr); break; case JNE: emit_jcc(inst, 0x74, pc2addr, rodata_addr); break; case JLT: emit_jcc(inst, 0x7d, pc2addr, rodata_addr); break; case JGT: emit_jcc(inst, 0x7e, pc2addr, rodata_addr); break; case JLE: emit_jcc(inst, 0x7f, pc2addr, rodata_addr); break; case JGE: emit_jcc(inst, 0x7c, pc2addr, rodata_addr); break; case JMP: emit_jcc(inst, 0, pc2addr, rodata_addr); break; default: error("oops"); } }