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.
Consider the following assembly;
It fails with
Immediate value 0x3F8 out of range
. To make it work we can either changellv v1[0],lo(label_neg)(zero)
tollv v1[0],lo(label_neg-0x40001000)(zero)
or add a.headersize 0x40000000-0x1000
before thelabel_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. Theoffset
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 thezero
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 fromimmediate_offset & 0x1FFF
to both0x0
and0x1000
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.