RISC-V: PR30449, Add lga assembler macro support.
authorJim Wilson <jimw@sifive.com>
Thu, 1 Jun 2023 04:10:16 +0000 (12:10 +0800)
committerNelson Chu <nelson@rivosinc.com>
Thu, 1 Jun 2023 04:25:08 +0000 (12:25 +0800)
Originally discussion, https://github.com/riscv/riscv-isa-manual/pull/539

Added new load address pseudo instruction which is always expanded to GOT
access, no matter the .option rvc is set or not.

gas/
PR 30449
* config/tc-riscv.c (macro): Add M_LGA support.
* testsuite/gas/riscv/la-variants.d: New.
* testsuite/gas/riscv/la-variants.s: New.
include/
PR 30449
* opcode/riscv.h (M_LGA): New.
opcodes/
PR 30449
* riscv-opc.c (riscv_opcodes): Add lga support.

gas/config/tc-riscv.c
gas/testsuite/gas/riscv/la-variants.d [new file with mode: 0644]
gas/testsuite/gas/riscv/la-variants.s [new file with mode: 0644]
include/opcode/riscv.h
opcodes/riscv-opc.c

index fceb53e54a67101b89f027e161ad89dbea150bac..7684fa7e06d5e5815318e2a8eba277fd96ffac85 100644 (file)
@@ -2010,16 +2010,20 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
 
     case M_LA:
     case M_LLA:
+    case M_LGA:
       /* Load the address of a symbol into a register.  */
       if (!IS_SEXT_32BIT_NUM (imm_expr->X_add_number))
        as_bad (_("offset too large"));
 
       if (imm_expr->X_op == O_constant)
        load_const (rd, imm_expr);
