aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp')
-rw-r--r--llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp115
1 files changed, 109 insertions, 6 deletions
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index 35bd244..5c3e26e 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -84,6 +84,12 @@ void AArch64InstPrinter::printInst(const MCInst *MI, uint64_t Address,
return;
}
+ if (Opcode == AArch64::SYSLxt)
+ if (printSyslAlias(MI, STI, O)) {
+ printAnnotation(O, Annot);
+ return;
+ }
+
if (Opcode == AArch64::SYSPxt || Opcode == AArch64::SYSPxt_XZR)
if (printSyspAlias(MI, STI, O)) {
printAnnotation(O, Annot);
@@ -909,13 +915,25 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
Encoding |= CnVal << 7;
Encoding |= Op1Val << 11;
- bool NeedsReg;
+ bool NeedsReg = false;
+ bool OptionalReg = false;
std::string Ins;
std::string Name;
if (CnVal == 7) {
switch (CmVal) {
default: return false;
+ // MLBI aliases
+ case 0: {
+ const AArch64MLBI::MLBI *MLBI =
+ AArch64MLBI::lookupMLBIByEncoding(Encoding);
+ if (!MLBI || !MLBI->haveFeatures(STI.getFeatureBits()))
+ return false;
+
+ NeedsReg = MLBI->NeedsReg;
+ Ins = "mlbi\t";
+ Name = std::string(MLBI->Name);
+ } break;
// Maybe IC, maybe Prediction Restriction
case 1:
switch (Op1Val) {
@@ -1004,19 +1022,41 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
return false;
NeedsReg = TLBI->NeedsReg;
+ if (STI.hasFeature(AArch64::FeatureAll) ||
+ STI.hasFeature(AArch64::FeatureTLBID))
+ OptionalReg = TLBI->OptionalReg;
Ins = "tlbi\t";
Name = std::string(TLBI->Name);
- }
- else
+ } else if (CnVal == 12) {
+ if (CmVal != 0) {
+ // GIC aliases
+ const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByEncoding(Encoding);
+ if (!GIC || !GIC->haveFeatures(STI.getFeatureBits()))
+ return false;
+
+ NeedsReg = true;
+ Ins = "gic\t";
+ Name = std::string(GIC->Name);
+ } else {
+ // GSB aliases
+ const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByEncoding(Encoding);
+ if (!GSB || !GSB->haveFeatures(STI.getFeatureBits()))
+ return false;
+
+ NeedsReg = false;
+ Ins = "gsb\t";
+ Name = std::string(GSB->Name);
+ }
+ } else
return false;
StringRef Reg = getRegisterName(MI->getOperand(4).getReg());
bool NotXZR = Reg != "xzr";
- // If a mandatory is not specified in the TableGen
+ // If a mandatory or optional register is not specified in the TableGen
// (i.e. no register operand should be present), and the register value
// is not xzr/x31, then disassemble to a SYS alias instead.
- if (NotXZR && !NeedsReg)
+ if (NotXZR && !NeedsReg && !OptionalReg)
return false;
std::string Str = Ins + Name;
@@ -1024,12 +1064,64 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
O << '\t' << Str;
- if (NeedsReg)
+ // For optional registers, don't print the value if it's xzr/x31
+ // since this defaults to xzr/x31 if register is not specified.
+ if (NeedsReg || (OptionalReg && NotXZR))
O << ", " << Reg;
return true;
}
+bool AArch64InstPrinter::printSyslAlias(const MCInst *MI,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+#ifndef NDEBUG
+ unsigned Opcode = MI->getOpcode();
+ assert(Opcode == AArch64::SYSLxt && "Invalid opcode for SYSL alias!");
+#endif
+
+ StringRef Reg = getRegisterName(MI->getOperand(0).getReg());
+ const MCOperand &Op1 = MI->getOperand(1);
+ const MCOperand &Cn = MI->getOperand(2);
+ const MCOperand &Cm = MI->getOperand(3);
+ const MCOperand &Op2 = MI->getOperand(4);
+
+ unsigned Op1Val = Op1.getImm();
+ unsigned CnVal = Cn.getImm();
+ unsigned CmVal = Cm.getImm();
+ unsigned Op2Val = Op2.getImm();
+
+ uint16_t Encoding = Op2Val;
+ Encoding |= CmVal << 3;
+ Encoding |= CnVal << 7;
+ Encoding |= Op1Val << 11;
+
+ std::string Ins;
+ std::string Name;
+
+ if (CnVal == 12) {
+ if (CmVal == 3) {
+ // GICR aliases
+ const AArch64GICR::GICR *GICR =
+ AArch64GICR::lookupGICRByEncoding(Encoding);
+ if (!GICR || !GICR->haveFeatures(STI.getFeatureBits()))
+ return false;
+
+ Ins = "gicr";
+ Name = std::string(GICR->Name);
+ } else
+ return false;
+ } else
+ return false;
+
+ std::string Str;
+ llvm::transform(Name, Name.begin(), ::tolower);
+
+ O << '\t' << Ins << '\t' << Reg.str() << ", " << Name;
+
+ return true;
+}
+
bool AArch64InstPrinter::printSyspAlias(const MCInst *MI,
const MCSubtargetInfo &STI,
raw_ostream &O) {
@@ -1508,6 +1600,17 @@ void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum,
markup(O, Markup::Immediate) << '#' << formatImm(btihintop);
}
+void AArch64InstPrinter::printCMHPriorityHintOp(const MCInst *MI,
+ unsigned OpNum,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ unsigned priorityhint_op = MI->getOperand(OpNum).getImm();
+ auto PHint =
+ AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(priorityhint_op);
+ if (PHint)
+ O << PHint->Name;
+}
+
void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {