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~

Reply via email to