From bb2ed4992625af9b6ba2ded2be2e36f8afa1cdea Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Wed, 13 Aug 2008 10:18:56 +0000 Subject: [PATCH] - Introduce cc_fixed: the calling convention must not be changed later on - Handle cc_callee_clear_stk in the x86 backend [r21138] --- include/libfirm/typerep.h | 1 + ir/be/ia32/bearch_ia32.c | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/libfirm/typerep.h b/include/libfirm/typerep.h index 40ab36b39..495a1f350 100644 --- a/include/libfirm/typerep.h +++ b/include/libfirm/typerep.h @@ -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_fixed = (int)0x80000000, /**< The calling convention must not be changed later on */ cc_bits = (0xFF << 24)/**< The calling convention bits. */ } calling_convention; diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index c1461e1b1..e52ee6dbe 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -1864,7 +1864,9 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, ir_mode *mode; unsigned cc; int n, i, regnum; + int pop_amount = 0; be_abi_call_flags_t call_flags = be_abi_call_get_flags(abi); + (void) self; /* set abi flags for calls */ @@ -1882,8 +1884,9 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, cc = cc_cdecl_set; } else { cc = get_method_calling_convention(method_type); - if (get_method_additional_properties(method_type) & mtp_property_private - && (ia32_cg_config.optimize_cc)) { + if (!(cc & cc_fixed) && + get_method_additional_properties(method_type) & mtp_property_private && + ia32_cg_config.optimize_cc) { /* set the calling conventions to register parameter */ cc = (cc & ~cc_bits) | cc_reg_param; } @@ -1892,7 +1895,7 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, /* we have to pop the shadow parameter ourself for compound calls */ if( (get_method_calling_convention(method_type) & cc_compound_ret) && !(cc & cc_reg_param)) { - be_abi_call_set_pop(abi, get_mode_size_bytes(mode_P_data)); + pop_amount += get_mode_size_bytes(mode_P_data); } n = get_method_n_params(method_type); @@ -1911,12 +1914,21 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, } else { /* Micro optimisation: if the mode is shorter than 4 bytes, load 4 bytes. * movl has a shorter opcode than mov[sz][bw]l */ - ir_mode *load_mode = mode; - if (mode != NULL && get_mode_size_bytes(mode) < 4) load_mode = mode_Iu; + ir_mode *load_mode = mode; + unsigned size = get_mode_size_bytes(mode); + + if (cc & cc_callee_clear_stk) { + pop_amount += (size + 3U) & ~3U; + } + + if (mode != NULL && size < 4) load_mode = mode_Iu; + be_abi_call_param_stack(abi, i, load_mode, 4, 0, 0); } } + be_abi_call_set_pop(abi, pop_amount); + /* set return registers */ n = get_method_n_ress(method_type); -- 2.20.1