Skip to content

Commit b749c3f

Browse files
lenaryDanielCChen
authored andcommitted
[RISCV] Support Expressions in .insn Directives (llvm#111893)
When assembling raw instructions, often you want to or together several fields for clarity, or because you're using an assembly macro with separate arguments. This brings the use of `.insn` closer into line with what can be done with the binutils assembler. The 64-bit instruction test here explicitly sets the top bit to make sure this works, even though the assembler is really using `int64_t` in most places internally.
1 parent aedcee1 commit b749c3f

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,12 +3172,11 @@ bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
31723172
// Try parsing .insn [ length , ] value
31733173
std::optional<int64_t> Length;
31743174
int64_t Value = 0;
3175-
if (Parser.parseIntToken(
3176-
Value, "expected instruction format or an integer constant"))
3175+
if (Parser.parseAbsoluteExpression(Value))
31773176
return true;
31783177
if (Parser.parseOptionalToken(AsmToken::Comma)) {
31793178
Length = Value;
3180-
if (Parser.parseIntToken(Value, "expected an integer constant"))
3179+
if (Parser.parseAbsoluteExpression(Value))
31813180
return true;
31823181

31833182
if (*Length == 0 || (*Length % 2) != 0)

llvm/test/MC/RISCV/insn-invalid.s

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
# Make fake mnemonics we use to match these in the tablegened asm match table isn't exposed.
2525
.insn_i 0x13, 0, a0, a1, 13, 14 # CHECK: :[[@LINE]]:1: error: unknown directive
2626

27-
.insn . # CHECK: :[[@LINE]]:7: error: expected instruction format or an integer constant
28-
.insn 0x2, # CHECK: :[[@LINE]]:12: error: expected an integer constant
27+
.insn . # CHECK: :[[@LINE]]:7: error: expected absolute expression
28+
.insn 0x2, # CHECK: :[[@LINE]]:12: error: unknown token in expression
2929

3030
.insn 0x4, 0x13, 0 # CHECK: :[[@LINE]]:16: error: invalid operand for instruction
3131

@@ -49,7 +49,10 @@
4949
.insn 0x2, 0x10001 # CHECK: :[[@LINE]]:7: error: encoding value does not fit into instruction
5050
.insn 0x4, 0x100000003 # CHECK: :[[@LINE]]:7: error: encoding value does not fit into instruction
5151
.insn 0x6, 0x100000000001f # CHECK: :[[@LINE]]:7: error: encoding value does not fit into instruction
52-
.insn 0x8, 0x1000000000000003f # CHECK: :[[@LINE]]:12: error: expected an integer constant
52+
.insn 0x8, 0x1000000000000003f # CHECK: :[[@LINE]]:12: error: literal value out of range for directive
5353

5454
.insn 0x0010 # CHECK: :[[@LINE]]:7: error: compressed instructions are not allowed
5555
.insn 0x2, 0x0001 # CHECK: :[[@LINE]]:7: error: compressed instructions are not allowed
56+
57+
.insn 0x2 + 0x2, 0x3 | (31 # CHECK: :[[@LINE]]:28: error: expected ')'
58+
.insn 0x4 * , 0xbf | (31 << 59) # CHECK: :[[@LINE]]:13: error: unknown token in expression

llvm/test/MC/RISCV/insn.s

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,16 @@ target:
185185
# CHECK-OBJ: <unknown>
186186
.insn 0x8, 0xffffffffffffffbf
187187

188+
# CHECK-ASM: .insn 0x4, 3971
189+
# CHECK-ASM: encoding: [0x83,0x0f,0x00,0x00]
190+
# CHECK-OBJ: lb t6, 0x0(zero)
191+
.insn 0x2 + 0x2, 0x3 | (31 << 7)
192+
193+
# CHECK-ASM: .insn 0x8, -576460752303423297
194+
# CHECK-ASM: encoding: [0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0xf8]
195+
# CHECK-OBJ: <unknown>
196+
.insn 0x4 * 0x2, 0xbf | (31 << 59)
197+
188198
odd_lengths:
189199
# CHECK-ASM-LABEL: odd_lengths:
190200
# CHECK-OBJ-LABEL: <odd_lengths>:

0 commit comments

Comments
 (0)