From 21a186f28061ea51e422ae47d062793ceac2180f Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Wed, 20 Dec 2017 13:37:44 -0800 Subject: [PATCH] RISC-V: Add compressed instruction hints, and a few misc cleanups. gas/ * config/tc-riscv.c (risc_ip) : Add comment. * testsuite/gas/riscv/c-nonzero-imm.d, * testsuite/gas/riscv/c-nonzero-imm.l, * testsuite/gas/riscv/c-nonzero-imm.s, * testsuite/gas/riscv/c-nonzero-reg.d, * testsuite/gas/riscv/c-nonzero-reg.l, * testsuite/gas/riscv/c-nonzero-reg.s, * testsuite/gas/riscv/c-zero-imm-64.d, * testsuite/gas/riscv/c-zero-imm-64.s, * testsuite/gas/riscv/c-zero-imm.d, testsuite/gas/riscv/c-zero-imm.s, * testsuite/gas/riscv/c-zero-reg.d, * testsuite/gas/riscv/c-zero-reg.s: New. opcodes/ * riscv-opc.c (match_c_add_with_hint, match_c_lui_with_hint): New. (riscv_opcodes)
  • : Delete "d,0" line. Change Cj to Co. : Change Cj to Co. : Add explanatory comment for 4-operand add instruction. : Add support for immediate operand. : Use match_c_add_with_hint instead of match_c_add. : Use match_c_lui_with_hint instead of match_c_lui. : Use match_opcode instead of match_rd_nonzero. --- gas/ChangeLog | 15 ++++++++ gas/config/tc-riscv.c | 3 ++ gas/testsuite/gas/riscv/c-nonzero-imm.d | 3 ++ gas/testsuite/gas/riscv/c-nonzero-imm.l | 2 ++ gas/testsuite/gas/riscv/c-nonzero-imm.s | 3 ++ gas/testsuite/gas/riscv/c-nonzero-reg.d | 3 ++ gas/testsuite/gas/riscv/c-nonzero-reg.l | 4 +++ gas/testsuite/gas/riscv/c-nonzero-reg.s | 3 ++ gas/testsuite/gas/riscv/c-zero-imm-64.d | 11 ++++++ gas/testsuite/gas/riscv/c-zero-imm-64.s | 4 +++ gas/testsuite/gas/riscv/c-zero-imm.d | 16 +++++++++ gas/testsuite/gas/riscv/c-zero-imm.s | 10 ++++++ gas/testsuite/gas/riscv/c-zero-reg.d | 20 +++++++++++ gas/testsuite/gas/riscv/c-zero-reg.s | 13 +++++++ opcodes/ChangeLog | 11 ++++++ opcodes/riscv-opc.c | 48 ++++++++++++++++++------- 16 files changed, 156 insertions(+), 13 deletions(-) create mode 100644 gas/testsuite/gas/riscv/c-nonzero-imm.d create mode 100644 gas/testsuite/gas/riscv/c-nonzero-imm.l create mode 100644 gas/testsuite/gas/riscv/c-nonzero-imm.s create mode 100644 gas/testsuite/gas/riscv/c-nonzero-reg.d create mode 100644 gas/testsuite/gas/riscv/c-nonzero-reg.l create mode 100644 gas/testsuite/gas/riscv/c-nonzero-reg.s create mode 100644 gas/testsuite/gas/riscv/c-zero-imm-64.d create mode 100644 gas/testsuite/gas/riscv/c-zero-imm-64.s create mode 100644 gas/testsuite/gas/riscv/c-zero-imm.d create mode 100644 gas/testsuite/gas/riscv/c-zero-imm.s create mode 100644 gas/testsuite/gas/riscv/c-zero-reg.d create mode 100644 gas/testsuite/gas/riscv/c-zero-reg.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 525f771f0be..3d12e935821 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,18 @@ +2017-12-20 Jim Wilson + + * config/tc-riscv.c (risc_ip) : Add comment. + * testsuite/gas/riscv/c-nonzero-imm.d, + * testsuite/gas/riscv/c-nonzero-imm.l, + * testsuite/gas/riscv/c-nonzero-imm.s, + * testsuite/gas/riscv/c-nonzero-reg.d, + * testsuite/gas/riscv/c-nonzero-reg.l, + * testsuite/gas/riscv/c-nonzero-reg.s, + * testsuite/gas/riscv/c-zero-imm-64.d, + * testsuite/gas/riscv/c-zero-imm-64.s, + * testsuite/gas/riscv/c-zero-imm.d, testsuite/gas/riscv/c-zero-imm.s, + * testsuite/gas/riscv/c-zero-reg.d, + * testsuite/gas/riscv/c-zero-reg.s: New. + 2017-12-19 Tamar Christina PR 22559 diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index c2e5f30e506..a4e01b6c798 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -1384,6 +1384,9 @@ rvc_imm_done: case 'o': if (my_getSmallExpression (imm_expr, imm_reloc, s, p) || imm_expr->X_op != O_constant + /* C.addiw, c.li, and c.andi allow zero immediate. + C.addi allows zero immediate as hint. Otherwise this + is same as 'j'. */ || !VALID_RVC_IMM (imm_expr->X_add_number)) break; ip->insn_opcode |= ENCODE_RVC_IMM (imm_expr->X_add_number); diff --git a/gas/testsuite/gas/riscv/c-nonzero-imm.d b/gas/testsuite/gas/riscv/c-nonzero-imm.d new file mode 100644 index 00000000000..2c62290904a --- /dev/null +++ b/gas/testsuite/gas/riscv/c-nonzero-imm.d @@ -0,0 +1,3 @@ +#as: +#objdump: -dr +#error-output: c-nonzero-imm.l diff --git a/gas/testsuite/gas/riscv/c-nonzero-imm.l b/gas/testsuite/gas/riscv/c-nonzero-imm.l new file mode 100644 index 00000000000..09327195871 --- /dev/null +++ b/gas/testsuite/gas/riscv/c-nonzero-imm.l @@ -0,0 +1,2 @@ +.*: Assembler messages: +.*: Error: illegal operands `c.nop 0' diff --git a/gas/testsuite/gas/riscv/c-nonzero-imm.s b/gas/testsuite/gas/riscv/c-nonzero-imm.s new file mode 100644 index 00000000000..1b876ab56ba --- /dev/null +++ b/gas/testsuite/gas/riscv/c-nonzero-imm.s @@ -0,0 +1,3 @@ + .option rvc + c.nop 0 + c.nop 1 diff --git a/gas/testsuite/gas/riscv/c-nonzero-reg.d b/gas/testsuite/gas/riscv/c-nonzero-reg.d new file mode 100644 index 00000000000..39a65b53ebc --- /dev/null +++ b/gas/testsuite/gas/riscv/c-nonzero-reg.d @@ -0,0 +1,3 @@ +#as: -march=rv64gc +#objdump: -dr +#error-output: c-nonzero-reg.l diff --git a/gas/testsuite/gas/riscv/c-nonzero-reg.l b/gas/testsuite/gas/riscv/c-nonzero-reg.l new file mode 100644 index 00000000000..1d8fb6b8bae --- /dev/null +++ b/gas/testsuite/gas/riscv/c-nonzero-reg.l @@ -0,0 +1,4 @@ +.*: Assembler messages: +.*: Error: illegal operands `c.addiw x0,10' +.*: Error: illegal operands `c.jr x0' + diff --git a/gas/testsuite/gas/riscv/c-nonzero-reg.s b/gas/testsuite/gas/riscv/c-nonzero-reg.s new file mode 100644 index 00000000000..23d51c31b72 --- /dev/null +++ b/gas/testsuite/gas/riscv/c-nonzero-reg.s @@ -0,0 +1,3 @@ + .option rvc + c.addiw x0, 10 + c.jr x0 diff --git a/gas/testsuite/gas/riscv/c-zero-imm-64.d b/gas/testsuite/gas/riscv/c-zero-imm-64.d new file mode 100644 index 00000000000..9d1e490f859 --- /dev/null +++ b/gas/testsuite/gas/riscv/c-zero-imm-64.d @@ -0,0 +1,11 @@ +#as: -march=rv64gc +#objdump: -dr + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 <.text>: +[ ]+0:[ ]+2801[ ]+sext.w[ ]+a6,a6 +[ ]+2:[ ]+2881[ ]+sext.w[ ]+a7,a7 diff --git a/gas/testsuite/gas/riscv/c-zero-imm-64.s b/gas/testsuite/gas/riscv/c-zero-imm-64.s new file mode 100644 index 00000000000..ffe743e92d8 --- /dev/null +++ b/gas/testsuite/gas/riscv/c-zero-imm-64.s @@ -0,0 +1,4 @@ + .option rvc + # These are valid instructions. + addiw a6,a6,0 + c.addiw a7,0 diff --git a/gas/testsuite/gas/riscv/c-zero-imm.d b/gas/testsuite/gas/riscv/c-zero-imm.d new file mode 100644 index 00000000000..ac47e8061d2 --- /dev/null +++ b/gas/testsuite/gas/riscv/c-zero-imm.d @@ -0,0 +1,16 @@ +#as: +#objdump: -dr + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 <.text>: +[ ]+0:[ ]+4501[ ]+li[ ]+a0,0 +[ ]+2:[ ]+4581[ ]+li[ ]+a1,0 +[ ]+4:[ ]+8a01[ ]+andi[ ]+a2,a2,0 +[ ]+6:[ ]+8a81[ ]+andi[ ]+a3,a3,0 +[ ]+8:[ ]+00070713[ ]+mv[ ]+a4,a4 +[ ]+c:[ ]+0781[ ]+addi[ ]+a5,a5,0 +#... diff --git a/gas/testsuite/gas/riscv/c-zero-imm.s b/gas/testsuite/gas/riscv/c-zero-imm.s new file mode 100644 index 00000000000..650313d7cb0 --- /dev/null +++ b/gas/testsuite/gas/riscv/c-zero-imm.s @@ -0,0 +1,10 @@ + .option rvc + # These are valid instructions. + li a0,0 + c.li a1,0 + andi a2,a2,0 + c.andi a3,0 + # Don't let this compress to a hint. + addi a4,a4,0 + # These are hints. + c.addi a5,0 diff --git a/gas/testsuite/gas/riscv/c-zero-reg.d b/gas/testsuite/gas/riscv/c-zero-reg.d new file mode 100644 index 00000000000..2daf8963eb3 --- /dev/null +++ b/gas/testsuite/gas/riscv/c-zero-reg.d @@ -0,0 +1,20 @@ +#as: +#objdump: -dr + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 <.text>: +[ ]+0:[ ]+4005[ ]+c.li[ ]+zero,1 +[ ]+2:[ ]+6009[ ]+c.lui[ ]+zero,0x2 +[ ]+4:[ ]+000e[ ]+c.slli[ ]+zero,0x3 +[ ]+6:[ ]+8006[ ]+c.mv[ ]+zero,ra +[ ]+8:[ ]+9006[ ]+c.add[ ]+zero,ra +[ ]+a:[ ]+00500013[ ]+li[ ]+zero,5 +[ ]+e:[ ]+00006037[ ]+lui[ ]+zero,0x6 +[ ]+12:[ ]+00709013[ ]+slli[ ]+zero,ra,0x7 +[ ]+16:[ ]+00008013[ ]+mv[ ]+zero,ra +[ ]+1a:[ ]+00100033[ ]+add[ ]+zero,zero,ra +#... diff --git a/gas/testsuite/gas/riscv/c-zero-reg.s b/gas/testsuite/gas/riscv/c-zero-reg.s new file mode 100644 index 00000000000..414c8a490e6 --- /dev/null +++ b/gas/testsuite/gas/riscv/c-zero-reg.s @@ -0,0 +1,13 @@ + .option rvc + # These are hints. + c.li x0, 1 + c.lui x0, 2 + c.slli x0, 3 + c.mv x0, x1 + c.add x0, x1 + # Don't let these compress to hints. + li x0, 5 + lui x0, 6 + slli x0, x1, 7 + mv x0, x1 + add x0, x0, x1 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index aa31dd30138..3c5de6125ee 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,14 @@ +2017-12-20 Jim Wilson + + * riscv-opc.c (match_c_add_with_hint, match_c_lui_with_hint): New. + (riscv_opcodes)
  • : Delete "d,0" line. Change Cj to Co. + : Change Cj to Co. + : Add explanatory comment for 4-operand add instruction. + : Add support for immediate operand. + : Use match_c_add_with_hint instead of match_c_add. + : Use match_c_lui_with_hint instead of match_c_lui. + : Use match_opcode instead of match_rd_nonzero. + 2017-12-19 Tamar Christina PR gas/22559 diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 10448dac964..094541cff0d 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -113,6 +113,15 @@ match_c_add (const struct riscv_opcode *op, insn_t insn) return match_rd_nonzero (op, insn) && ((insn & MASK_CRS2) != 0); } +/* We don't allow mv zero,X to become a c.mv hint, so we need a separate + matching function for this. */ + +static int +match_c_add_with_hint (const struct riscv_opcode *op, insn_t insn) +{ + return match_opcode (op, insn) && ((insn & MASK_CRS2) != 0); +} + static int match_c_addi16sp (const struct riscv_opcode *op, insn_t insn) { @@ -129,6 +138,17 @@ match_c_lui (const struct riscv_opcode *op, insn_t insn) && EXTRACT_RVC_LUI_IMM (insn) != 0); } +/* We don't allow lui zero,X to become a c.lui hint, so we need a separate + matching function for this. */ + +static int +match_c_lui_with_hint (const struct riscv_opcode *op, insn_t insn) +{ + return (match_opcode (op, insn) + && (((insn & MASK_RD) >> OP_SH_RD) != 2) + && EXTRACT_RVC_LUI_IMM (insn) != 0); +} + static int match_c_addi4spn (const struct riscv_opcode *op, insn_t insn) { @@ -171,19 +191,18 @@ const struct riscv_opcode riscv_opcodes[] = {"lui", "C", "d,Cu", MATCH_C_LUI, MASK_C_LUI, match_c_lui, INSN_ALIAS }, {"lui", "I", "d,u", MATCH_LUI, MASK_LUI, match_opcode, 0 }, {"li", "C", "d,Cv", MATCH_C_LUI, MASK_C_LUI, match_c_lui, INSN_ALIAS }, -{"li", "C", "d,Cj", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, INSN_ALIAS }, -{"li", "C", "d,0", MATCH_C_LI, MASK_C_LI | MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS }, +{"li", "C", "d,Co", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, INSN_ALIAS }, {"li", "I", "d,j", MATCH_ADDI, MASK_ADDI | MASK_RS1, match_opcode, INSN_ALIAS }, /* addi */ {"li", "I", "d,I", 0, (int) M_LI, match_never, INSN_MACRO }, {"mv", "C", "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS }, {"mv", "I", "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS }, {"move", "C", "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS }, {"move", "I", "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS }, -{"andi", "C", "Cs,Cw,Cj", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS }, +{"andi", "C", "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS }, {"andi", "I", "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, 0 }, {"and", "C", "Cs,Cw,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS }, {"and", "C", "Cs,Ct,Cw", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS }, -{"and", "C", "Cs,Cw,Cj", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS }, +{"and", "C", "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS }, {"and", "I", "d,s,t", MATCH_AND, MASK_AND, match_opcode, 0 }, {"and", "I", "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, INSN_ALIAS }, {"beqz", "C", "Cs,Cp", MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, INSN_ALIAS }, @@ -210,10 +229,12 @@ const struct riscv_opcode riscv_opcodes[] = {"addi", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, 0 }, {"add", "C", "d,CU,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS }, {"add", "C", "d,CV,CU", MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS }, -{"add", "C", "d,CU,Cj", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS }, +{"add", "C", "d,CU,Co", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS }, {"add", "C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, INSN_ALIAS }, {"add", "C", "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, INSN_ALIAS }, {"add", "I", "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", "I", "d,s,t,0",MATCH_ADD, MASK_ADD, match_opcode, 0 }, {"add", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, INSN_ALIAS }, {"la", "I", "d,A", 0, (int) M_LA, match_never, INSN_MACRO }, @@ -305,11 +326,11 @@ const struct riscv_opcode riscv_opcodes[] = {"sd", "64I", "t,A,s", 0, (int) M_SD, match_never, INSN_MACRO }, {"sext.w", "64C", "d,CU", MATCH_C_ADDIW, MASK_C_ADDIW | MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS }, {"sext.w", "64I", "d,s", MATCH_ADDIW, MASK_ADDIW | MASK_IMM, match_opcode, INSN_ALIAS }, -{"addiw", "64C", "d,CU,Cj", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS }, +{"addiw", "64C", "d,CU,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS }, {"addiw", "64I", "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, 0 }, {"addw", "64C", "Cs,Cw,Ct", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, INSN_ALIAS }, {"addw", "64C", "Cs,Ct,Cw", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, INSN_ALIAS }, -{"addw", "64C", "d,CU,Cj", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS }, +{"addw", "64C", "d,CU,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS }, {"addw", "64I", "d,s,t", MATCH_ADDW, MASK_ADDW, match_opcode, 0 }, {"addw", "64I", "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, INSN_ALIAS }, {"negw", "64I", "d,t", MATCH_SUBW, MASK_SUBW | MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0 */ @@ -645,18 +666,19 @@ const struct riscv_opcode riscv_opcodes[] = {"c.swsp", "C", "CV,CM(Cc)", MATCH_C_SWSP, MASK_C_SWSP, match_opcode, 0 }, {"c.sw", "C", "Ct,Ck(Cs)", MATCH_C_SW, MASK_C_SW, match_opcode, 0 }, {"c.nop", "C", "", MATCH_C_ADDI, 0xffff, match_opcode, INSN_ALIAS }, -{"c.mv", "C", "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, 0 }, -{"c.lui", "C", "d,Cu", MATCH_C_LUI, MASK_C_LUI, match_c_lui, 0 }, -{"c.li", "C", "d,Co", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, 0 }, +{"c.nop", "C", "Cj", MATCH_C_ADDI, MASK_C_ADDI | MASK_RD, match_opcode, INSN_ALIAS }, +{"c.mv", "C", "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add_with_hint, 0 }, +{"c.lui", "C", "d,Cu", MATCH_C_LUI, MASK_C_LUI, match_c_lui_with_hint, 0 }, +{"c.li", "C", "d,Co", MATCH_C_LI, MASK_C_LI, match_opcode, 0 }, {"c.addi4spn","C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, 0 }, {"c.addi16sp","C", "Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, 0 }, -{"c.addi", "C", "d,Cj", MATCH_C_ADDI, MASK_C_ADDI, match_opcode, 0 }, -{"c.add", "C", "d,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add, 0 }, +{"c.addi", "C", "d,Co", MATCH_C_ADDI, MASK_C_ADDI, match_opcode, 0 }, +{"c.add", "C", "d,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add_with_hint, 0 }, {"c.sub", "C", "Cs,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, 0 }, {"c.and", "C", "Cs,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, 0 }, {"c.or", "C", "Cs,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, 0 }, {"c.xor", "C", "Cs,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, 0 }, -{"c.slli", "C", "d,C>", MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, 0 }, +{"c.slli", "C", "d,C>", MATCH_C_SLLI, MASK_C_SLLI, match_opcode, 0 }, {"c.srli", "C", "Cs,C>", MATCH_C_SRLI, MASK_C_SRLI, match_opcode, 0 }, {"c.srai", "C", "Cs,C>", MATCH_C_SRAI, MASK_C_SRAI, match_opcode, 0 }, {"c.andi", "C", "Cs,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, 0 }, -- 2.30.2