[PATCH v2] RISC-V: Add sext.[bh] and zext.[bhw] pseudo instructions.
Nelson Chu
nelson.chu@sifive.com
Wed Dec 9 07:49:54 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. 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.
* 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..f37951f 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -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 },
--
2.7.4
More information about the Binutils
mailing list