コード例 #1
0
ファイル: i386-gen.c プロジェクト: cartman300/TCC.NET
/* XXX: handle long long case */
ST_FUNC void gen_cvt_ftoi(int t)
{
	int r, r2, size;
	Sym *sym;
	CType ushort_type;

	ushort_type.t = VT_SHORT | VT_UNSIGNED;
	ushort_type.ref = 0;

	gv(RC_FLOAT);
	if (t != VT_INT)
		size = 8;
	else 
		size = 4;

	o(0x2dd9); /* ldcw xxx */
	sym = external_global_sym(TOK___tcc_int_fpu_control, 
		&ushort_type, VT_LVAL);
	greloc(cur_text_section, sym, 
		ind, R_386_32);
	gen_le32(0);

	oad(0xec81, size); /* sub $xxx, %esp */
	if (size == 4)
		o(0x1cdb); /* fistpl */
	else
		o(0x3cdf); /* fistpll */
	o(0x24);
	o(0x2dd9); /* ldcw xxx */
	sym = external_global_sym(TOK___tcc_fpu_control, 
		&ushort_type, VT_LVAL);
	greloc(cur_text_section, sym, 
		ind, R_386_32);
	gen_le32(0);

	r = get_reg(RC_INT);
	o(0x58 + r); /* pop r */
	if (size == 8) {
		if (t == VT_LLONG) {
			vtop->r = r; /* mark reg as used */
			r2 = get_reg(RC_INT);
			o(0x58 + r2); /* pop r2 */
			vtop->r2 = r2;
		} else {
			o(0x04c483); /* add $4, %esp */
		}
	}
	vtop->r = r;
}
コード例 #2
0
ファイル: codegen386.c プロジェクト: HarryR/sanos
// Output constant with relocation if 'r & VT_SYM' is true
void gen_addr32(int r, Sym *sym, int c) {
  if (r & VT_SYM) {
    greloc(sym, c, 0);
  } else {
    gen_le32(c);
  }
}
コード例 #3
0
ファイル: codegen386.c プロジェクト: HarryR/sanos
// Convert fp to int 't' type
// TODO: handle long long case
void gen_cvt_ftoi(int t) {
  int r, r2, size;
  CType ushort_type;

  ushort_type.t = VT_SHORT | VT_UNSIGNED;

  gv(RC_FLOAT);
  if (t != VT_INT) {
    size = 8;
  } else {
    size = 4;
  }

  o(0x2dd9); // ldcw xxx
  greloc(external_global_sym(TOK___tcc_int_fpu_control, &ushort_type, VT_LVAL), 0, 0);
  
  oad(0xec81, size); // sub $xxx, %esp
  if (size == 4)  {
    o(0x1cdb); // fistpl
  } else {
    o(0x3cdf); // fistpll
  }
  o(0x24);
  o(0x2dd9); // ldcw xxx
  greloc(external_global_sym(TOK___tcc_fpu_control, &ushort_type, VT_LVAL), 0, 0);

  r = get_reg(RC_INT);
  o(0x58 + r); // pop r
  if (size == 8) {
    if (t == VT_LLONG) {
      vtop->r = r; // Mark reg as used
      r2 = get_reg(RC_INT);
      o(0x58 + r2); // pop r2
      vtop->r2 = r2;
    } else {
      o(0x04c483); // add $4, %esp
    }
  }
  vtop->r = r;
}
コード例 #4
0
ファイル: codegen386.c プロジェクト: HarryR/sanos
// 'is_jmp' is '1' if it is a jump
void gcall_or_jmp(int is_jmp) {
  int r;
  Sym *sym;

  if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
    // Constant case
    o(0xe8 + is_jmp); // call/jmp im
    sym = NULL;
    if (vtop->r & VT_SYM) sym = vtop->sym;
    greloc(sym, vtop->c.ul - 4, 1);
  } else {
    // Otherwise, indirect call
    r = gv(RC_INT);
    o(0xff); // call/jmp *r
    o(0xd0 + r + (is_jmp << 4));
  }
}
コード例 #5
0
ファイル: i386-gen.c プロジェクト: 00shiv/Nimrod
/* generate a bounded pointer addition */
void gen_bounded_ptr_add(void)
{
    Sym *sym;

    /* prepare fast i386 function call (args in eax and edx) */
    gv2(RC_EAX, RC_EDX);
    /* save all temporary registers */
    vtop -= 2;
    save_regs(0);
    /* do a fast function call */
    sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
    greloc(cur_text_section, sym, 
           ind + 1, R_386_PC32);
    oad(0xe8, -4);
    /* returned pointer is in eax */
    vtop++;
    vtop->r = TREG_EAX | VT_BOUNDED;
    /* address of bounding function call point */
    vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); 
}
コード例 #6
0
ファイル: i386-gen.c プロジェクト: 00shiv/Nimrod
/* 'is_jmp' is '1' if it is a jump */
static void gcall_or_jmp(int is_jmp)
{
    int r;
    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
        /* constant case */
        if (vtop->r & VT_SYM) {
            /* relocation case */
            greloc(cur_text_section, vtop->sym, 
                   ind + 1, R_386_PC32);
        } else {
            /* put an empty PC32 relocation */
            put_elf_reloc(symtab_section, cur_text_section, 
                          ind + 1, R_386_PC32, 0);
        }
        oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
    } else {
        /* otherwise, indirect call */
        r = gv(RC_INT);
        o(0xff); /* call/jmp *r */
        o(0xd0 + r + (is_jmp << 4));
    }
}
コード例 #7
0
ファイル: i386-gen.c プロジェクト: 00shiv/Nimrod
/* generate function epilog */
void gfunc_epilog(void)
{
    int v, saved_ind;

#ifdef CONFIG_TCC_BCHECK
    if (tcc_state->do_bounds_check
     && func_bound_offset != lbounds_section->data_offset) {
        int saved_ind;
        int *bounds_ptr;
        Sym *sym, *sym_data;
        /* add end of table info */
        bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
        *bounds_ptr = 0;
        /* generate bound local allocation */
        saved_ind = ind;
        ind = func_sub_sp_offset;
        sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
                               func_bound_offset, lbounds_section->data_offset);
        greloc(cur_text_section, sym_data,
               ind + 1, R_386_32);
        oad(0xb8, 0); /* mov %eax, xxx */
        sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
        greloc(cur_text_section, sym, 
               ind + 1, R_386_PC32);
        oad(0xe8, -4);
        ind = saved_ind;
        /* generate bound check local freeing */
        o(0x5250); /* save returned value, if any */
        greloc(cur_text_section, sym_data,
               ind + 1, R_386_32);
        oad(0xb8, 0); /* mov %eax, xxx */
        sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
        greloc(cur_text_section, sym, 
               ind + 1, R_386_PC32);
        oad(0xe8, -4);
        o(0x585a); /* restore returned value, if any */
    }
