armips
armips copied to clipboard
Improve RSP immediate value range
Consider the following assembly;
.rsp
.create "text.bin", 0x40001000
llv v1[0],lo(label1)(zero)
llv v1[0],lo(label2)(zero)
llv v1[0],lo(label3-_ref)($5)
llv v1[0],lo(label_neg)(zero)
.close
.create "data.bin", 0x40000000
label1:
.word 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF
.word 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF
label2:
.word 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF
.org 0x40000800-32
label3:
.word 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF
.org 0x40000800
_ref:
.org 0x40000800+16
label4:
.word 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF
.org 0x40001000-32
label_neg:
.word 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF
.close
It fails with Immediate value 0x3F8 out of range
. To make it work we can either change llv v1[0],lo(label_neg)(zero)
to llv v1[0],lo(label_neg-0x40001000)(zero)
or add a .headersize 0x40000000-0x1000
before the label_neg
label. This is something that can be improved in practice.
The RSP dmem is limited to 4Kb and it should be possible to wrap around near the end of memory space when using zero
relative addressing. The offset
for the RSP load/store instructions is 7 bits so my proposal is that the assembler should just use the lowest 7 bits of the calculated value (after it is shifted depending on the instruction). It will properly become a negative offset when truncated to 7 bits.
e.g 0x3F8 & 0x7F = 0x78
which is (correctly) -8
in 7 bit two's complement.
It is not that easy for addressing with a random base register (see label3
in the above example) as the value of the register is dynamic - although we may even find a convention for that to enable it - but for the zero
register the wrapping behavior is deterministic.
When the base register is zero
, instead of doing the range check w.r.t a given threshold after shifting it, the assembler can just look at the distance from immediate_offset & 0x1FFF
to both 0x0
and 0x1000
before shifting and truncating it. If the distance can be represented with a valid 7bit two's complement, it should not produce an error and continue with the shift and truncation.