On 9/17/22 00:43, Song Gao wrote:
+sub write_mov_positive_ri($$) +{ + # Use lu12i.w and ori instruction + my ($rd, $imm) = @_; + my $high_20 = ($imm >> 12) & 0xfffff; + + if ($high_20) { + # lu12i.w rd, si20 + insn32(0x14000000 | $high_20 << 5 | $rd);
This isn't necessarily positive -- lu12i.w sign-extends from 32-bits.
+ # ori rd, rd, ui12 + insn32(0x03800000 | ($imm & 0xfff) << 10 | $rd << 5 | $rd); + } else { + # ori rd, 0, ui12 + insn32(0x03800000 | ($imm & 0xfff) << 10 | 0 << 5 | $rd); + } +} + +sub write_mov_ri($$) +{ + my ($rd, $imm) = @_; + + if ($imm < 0) { + my $tmp = 0 - $imm ; + write_mov_positive_ri($rd, $tmp); + write_sub_rrr($rd, 0, $rd); + } else { + write_mov_positive_ri($rd, $imm); + } +}
OTOH, I'm not sure why you'd need to split out write_mov_positive_ri and negate. I don't *think* we need to handle completely arbitrary constants. From the aarch64 code we certainly don't.
I might write if ($imm >= -0x1000 && $imm <= 0xfff) { addi.w } elsif ($imm >= -0x80000000 && $imm <= 0x7fffffff) { lu12i.w ori } else { die "unhandled immediate load"; } Otherwise, Reviewed-by: Richard Henderson <richard.hender...@linaro.org> r~