Author: Armin Rigo <ar...@tunes.org> Branch: arm-longlong Changeset: r73238:7befb5f6d6db Date: 2014-08-31 19:39 +0300 http://bitbucket.org/pypy/pypy/changeset/7befb5f6d6db/
Log: in-progress diff --git a/rpython/jit/backend/arm/callbuilder.py b/rpython/jit/backend/arm/callbuilder.py --- a/rpython/jit/backend/arm/callbuilder.py +++ b/rpython/jit/backend/arm/callbuilder.py @@ -316,10 +316,12 @@ float_regs = [] stack_args = [] singlefloats = None + longlong_mask = 0 arglocs = self.arglocs argtypes = self.argtypes + r_register_count = 0 count = 0 # stack alignment counter on_stack = 0 for i in range(len(arglocs)): @@ -327,23 +329,51 @@ if i < len(argtypes) and argtypes[i] == 'S': argtype = argtypes[i] arg = arglocs[i] + if arg.is_float(): - argtype = FLOAT - reg = self.get_next_vfp(argtype) - if reg: - assert len(float_regs) < len(r.vfp_argument_regs) - float_locs.append(arg) - assert reg not in float_regs - float_regs.append(reg) - else: # float argument that needs to go on the stack - if count % 2 != 0: - stack_args.append(None) - count = 0 - on_stack += 1 - stack_args.append(arg) - on_stack += 2 + if i < len(argtypes) and argtypes[i] == 'L': + # A longlong argument. It uses two regular argument + # positions, but aligned to an even number. This is + # a bit strange, but it is the case even for registers: + # it can be in r0-r1 or in r2-r3 but not in r1-r2. + assert arg.is_float() + if r_register_count == 0: + # will temporarily load the register into d8 + float_locs.append(arg) + float_regs.append(r.d8) + longlong_mask |= 1 + r_register_count = 2 + continue + elif r_register_count <= 2: + # will temporarily load the register into d9 + float_locs.append(arg) + float_regs.append(r.d9) + longlong_mask |= 2 + r_register_count = 4 + continue + else: + # A 64-bit float argument. Goes into the next free v# + # register, or if none, to the stack aligned to an + # even number of words. + argtype = FLOAT + reg = self.get_next_vfp(argtype) + if reg: + assert len(float_regs) < len(r.vfp_argument_regs) + float_locs.append(arg) + assert reg not in float_regs + float_regs.append(reg) + continue + # float or longlong argument that needs to go on the stack + if count % 2 != 0: + stack_args.append(None) + count = 0 + on_stack += 1 + stack_args.append(arg) + on_stack += 2 + elif argtype == 'S': - # Singlefloat argument + # Singlefloat (32-bit) argument. Goes into the next free + # v# register, or if none, to the stack in a single word. if singlefloats is None: singlefloats = [] tgt = self.get_next_vfp(argtype) @@ -355,19 +385,24 @@ on_stack += 1 stack_args.append(arg) else: - if len(non_float_regs) < len(r.argument_regs): - reg = r.argument_regs[len(non_float_regs)] + # Regular one-word argument. Goes into the next register + # free from the list r0, r1, r2, r3, or to the stack. + if r_register_count < len(r.argument_regs): + reg = r.argument_regs[r_register_count] + r_register_count += 1 non_float_locs.append(arg) non_float_regs.append(reg) else: # non-float argument that needs to go on the stack count += 1 on_stack += 1 stack_args.append(arg) + # align the stack if count % 2 != 0: stack_args.append(None) on_stack += 1 self._push_stack_args(stack_args, on_stack*WORD) + # Check that the address of the function we want to call is not # currently stored in one of the registers used to pass the arguments # or on the stack, which we can not access later @@ -377,6 +412,7 @@ non_float_locs.append(self.fnloc) non_float_regs.append(r.r4) self.fnloc = r.r4 + # remap values stored in vfp registers remap_frame_layout(self.asm, float_locs, float_regs, r.vfp_ip) if singlefloats: @@ -392,8 +428,14 @@ src = r.ip if src.is_core_reg(): self.mc.VMOV_cs(dest.value, src.value) + # remap values stored in core registers remap_frame_layout(self.asm, non_float_locs, non_float_regs, r.ip) + if longlong_mask & 1: + self.mc.FMRRD(r.r0.value, r.r1.value, r.d8.value) + if longlong_mask & 2: + self.mc.FMRRD(r.r2.value, r.r3.value, r.d9.value) + def load_result(self): resloc = self.resloc diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -339,6 +339,20 @@ MOD = binary_helper_call('int_mod') UDIV = binary_helper_call('uint_div') + def FMDRR(self, dm, rd, rn, c=cond.AL): + self.write32(c << 28 + | 0x0c400b10 + | (dm & 0xF) + | (rd & 0xF) << 12 + | (rn & 0xF) << 16) + + def FMRRD(self, rd, rn, dm, c=cond.AL): + self.write32(c << 28 + | 0x0c500b10 + | (dm & 0xF) + | (rd & 0xF) << 12 + | (rn & 0xF) << 16) + def _encode_reg_list(self, instr, regs): for reg in regs: instr |= 0x1 << reg diff --git a/rpython/jit/backend/arm/test/test_instr_codebuilder.py b/rpython/jit/backend/arm/test/test_instr_codebuilder.py --- a/rpython/jit/backend/arm/test/test_instr_codebuilder.py +++ b/rpython/jit/backend/arm/test/test_instr_codebuilder.py @@ -199,6 +199,14 @@ self.cb.DMB() self.assert_equal('DMB') + def test_fmdrr(self): + self.cb.FMDRR(r.d11.value, r.r9.value, r.r14.value) + self.assert_equal('FMDRR d11, r9, r14') + + def test_fmrrd(self): + self.cb.FMRRD(r.r9.value, r.r14.value, r.d11.value) + self.assert_equal('FMRRD r9, r14, d11') + def test_size_of_gen_load_int(): for v, n in [(5, 4), (6, 4), (7, 2)]: _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit