123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- From 16266fab77ff6e3760a08f107c782b91e595b33e Mon Sep 17 00:00:00 2001
- From: Nelson Chu <nelson.chu@sifive.com>
- Date: Wed, 9 Dec 2020 13:53:22 +0800
- Subject: [PATCH 44/48] RISC-V: Add sext.[bh] and zext.[bhw] pseudo
- instructions.
- https://github.com/riscv/riscv-asm-manual/pull/61
- We aleady have sext.w, so just add sext.b, sext.h, zext.b, zext.h
- and zext.w. In a certain sense, zext.b is not a pseudo - It is an
- alias of andi. Similarly, sext.b and sext.h are aliases of other
- rvb instructions, when we enable b extension; But they are pseudos
- when we just enable rvi. However, this patch does not consider the
- rvb cases. Besides, zext.w is only valid in rv64.
- gas/
- * config/tc-riscv.c (riscv_ext): New function. Use md_assemblef
- to expand the zext and sext pseudos, to give them a chance to be
- expanded into c-ext instructions.
- (macro): Handle M_ZEXTH, M_ZEXTW, M_SEXTB and M_SEXTH.
- * testsuite/gas/riscv/ext.s: New testcase.
- * testsuite/gas/riscv/ext-32.d: Likewise.
- * testsuite/gas/riscv/ext-64.d: Likewise.
- include/
- * opcode/riscv.h (M_ZEXTH, M_ZEXTW, M_SEXTB, M_SEXTH.): Added.
- opcodes/
- * riscv-opc.c (riscv_opcodes): Add sext.[bh] and zext.[bhw].
- ---
- gas/config/tc-riscv.c | 33 +++++++++++++++++++++
- gas/testsuite/gas/riscv/ext-32.d | 39 ++++++++++++++++++++++++
- gas/testsuite/gas/riscv/ext-64.d | 51 ++++++++++++++++++++++++++++++++
- gas/testsuite/gas/riscv/ext.s | 38 ++++++++++++++++++++++++
- include/opcode/riscv.h | 4 +++
- opcodes/riscv-opc.c | 5 ++++
- 6 files changed, 170 insertions(+)
- create mode 100644 gas/testsuite/gas/riscv/ext-32.d
- create mode 100644 gas/testsuite/gas/riscv/ext-64.d
- create mode 100644 gas/testsuite/gas/riscv/ext.s
- diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
- index 2a5ac9c861..bee1186c3a 100644
- --- a/gas/config/tc-riscv.c
- +++ b/gas/config/tc-riscv.c
- @@ -1623,6 +1623,23 @@ vector_macro (struct riscv_cl_insn *ip)
- }
- }
-
- +/* Zero extend and sign extend byte/half-word/word. */
- +
- +static void
- +riscv_ext (int destreg, int srcreg, unsigned shift, bfd_boolean sign)
- +{
- + if (sign)
- + {
- + md_assemblef ("slli x%d, x%d, 0x%x", destreg, srcreg, shift);
- + md_assemblef ("srai x%d, x%d, 0x%x", destreg, destreg, shift);
- + }
- + else
- + {
- + md_assemblef ("slli x%d, x%d, 0x%x", destreg, srcreg, shift);
- + md_assemblef ("srli x%d, x%d, 0x%x", destreg, destreg, shift);
- + }
- +}
- +
- /* Expand RISC-V assembly macros into one or more instructions. */
- static void
- macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
- @@ -1769,6 +1786,22 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
- vector_macro (ip);
- break;
-
- + case M_ZEXTH:
- + riscv_ext (rd, rs1, xlen - 16, FALSE);
- + break;
- +
- + case M_ZEXTW:
- + riscv_ext (rd, rs1, xlen - 32, FALSE);
- + break;
- +
- + case M_SEXTB:
- + riscv_ext (rd, rs1, xlen - 8, TRUE);
- + break;
- +
- + case M_SEXTH:
- + riscv_ext (rd, rs1, xlen - 16, TRUE);
- + break;
- +
- default:
- as_bad (_("Macro %s not implemented"), ip->insn_mo->name);
- break;
- diff --git a/gas/testsuite/gas/riscv/ext-32.d b/gas/testsuite/gas/riscv/ext-32.d
- new file mode 100644
- index 0000000000..918c9c8a16
- --- /dev/null
- +++ b/gas/testsuite/gas/riscv/ext-32.d
- @@ -0,0 +1,39 @@
- +#as: -march=rv32i
- +#source: ext.s
- +#objdump: -d
- +
- +.*:[ ]+file format .*
- +
- +
- +Disassembly of section .text:
- +
- +0+000 <target>:
- +[ ]+0:[ ]+0ff57513[ ]+zext.b[ ]+a0,a0
- +[ ]+4:[ ]+01051513[ ]+slli[ ]+a0,a0,0x10
- +[ ]+8:[ ]+01055513[ ]+srli[ ]+a0,a0,0x10
- +[ ]+c:[ ]+01851513[ ]+slli[ ]+a0,a0,0x18
- +[ ]+10:[ ]+41855513[ ]+srai[ ]+a0,a0,0x18
- +[ ]+14:[ ]+01051513[ ]+slli[ ]+a0,a0,0x10
- +[ ]+18:[ ]+41055513[ ]+srai[ ]+a0,a0,0x10
- +[ ]+1c:[ ]+0ff67593[ ]+zext.b[ ]+a1,a2
- +[ ]+20:[ ]+01061593[ ]+slli[ ]+a1,a2,0x10
- +[ ]+24:[ ]+0105d593[ ]+srli[ ]+a1,a1,0x10
- +[ ]+28:[ ]+01861593[ ]+slli[ ]+a1,a2,0x18
- +[ ]+2c:[ ]+4185d593[ ]+srai[ ]+a1,a1,0x18
- +[ ]+30:[ ]+01061593[ ]+slli[ ]+a1,a2,0x10
- +[ ]+34:[ ]+4105d593[ ]+srai[ ]+a1,a1,0x10
- +[ ]+38:[ ]+0ff57513[ ]+zext.b[ ]+a0,a0
- +[ ]+3c:[ ]+0542[ ]+slli[ ]+a0,a0,0x10
- +[ ]+3e:[ ]+8141[ ]+srli[ ]+a0,a0,0x10
- +[ ]+40:[ ]+0562[ ]+slli[ ]+a0,a0,0x18
- +[ ]+42:[ ]+8561[ ]+srai[ ]+a0,a0,0x18
- +[ ]+44:[ ]+0542[ ]+slli[ ]+a0,a0,0x10
- +[ ]+46:[ ]+8541[ ]+srai[ ]+a0,a0,0x10
- +[ ]+48:[ ]+0ff67593[ ]+zext.b[ ]+a1,a2
- +[ ]+4c:[ ]+01061593[ ]+slli[ ]+a1,a2,0x10
- +[ ]+50:[ ]+81c1[ ]+srli[ ]+a1,a1,0x10
- +[ ]+52:[ ]+01861593[ ]+slli[ ]+a1,a2,0x18
- +[ ]+56:[ ]+85e1[ ]+srai[ ]+a1,a1,0x18
- +[ ]+58:[ ]+01061593[ ]+slli[ ]+a1,a2,0x10
- +[ ]+5c:[ ]+85c1[ ]+srai[ ]+a1,a1,0x10
- +#...
- diff --git a/gas/testsuite/gas/riscv/ext-64.d b/gas/testsuite/gas/riscv/ext-64.d
- new file mode 100644
- index 0000000000..49d109b1db
- --- /dev/null
- +++ b/gas/testsuite/gas/riscv/ext-64.d
- @@ -0,0 +1,51 @@
- +#as: -march=rv64i -defsym __64_bit__=1
- +#source: ext.s
- +#objdump: -d
- +
- +.*:[ ]+file format .*
- +
- +
- +Disassembly of section .text:
- +
- +0+000 <target>:
- +[ ]+0:[ ]+0ff57513[ ]+zext.b[ ]+a0,a0
- +[ ]+4:[ ]+03051513[ ]+slli[ ]+a0,a0,0x30
- +[ ]+8:[ ]+03055513[ ]+srli[ ]+a0,a0,0x30
- +[ ]+c:[ ]+03851513[ ]+slli[ ]+a0,a0,0x38
- +[ ]+10:[ ]+43855513[ ]+srai[ ]+a0,a0,0x38
- +[ ]+14:[ ]+03051513[ ]+slli[ ]+a0,a0,0x30
- +[ ]+18:[ ]+43055513[ ]+srai[ ]+a0,a0,0x30
- +[ ]+1c:[ ]+0ff67593[ ]+zext.b[ ]+a1,a2
- +[ ]+20:[ ]+03061593[ ]+slli[ ]+a1,a2,0x30
- +[ ]+24:[ ]+0305d593[ ]+srli[ ]+a1,a1,0x30
- +[ ]+28:[ ]+03861593[ ]+slli[ ]+a1,a2,0x38
- +[ ]+2c:[ ]+4385d593[ ]+srai[ ]+a1,a1,0x38
- +[ ]+30:[ ]+03061593[ ]+slli[ ]+a1,a2,0x30
- +[ ]+34:[ ]+4305d593[ ]+srai[ ]+a1,a1,0x30
- +[ ]+38:[ ]+02051513[ ]+slli[ ]+a0,a0,0x20
- +[ ]+3c:[ ]+02055513[ ]+srli[ ]+a0,a0,0x20
- +[ ]+40:[ ]+0005051b[ ]+sext.w[ ]+a0,a0
- +[ ]+44:[ ]+02061593[ ]+slli[ ]+a1,a2,0x20
- +[ ]+48:[ ]+0205d593[ ]+srli[ ]+a1,a1,0x20
- +[ ]+4c:[ ]+0006059b[ ]+sext.w[ ]+a1,a2
- +[ ]+50:[ ]+0ff57513[ ]+zext.b[ ]+a0,a0
- +[ ]+54:[ ]+1542[ ]+slli[ ]+a0,a0,0x30
- +[ ]+56:[ ]+9141[ ]+srli[ ]+a0,a0,0x30
- +[ ]+58:[ ]+1562[ ]+slli[ ]+a0,a0,0x38
- +[ ]+5a:[ ]+9561[ ]+srai[ ]+a0,a0,0x38
- +[ ]+5c:[ ]+1542[ ]+slli[ ]+a0,a0,0x30
- +[ ]+5e:[ ]+9541[ ]+srai[ ]+a0,a0,0x30
- +[ ]+60:[ ]+0ff67593[ ]+zext.b[ ]+a1,a2
- +[ ]+64:[ ]+03061593[ ]+slli[ ]+a1,a2,0x30
- +[ ]+68:[ ]+91c1[ ]+srli[ ]+a1,a1,0x30
- +[ ]+6a:[ ]+03861593[ ]+slli[ ]+a1,a2,0x38
- +[ ]+6e:[ ]+95e1[ ]+srai[ ]+a1,a1,0x38
- +[ ]+70:[ ]+03061593[ ]+slli[ ]+a1,a2,0x30
- +[ ]+74:[ ]+95c1[ ]+srai[ ]+a1,a1,0x30
- +[ ]+76:[ ]+1502[ ]+slli[ ]+a0,a0,0x20
- +[ ]+78:[ ]+9101[ ]+srli[ ]+a0,a0,0x20
- +[ ]+7a:[ ]+2501[ ]+sext.w[ ]+a0,a0
- +[ ]+7c:[ ]+02061593[ ]+slli[ ]+a1,a2,0x20
- +[ ]+80:[ ]+9181[ ]+srli[ ]+a1,a1,0x20
- +[ ]+82:[ ]+0006059b[ ]+sext.w[ ]+a1,a2
- +#...
- diff --git a/gas/testsuite/gas/riscv/ext.s b/gas/testsuite/gas/riscv/ext.s
- new file mode 100644
- index 0000000000..f95713422a
- --- /dev/null
- +++ b/gas/testsuite/gas/riscv/ext.s
- @@ -0,0 +1,38 @@
- +target:
- + .option norvc
- + zext.b a0, a0
- + zext.h a0, a0
- + sext.b a0, a0
- + sext.h a0, a0
- +
- + zext.b a1, a2
- + zext.h a1, a2
- + sext.b a1, a2
- + sext.h a1, a2
- +
- +.ifdef __64_bit__
- + zext.w a0, a0
- + sext.w a0, a0
- +
- + zext.w a1, a2
- + sext.w a1, a2
- +.endif
- +
- + .option rvc
- + zext.b a0, a0
- + zext.h a0, a0
- + sext.b a0, a0
- + sext.h a0, a0
- +
- + zext.b a1, a2
- + zext.h a1, a2
- + sext.b a1, a2
- + sext.h a1, a2
- +
- +.ifdef __64_bit__
- + zext.w a0, a0
- + sext.w a0, a0
- +
- + zext.w a1, a2
- + sext.w a1, a2
- +.endif
- diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
- index 9af4f6514c..71498563c3 100644
- --- a/include/opcode/riscv.h
- +++ b/include/opcode/riscv.h
- @@ -583,6 +583,10 @@ enum
- M_VMSGEU,
- M_RL,
- M_FL,
- + M_ZEXTH,
- + M_ZEXTW,
- + M_SEXTB,
- + M_SEXTH,
- M_NUM_MACROS
- };
-
- diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
- index 5d49912e2e..5f0885b5c6 100644
- --- a/opcodes/riscv-opc.c
- +++ b/opcodes/riscv-opc.c
- @@ -705,6 +705,7 @@ const struct riscv_opcode riscv_opcodes[] =
- {"mv", 0, INSN_CLASS_I, "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS },
- {"move", 0, INSN_CLASS_C, "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
- {"move", 0, INSN_CLASS_I, "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS },
- +{"zext.b", 0, INSN_CLASS_I, "d,s", MATCH_ANDI | ENCODE_ITYPE_IMM (255), MASK_ANDI | MASK_IMM, match_opcode, INSN_ALIAS },
- {"andi", 0, INSN_CLASS_C, "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
- {"andi", 0, INSN_CLASS_I, "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, 0 },
- {"and", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS },
- @@ -1162,6 +1163,7 @@ const struct riscv_opcode riscv_opcodes[] =
- {"sh3add", 0, INSN_CLASS_B_OR_ZBA, "d,s,t", MATCH_SH3ADD, MASK_SH3ADD, match_opcode, 0 },
- {"slliu.w", 64, INSN_CLASS_B_OR_ZBA, "d,s,>", MATCH_SLLIU_W, MASK_SLLIU_W, match_opcode, 0 },
- {"zext.w", 64, INSN_CLASS_B_OR_ZBA_OR_ZBB, "d,s", MATCH_ADDU_W, MASK_ADDU_W | MASK_RS2, match_opcode, INSN_ALIAS },
- +{"zext.w", 64, INSN_CLASS_I, "d,s", 0, (int) M_ZEXTW, match_never, INSN_MACRO },
- {"addu.w", 64, INSN_CLASS_B_OR_ZBA, "d,s,t", MATCH_ADDU_W, MASK_ADDU_W, match_opcode, 0 },
- {"sh1addu.w",64, INSN_CLASS_B_OR_ZBA, "d,s,t", MATCH_SH1ADDU_W, MASK_SH1ADDU_W, match_opcode, 0 },
- {"sh2addu.w",64, INSN_CLASS_B_OR_ZBA, "d,s,t", MATCH_SH2ADDU_W, MASK_SH2ADDU_W, match_opcode, 0 },
- @@ -1184,9 +1186,12 @@ const struct riscv_opcode riscv_opcodes[] =
- {"ror", 0, INSN_CLASS_B_OR_ZBB, "d,s,t", MATCH_ROR, MASK_ROR, match_opcode, 0 },
- {"ror", 0, INSN_CLASS_B_OR_ZBB, "d,s,>", MATCH_RORI, MASK_RORI, match_opcode, INSN_ALIAS },
- {"sext.b", 0, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_SEXT_B, MASK_SEXT_B, match_opcode, 0 },
- +{"sext.b", 0, INSN_CLASS_I, "d,s", 0, (int) M_SEXTB, match_never, INSN_MACRO },
- {"sext.h", 0, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_SEXT_H, MASK_SEXT_H, match_opcode, 0 },
- +{"sext.h", 0, INSN_CLASS_I, "d,s", 0, (int) M_SEXTH, match_never, INSN_MACRO },
- {"zext.h", 32, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_PACK, MASK_PACK | MASK_RS2, match_opcode, INSN_ALIAS }, /* pack with rs2=x0 */
- {"zext.h", 64, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_PACKW, MASK_PACKW | MASK_RS2, match_opcode, INSN_ALIAS }, /* packw with rs2=x0 */
- +{"zext.h", 0, INSN_CLASS_I, "d,s", 0, (int) M_ZEXTH, match_never, INSN_MACRO },
- {"clzw", 64, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_CLZW, MASK_CLZW, match_opcode, 0 },
- {"ctzw", 64, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_CTZW, MASK_CTZW, match_opcode, 0 },
- {"pcntw", 64, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_PCNTW, MASK_PCNTW, match_opcode, 0 },
- --
- 2.33.0
|