diff --git a/ChangeLog b/ChangeLog index bfd50a657..a17a444d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-06-20 Paulo Andrade + + * lib/jit_sparc-cpu.c, lib/jit_sparc-fpu.c, lib/jit_sparc.c: + Add base support to jit vararg functions to the sparc backend. + 2015-06-20 Paulo Andrade * lib/jit_alpha-cpu.c, lib/jit_alpha-fpu.c, lib/jit_alpha.c: diff --git a/lib/jit_sparc-cpu.c b/lib/jit_sparc-cpu.c index 8922054b4..43a307f9e 100644 --- a/lib/jit_sparc-cpu.c +++ b/lib/jit_sparc-cpu.c @@ -673,6 +673,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(jump, label) _patch_at(_jit, jump, label) static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); #endif @@ -1672,6 +1676,11 @@ _prolog(jit_state_t *_jit, jit_node_t *node) stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(reg)); jit_unget_reg(reg); } + + if (_jitc->function->self.call & jit_call_varargs) { + for (reg = _jitc->function->vagp; jit_arg_reg_p(reg); ++reg) + stxi(68 + reg * 4, _SP_REGNO, rn(_I0 + reg)); + } } static void @@ -1702,6 +1711,25 @@ _epilog(jit_state_t *_jit, jit_node_t *node) NOP(); } +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + /* Initialize stack pointer to the first stack argument. */ + addi(r0, _SP_REGNO, 68 + _jitc->function->vagp * 4); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + + /* Load argument. */ + ldr(r0, r1); + + /* Update vararg stack pointer. */ + addi(r1, r1, 4); +} + static void _patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) { diff --git a/lib/jit_sparc-fpu.c b/lib/jit_sparc-fpu.c index db32ad0cc..5ec9c8e4f 100644 --- a/lib/jit_sparc-fpu.c +++ b/lib/jit_sparc-fpu.c @@ -362,6 +362,8 @@ _dbw(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float64_t*); # define bordi_d(i0, r0, i1) dbw(SPARC_FBO, i0, r0, i1) # define bunordr_d(i0, r0, r1) dbr(SPARC_FBU, i0, r0, r1) # define bunordi_d(i0, r0, i1) dbw(SPARC_FBU, i0, r0, i1) +# 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 @@ -757,4 +759,16 @@ _dbw(jit_state_t *_jit, jit_int32_t cc, NOP(); return (w); } + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + + /* Load argument. */ + ldr_d(r0, r1); + + /* Update vararg stack pointer. */ + addi(r1, r1, 8); +} #endif diff --git a/lib/jit_sparc.c b/lib/jit_sparc.c index 5b14e4489..101abfac6 100644 --- a/lib/jit_sparc.c +++ b/lib/jit_sparc.c @@ -22,6 +22,11 @@ #define jit_arg_reg_p(i) ((i) >= 0 && (i) < 6) #define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 5) +/* + * Types + */ +typedef jit_pointer_t jit_va_list_t; + /* * Prototypes */ @@ -268,6 +273,8 @@ _jit_ellipsis(jit_state_t *_jit) else { assert(!(_jitc->function->self.call & jit_call_varargs)); _jitc->function->self.call |= jit_call_varargs; + + _jitc->function->vagp = _jitc->function->self.argi; } } @@ -1274,9 +1281,19 @@ _emit_code(jit_state_t *_jit) epilog(node); _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; default: abort();