From f50fabe4f66534c9addacddeaa439e8d164eadda Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Fri, 7 Dec 2018 12:31:05 -0800 Subject: [PATCH] RISC-V: Fix 4-arg add parsing. 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. : 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 | 13 +++++++++++++ gas/config/tc-riscv.c | 15 ++++++++++++--- gas/testsuite/gas/riscv/tprel-add.d | 3 +++ gas/testsuite/gas/riscv/tprel-add.l | 4 ++++ gas/testsuite/gas/riscv/tprel-add.s | 11 +++++++++++ opcodes/ChangeLog | 5 +++++ opcodes/riscv-opc.c | 2 +- 7 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 gas/testsuite/gas/riscv/tprel-add.d create mode 100644 gas/testsuite/gas/riscv/tprel-add.l create mode 100644 gas/testsuite/gas/riscv/tprel-add.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 72ae3bcd2f6..10eede5ce4b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2018-12-07 Jim Wilson + + 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. + : 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 * config/tc-ppc.c (md_assemble): Adjust relocs for VLE before diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 92ddf80cb41..9e2035b1092 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -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 index 00000000000..d81c1e23104 --- /dev/null +++ b/gas/testsuite/gas/riscv/tprel-add.d @@ -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 index 00000000000..74bb5352971 --- /dev/null +++ b/gas/testsuite/gas/riscv/tprel-add.l @@ -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 index 00000000000..15d748d7b6d --- /dev/null +++ b/gas/testsuite/gas/riscv/tprel-add.s @@ -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 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 5588e4b500e..880f863b4a4 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,8 @@ +2018-12-07 Jim Wilson + + PR gas/23956 + * riscv-opc.c (riscv_opcodes) <"add">: Use 1 not 0 for fourth arg. + 2018-12-06 Andrew Burgess * configure.ac (enable-cgen-maint): Support passing path to cgen diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 3da2a7702ba..29c6944a9a3 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -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 }, -- 2.30.2