-      else if (riscv_opts.pic && mask == M_LA) /* Global PIC symbol.  */
+      /* Global PIC symbol.  */
+      else if ((riscv_opts.pic && mask == M_LA)
+              || mask == M_LGA)
        pcrel_load (rd, rd, imm_expr, LOAD_ADDRESS_INSN,
                    BFD_RELOC_RISCV_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
-      else /* Local PIC symbol, or any non-PIC symbol.  */
+      /* Local PIC symbol, or any non-PIC symbol.  */
+      else
        pcrel_load (rd, rd, imm_expr, "addi",
                    BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
       break;
diff --git a/gas/testsuite/gas/riscv/la-variants.d b/gas/testsuite/gas/riscv/la-variants.d
new file mode 100644 (file)
index 0000000..b1d3169
--- /dev/null
@@ -0,0 +1,42 @@
+#as:
+#objdump: -dr
+
+.*:[   ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[      ]+[0-9a-f]+:[   ]+00000517[     ]+auipc[        ]+a0,0x0
+[      ]+[0-9a-f]+:[   ]+R_RISCV_PCREL_HI20[   ]+a
+[      ]+[0-9a-f]+:[   ]+R_RISCV_RELAX[        ]+\*ABS\*
+[      ]+[0-9a-f]+:[   ]+00050513[     ]+mv[   ]+a0,a0
+[      ]+[0-9a-f]+:[   ]+R_RISCV_PCREL_LO12_I[         ]+\.L0[ ]+
+[      ]+[0-9a-f]+:[   ]+R_RISCV_RELAX[        ]+\*ABS\*
+[      ]+[0-9a-f]+:[   ]+00000597[     ]+auipc[        ]+a1,0x0
+[      ]+[0-9a-f]+:[   ]+R_RISCV_PCREL_HI20[   ]+a
+[      ]+[0-9a-f]+:[   ]+R_RISCV_RELAX[        ]+\*ABS\*
+[      ]+[0-9a-f]+:[   ]+00058593[     ]+mv[   ]+a1,a1
+[      ]+[0-9a-f]+:[   ]+R_RISCV_PCREL_LO12_I[         ]+\.L0[ ]+
+[      ]+[0-9a-f]+:[   ]+R_RISCV_RELAX[        ]+\*ABS\*
+[      ]+[0-9a-f]+:[   ]+00000617[     ]+auipc[        ]+a2,0x0
+[      ]+[0-9a-f]+:[   ]+R_RISCV_GOT_HI20[     ]+a
+[      ]+[0-9a-f]+:[   ]+(00062603|00063603)[  ]+(lw|ld)[      ]+a2,0\(a2\).*
+[      ]+[0-9a-f]+:[   ]+R_RISCV_PCREL_LO12_I[         ]+\.L0[ ]+
+[      ]+[0-9a-f]+:[   ]+R_RISCV_RELAX[        ]+\*ABS\*
+[      ]+[0-9a-f]+:[   ]+00000697[     ]+auipc[        ]+a3,0x0
+[      ]+[0-9a-f]+:[   ]+R_RISCV_GOT_HI20[     ]+a
+[      ]+[0-9a-f]+:[   ]+(0006a683|0006b683)[  ]+(lw|ld)[      ]+a3,0\(a3\).*
+[      ]+[0-9a-f]+:[   ]+R_RISCV_PCREL_LO12_I[         ]+\.L0[ ]+
+[      ]+[0-9a-f]+:[   ]+R_RISCV_RELAX[        ]+\*ABS\*
+[      ]+[0-9a-f]+:[   ]+00000717[     ]+auipc[        ]+a4,0x0
+[      ]+[0-9a-f]+:[   ]+R_RISCV_PCREL_HI20[   ]+a
+[      ]+[0-9a-f]+:[   ]+R_RISCV_RELAX[        ]+\*ABS\*
+[      ]+[0-9a-f]+:[   ]+00070713[     ]+mv[   ]+a4,a4
+[      ]+[0-9a-f]+:[   ]+R_RISCV_PCREL_LO12_I[         ]+\.L0[ ]+
+[      ]+[0-9a-f]+:[   ]+R_RISCV_RELAX[        ]+\*ABS\*
+[      ]+[0-9a-f]+:[   ]+00000797[     ]+auipc[        ]+a5,0x0
+[      ]+[0-9a-f]+:[   ]+R_RISCV_GOT_HI20[     ]+a
+[      ]+[0-9a-f]+:[   ]+(0007a783|0007b783)[  ]+(lw|ld)[      ]+a5,0\(a5\).*
+[      ]+[0-9a-f]+:[   ]+R_RISCV_PCREL_LO12_I[         ]+\.L0[ ]+
+[      ]+[0-9a-f]+:[   ]+R_RISCV_RELAX[        ]+\*ABS\*
diff --git a/gas/testsuite/gas/riscv/la-variants.s b/gas/testsuite/gas/riscv/la-variants.s
new file mode 100644 (file)
index 0000000..bc3b0fe
--- /dev/null
@@ -0,0 +1,11 @@
+# lla is always local, lga is always global, and la depends on pic
+       .extern a
+.text
+       .option nopic
+       la a0, a
+       lla a1, a
+       lga a2, a
+       .option pic
+       la a3, a
+       lla a4, a
+       lga a5, a
index e86a1bd082492df5325f1b4b409a3b3914fdd642..877ec66b957f3c34af8d01aef9e2421c911e191e 100644 (file)
@@ -502,6 +502,7 @@ enum
 {
   M_LA,
   M_LLA,
+  M_LGA,
   M_LA_TLS_GD,
   M_LA_TLS_IE,
   M_LB,
index 1c3d9b0903ecd1220882ea691a37f3d5f769a3f0..57e7b90e480cefc9473d8b96927cd51dcbbb60fe 100644 (file)
@@ -405,6 +405,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"addi",        0, INSN_CLASS_I, "d,s,j",     MATCH_ADDI, MASK_ADDI, match_opcode, 0 },
 {"la",          0, INSN_CLASS_I, "d,B",       0, (int) M_LA, match_never, INSN_MACRO },
 {"lla",         0, INSN_CLASS_I, "d,B",       0, (int) M_LLA, match_never, INSN_MACRO },
+{"lga",         0, INSN_CLASS_I, "d,B",       0, (int) M_LGA, match_never, INSN_MACRO },
 {"la.tls.gd",   0, INSN_CLASS_I, "d,A",       0, (int) M_LA_TLS_GD, match_never, INSN_MACRO },
 {"la.tls.ie",   0, INSN_CLASS_I, "d,A",       0, (int) M_LA_TLS_IE, match_never, INSN_MACRO },
 {"neg",         0, INSN_CLASS_I, "d,t",       MATCH_SUB, MASK_SUB|MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0  */