[RISCV][MC] Accept %lo and %pcrel_lo on operands to li

This matches GNU assembler behaviour.

llvm-svn: 350321
This commit is contained in:
Alex Bradbury 2019-01-03 14:41:41 +00:00
parent b2e5845838
commit 2ba76be882
4 changed files with 50 additions and 10 deletions

View File

@ -310,12 +310,14 @@ public:
return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
} }
bool isImmXLen() const { bool isImmXLenLI() const {
int64_t Imm; int64_t Imm;
RISCVMCExpr::VariantKind VK; RISCVMCExpr::VariantKind VK;
if (!isImm()) if (!isImm())
return false; return false;
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO)
return true;
// Given only Imm, ensuring that the actually specified constant is either // Given only Imm, ensuring that the actually specified constant is either
// a signed or unsigned 64-bit number is unfortunately impossible. // a signed or unsigned 64-bit number is unfortunately impossible.
bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm); bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm);
@ -782,7 +784,7 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
switch(Result) { switch(Result) {
default: default:
break; break;
case Match_InvalidImmXLen: case Match_InvalidImmXLenLI:
if (isRV64()) { if (isRV64()) {
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
return Error(ErrorLoc, "operand must be a constant 64-bit integer"); return Error(ErrorLoc, "operand must be a constant 64-bit integer");
@ -1449,7 +1451,17 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Inst.setLoc(IDLoc); Inst.setLoc(IDLoc);
if (Inst.getOpcode() == RISCV::PseudoLI) { if (Inst.getOpcode() == RISCV::PseudoLI) {
auto Reg = Inst.getOperand(0).getReg(); unsigned Reg = Inst.getOperand(0).getReg();
const MCOperand &Op1 = Inst.getOperand(1);
if (Op1.isExpr()) {
// We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
// Just convert to an addi. This allows compatibility with gas.
emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
.addReg(Reg)
.addReg(RISCV::X0)
.addExpr(Op1.getExpr()));
return false;
}
int64_t Imm = Inst.getOperand(1).getImm(); int64_t Imm = Inst.getOperand(1).getImm();
// On RV32 the immediate here can either be a signed or an unsigned // On RV32 the immediate here can either be a signed or an unsigned
// 32-bit number. Sign extension has to be performed to ensure that Imm // 32-bit number. Sign extension has to be performed to ensure that Imm

View File

@ -198,8 +198,10 @@ def csr_sysreg : Operand<XLenVT> {
} }
// A parameterized register class alternative to i32imm/i64imm from Target.td. // A parameterized register class alternative to i32imm/i64imm from Target.td.
def ixlenimm : Operand<XLenVT> { def ixlenimm : Operand<XLenVT>;
let ParserMatchClass = ImmXLenAsmOperand<"">;
def ixlenimm_li : Operand<XLenVT> {
let ParserMatchClass = ImmXLenAsmOperand<"", "LI">;
} }
// Standalone (codegen-only) immleaf patterns. // Standalone (codegen-only) immleaf patterns.
@ -497,7 +499,7 @@ def : InstAlias<"nop", (ADDI X0, X0, 0)>;
// expanded to real instructions immediately. // expanded to real instructions immediately.
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32, let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,
isCodeGenOnly = 0, isAsmParserOnly = 1 in isCodeGenOnly = 0, isAsmParserOnly = 1 in
def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm:$imm), [], def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm_li:$imm), [],
"li", "$rd, $imm">; "li", "$rd, $imm">;
def : InstAlias<"mv $rd, $rs", (ADDI GPR:$rd, GPR:$rs, 0)>; def : InstAlias<"mv $rd, $rs", (ADDI GPR:$rd, GPR:$rs, 0)>;

View File

@ -3,10 +3,10 @@
# RUN: llvm-mc %s -triple=riscv32 \ # RUN: llvm-mc %s -triple=riscv32 \
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s # RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \ # RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
# RUN: | llvm-objdump -riscv-no-aliases -d - \ # RUN: | llvm-objdump -riscv-no-aliases -d -r - \
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s # RUN: | FileCheck -check-prefixes=CHECK-OBJ-NOALIAS,CHECK-EXPAND,CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \ # RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
# RUN: | llvm-objdump -d - \ # RUN: | llvm-objdump -d -r - \
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s # RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
# The following check prefixes are used in this test: # The following check prefixes are used in this test:
@ -69,6 +69,19 @@ li x12, 0x80000000
# CHECK-EXPAND: addi a2, zero, -1 # CHECK-EXPAND: addi a2, zero, -1
li x12, 0xFFFFFFFF li x12, 0xFFFFFFFF
# CHECK-EXPAND: addi a0, zero, 1110
li a0, %lo(0x123456)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_PCREL_LO12
li a0, %pcrel_lo(0x123456)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_LO12
li a0, %lo(foo)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_PCREL_LO12
li a0, %pcrel_lo(foo)
# CHECK-INST: csrrs t4, instreth, zero # CHECK-INST: csrrs t4, instreth, zero
# CHECK-ALIAS: rdinstreth t4 # CHECK-ALIAS: rdinstreth t4
rdinstreth x29 rdinstreth x29

View File

@ -4,7 +4,7 @@
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s # RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \ # RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
# RUN: | llvm-objdump -riscv-no-aliases -d - \ # RUN: | llvm-objdump -riscv-no-aliases -d - \
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s # RUN: | FileCheck -check-prefixes=CHECK-OBJ-NOALIAS,CHECK-EXPAND,CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \ # RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
# RUN: | llvm-objdump -d - \ # RUN: | llvm-objdump -d - \
# RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s # RUN: | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
@ -105,6 +105,19 @@ li t4, 0x123456789abcdef0
# CHECK-EXPAND: addi t5, zero, -1 # CHECK-EXPAND: addi t5, zero, -1
li t5, 0xFFFFFFFFFFFFFFFF li t5, 0xFFFFFFFFFFFFFFFF
# CHECK-EXPAND: addi a0, zero, 1110
li a0, %lo(0x123456)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_PCREL_LO12
li a0, %pcrel_lo(0x123456)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_LO12
li a0, %lo(foo)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_PCREL_LO12
li a0, %pcrel_lo(foo)
# CHECK-INST: subw t6, zero, ra # CHECK-INST: subw t6, zero, ra
# CHECK-ALIAS: negw t6, ra # CHECK-ALIAS: negw t6, ra
negw x31, x1 negw x31, x1