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].
This commit is contained in:
Nelson Chu 2020-12-09 13:53:22 +08:00
parent 8152e0407c
commit c2137f55ad
9 changed files with 188 additions and 0 deletions

View 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

View 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;

View File

@ -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
#...

View File

@ -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
#...

View File

@ -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

View 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.

View File

@ -480,6 +480,10 @@ enum
M_CALL,
M_J,
M_LI,
M_ZEXTH,
M_ZEXTW,
M_SEXTB,
M_SEXTH,
M_NUM_MACROS
};

View 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.

View 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 },