Skip to content

Commit 386aca4

Browse files
authored
[RISCV] Correct disassembly of cm.push/pop for RVE. (#133816)
We shouldn't disassemble any encoding that refers to registers x16-x31 with RV32E.
1 parent ea68b22 commit 386aca4

File tree

5 files changed

+90
-6
lines changed

5 files changed

+90
-6
lines changed

llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,10 +506,12 @@ static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
506506
const MCDisassembler *Decoder);
507507

508508
static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
509-
uint64_t Address, const void *Decoder);
509+
uint64_t Address,
510+
const MCDisassembler *Decoder);
510511

511512
static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm,
512-
uint64_t Address, const void *Decoder);
513+
uint64_t Address,
514+
const MCDisassembler *Decoder);
513515

514516
static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,
515517
uint64_t Address, const void *Decoder);
@@ -624,16 +626,20 @@ static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
624626
}
625627

626628
static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
627-
uint64_t Address, const void *Decoder) {
628-
if (Imm < RISCVZC::RA)
629+
uint64_t Address,
630+
const MCDisassembler *Decoder) {
631+
bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);
632+
if (Imm < RISCVZC::RA || (IsRVE && Imm >= RISCVZC::RA_S0_S2))
629633
return MCDisassembler::Fail;
630634
Inst.addOperand(MCOperand::createImm(Imm));
631635
return MCDisassembler::Success;
632636
}
633637

634638
static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm,
635-
uint64_t Address, const void *Decoder) {
636-
if (Imm < RISCVZC::RA_S0)
639+
uint64_t Address,
640+
const MCDisassembler *Decoder) {
641+
bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);
642+
if (Imm < RISCVZC::RA_S0 || (IsRVE && Imm >= RISCVZC::RA_S0_S2))
637643
return MCDisassembler::Fail;
638644
Inst.addOperand(MCOperand::createImm(Imm));
639645
return MCDisassembler::Success;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# RUN: not llvm-mc -triple riscv32 -mattr=+e,+experimental-xqccmp < %s 2>&1 | FileCheck %s
2+
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-xqccmp < %s \
3+
# RUN: | llvm-objdump --mattr=+e,+experimental-xqccmp -M no-aliases -d -r - \
4+
# RUN: | FileCheck -check-prefix=CHECK-DIS %s
5+
6+
# Perform a simple check that registers x16-x31 (and the equivalent ABI names)
7+
# are rejected for RV32E, when both assembling and disassembling.
8+
9+
10+
# CHECK-DIS: b872 <unknown>
11+
# CHECK: :[[@LINE+1]]:19: error: invalid register
12+
qc.cm.push {ra,s0-s2}, -16
13+
# CHECK-DIS: be72 <unknown>
14+
# CHECK: :[[@LINE+1]]:21: error: invalid register
15+
qc.cm.popret {ra,s0-s2}, 16
16+
# CHECK-DIS: ba72 <unknown>
17+
# CHECK: :[[@LINE+1]]:21: error: register list must end with '}'
18+
qc.cm.pop {x1, x8-x9, x18}, 16
19+
# CHECK-DIS: b972 <unknown>
20+
# CHECK: :[[@LINE+1]]:24: error: register list must end with '}'
21+
qc.cm.pushfp {x1, x8-x9, x18}, -16
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# RUN: not llvm-mc -triple riscv32 -mattr=+e,+zcmp < %s 2>&1 | FileCheck %s
2+
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zcmp < %s \
3+
# RUN: | llvm-objdump --mattr=+e,+zcmp -M no-aliases -d -r - \
4+
# RUN: | FileCheck -check-prefix=CHECK-DIS %s
5+
6+
# Perform a simple check that registers x16-x31 (and the equivalent ABI names)
7+
# are rejected for RV32E, when both assembling and disassembling.
8+
9+
10+
# CHECK-DIS: b872 <unknown>
11+
# CHECK: :[[@LINE+1]]:16: error: invalid register
12+
cm.push {ra,s0-s2}, -16
13+
# CHECK-DIS: be72 <unknown>
14+
# CHECK: :[[@LINE+1]]:18: error: invalid register
15+
cm.popret {ra,s0-s2}, 16
16+
# CHECK-DIS: ba72 <unknown>
17+
# CHECK: :[[@LINE+1]]:18: error: register list must end with '}'
18+
cm.pop {x1, x8-x9, x18}, 16
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# RUN: not llvm-mc -triple riscv64 -mattr=+e,+experimental-xqccmp < %s 2>&1 | FileCheck %s
2+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-xqccmp < %s \
3+
# RUN: | llvm-objdump --mattr=+e,+experimental-xqccmp -M no-aliases -d -r - \
4+
# RUN: | FileCheck -check-prefix=CHECK-DIS %s
5+
6+
# Perform a simple check that registers x16-x31 (and the equivalent ABI names)
7+
# are rejected for RV64E, when both assembling and disassembling.
8+
9+
10+
# CHECK-DIS: b872 <unknown>
11+
# CHECK: :[[@LINE+1]]:19: error: invalid register
12+
qc.cm.push {ra,s0-s2}, -32
13+
# CHECK-DIS: be72 <unknown>
14+
# CHECK: :[[@LINE+1]]:21: error: invalid register
15+
qc.cm.popret {ra,s0-s2}, 32
16+
# CHECK-DIS: ba72 <unknown>
17+
# CHECK: :[[@LINE+1]]:21: error: register list must end with '}'
18+
qc.cm.pop {x1, x8-x9, x18}, 32
19+
# CHECK-DIS: b972 <unknown>
20+
# CHECK: :[[@LINE+1]]:24: error: register list must end with '}'
21+
qc.cm.pushfp {x1, x8-x9, x18}, -32
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# RUN: not llvm-mc -triple riscv64 -mattr=+e,+zcmp < %s 2>&1 | FileCheck %s
2+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zcmp < %s \
3+
# RUN: | llvm-objdump --mattr=+e,+zcmp -M no-aliases -d -r - \
4+
# RUN: | FileCheck -check-prefix=CHECK-DIS %s
5+
6+
# Perform a simple check that registers x16-x31 (and the equivalent ABI names)
7+
# are rejected for RV64E, when both assembling and disassembling.
8+
9+
10+
# CHECK-DIS: b872 <unknown>
11+
# CHECK: :[[@LINE+1]]:16: error: invalid register
12+
cm.push {ra,s0-s2}, -32
13+
# CHECK-DIS: be72 <unknown>
14+
# CHECK: :[[@LINE+1]]:18: error: invalid register
15+
cm.popret {ra,s0-s2}, 32
16+
# CHECK-DIS: ba72 <unknown>
17+
# CHECK: :[[@LINE+1]]:18: error: register list must end with '}'
18+
cm.pop {x1, x8-x9, x18}, 32

0 commit comments

Comments
 (0)