From c6b8fb2a7420f369dd8688b6855688ad68eecfc4 Mon Sep 17 00:00:00 2001 From: Paulo Andrade Date: Sat, 6 Jun 2015 22:28:20 -0300 Subject: [PATCH] ia64: Pass all tests for variadic jit functions * lib/jit_ia64-cpu.c: Search backward for the last output register used, otherwise would stop too early if a float argument used the slot. Correct offset of first va_list argument, and use proper va_list abi. * lib/jit_ia64-fpu.c: Add new functions to move a gpr to a fpr register, to counterpart the ones that move a fpr to a gpr. These are required to properly implement jit_getarg*_{f,d} on complex prototypes, or variadic jit functions. * lib/jit_ia64-sz.c: Update for support to jit variadic functions. * lib/jit_ia64.c: Implement proper abi for variadic jit functions. --- ChangeLog | 20 +++ lib/jit_ia64-cpu.c | 42 ++--- lib/jit_ia64-fpu.c | 39 +++-- lib/jit_ia64-sz.c | 398 ++++++++++++++++++++++----------------------- lib/jit_ia64.c | 100 ++++++++---- 5 files changed, 324 insertions(+), 275 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34eeefa7f..0af9b4673 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2015-06-06 Paulo Andrade + + * lib/jit_ia64-cpu.c: Search backward for the last output + register used, otherwise would stop too early if a float + argument used the slot. + Correct offset of first va_list argument, and use proper + va_list abi. + + * lib/jit_ia64-fpu.c: Add new functions to move a gpr + to a fpr register, to counterpart the ones that move a + fpr to a gpr. These are required to properly implement + jit_getarg*_{f,d} on complex prototypes, or variadic + jit functions. + + * lib/jit_ia64-sz.c: Update for support to jit variadic + functions. + + * lib/jit_ia64.c: Implement proper abi for variadic + jit functions. + 2015-06-04 Paulo Andrade * lib/jit_rewind.c: New file implementing generic functions diff --git a/lib/jit_ia64-cpu.c b/lib/jit_ia64-cpu.c index 831d3232b..680ea0966 100644 --- a/lib/jit_ia64-cpu.c +++ b/lib/jit_ia64-cpu.c @@ -5210,11 +5210,11 @@ _prolog(jit_state_t *_jit, jit_node_t *node) /* How many out argument registers required? */ if (!_jitc->function->define_frame) { - for (reg = _OUT0; reg <= _OUT7; reg++) { - if (!jit_regset_tstbit(&_jitc->function->regset, reg)) + for (reg = _OUT7; reg >= _OUT0; --reg) { + if (jit_regset_tstbit(&_jitc->function->regset, reg)) break; } - rout = reg - _OUT0; + rout = (reg + 1) - _OUT0; } else rout = 8; @@ -5269,7 +5269,7 @@ _prolog(jit_state_t *_jit, jit_node_t *node) if (_jitc->function->self.call & jit_call_varargs) { for (reg = _jitc->function->vagp; reg < 8; ++reg) - stxi(96 + reg * 8, GR_4, GR_32 + reg); + stxi(112 + reg * 8, GR_4, GR_32 + reg); } } @@ -5314,40 +5314,22 @@ _epilog(jit_state_t *_jit, jit_node_t *node) static void _vastart(jit_state_t *_jit, jit_int32_t r0) { - jit_int32_t reg; - assert(_jitc->function->self.call & jit_call_varargs); - - /* Return jit_va_list_t in the register argument */ - addi(r0, GR_4, _jitc->function->vaoff); - reg = jit_get_reg(jit_class_gpr); - - /* Initialize stack pointer to the first stack argument. */ - addi(rn(reg), GR_4, 96 + _jitc->function->vagp * 8); - stxi(offsetof(jit_va_list_t, stack), r0, rn(reg)); - - jit_unget_reg(reg); + /* Initialize va_list to the first stack argument. */ + if (_jitc->function->vagp < 8) + addi(r0, GR_4, 112 + _jitc->function->vagp * 8); + else + addi(r0, GR_4, _jitc->function->self.size); } static void _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { - jit_int32_t reg; - assert(_jitc->function->self.call & jit_call_varargs); - reg = jit_get_reg(jit_class_gpr); - - /* Load varargs stack pointer. */ - ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack)); - /* Load argument. */ - ldr(r0, rn(reg)); - - /* Update vararg stack pointer. */ - addi(rn(reg), rn(reg), 8); - stxi(offsetof(jit_va_list_t, stack), r1, rn(reg)); - - jit_unget_reg(reg); + ldr(r0, r1); + /* Update va_list. */ + addi(r1, r1, 8); } static void diff --git a/lib/jit_ia64-fpu.c b/lib/jit_ia64-fpu.c index a539bfd52..a49a72def 100644 --- a/lib/jit_ia64-fpu.c +++ b/lib/jit_ia64-fpu.c @@ -435,8 +435,12 @@ static void F16_(jit_state_t*,jit_word_t, static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); #define movi_d(r0,i0) _movi_d(_jit,r0,i0) static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t*); +#define movr_w_f(r0,r1) _movr_w_f(_jit,r0,r1) +static void _movr_w_f(jit_state_t*,jit_int32_t,jit_int32_t); #define movr_f_w(r0,r1) _movr_f_w(_jit,r0,r1) static void _movr_f_w(jit_state_t*,jit_int32_t,jit_int32_t); +#define movr_w_d(r0,r1) _movr_w_d(_jit,r0,r1) +static void _movr_w_d(jit_state_t*,jit_int32_t,jit_int32_t); #define movr_d_w(r0,r1) _movr_d_w(_jit,r0,r1) static void _movr_d_w(jit_state_t*,jit_int32_t,jit_int32_t); #define movi_f_w(r0,i0) _movi_f_w(_jit,r0,i0) @@ -1049,6 +1053,15 @@ _movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) ldi_d(r0, (jit_word_t)i0); } +static void +_movr_w_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + /* Should be used only in this case (with out0 == 120) */ + if (r1 >= 120) + r1 = _jitc->rout + (r1 - 120); + SETF_S(r0, r1); +} + static void _movr_f_w(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { @@ -1074,6 +1087,15 @@ _movi_f_w(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) ldi_i(r0, (jit_word_t)i0); } +static void +_movr_w_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + /* Should be used only in this case (with out0 == 120) */ + if (r1 >= 120) + r1 = _jitc->rout + (r1 - 120); + SETF_D(r0, r1); +} + static void _movr_d_w(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { @@ -1731,21 +1753,10 @@ dbopi(unord) static void _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { - jit_int32_t reg; - assert(_jitc->function->self.call & jit_call_varargs); - reg = jit_get_reg(jit_class_gpr); - - /* Load varargs stack pointer. */ - ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack)); - /* Load argument. */ - ldr_d(r0, rn(reg)); - - /* Update vararg stack pointer. */ - addi(rn(reg), rn(reg), 8); - stxi(offsetof(jit_va_list_t, stack), r1, rn(reg)); - - jit_unget_reg(reg); + ldr_d(r0, r1); + /* Update va_list. */ + addi(r1, r1, 8); } #endif diff --git a/lib/jit_ia64-sz.c b/lib/jit_ia64-sz.c index d954c3031..89c7fd7c2 100644 --- a/lib/jit_ia64-sz.c +++ b/lib/jit_ia64-sz.c @@ -1,15 +1,15 @@ #if __WORDSIZE == 64 -#define JIT_INSTR_MAX 144 +#define JIT_INSTR_MAX 224 0, /* data */ 0, /* live */ 0, /* align */ 0, /* save */ 0, /* load */ - 16, /* #name */ - 16, /* #note */ - 48, /* label */ - 128, /* prolog */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 224, /* prolog */ 0, /* ellipsis */ 0, /* allocai */ 0, /* allocar */ @@ -23,41 +23,41 @@ 0, /* getarg_l */ 0, /* putargr */ 0, /* putargi */ - 0, /* va_start */ - 0, /* va_arg */ - 0, /* va_arg_d */ + 16, /* va_start */ + 32, /* va_arg */ + 32, /* va_arg_d */ 0, /* va_end */ 16, /* addr */ 32, /* addi */ - 48, /* addcr */ + 32, /* addcr */ 48, /* addci */ 64, /* addxr */ 64, /* addxi */ 16, /* subr */ 32, /* subi */ - 48, /* subcr */ + 32, /* subcr */ 48, /* subci */ 64, /* subxr */ 64, /* subxi */ - 48, /* rsbi */ - 32, /* mulr */ - 48, /* muli */ - 96, /* qmulr */ - 80, /* qmuli */ - 96, /* qmulr_u */ - 80, /* qmuli_u */ - 64, /* divr */ - 80, /* divi */ - 64, /* divr_u */ - 80, /* divi_u */ - 128, /* qdivr */ - 112, /* qdivi */ - 128, /* qdivr_u */ - 112, /* qdivi_u */ - 64, /* remr */ - 80, /* remi */ - 64, /* remr_u */ - 80, /* remi_u */ + 32, /* rsbi */ + 48, /* mulr */ + 64, /* muli */ + 112, /* qmulr */ + 112, /* qmuli */ + 112, /* qmulr_u */ + 112, /* qmuli_u */ + 80, /* divr */ + 96, /* divi */ + 80, /* divr_u */ + 96, /* divi_u */ + 144, /* qdivr */ + 144, /* qdivi */ + 144, /* qdivr_u */ + 144, /* qdivi_u */ + 80, /* remr */ + 96, /* remi */ + 80, /* remr_u */ + 96, /* remi_u */ 16, /* andr */ 32, /* andi */ 16, /* orr */ @@ -71,52 +71,52 @@ 16, /* rshr_u */ 16, /* rshi_u */ 16, /* negr */ - 0, /* comr */ - 16, /* ltr */ - 16, /* lti */ - 16, /* ltr_u */ - 16, /* lti_u */ - 16, /* ler */ - 16, /* lei */ - 16, /* ler_u */ - 16, /* lei_u */ - 16, /* eqr */ - 16, /* eqi */ - 16, /* ger */ - 16, /* gei */ - 16, /* ger_u */ - 16, /* gei_u */ - 16, /* gtr */ - 16, /* gti */ - 16, /* gtr_u */ - 16, /* gti_u */ - 16, /* ner */ - 16, /* nei */ + 16, /* comr */ + 32, /* ltr */ + 32, /* lti */ + 32, /* ltr_u */ + 32, /* lti_u */ + 32, /* ler */ + 32, /* lei */ + 32, /* ler_u */ + 32, /* lei_u */ + 32, /* eqr */ + 32, /* eqi */ + 32, /* ger */ + 32, /* gei */ + 32, /* ger_u */ + 32, /* gei_u */ + 32, /* gtr */ + 32, /* gti */ + 32, /* gtr_u */ + 32, /* gti_u */ + 32, /* ner */ + 32, /* nei */ 16, /* movr */ - 32, /* movi */ + 16, /* movi */ 16, /* extr_c */ 16, /* extr_uc */ 16, /* extr_s */ 16, /* extr_us */ 16, /* extr_i */ 16, /* extr_ui */ - 16, /* htonr_us */ - 16, /* htonr_ui */ + 64, /* htonr_us */ + 160, /* htonr_ui */ 16, /* htonr_ul */ 16, /* ldr_c */ 32, /* ldi_c */ - 0, /* ldr_uc */ - 16, /* ldi_uc */ + 16, /* ldr_uc */ + 32, /* ldi_uc */ 16, /* ldr_s */ 32, /* ldi_s */ - 0, /* ldr_us */ - 16, /* ldi_us */ + 16, /* ldr_us */ + 32, /* ldi_us */ 16, /* ldr_i */ 32, /* ldi_i */ - 0, /* ldr_ui */ - 16, /* ldi_ui */ + 16, /* ldr_ui */ + 32, /* ldi_ui */ 16, /* ldr_l */ - 16, /* ldi_l */ + 32, /* ldi_l */ 32, /* ldxr_c */ 48, /* ldxi_c */ 16, /* ldxr_uc */ @@ -133,49 +133,49 @@ 32, /* ldxi_l */ 16, /* str_c */ 32, /* sti_c */ - 0, /* str_s */ + 16, /* str_s */ 32, /* sti_s */ 16, /* str_i */ 32, /* sti_i */ - 0, /* str_l */ + 16, /* str_l */ 32, /* sti_l */ 16, /* stxr_c */ - 16, /* stxi_c */ - 32, /* stxr_s */ - 16, /* stxi_s */ + 32, /* stxi_c */ + 16, /* stxr_s */ + 32, /* stxi_s */ 16, /* stxr_i */ - 16, /* stxi_i */ - 32, /* stxr_l */ - 16, /* stxi_l */ - 16, /* bltr */ - 16, /* blti */ - 16, /* bltr_u */ + 32, /* stxi_i */ + 16, /* stxr_l */ + 32, /* stxi_l */ + 32, /* bltr */ + 32, /* blti */ + 32, /* bltr_u */ 32, /* blti_u */ 32, /* bler */ 32, /* blei */ 32, /* bler_u */ - 16, /* blei_u */ - 64, /* beqr */ - 64, /* beqi */ + 32, /* blei_u */ + 32, /* beqr */ + 48, /* beqi */ 32, /* bger */ - 48, /* bgei */ + 32, /* bgei */ 32, /* bger_u */ - 16, /* bgei_u */ - 16, /* bgtr */ - 16, /* bgti */ - 16, /* bgtr_u */ - 16, /* bgti_u */ - 64, /* bner */ - 64, /* bnei */ + 32, /* bgei_u */ + 32, /* bgtr */ + 32, /* bgti */ + 32, /* bgtr_u */ + 32, /* bgti_u */ + 32, /* bner */ + 48, /* bnei */ 32, /* bmsr */ - 32, /* bmsi */ + 48, /* bmsi */ 32, /* bmcr */ - 32, /* bmci */ - 112, /* boaddr */ + 48, /* bmci */ + 96, /* boaddr */ 112, /* boaddi */ 64, /* boaddr_u */ 64, /* boaddi_u */ - 112, /* bxaddr */ + 96, /* bxaddr */ 112, /* bxaddi */ 64, /* bxaddr_u */ 64, /* bxaddi_u */ @@ -187,10 +187,10 @@ 112, /* bxsubi */ 64, /* bxsubr_u */ 64, /* bxsubi_u */ - 0, /* jmpr */ - 48, /* jmpi */ + 16, /* jmpr */ + 16, /* jmpi */ 32, /* callr */ - 64, /* calli */ + 48, /* calli */ 0, /* prepare */ 0, /* pushargr */ 0, /* pushargi */ @@ -206,90 +206,90 @@ 0, /* retval_i */ 0, /* retval_ui */ 0, /* retval_l */ - 144, /* epilog */ + 128, /* epilog */ 0, /* arg_f */ 0, /* getarg_f */ 0, /* putargr_f */ 0, /* putargi_f */ - 0, /* addr_f */ - 32, /* addi_f */ + 16, /* addr_f */ + 48, /* addi_f */ 16, /* subr_f */ - 16, /* subi_f */ - 16, /* rsbi_f */ - 0, /* mulr_f */ - 16, /* muli_f */ - 144, /* divr_f */ - 144, /* divi_f */ + 48, /* subi_f */ + 48, /* rsbi_f */ + 16, /* mulr_f */ + 48, /* muli_f */ + 160, /* divr_f */ + 192, /* divi_f */ 16, /* negr_f */ 16, /* absr_f */ 80, /* sqrtr_f */ - 16, /* ltr_f */ - 48, /* lti_f */ - 16, /* ler_f */ - 48, /* lei_f */ - 16, /* eqr_f */ - 48, /* eqi_f */ - 16, /* ger_f */ - 48, /* gei_f */ - 16, /* gtr_f */ - 48, /* gti_f */ - 16, /* ner_f */ - 48, /* nei_f */ - 16, /* unltr_f */ - 48, /* unlti_f */ - 16, /* unler_f */ - 48, /* unlei_f */ + 32, /* ltr_f */ + 64, /* lti_f */ + 32, /* ler_f */ + 64, /* lei_f */ + 32, /* eqr_f */ + 64, /* eqi_f */ + 32, /* ger_f */ + 64, /* gei_f */ + 32, /* gtr_f */ + 64, /* gti_f */ + 32, /* ner_f */ + 64, /* nei_f */ + 32, /* unltr_f */ + 64, /* unlti_f */ + 32, /* unler_f */ + 64, /* unlei_f */ 48, /* uneqr_f */ - 80, /* uneqi_f */ - 16, /* unger_f */ - 48, /* ungei_f */ - 16, /* ungtr_f */ - 48, /* ungti_f */ + 96, /* uneqi_f */ + 32, /* unger_f */ + 64, /* ungei_f */ + 32, /* ungtr_f */ + 64, /* ungti_f */ 48, /* ltgtr_f */ - 80, /* ltgti_f */ - 16, /* ordr_f */ - 48, /* ordi_f */ - 16, /* unordr_f */ - 48, /* unordi_f */ + 96, /* ltgti_f */ + 32, /* ordr_f */ + 64, /* ordi_f */ + 32, /* unordr_f */ + 64, /* unordi_f */ 32, /* truncr_f_i */ 32, /* truncr_f_l */ - 32, /* extr_f */ + 48, /* extr_f */ 16, /* extr_d_f */ 16, /* movr_f */ - 48, /* movi_f */ + 32, /* movi_f */ 16, /* ldr_f */ - 16, /* ldi_f */ - 0, /* ldxr_f */ + 32, /* ldi_f */ + 16, /* ldxr_f */ 32, /* ldxi_f */ 16, /* str_f */ - 16, /* sti_f */ + 32, /* sti_f */ 16, /* stxr_f */ - 16, /* stxi_f */ + 32, /* stxi_f */ 32, /* bltr_f */ 64, /* blti_f */ - 48, /* bler_f */ + 32, /* bler_f */ 64, /* blei_f */ - 64, /* beqr_f */ - 96, /* beqi_f */ - 48, /* bger_f */ + 32, /* beqr_f */ + 64, /* beqi_f */ + 32, /* bger_f */ 64, /* bgei_f */ 32, /* bgtr_f */ 64, /* bgti_f */ - 48, /* bner_f */ + 32, /* bner_f */ 64, /* bnei_f */ - 48, /* bunltr_f */ + 32, /* bunltr_f */ 64, /* bunlti_f */ - 48, /* bunler_f */ + 32, /* bunler_f */ 64, /* bunlei_f */ - 112, /* buneqr_f */ - 144, /* buneqi_f */ - 48, /* bunger_f */ + 80, /* buneqr_f */ + 112, /* buneqi_f */ + 32, /* bunger_f */ 64, /* bungei_f */ - 48, /* bungtr_f */ + 32, /* bungtr_f */ 64, /* bungti_f */ - 96, /* bltgtr_f */ - 128, /* bltgti_f */ - 48, /* bordr_f */ + 80, /* bltgtr_f */ + 112, /* bltgti_f */ + 32, /* bordr_f */ 64, /* bordi_f */ 32, /* bunordr_f */ 64, /* bunordi_f */ @@ -302,85 +302,85 @@ 0, /* getarg_d */ 0, /* putargr_d */ 0, /* putargi_d */ - 0, /* addr_d */ - 32, /* addi_d */ + 16, /* addr_d */ + 48, /* addi_d */ 16, /* subr_d */ - 16, /* subi_d */ - 16, /* rsbi_d */ - 0, /* mulr_d */ - 16, /* muli_d */ - 128, /* divr_d */ - 144, /* divi_d */ + 48, /* subi_d */ + 48, /* rsbi_d */ + 16, /* mulr_d */ + 48, /* muli_d */ + 160, /* divr_d */ + 192, /* divi_d */ 16, /* negr_d */ 16, /* absr_d */ 80, /* sqrtr_d */ - 16, /* ltr_d */ - 48, /* lti_d */ - 16, /* ler_d */ - 48, /* lei_d */ - 16, /* eqr_d */ - 48, /* eqi_d */ - 16, /* ger_d */ - 48, /* gei_d */ - 16, /* gtr_d */ - 48, /* gti_d */ - 16, /* ner_d */ - 48, /* nei_d */ - 16, /* unltr_d */ - 48, /* unlti_d */ - 16, /* unler_d */ - 48, /* unlei_d */ + 32, /* ltr_d */ + 64, /* lti_d */ + 32, /* ler_d */ + 64, /* lei_d */ + 32, /* eqr_d */ + 64, /* eqi_d */ + 32, /* ger_d */ + 64, /* gei_d */ + 32, /* gtr_d */ + 64, /* gti_d */ + 32, /* ner_d */ + 64, /* nei_d */ + 32, /* unltr_d */ + 64, /* unlti_d */ + 32, /* unler_d */ + 64, /* unlei_d */ 48, /* uneqr_d */ - 80, /* uneqi_d */ - 16, /* unger_d */ - 48, /* ungei_d */ - 16, /* ungtr_d */ - 48, /* ungti_d */ + 96, /* uneqi_d */ + 32, /* unger_d */ + 64, /* ungei_d */ + 32, /* ungtr_d */ + 64, /* ungti_d */ 48, /* ltgtr_d */ - 80, /* ltgti_d */ - 16, /* ordr_d */ - 48, /* ordi_d */ - 16, /* unordr_d */ - 48, /* unordi_d */ + 96, /* ltgti_d */ + 32, /* ordr_d */ + 64, /* ordi_d */ + 32, /* unordr_d */ + 64, /* unordi_d */ 32, /* truncr_d_i */ 32, /* truncr_d_l */ - 32, /* extr_d */ + 48, /* extr_d */ 16, /* extr_f_d */ 16, /* movr_d */ - 48, /* movi_d */ + 32, /* movi_d */ 16, /* ldr_d */ - 16, /* ldi_d */ - 0, /* ldxr_d */ + 32, /* ldi_d */ + 16, /* ldxr_d */ 32, /* ldxi_d */ 16, /* str_d */ - 16, /* sti_d */ + 32, /* sti_d */ 16, /* stxr_d */ - 16, /* stxi_d */ + 32, /* stxi_d */ 32, /* bltr_d */ 64, /* blti_d */ - 48, /* bler_d */ + 32, /* bler_d */ 64, /* blei_d */ - 64, /* beqr_d */ - 96, /* beqi_d */ - 48, /* bger_d */ - 80, /* bgei_d */ + 32, /* beqr_d */ + 64, /* beqi_d */ + 32, /* bger_d */ + 64, /* bgei_d */ 32, /* bgtr_d */ 64, /* bgti_d */ - 48, /* bner_d */ + 32, /* bner_d */ 64, /* bnei_d */ - 48, /* bunltr_d */ + 32, /* bunltr_d */ 64, /* bunlti_d */ - 48, /* bunler_d */ + 32, /* bunler_d */ 64, /* bunlei_d */ - 112, /* buneqr_d */ - 144, /* buneqi_d */ - 48, /* bunger_d */ + 80, /* buneqr_d */ + 112, /* buneqi_d */ + 32, /* bunger_d */ 64, /* bungei_d */ - 48, /* bungtr_d */ + 32, /* bungtr_d */ 64, /* bungti_d */ - 96, /* bltgtr_d */ - 128, /* bltgti_d */ - 48, /* bordr_d */ + 80, /* bltgtr_d */ + 112, /* bltgti_d */ + 32, /* bordr_d */ 64, /* bordi_d */ 32, /* bunordr_d */ 64, /* bunordi_d */ diff --git a/lib/jit_ia64.c b/lib/jit_ia64.c index f5345c081..a1cff5f1b 100644 --- a/lib/jit_ia64.c +++ b/lib/jit_ia64.c @@ -36,9 +36,7 @@ /* * Types */ -typedef struct jit_va_list { - jit_pointer_t stack; -} jit_va_list_t; +typedef jit_pointer_t jit_va_list_t; /* * Prototypes @@ -421,19 +419,15 @@ _jit_ellipsis(jit_state_t *_jit) { jit_inc_synth(ellipsis); if (_jitc->prepare) { - jit_link_prepare(); assert(!(_jitc->function->call.call & jit_call_varargs)); _jitc->function->call.call |= jit_call_varargs; + jit_link_prepare(); } else { - jit_link_prolog(); assert(!(_jitc->function->self.call & jit_call_varargs)); _jitc->function->self.call |= jit_call_varargs; - - /* Allocate va_list like object in the stack. */ - _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t)); - _jitc->function->vagp = _jitc->function->self.argi; + jit_link_prolog(); } jit_dec_synth(); } @@ -462,9 +456,14 @@ _jit_arg_f(jit_state_t *_jit) jit_node_t *node; jit_int32_t offset; assert(_jitc->function); - if (jit_arg_reg_p(_jitc->function->self.argi)) - offset = _jitc->function->self.argi++; - else { + if (jit_arg_reg_p(_jitc->function->self.argi)) { + if (!(_jitc->function->self.call & jit_call_varargs)) + offset = 8 + _jitc->function->self.argf++; + else + offset = _jitc->function->self.argi; + ++_jitc->function->self.argi; + } + else { offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } @@ -480,11 +479,16 @@ _jit_arg_d(jit_state_t *_jit) jit_node_t *node; jit_int32_t offset; assert(_jitc->function); - if (jit_arg_reg_p(_jitc->function->self.argi)) - offset = _jitc->function->self.argi++; - else { + if (jit_arg_reg_p(_jitc->function->self.argi)) { + if (!(_jitc->function->self.call & jit_call_varargs)) + offset = 8 + _jitc->function->self.argf++; + else + offset = _jitc->function->self.argi; + ++_jitc->function->self.argi; + } + else { offset = _jitc->function->self.size; - _jitc->function->self.size += sizeof(jit_word_t); + _jitc->function->self.size += sizeof(jit_float64_t); } node = jit_new_node_ww(jit_code_arg_d, offset, ++_jitc->function->self.argn); @@ -611,7 +615,9 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) assert(v->code == jit_code_arg_f); jit_inc_synth_wp(getarg_f, u, v); if (jit_arg_reg_p(v->u.w)) - jit_movr_f(u, _F8 + v->u.w); + jit_movr_w_f(u, _OUT0 + v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_f(u, _F8 + (v->u.w - 8)); else jit_ldxi_f(u, JIT_FP, v->u.w + F_DISP); jit_dec_synth(); @@ -623,7 +629,9 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) assert(v->code == jit_code_arg_f); jit_inc_synth_wp(putargr_f, u, v); if (jit_arg_reg_p(v->u.w)) - jit_movr_f(_F8 + v->u.w, u); + jit_movr_f_w(_OUT0 + v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_f(_F8 + (v->u.w - 8), u); else jit_stxi_f(v->u.w, JIT_FP, u + F_DISP); jit_dec_synth(); @@ -636,7 +644,9 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) assert(v->code == jit_code_arg_f); jit_inc_synth_fp(putargi_f, u, v); if (jit_arg_reg_p(v->u.w)) - jit_movi_f(_F8 + v->u.w, u); + jit_movi_f_w(_OUT0 + v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movi_f(_F8 + (v->u.w - 8), u); else { regno = jit_get_reg(jit_class_fpr); jit_movi_f(regno, u); @@ -652,7 +662,9 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) assert(v->code == jit_code_arg_d); jit_inc_synth_wp(getarg_d, u, v); if (jit_arg_reg_p(v->u.w)) - jit_movr_d(u, _F8 + v->u.w); + jit_movr_w_d(u, _OUT0 + v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_d(u, _F8 + (v->u.w - 8)); else jit_ldxi_d(u, JIT_FP, v->u.w); jit_dec_synth(); @@ -664,7 +676,9 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) assert(v->code == jit_code_arg_d); jit_inc_synth_wp(putargr_d, u, v); if (jit_arg_reg_p(v->u.w)) - jit_movr_d(_F8 + v->u.w, u); + jit_movr_d_w(_OUT0 + v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_d(_F8 + (v->u.w - 8), u); else jit_stxi_d(v->u.w, JIT_FP, u); jit_dec_synth(); @@ -677,7 +691,9 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) assert(v->code == jit_code_arg_d); jit_inc_synth_dp(putargi_d, u, v); if (jit_arg_reg_p(v->u.w)) - jit_movi_d(_F8 + v->u.w, u); + jit_movi_d_w(_OUT0 + v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movi_d(_F8 + (v->u.w - 8), u); else { regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); @@ -732,8 +748,10 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) jit_inc_synth_w(pushargr_f, u); jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { - if (!(_jitc->function->call.call & jit_call_varargs)) - jit_movr_f(_F8 + _jitc->function->call.argi, u); + if (!(_jitc->function->call.call & jit_call_varargs)) { + jit_movr_f(_F8 + _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } else jit_movr_f_w(_OUT0 + _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -754,8 +772,10 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) jit_inc_synth_f(pushargi_f, u); jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { - if (!(_jitc->function->call.call & jit_call_varargs)) - jit_movi_f(_F8 + _jitc->function->call.argi, u); + if (!(_jitc->function->call.call & jit_call_varargs)) { + jit_movi_f(_F8 + _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } else jit_movi_f_w(_OUT0 + _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -778,15 +798,17 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) jit_inc_synth_w(pushargr_d, u); jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { - if (!(_jitc->function->call.call & jit_call_varargs)) - jit_movr_d(_F8 + _jitc->function->call.argi, u); + if (!(_jitc->function->call.call & jit_call_varargs)) { + jit_movr_d(_F8 + _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } else jit_movr_d_w(_OUT0 + _jitc->function->call.argi, u); ++_jitc->function->call.argi; } else { jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u); - _jitc->function->call.size += sizeof(jit_word_t); + _jitc->function->call.size += sizeof(jit_float64_t); } jit_dec_synth(); } @@ -799,8 +821,10 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) jit_inc_synth_d(pushargi_d, u); jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { - if (!(_jitc->function->call.call & jit_call_varargs)) - jit_movi_d(_F8 + _jitc->function->call.argi, u); + if (!(_jitc->function->call.call & jit_call_varargs)) { + jit_movi_d(_F8 + _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } else jit_movi_d_w(_OUT0 + _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -809,7 +833,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno); - _jitc->function->call.size += sizeof(jit_word_t); + _jitc->function->call.size += sizeof(jit_float64_t); jit_unget_reg(regno); } jit_dec_synth(); @@ -1071,7 +1095,13 @@ _emit_code(jit_state_t *_jit) sync(); #endif #if DEVEL_DISASSEMBLER + /* FIXME DEVEL_DISASSEMBLER should become DISASSEMBLER, + * but a "real" DEVEL_DISASSEMBLER should be required + * to turn the below "#if 0" into "#if 1" */ +# if 0 /* Since disassembly outputs 3 instructions at a time, + * make it "#if 1" for more clear debug output. */ sync(); +# endif node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; prevw = _jit->pc.w; #endif @@ -1574,9 +1604,15 @@ _emit_code(jit_state_t *_jit) case jit_code_prepare: case jit_code_finishr: case jit_code_finishi: break; + case jit_code_movr_w_f: + movr_w_f(rn(node->u.w), rn(node->v.w)); + break; case jit_code_movr_f_w: movr_f_w(rn(node->u.w), rn(node->v.w)); break; + case jit_code_movr_w_d: + movr_w_d(rn(node->u.w), rn(node->v.w)); + break; case jit_code_movr_d_w: movr_d_w(rn(node->u.w), rn(node->v.w)); break;