Пример #1
0
int x86_jmp_forward( struct x86_function *p)
{
   DUMP();
   emit_1ub(p, 0xe9);
   emit_1i(p, 0);
   return x86_get_label(p);
}
Пример #2
0
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);
   }
}
Пример #3
0
/* Always use a 32bit offset for forward jumps:
 */
unsigned char *x86_jcc_forward( struct x86_function *p,
			  enum x86_cc cc )
{
   emit_2ub(p, 0x0f, 0x80 + cc);
   emit_1i(p, 0);
   return x86_get_label(p);
}
Пример #4
0
void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm )
{
   DUMP_RI( dst, imm );
   assert(dst.file == file_REG32);
   assert(dst.mod == mod_REG);
   emit_1ub(p, 0xb8 + dst.idx);
   emit_1i(p, imm);
}
Пример #5
0
/* Always use a 32bit offset for forward jumps:
 */
int x86_jcc_forward( struct x86_function *p,
                     enum x86_cc cc )
{
   DUMP_I(cc);
   emit_2ub(p, 0x0f, 0x80 + cc);
   emit_1i(p, 0);
   return x86_get_label(p);
}
Пример #6
0
void x86_push_imm32( struct x86_function *p,
                     int imm32 )
{
   DUMP_I( imm32 );
   emit_1ub(p, 0x68);
   emit_1i(p,  imm32);

   p->stack_offset += 4;
}
Пример #7
0
void x86_mov_imm( struct x86_function *p, struct x86_reg dst, int imm )
{
   DUMP_RI( dst, imm );
   if(dst.mod == mod_REG)
      x86_mov_reg_imm(p, dst, imm);
   else
   {
      emit_1ub(p, 0xc7);
      emit_modrm_noreg(p, 0, dst);
      emit_1i(p, imm);
   }
}
Пример #8
0
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);
   }
}
Пример #9
0
/**
 * 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);
   }
}
Пример #10
0
/* 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;
   }
}
Пример #11
0
void x86_jmp( struct x86_function *p, int label)
{
   DUMP_I( label );
   emit_1ub(p, 0xe9);
   emit_1i(p, label - x86_get_label(p) - 4);
}
Пример #12
0
/* michal:
 * Temporary. As I need immediate operands, and dont want to mess with the codegen,
 * I load the immediate into general purpose register and use it.
 */
void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm )
{
   assert(dst.mod == mod_REG);
   emit_1ub(p, 0xb8 + dst.idx);
   emit_1i(p, imm);
}
Пример #13
0
/* This doesn't work once we start reallocating & copying the
 * generated code on buffer fills, because the call is relative to the
 * current pc.
 */
void x86_call( struct x86_function *p, void (*label)())
{
   emit_1ub(p, 0xe8);
   emit_1i(p, cptr(label) - x86_get_label(p) - 4);
}
Пример #14
0
void x86_jmp( struct x86_function *p, unsigned char *label)
{
   emit_1ub(p, 0xe9);
   emit_1i(p, label - x86_get_label(p) - 4);
}
Пример #15
0
unsigned char *x86_call_forward( struct x86_function *p)
{
   emit_1ub(p, 0xe8);
   emit_1i(p, 0);
   return x86_get_label(p);
}