diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 41 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfo.td | 14 |
2 files changed, 42 insertions, 13 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 7b010f54b0b..f54d4a58627 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -443,20 +443,36 @@ public: VK == RISCVMCExpr::VK_RISCV_None; } - bool isUImm20() const { + bool isUImm20LUI() const { RISCVMCExpr::VariantKind VK; int64_t Imm; bool IsValid; if (!isImm()) return false; bool IsConstantImm = evaluateConstantImm(Imm, VK); - if (!IsConstantImm) + if (!IsConstantImm) { IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); - else - IsValid = isUInt<20>(Imm); - return IsValid && (VK == RISCVMCExpr::VK_RISCV_None || - VK == RISCVMCExpr::VK_RISCV_HI || - VK == RISCVMCExpr::VK_RISCV_PCREL_HI); + return IsValid && VK == RISCVMCExpr::VK_RISCV_HI; + } else { + return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || + VK == RISCVMCExpr::VK_RISCV_HI); + } + } + + bool isUImm20AUIPC() const { + RISCVMCExpr::VariantKind VK; + int64_t Imm; + bool IsValid; + if (!isImm()) + return false; + bool IsConstantImm = evaluateConstantImm(Imm, VK); + if (!IsConstantImm) { + IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); + return IsValid && VK == RISCVMCExpr::VK_RISCV_PCREL_HI; + } else { + return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || + VK == RISCVMCExpr::VK_RISCV_PCREL_HI); + } } bool isSImm21Lsb0() const { return isBareSimmNLsb0<21>(); } @@ -781,8 +797,15 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, "immediate must be a multiple of 2 bytes in the range"); - case Match_InvalidUImm20: - return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1); + case Match_InvalidUImm20LUI: + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1, + "operand must be a symbol with %hi() " + "modifier or an integer in the range"); + case Match_InvalidUImm20AUIPC: + return generateImmOutOfRangeError( + Operands, ErrorInfo, 0, (1 << 20) - 1, + "operand must be a symbol with %pcrel_hi() modifier or an integer in " + "the range"); case Match_InvalidSImm21Lsb0: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 1dc60737a16..dca5759bf53 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -143,8 +143,7 @@ def simm13_lsb0 : Operand<OtherVT> { }]; } -def uimm20 : Operand<XLenVT> { - let ParserMatchClass = UImmAsmOperand<20>; +class UImm20Operand : Operand<XLenVT> { let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeUImmOperand<20>"; let MCOperandPredicate = [{ @@ -155,6 +154,13 @@ def uimm20 : Operand<XLenVT> { }]; } +def uimm20_lui : UImm20Operand { + let ParserMatchClass = UImmAsmOperand<20, "LUI">; +} +def uimm20_auipc : UImm20Operand { + let ParserMatchClass = UImmAsmOperand<20, "AUIPC">; +} + // A 21-bit signed immediate where the least significant bit is zero. def simm21_lsb0 : Operand<OtherVT> { let ParserMatchClass = SImmAsmOperand<21, "Lsb0">; @@ -285,10 +291,10 @@ class Priv<string opcodestr, bits<7> funct7> //===----------------------------------------------------------------------===// let hasSideEffects = 0, isReMaterializable = 1, mayLoad = 0, mayStore = 0 in { -def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20:$imm20), +def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20_lui:$imm20), "lui", "$rd, $imm20">; -def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20:$imm20), +def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20_auipc:$imm20), "auipc", "$rd, $imm20">; let isCall = 1 in |