void x86_jcc( struct x86_function *p, enum x86_cc cc, int label ) { int offset = label - (x86_get_label(p) + 2); DUMP_I(cc); if (offset < 0) { /*assert(p->csr - p->store > -offset);*/ if (p->csr - p->store <= -offset) { /* probably out of memory (using the error_overflow buffer) */ return; } } if (offset <= 127 && offset >= -128) { emit_1ub(p, 0x70 + cc); emit_1b(p, (char) offset); } else { offset = label - (x86_get_label(p) + 6); emit_2ub(p, 0x0f, 0x80 + cc); emit_1i(p, offset); } }
void x86_jcc( struct x86_function *p, enum x86_cc cc, unsigned char *label ) { int offset = label - (x86_get_label(p) + 2); if (offset <= 127 && offset >= -128) { emit_1ub(p, 0x70 + cc); emit_1b(p, (char) offset); } else { offset = label - (x86_get_label(p) + 6); emit_2ub(p, 0x0f, 0x80 + cc); emit_1i(p, offset); } }
/** * Immediate group 1 instructions. */ static INLINE void x86_group1_imm( struct x86_function *p, unsigned op, struct x86_reg dst, int imm ) { assert(dst.file == file_REG32); assert(dst.mod == mod_REG); if(-0x80 <= imm && imm < 0x80) { emit_1ub(p, 0x83); emit_modrm_noreg(p, op, dst); emit_1b(p, (char)imm); } else { emit_1ub(p, 0x81); emit_modrm_noreg(p, op, dst); emit_1i(p, imm); } }
/* Build a modRM byte + possible displacement. No treatment of SIB * indexing. BZZT - no way to encode an absolute address. * * This is the "/r" field in the x86 manuals... */ static void emit_modrm( struct x86_function *p, struct x86_reg reg, struct x86_reg regmem ) { unsigned char val = 0; assert(reg.mod == mod_REG); /* TODO: support extended x86-64 registers */ assert(reg.idx < 8); assert(regmem.idx < 8); val |= regmem.mod << 6; /* mod field */ val |= reg.idx << 3; /* reg field */ val |= regmem.idx; /* r/m field */ emit_1ub(p, val); /* Oh-oh we've stumbled into the SIB thing. */ if (regmem.file == file_REG32 && regmem.idx == reg_SP && regmem.mod != mod_REG) { emit_1ub(p, 0x24); /* simplistic! */ } switch (regmem.mod) { case mod_REG: case mod_INDIRECT: break; case mod_DISP8: emit_1b(p, (char) regmem.disp); break; case mod_DISP32: emit_1i(p, regmem.disp); break; default: assert(0); break; } }