summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rpython/jit/backend/riscv/assembler.py26
-rw-r--r--rpython/jit/backend/riscv/codebuilder.py20
2 files changed, 40 insertions, 6 deletions
diff --git a/rpython/jit/backend/riscv/assembler.py b/rpython/jit/backend/riscv/assembler.py
index 5f6029bba2..3aa4828805 100644
--- a/rpython/jit/backend/riscv/assembler.py
+++ b/rpython/jit/backend/riscv/assembler.py
@@ -1671,9 +1671,11 @@ class AssemblerRISCV(OpAssembler):
def _mov_stack_to_loc(self, prev_loc, loc):
offset = prev_loc.value
if loc.is_core_reg():
- self.mc.load_int(loc.value, r.jfp.value, offset)
+ self.mc.load_int_from_base_plus_offset(loc.value, r.jfp.value,
+ offset)
elif loc.is_fp_reg():
- self.mc.load_float(loc.value, r.jfp.value, offset)
+ self.mc.load_float_from_base_plus_offset(loc.value, r.jfp.value,
+ offset, tmp=r.x31.value)
else:
assert 0, 'unsupported case'
@@ -1681,7 +1683,15 @@ class AssemblerRISCV(OpAssembler):
if loc.is_core_reg():
self.mc.MV(loc.value, prev_loc.value)
elif loc.is_stack():
- self.mc.store_int(prev_loc.value, r.jfp.value, loc.value)
+ # Use `r.shadow_old` as `scratch_reg`. We can't use `r.x31`
+ # because `prev_loc` can be `r.x31` (see also.
+ # `regalloc_prepare_move`). We can't use `r.ra` because `r.ra` is
+ # allocated for the callee function address in `callbuiler.py`
+ # and its lifetime overlaps with `remap_frame_layout`.
+ scratch_reg = r.shadow_old
+ self.mc.store_int_to_base_plus_offset(prev_loc.value, r.jfp.value,
+ loc.value,
+ tmp=scratch_reg.value)
else:
assert 0, 'unsupported case'
@@ -1692,7 +1702,9 @@ class AssemblerRISCV(OpAssembler):
assert XLEN == 8 and FLEN == 8
self.mc.FMV_X_D(loc.value, prev_loc.value)
elif loc.is_stack():
- self.mc.store_float(prev_loc.value, r.jfp.value, loc.value)
+ self.mc.store_float_to_base_plus_offset(prev_loc.value,
+ r.jfp.value, loc.value,
+ tmp=r.x31.value)
else:
assert 0, 'unsupported case'
@@ -1701,7 +1713,8 @@ class AssemblerRISCV(OpAssembler):
self.mc.load_float_imm(loc.value, prev_loc.value)
elif loc.is_stack():
self.mc.load_float_imm(r.f31.value, prev_loc.value)
- self.mc.store_float(r.f31.value, r.jfp.value, loc.value)
+ self.mc.store_float_to_base_plus_offset(r.f31.value, r.jfp.value,
+ loc.value, tmp=r.x31.value)
else:
assert 0, 'unsupported case'
@@ -1713,7 +1726,8 @@ class AssemblerRISCV(OpAssembler):
elif loc.is_stack():
# Move a value from JITFRAME stack to raw stack.
scratch_reg = r.x31
- self.mc.load_int(scratch_reg.value, r.jfp.value, loc.value)
+ self.mc.load_int_from_base_plus_offset(scratch_reg.value,
+ r.jfp.value, loc.value)
self.mc.store_int(scratch_reg.value, r.sp.value, sp_offset)
elif loc.is_fp_reg():
self.mc.store_float(loc.value, r.sp.value, sp_offset)
diff --git a/rpython/jit/backend/riscv/codebuilder.py b/rpython/jit/backend/riscv/codebuilder.py
index 8e05b9640f..c5654e2a14 100644
--- a/rpython/jit/backend/riscv/codebuilder.py
+++ b/rpython/jit/backend/riscv/codebuilder.py
@@ -172,6 +172,26 @@ class AbstractRISCVBuilder(object):
def store_float(self, rs2, rs1, imm):
self.FSD(rs2, rs1, imm)
+ # Load an FLEN-bit float from rs1+imm (imm can be a large constant)
+ def load_float_from_base_plus_offset(self, rd, rs1, imm, tmp):
+ assert tmp != rs1
+ if check_imm_arg(imm):
+ self.load_float(rd, rs1, imm)
+ else:
+ self.load_int_imm(tmp, imm)
+ self.ADD(tmp, tmp, rs1)
+ self.load_float(rd, tmp, 0)
+
+ # Store an FLEN-bit float to rs1+imm (imm can be a large constant)
+ def store_float_to_base_plus_offset(self, rs2, rs1, imm, tmp):
+ assert tmp != rs1
+ if check_imm_arg(imm):
+ self.store_float(rs2, rs1, imm)
+ else:
+ self.load_int_imm(tmp, imm)
+ self.ADD(tmp, tmp, rs1)
+ self.store_float(rs2, tmp, 0)
+
# Load a rffi.INT from imm(rs1)
def load_rffi_int(self, rd, rs1, imm):
# Note: On RV64 (LP64), rffi.INT is 32-bit signed integer.