diff --git a/ChangeLog b/ChangeLog index 90244b8f1..6de334244 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-06-10 Paulo Andrade + + * lib/jit_ia64-cpu.c, lib/jit_ia64-fpu.c, lib/jit_ia64.c: + Add base support to jit vararg functions to the ia64 backend. + 2015-06-10 Paulo Andrade * lib/jit_ia64-fpu.c, lib/jit_ia64.c: Correct movi_d_w diff --git a/lib/jit_ia64-cpu.c b/lib/jit_ia64-cpu.c index 0392138ff..831d3232b 100644 --- a/lib/jit_ia64-cpu.c +++ b/lib/jit_ia64-cpu.c @@ -18,7 +18,7 @@ */ #if PROTO -#define stack_framesize 96 +#define stack_framesize 144 #define params_offset 16 #define INST_NONE 0 /* should never be generated */ #define INST_STOP 1 /* or'ed if stop is required */ @@ -1508,6 +1508,10 @@ static jit_word_t _calli_p(jit_state_t*,jit_word_t); static void _prolog(jit_state_t*,jit_node_t*); #define epilog(node) _epilog(_jit,node) static void _epilog(jit_state_t*,jit_node_t*); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); #define patch_at(node,instr,label) _patch_at(_jit,node,instr,label) static void _patch_at(jit_state_t*,jit_code_t,jit_word_t,jit_word_t); #endif @@ -5262,6 +5266,11 @@ _prolog(jit_state_t *_jit, jit_node_t *node) stxi_i(_jitc->function->aoffoff, GR_4, rn(reg)); jit_unget_reg(reg); } + + 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); + } } static void @@ -5302,6 +5311,45 @@ _epilog(jit_state_t *_jit, jit_node_t *node) flush(); } +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); +} + +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); +} + static void _patch_at(jit_state_t *_jit, jit_code_t code, jit_word_t instr, jit_word_t label) diff --git a/lib/jit_ia64-fpu.c b/lib/jit_ia64-fpu.c index 20970fb4a..a539bfd52 100644 --- a/lib/jit_ia64-fpu.c +++ b/lib/jit_ia64-fpu.c @@ -718,6 +718,8 @@ static jit_word_t _bunordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); static jit_word_t _bunordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); #define bunordi_d(i0,r0,i1) _bunordi_d(_jit,i0,r0,i1) static jit_word_t _bunordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); #endif #if CODE @@ -1725,4 +1727,25 @@ _bunordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) } fbopi(unord) 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); +} #endif diff --git a/lib/jit_ia64.c b/lib/jit_ia64.c index a9287c4fa..28a5d750f 100644 --- a/lib/jit_ia64.c +++ b/lib/jit_ia64.c @@ -35,6 +35,13 @@ # define F_DISP 8 - sizeof(jit_float32_t) #endif +/* + * Types + */ +typedef struct jit_va_list { + jit_pointer_t stack; +} jit_va_list_t; + /* * Prototypes */ @@ -402,6 +409,11 @@ _jit_ellipsis(jit_state_t *_jit) else { 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; } } @@ -1409,9 +1421,19 @@ _emit_code(jit_state_t *_jit) _jitc->pred = 0; _jitc->function = NULL; break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; case jit_code_live: case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: break; case jit_code_movr_f_w: movr_f_w(rn(node->u.w), rn(node->v.w));