Skip to content

Commit b5ea5be

Browse files
authored
[RISCV][MC] Fix >32bit .insn Directives (#111878)
The original patch had a reasonably significant bug. You could not use `.insn` to assemble encodings that had any bits set above the low 32 bits. This is due to the fact that `getMachineOpValue` was truncating the immediate value, and I did not commit enough tests of useful cases. This changes the result of `getMachineOpValue` to be able to return the 48-bit and 64-bit immediates needed for the wider `.insn` directives. I took the opportunity to move some of the test cases around in the file to make looking at the output of `llvm-objdump` a little clearer.
1 parent 0163ac1 commit b5ea5be

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class RISCVMCCodeEmitter : public MCCodeEmitter {
7777

7878
/// Return binary encoding of operand. If the machine operand requires
7979
/// relocation, record the relocation and return zero.
80-
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
80+
uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
8181
SmallVectorImpl<MCFixup> &Fixups,
8282
const MCSubtargetInfo &STI) const;
8383

@@ -375,7 +375,7 @@ void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI,
375375
++MCNumEmitted; // Keep track of the # of mi's emitted.
376376
}
377377

378-
unsigned
378+
uint64_t
379379
RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
380380
SmallVectorImpl<MCFixup> &Fixups,
381381
const MCSubtargetInfo &STI) const {
@@ -384,7 +384,7 @@ RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
384384
return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
385385

386386
if (MO.isImm())
387-
return static_cast<unsigned>(MO.getImm());
387+
return MO.getImm();
388388

389389
llvm_unreachable("Unhandled expression!");
390390
return 0;

llvm/test/MC/RISCV/insn.s

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,17 +170,40 @@ target:
170170
# CHECK-OBJ: <unknown>
171171
.insn 6, 0x1f
172172

173-
# CHECK-ASM: .insn 0x4, 65503
174-
# CHECK-ASM: encoding: [0xdf,0xff,0x00,0x00]
175-
# CHECK-OBJ: <unknown>
176-
.insn 0xffdf
177-
178173
# CHECK-ASM: .insn 0x8, 63
179174
# CHECK-ASM: encoding: [0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
180175
# CHECK-OBJ: <unknown>
181176
.insn 8, 0x3f
182177

178+
# CHECK-ASM: .insn 0x6, 281474976710623
179+
# CHECK-ASM: encoding: [0xdf,0xff,0xff,0xff,0xff,0xff]
180+
# CHECK-OBJ: <unknown>
181+
.insn 0x6, 0xffffffffffdf
182+
183+
# CHECK-ASM: .insn 0x8, -65
184+
# CHECK-ASM: encoding: [0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff]
185+
# CHECK-OBJ: <unknown>
186+
.insn 0x8, 0xffffffffffffffbf
187+
188+
odd_lengths:
189+
# CHECK-ASM-LABEL: odd_lengths:
190+
# CHECK-OBJ-LABEL: <odd_lengths>:
191+
192+
## These deliberately disagree with the lengths objdump expects them to have, so
193+
## keep them at the end so that the disassembled instruction stream is not out
194+
## of sync with the encoded instruction stream. We don't check for `<unknown>`
195+
## as we could get any number of those, so instead check for the encoding
196+
## halfwords. These might be split into odd 16-bit chunks, so each chunk is on
197+
## one line.
198+
199+
# CHECK-ASM: .insn 0x4, 65503
200+
# CHECK-ASM: encoding: [0xdf,0xff,0x00,0x00]
201+
# CHECK-OBJ: ffdf
202+
# CHECK-OBJ: 0000
203+
.insn 0xffdf
204+
183205
# CHECK-ASM: .insn 0x4, 65471
184206
# CHECK-ASM: encoding: [0xbf,0xff,0x00,0x00]
185-
# CHECK-OBJ: <unknown>
207+
# CHECK-OBJ: ffbf
208+
# CHECK-OBJ: 0000
186209
.insn 0xffbf

0 commit comments

Comments
 (0)