#endif
    o(0xc9); /* leave */
    if (func_ret_sub == 0) {
        o(0xc3); /* ret */
    } else {
        o(0xc2); /* ret n */
        g(func_ret_sub);
        g(func_ret_sub >> 8);
    }
    /* align local size to word & save local variables */
    
    v = (-loc + 3) & -4; 
    saved_ind = ind;
    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
#ifdef TCC_TARGET_PE
    if (v >= 4096) {
        Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
        oad(0xb8, v); /* mov stacksize, %eax */
        oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
        greloc(cur_text_section, sym, ind-4, R_386_PC32);
    } else
#endif
    {
        o(0xe58955);  /* push %ebp, mov %esp, %ebp */
        o(0xec81);  /* sub esp, stacksize */
        gen_le32(v);
#if FUNC_PROLOG_SIZE == 10
        o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
#endif
    }
    ind = saved_ind;
}
コード例 #8
0
ファイル: i386-gen.c プロジェクト: 00shiv/Nimrod
/* output constant with relocation if 'r & VT_SYM' is true */
static void gen_addr32(int r, Sym *sym, int c)
{
    if (r & VT_SYM)
        greloc(cur_text_section, sym, ind, R_386_32);
    gen_le32(c);
}
コード例 #9
0
ファイル: i386-gen.c プロジェクト: cartman300/TCC.NET
ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
{
	if (r & VT_SYM)
		greloc(cur_text_section, sym, ind, R_386_PC32);
	gen_le32(c - 4);
}