Skip to content

Commit

Permalink
[RISCV] Support Expressions in .insn Directives (llvm#111893)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lenary authored and EricWF committed Oct 22, 2024
1 parent 00974ca commit fac50e8
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 6 deletions.
5 changes: 2 additions & 3 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3172,12 +3172,11 @@ bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
// Try parsing .insn [ length , ] value
std::optional<int64_t> Length;
int64_t Value = 0;
if (Parser.parseIntToken(
Value, "expected instruction format or an integer constant"))
if (Parser.parseAbsoluteExpression(Value))
return true;
if (Parser.parseOptionalToken(AsmToken::Comma)) {
Length = Value;
if (Parser.parseIntToken(Value, "expected an integer constant"))
if (Parser.parseAbsoluteExpression(Value))
return true;

if (*Length == 0 || (*Length % 2) != 0)
Expand Down
9 changes: 6 additions & 3 deletions llvm/test/MC/RISCV/insn-invalid.s
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
# Make fake mnemonics we use to match these in the tablegened asm match table isn't exposed.
.insn_i 0x13, 0, a0, a1, 13, 14 # CHECK: :[[@LINE]]:1: error: unknown directive

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

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

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

.insn 0x0010 # CHECK: :[[@LINE]]:7: error: compressed instructions are not allowed
.insn 0x2, 0x0001 # CHECK: :[[@LINE]]:7: error: compressed instructions are not allowed

.insn 0x2 + 0x2, 0x3 | (31 # CHECK: :[[@LINE]]:28: error: expected ')'
.insn 0x4 * , 0xbf | (31 << 59) # CHECK: :[[@LINE]]:13: error: unknown token in expression
10 changes: 10 additions & 0 deletions llvm/test/MC/RISCV/insn.s
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,16 @@ target:
# CHECK-OBJ: <unknown>
.insn 0x8, 0xffffffffffffffbf

# CHECK-ASM: .insn 0x4, 3971
# CHECK-ASM: encoding: [0x83,0x0f,0x00,0x00]
# CHECK-OBJ: lb t6, 0x0(zero)
.insn 0x2 + 0x2, 0x3 | (31 << 7)

# CHECK-ASM: .insn 0x8, -576460752303423297
# CHECK-ASM: encoding: [0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0xf8]
# CHECK-OBJ: <unknown>
.insn 0x4 * 0x2, 0xbf | (31 << 59)

odd_lengths:
# CHECK-ASM-LABEL: odd_lengths:
# CHECK-OBJ-LABEL: <odd_lengths>:
Expand Down

0 comments on commit fac50e8

Please sign in to comment.