diff --git a/ChangeLog b/ChangeLog index 5d8ac8422..e0d153274 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2013-02-11 Paulo Andrade + + * lib/jit_arm.c: Correct jit_pushargi_f in the arm hardfp abi. + Most of the logic uses even numbered register numbers, so that + a float and a double can be used in the same register, but + the abi requires packing the float arguments, so jit_pushargi_f + needs to allocate a temporary register to modify only the + proper register argument (or be very smart to push two + immediate arguments if applicable). + 2013-02-11 Paulo Andrade * include/lightning.h, lib/lightning.c: Implement the new diff --git a/lib/jit_arm.c b/lib/jit_arm.c index 4c760f845..230228632 100644 --- a/lib/jit_arm.c +++ b/lib/jit_arm.c @@ -386,21 +386,20 @@ _jit_arg_f(jit_state_t *_jit) assert(_jit->function); if (jit_cpu.abi && !(_jit->function->self.call & jit_call_varargs)) { - if (_jit->function->self.argf < 16) + if (_jit->function->self.argf < 16) { offset = _jit->function->self.argf++; - else { - offset = _jit->function->self.size; - _jit->function->self.size += sizeof(jit_word_t); + goto done; } } else { - if (_jit->function->self.argi < 4) + if (_jit->function->self.argi < 4) { offset = _jit->function->self.argi++; - else { - offset = _jit->function->self.size; - _jit->function->self.size += sizeof(jit_float32_t); + goto done; } } + offset = _jit->function->self.size; + _jit->function->self.size += sizeof(jit_float32_t); +done: return (jit_new_node_w(jit_code_arg_f, offset)); } @@ -604,7 +603,14 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) assert(_jit->function); if (jit_cpu.abi && !(_jit->function->call.call & jit_call_varargs)) { if (_jit->function->call.argf < 16) { - jit_movi_f(JIT_FA0 - _jit->function->call.argf, u); + /* cannot jit_movi_f in the argument register because + * float arguments are packed, and that would cause + * either an assertion in debug mode, or overwritting + * two registers */ + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_movr_f(JIT_FA0 - _jit->function->call.argf, regno); + jit_unget_reg(regno); ++_jit->function->call.argf; return; }