[PATCH] RISC-V: Add sext.[bh] and zext.[bhw] pseudo instructions.

Nelson Chu nelson.chu@sifive.com
Wed Dec 9 07:22:00 GMT 2020


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.

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.
    * testsuite/gas/riscv/ext-noalias-32.d: Likewise.
    * testsuite/gas/riscv/ext-noalias-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-noalias-32.d | 39 ++++++++++++++++++++++++
 gas/testsuite/gas/riscv/ext-noalias-64.d | 51 ++++++++++++++++++++++++++++++++
 gas/testsuite/gas/riscv/ext.s            | 38 ++++++++++++++++++++++++
 include/opcode/riscv.h                   |  4 +++
 opcodes/riscv-opc.c                      |  5 ++++
 8 files changed, 260 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-noalias-32.d
 create mode 100644 gas/testsuite/gas/riscv/ext-noalias-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 5e140fe..f902486 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1427,6 +1427,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,
@@ -1548,6 +1565,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
index 0000000..918c9c8
--- /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 0000000..49d109b
--- /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-noalias-32.d b/gas/testsuite/gas/riscv/ext-noalias-32.d
new file mode 100644
index 0000000..7ec1a41
--- /dev/null
+++ b/gas/testsuite/gas/riscv/ext-noalias-32.d
@@ -0,0 +1,39 @@
+#as: -march=rv32i
+#source: ext.s
+#objdump: -d -Mno-aliases
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+0:[ 	]+0ff57513[ 	]+andi[ 	]+a0,a0,255
+[ 	]+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[ 	]+andi[ 	]+a1,a2,255
+[ 	]+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[ 	]+andi[ 	]+a0,a0,255
+[ 	]+3c:[ 	]+0542[ 	]+c.slli[ 	]+a0,0x10
+[ 	]+3e:[ 	]+8141[ 	]+c.srli[ 	]+a0,0x10
+[ 	]+40:[ 	]+0562[ 	]+c.slli[ 	]+a0,0x18
+[ 	]+42:[ 	]+8561[ 	]+c.srai[ 	]+a0,0x18
+[ 	]+44:[ 	]+0542[ 	]+c.slli[ 	]+a0,0x10
+[ 	]+46:[ 	]+8541[ 	]+c.srai[ 	]+a0,0x10
+[ 	]+48:[ 	]+0ff67593[ 	]+andi[ 	]+a1,a2,255
+[ 	]+4c:[ 	]+01061593[ 	]+slli[ 	]+a1,a2,0x10
+[ 	]+50:[ 	]+81c1[ 	]+c.srli[ 	]+a1,0x10
+[ 	]+52:[ 	]+01861593[ 	]+slli[ 	]+a1,a2,0x18
+[ 	]+56:[ 	]+85e1[ 	]+c.srai[ 	]+a1,0x18
+[ 	]+58:[ 	]+01061593[ 	]+slli[ 	]+a1,a2,0x10
+[ 	]+5c:[ 	]+85c1[ 	]+c.srai[ 	]+a1,0x10
+#...
diff --git a/gas/testsuite/gas/riscv/ext-noalias-64.d b/gas/testsuite/gas/riscv/ext-noalias-64.d
new file mode 100644
index 0000000..543db1b
--- /dev/null
+++ b/gas/testsuite/gas/riscv/ext-noalias-64.d
@@ -0,0 +1,51 @@
+#as: -march=rv64i -defsym __64_bit__=1
+#source: ext.s
+#objdump: -d -Mno-aliases
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+0:[ 	]+0ff57513[ 	]+andi[ 	]+a0,a0,255
+[ 	]+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[ 	]+andi[ 	]+a1,a2,255
+[ 	]+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[ 	]+addiw[ 	]+a0,a0,0
+[ 	]+44:[ 	]+02061593[ 	]+slli[ 	]+a1,a2,0x20
+[ 	]+48:[ 	]+0205d593[ 	]+srli[ 	]+a1,a1,0x20
+[ 	]+4c:[ 	]+0006059b[ 	]+addiw[ 	]+a1,a2,0
+[ 	]+50:[ 	]+0ff57513[ 	]+andi[ 	]+a0,a0,255
+[ 	]+54:[ 	]+1542[ 	]+c.slli[ 	]+a0,0x30
+[ 	]+56:[ 	]+9141[ 	]+c.srli[ 	]+a0,0x30
+[ 	]+58:[ 	]+1562[ 	]+c.slli[ 	]+a0,0x38
+[ 	]+5a:[ 	]+9561[ 	]+c.srai[ 	]+a0,0x38
+[ 	]+5c:[ 	]+1542[ 	]+c.slli[ 	]+a0,0x30
+[ 	]+5e:[ 	]+9541[ 	]+c.srai[ 	]+a0,0x30
+[ 	]+60:[ 	]+0ff67593[ 	]+andi[ 	]+a1,a2,255
+[ 	]+64:[ 	]+03061593[ 	]+slli[ 	]+a1,a2,0x30
+[ 	]+68:[ 	]+91c1[ 	]+c.srli[ 	]+a1,0x30
+[ 	]+6a:[ 	]+03861593[ 	]+slli[ 	]+a1,a2,0x38
+[ 	]+6e:[ 	]+95e1[ 	]+c.srai[ 	]+a1,0x38
+[ 	]+70:[ 	]+03061593[ 	]+slli[ 	]+a1,a2,0x30
+[ 	]+74:[ 	]+95c1[ 	]+c.srai[ 	]+a1,0x30
+[ 	]+76:[ 	]+1502[ 	]+c.slli[ 	]+a0,0x20
+[ 	]+78:[ 	]+9101[ 	]+c.srli[ 	]+a0,0x20
+[ 	]+7a:[ 	]+2501[ 	]+c.addiw[ 	]+a0,0
+[ 	]+7c:[ 	]+02061593[ 	]+slli[ 	]+a1,a2,0x20
+[ 	]+80:[ 	]+9181[ 	]+c.srli[ 	]+a1,0x20
+[ 	]+82:[ 	]+0006059b[ 	]+addiw[ 	]+a1,a2,0
+#...
diff --git a/gas/testsuite/gas/riscv/ext.s b/gas/testsuite/gas/riscv/ext.s
new file mode 100644
index 0000000..f957134
--- /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 680780a..69307c0 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -478,6 +478,10 @@ enum
   M_CALL,
   M_J,
   M_LI,
+  M_ZEXTH,
+  M_ZEXTW,
+  M_SEXTB,
+  M_SEXTH,
   M_NUM_MACROS
 };
 
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 7ca44dc..818fccb 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -238,6 +238,11 @@ 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 },
+{"zext.w",      0, INSN_CLASS_I,   "d,s",  0,    (int) M_ZEXTW,  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 },
-- 
2.7.4



More information about the Binutils mailing list