summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
diff options
context:
space:
mode:
authorLewis Revill <lewis.revill@embecosm.com>2019-04-04 14:13:37 +0000
committerLewis Revill <lewis.revill@embecosm.com>2019-04-04 14:13:37 +0000
commitaa79a3fe8e09da6b6cb30a70308a804d9b232112 (patch)
tree6afa7dcd62b265871a498c8fc93a8357398371a9 /llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
parent9f598ac7062cfb72d17d59a8f2ab322d2d31a60d (diff)
downloadbcm5719-llvm-aa79a3fe8e09da6b6cb30a70308a804d9b232112.tar.gz
bcm5719-llvm-aa79a3fe8e09da6b6cb30a70308a804d9b232112.zip
[RISCV] Support assembling TLS add and associated modifiers
This patch adds support in the MC layer for parsing and assembling the 4-operand add instruction needed for TLS addressing. This also involves parsing the %tprel_hi, %tprel_lo and %tprel_add operand modifiers. Differential Revision: https://reviews.llvm.org/D55341 llvm-svn: 357698
Diffstat (limited to 'llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp')
-rw-r--r--llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp32
1 files changed, 25 insertions, 7 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 6c46a401092..7113adcf65b 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -295,6 +295,16 @@ public:
VK == RISCVMCExpr::VK_RISCV_CALL_PLT);
}
+ bool isTPRelAddSymbol() const {
+ int64_t Imm;
+ RISCVMCExpr::VariantKind VK;
+ // Must be of 'immediate' type but not a constant.
+ if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
+ return false;
+ return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
+ VK == RISCVMCExpr::VK_RISCV_TPREL_ADD;
+ }
+
bool isCSRSystemRegister() const { return isSystemRegister(); }
/// Return true if the operand is a valid for the fence instruction e.g.
@@ -489,7 +499,8 @@ public:
IsValid = isInt<12>(Imm);
return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
VK == RISCVMCExpr::VK_RISCV_LO ||
- VK == RISCVMCExpr::VK_RISCV_PCREL_LO);
+ VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
+ VK == RISCVMCExpr::VK_RISCV_TPREL_LO);
}
bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
@@ -515,10 +526,12 @@ public:
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
if (!IsConstantImm) {
IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
- return IsValid && VK == RISCVMCExpr::VK_RISCV_HI;
+ return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI ||
+ VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
} else {
return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
- VK == RISCVMCExpr::VK_RISCV_HI);
+ VK == RISCVMCExpr::VK_RISCV_HI ||
+ VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
}
}
@@ -872,8 +885,8 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidSImm12:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
- "operand must be a symbol with %lo/%pcrel_lo modifier or an integer in "
- "the range");
+ "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
+ "integer in the range");
case Match_InvalidSImm12Lsb0:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
@@ -884,8 +897,9 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
"immediate must be a multiple of 2 bytes in the range");
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");
+ "operand must be a symbol with "
+ "%hi/%tprel_hi modifier or an integer in "
+ "the range");
case Match_InvalidUImm20AUIPC:
return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 20) - 1,
@@ -920,6 +934,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
return Error(ErrorLoc, "operand must be a bare symbol name");
}
+ case Match_InvalidTPRelAddSymbol: {
+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
+ return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier");
+ }
}
llvm_unreachable("Unknown match type detected!");
OpenPOWER on IntegriCloud