Exemplo n.º 1
0
void emit_jle(          assembler_buffer_t * buf, label_t * lab) {
    emit_jcc(buf, lab, LE);
}
Exemplo n.º 2
0
void emit_jne(          assembler_buffer_t * buf, label_t * lab) {
    emit_jcc(buf, lab, NEQ);
}
Exemplo n.º 3
0
Arquivo: x86.c Projeto: shen390s/elvm
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");
  }
}