RISC-V: Fix 4-arg add parsing.
authorJim Wilson <jimw@sifive.com>
Fri, 7 Dec 2018 20:31:05 +0000 (12:31 -0800)
committerJim Wilson <jimw@sifive.com>
Fri, 7 Dec 2018 20:31:05 +0000 (12:31 -0800)
PR gas/23956
gas/
* config/tc-riscv.c (validate_riscv_insn) <'1'>: New case.
(percent_op_null): New.
(riscv_ip) <'j'>: Set imm_reloc before p.
<'1'>: New case.
<'0'>: Use percent_op_null and don't set imm_reloc.
<alu_op>: Handle *args == '1'.
* testsuite/gas/riscv/tprel-add.d: New.
* testsuite/gas/riscv/tprel-add.l: New.
* testsuite/gas/riscv/tprel-add.s: New.
opcodes/
* riscv-opc.c (riscv_opcodes) <"add">: Use 1 not 0 for fourth arg.

gas/ChangeLog
gas/config/tc-riscv.c
gas/testsuite/gas/riscv/tprel-add.d [new file with mode: 0644]
gas/testsuite/gas/riscv/tprel-add.l [new file with mode: 0644]
gas/testsuite/gas/riscv/tprel-add.s [new file with mode: 0644]
opcodes/ChangeLog
opcodes/riscv-opc.c

index 72ae3bc..10eede5 100644 (file)
@@ -1,3 +1,16 @@
+2018-12-07  Jim Wilson  <jimw@sifive.com>
+
+       PR gas/23956
+       * config/tc-riscv.c (validate_riscv_insn) <'1'>: New case.
+       (percent_op_null): New.
+       (riscv_ip) <'j'>: Set imm_reloc before p.
+       <'1'>: New case.
+       <'0'>: Use percent_op_null and don't set imm_reloc.
+       <alu_op>: Handle *args == '1'.
+       * testsuite/gas/riscv/tprel-add.d: New.
+       * testsuite/gas/riscv/tprel-add.l: New.
+       * testsuite/gas/riscv/tprel-add.s: New.
+
 2018-12-06  Alan Modra  <amodra@gmail.com>
 
        * config/tc-ppc.c (md_assemble): Adjust relocs for VLE before
index 92ddf80..9e2035b 100644 (file)
@@ -637,6 +637,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
       case '[': break;
       case ']': break;
       case '0': break;
+      case '1': break;
       case 'F': /* funct */
        switch (c = *p++)
          {
@@ -1198,6 +1199,11 @@ static const struct percent_op_match percent_op_rtype[] =
   {0, 0}
 };
 
+static const struct percent_op_match percent_op_null[] =
+{
+  {0, 0}
+};
+
 /* Return true if *STR points to a relocation operator.  When returning true,
    move *STR over the operator and store its relocation code in *RELOC.
    Leave both *STR and *RELOC alone when returning false.  */
@@ -1878,8 +1884,8 @@ rvc_lui:
              continue;
 
            case 'j': /* Sign-extended immediate.  */
-             *imm_reloc = BFD_RELOC_RISCV_LO12_I;
              p = percent_op_itype;
+             *imm_reloc = BFD_RELOC_RISCV_LO12_I;
              goto alu_op;
            case 'q': /* Store displacement.  */
              p = percent_op_stype;
@@ -1889,9 +1895,11 @@ rvc_lui:
              p = percent_op_itype;
              *imm_reloc = BFD_RELOC_RISCV_LO12_I;
              goto load_store;
-           case '0': /* AMO "displacement," which must be zero.  */
+           case '1': /* 4-operand add, must be %tprel_add.  */
              p = percent_op_rtype;
-             *imm_reloc = BFD_RELOC_UNUSED;
+             goto alu_op;
+           case '0': /* AMO "displacement," which must be zero.  */
+             p = percent_op_null;
 load_store:
              if (riscv_handle_implicit_zero_offset (imm_expr, s))
                continue;
@@ -1904,6 +1912,7 @@ alu_op:
                  normalize_constant_expr (imm_expr);
                  if (imm_expr->X_op != O_constant
                      || (*args == '0' && imm_expr->X_add_number != 0)
+                     || (*args == '1')
                      || imm_expr->X_add_number >= (signed)RISCV_IMM_REACH/2
                      || imm_expr->X_add_number < -(signed)RISCV_IMM_REACH/2)
                    break;
diff --git a/gas/testsuite/gas/riscv/tprel-add.d b/gas/testsuite/gas/riscv/tprel-add.d
new file mode 100644 (file)
index 0000000..d81c1e2
--- /dev/null
@@ -0,0 +1,3 @@
+#as: -march=rv32ia
+#source tprel-add.s
+#error_output: tprel-add.l
diff --git a/gas/testsuite/gas/riscv/tprel-add.l b/gas/testsuite/gas/riscv/tprel-add.l
new file mode 100644 (file)
index 0000000..74bb535
--- /dev/null
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*: Error: bad expression
+.*: Error: illegal operands `amoadd.w x8,x9,%tprel_add\(i\)\(x10\)'
+.*: Error: illegal operands `add a5,a5,tp,0'
diff --git a/gas/testsuite/gas/riscv/tprel-add.s b/gas/testsuite/gas/riscv/tprel-add.s
new file mode 100644 (file)
index 0000000..15d748d
--- /dev/null
@@ -0,0 +1,11 @@
+       # Don't allow tprel_add in amoadd.
+       amoadd.w x8,x9,%tprel_add(i)(x10)
+       # Do require tprel_add in 4-operand add.
+       add     a5,a5,tp,0
+       .globl  i
+       .section        .tbss,"awT",@nobits
+       .align  2
+       .type   i, @object
+       .size   i, 4
+i:
+       .zero   4
index 5588e4b..880f863 100644 (file)
@@ -1,3 +1,8 @@
+2018-12-07  Jim Wilson  <jimw@sifive.com>
+
+       PR gas/23956
+       * riscv-opc.c (riscv_opcodes) <"add">: Use 1 not 0 for fourth arg.
+
 2018-12-06  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * configure.ac (enable-cgen-maint): Support passing path to cgen
index 3da2a77..29c6944 100644 (file)
@@ -276,7 +276,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"add",         0, {"I", 0},   "d,s,t",  MATCH_ADD, MASK_ADD, match_opcode, 0 },
 /* This is used for TLS, where the fourth arg is %tprel_add, to get a reloc
    applied to an add instruction, for relaxation to use.  */
-{"add",         0, {"I", 0},   "d,s,t,0",MATCH_ADD, MASK_ADD, match_opcode, 0 },
+{"add",         0, {"I", 0},   "d,s,t,1",MATCH_ADD, MASK_ADD, match_opcode, 0 },
 {"add",         0, {"I", 0},   "d,s,j",  MATCH_ADDI, MASK_ADDI, match_opcode, INSN_ALIAS },
 {"la",          0, {"I", 0},   "d,B",  0,    (int) M_LA,  match_never, INSN_MACRO },
 {"lla",         0, {"I", 0},   "d,B",  0,    (int) M_LLA,  match_never, INSN_MACRO },