RISC-V: Add sext.[bh] and zext.[bhw] pseudo instructions.
authorNelson Chu <nelson.chu@sifive.com>
Wed, 9 Dec 2020 05:53:22 +0000 (13:53 +0800)
committerNelson Chu <nelson.chu@sifive.com>
Thu, 10 Dec 2020 02:50:44 +0000 (10:50 +0800)
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/ChangeLog
gas/config/tc-riscv.c
gas/testsuite/gas/riscv/ext-32.d [new file with mode: 0644]
gas/testsuite/gas/riscv/ext-64.d [new file with mode: 0644]
gas/testsuite/gas/riscv/ext.s [new file with mode: 0644]
include/ChangeLog
include/opcode/riscv.h
opcodes/ChangeLog
opcodes/riscv-opc.c

index d657f87aa67cc903837ffa66429882c111b5547d..6672da456cb1128ddd58af78567e09d9b73dbac7 100644 (file)
@@ -1,3 +1,13 @@
+2020-12-10  Nelson Chu  <nelson.chu@sifive.com>
+
+       * 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.
+
 2020-12-10  Nelson Chu  <nelson.chu@sifive.com>
 
        * config/tc-riscv.c (riscv_multi_subset_supports): Handle INSN_CLASS_ZICSR
index dfdbadf19ee98a516ba5eceb8d0aaa6661941259..ca7e52a16915a405b9eb55fc887105fd4d976913 100644 (file)
@@ -1433,6 +1433,23 @@ load_const (int reg, expressionS *ep)
     }
 }
 
+/* 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,
@@ -1554,6 +1571,22 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
       riscv_call (rd, rs1, imm_expr, *imm_reloc);
       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 (file)
index 0000000..918c9c8
--- /dev/null
@@ -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 (file)
index 0000000..49d109b
--- /dev/null
@@ -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 (file)
index 0000000..f957134
--- /dev/null
@@ -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
index 6f4614f4a26f243537107507684f80926a21c225..cc235e08fab1a7649e1e29148d2b02a1a36b55de 100644 (file)
@@ -1,3 +1,7 @@
+2020-12-10  Nelson Chu  <nelson.chu@sifive.com>
+
+       * opcode/riscv.h (M_ZEXTH, M_ZEXTW, M_SEXTB, M_SEXTH.): Added.
+
 2020-12-10  Nelson Chu  <nelson.chu@sifive.com>
 
        * opcode/riscv.h: Add INSN_CLASS_ZICSR and INSN_CLASS_ZIFENCEI.
index 6a9fd4a7dcf91b38e2470c2a7bef2ccf48946d20..1949072b83833fc1dc7ca60212640d4f23d6e50c 100644 (file)
@@ -480,6 +480,10 @@ enum
   M_CALL,
   M_J,
   M_LI,
+  M_ZEXTH,
+  M_ZEXTW,
+  M_SEXTB,
+  M_SEXTH,
   M_NUM_MACROS
 };
 
index b3801196591a40876107635195bf586d823c9098..92a95254a541389971760b669bdf67a4bd74bd29 100644 (file)
@@ -1,3 +1,7 @@
+2020-12-10  Nelson Chu  <nelson.chu@sifive.com>
+
+       * riscv-opc.c (riscv_opcodes): Add sext.[bh] and zext.[bhw].
+
 2020-12-10  Nelson Chu  <nelson.chu@sifive.com>
 
        * disassemble.h (riscv_get_disassembler): Declare.
index 4d9ba369d741804592e83c2fa310ecd0043eb1c4..f90d717755070d5068b7f56d87b017512a5d55a1 100644 (file)
@@ -238,6 +238,10 @@ 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 },
+{"sext.b",      0, INSN_CLASS_I,   "d,s",  0,    (int) M_SEXTB,  match_never, INSN_MACRO },
+{"sext.h",      0, INSN_CLASS_I,   "d,s",  0,    (int) M_SEXTH,  match_never, INSN_MACRO },
+{"zext.b",      0, INSN_CLASS_I,   "d,s",  MATCH_ANDI | ENCODE_ITYPE_IMM (255), MASK_ANDI | MASK_IMM, match_opcode, INSN_ALIAS },
+{"zext.h",      0, INSN_CLASS_I,   "d,s",  0,    (int) M_ZEXTH,  match_never, INSN_MACRO },
 {"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 },
@@ -370,6 +374,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"sd",         64, INSN_CLASS_C, "Ct,Cl(Cs)",  MATCH_C_SD, MASK_C_SD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
 {"sd",         64, INSN_CLASS_I, "t,q(s)",  MATCH_SD, MASK_SD, match_opcode, INSN_DREF|INSN_8_BYTE },
 {"sd",         64, INSN_CLASS_I, "t,A,s",  0, (int) M_SD, match_never, INSN_MACRO },
+{"zext.w",     64, INSN_CLASS_I, "d,s",    0, (int) M_ZEXTW,  match_never, INSN_MACRO },
 {"sext.w",     64, INSN_CLASS_C, "d,CU",  MATCH_C_ADDIW, MASK_C_ADDIW | MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS },
 {"sext.w",     64, INSN_CLASS_I, "d,s",  MATCH_ADDIW, MASK_ADDIW | MASK_IMM, match_opcode, INSN_ALIAS },
 {"addiw",      64, INSN_CLASS_C, "d,CU,Co",  MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },