Commit 5f8ff636 authored by Michael Beck's avatar Michael Beck
Browse files

- fixed fastcall/regparam/thiscall registers for ia32

[r21144]
parent bb2ed499
......@@ -1974,6 +1974,7 @@ typedef enum {
cc_compound_ret = 0x10000000, /**< The method returns a compound type. */
cc_frame_on_caller_stk = 0x20000000, /**< The method did not allocate an own stack frame, instead the
caller must reserve size on its own stack. */
cc_fpreg_param = 0x40000000, /**< Transmit floating point parameters in registers, else the stack is used. */
cc_fixed = (int)0x80000000, /**< The calling convention must not be changed later on */
cc_bits = (0xFF << 24)/**< The calling convention bits. */
} calling_convention;
......
......@@ -39,41 +39,29 @@
#include "bearch_ia32_t.h"
#define MAXNUM_GPREG_ARGS 3
#define MAXNUM_SSE_ARGS 5
#define MAXNUM_SSE_ARGS 8
/* this is the order of the assigned registers usesd for parameter passing */
/* this is the order of the assigned registers used for parameter passing */
const arch_register_t *gpreg_param_reg_std[] = {
&ia32_gp_regs[REG_EAX],
&ia32_gp_regs[REG_EDX],
static const arch_register_t *gpreg_param_reg_fastcall[] = {
&ia32_gp_regs[REG_ECX],
&ia32_gp_regs[REG_EBX],
&ia32_gp_regs[REG_EDI],
&ia32_gp_regs[REG_ESI]
&ia32_gp_regs[REG_EDX],
NULL
};
const arch_register_t *gpreg_param_reg_this[] = {
&ia32_gp_regs[REG_ECX],
static const arch_register_t *gpreg_param_reg_regparam[] = {
&ia32_gp_regs[REG_EAX],
&ia32_gp_regs[REG_EDX],
&ia32_gp_regs[REG_EBX],
&ia32_gp_regs[REG_EDI],
&ia32_gp_regs[REG_ESI]
&ia32_gp_regs[REG_ECX]
};
const arch_register_t *fpreg_sse_param_reg_std[] = {
&ia32_xmm_regs[REG_XMM0],
&ia32_xmm_regs[REG_XMM1],
&ia32_xmm_regs[REG_XMM2],
&ia32_xmm_regs[REG_XMM3],
&ia32_xmm_regs[REG_XMM4],
&ia32_xmm_regs[REG_XMM5],
&ia32_xmm_regs[REG_XMM6],
&ia32_xmm_regs[REG_XMM7]
static const arch_register_t *gpreg_param_reg_this[] = {
&ia32_gp_regs[REG_ECX],
NULL,
NULL
};
const arch_register_t *fpreg_sse_param_reg_this[] = {
NULL, /* in case of a "this" pointer, the first parameter must not be a float */
static const arch_register_t *fpreg_sse_param_reg_std[] = {
&ia32_xmm_regs[REG_XMM0],
&ia32_xmm_regs[REG_XMM1],
&ia32_xmm_regs[REG_XMM2],
......@@ -84,6 +72,9 @@ const arch_register_t *fpreg_sse_param_reg_this[] = {
&ia32_xmm_regs[REG_XMM7]
};
static const arch_register_t *fpreg_sse_param_reg_this[] = {
NULL, /* in case of a "this" pointer, the first parameter must not be a float */
};
/* Mapping to store registers in firm nodes */
......@@ -165,30 +156,39 @@ const char *ia32_get_mapped_reg_name(pmap *reg_map, const arch_register_t *reg)
const arch_register_t *ia32_get_RegParam_reg(unsigned cc, size_t nr,
const ir_mode *mode)
{
if(! (cc & cc_reg_param))
if (! (cc & cc_reg_param))
return NULL;
if(mode_is_float(mode)) {
if(!ia32_cg_config.use_sse2)
if (mode_is_float(mode)) {
if (!ia32_cg_config.use_sse2 || (cc & cc_fpreg_param) == 0)
return NULL;
if(nr >= MAXNUM_SSE_ARGS)
if (nr >= MAXNUM_SSE_ARGS)
return NULL;
if(cc & cc_this_call) {
if (cc & cc_this_call) {
return fpreg_sse_param_reg_this[nr];
}
return fpreg_sse_param_reg_std[nr];
} else if(mode_is_int(mode) || mode_is_reference(mode)) {
if(get_mode_size_bits(mode) > 32)
} else if (mode_is_int(mode) || mode_is_reference(mode)) {
unsigned num_regparam;
if (get_mode_size_bits(mode) > 32)
return NULL;
if(nr >= MAXNUM_GPREG_ARGS)
if (nr >= MAXNUM_GPREG_ARGS)
return NULL;
if(cc & cc_this_call) {
if (cc & cc_this_call) {
return gpreg_param_reg_this[nr];
}
return gpreg_param_reg_std[nr];
num_regparam = cc & ~cc_bits;
if (num_regparam == 0) {
/* default fastcall */
return gpreg_param_reg_fastcall[nr];
}
if (nr < num_regparam)
return gpreg_param_reg_regparam[nr];
return NULL;
}
panic("unknown argument mode");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment