Index: lib/Target/AArch64/AArch64SystemOperands.td =================================================================== --- lib/Target/AArch64/AArch64SystemOperands.td +++ lib/Target/AArch64/AArch64SystemOperands.td @@ -30,6 +30,7 @@ let Encoding{10-7} = crn; let Encoding{6-3} = crm; let Encoding{2-0} = op2; + code Requires = [{ {} }]; } def : AT<"S1E1R", 0b01, 0b000, 0b0111, 0b1000, 0b000>; @@ -44,9 +45,11 @@ def : AT<"S12E1W", 0b01, 0b100, 0b0111, 0b1000, 0b101>; def : AT<"S12E0R", 0b01, 0b100, 0b0111, 0b1000, 0b110>; def : AT<"S12E0W", 0b01, 0b100, 0b0111, 0b1000, 0b111>; + +let Requires = [{ {AArch64::HasV8_2aOps} }] in { def : AT<"S1E1RP", 0b01, 0b000, 0b0111, 0b1001, 0b000>; def : AT<"S1E1WP", 0b01, 0b000, 0b0111, 0b1001, 0b001>; - +} //===----------------------------------------------------------------------===// // DMB/DSB (data barrier) instruction options. @@ -89,6 +92,7 @@ let Encoding{10-7} = crn; let Encoding{6-3} = crm; let Encoding{2-0} = op2; + code Requires = [{ {} }]; } def : DC<"ZVA", 0b01, 0b011, 0b0111, 0b0100, 0b001>; @@ -100,6 +104,9 @@ def : DC<"CIVAC", 0b01, 0b011, 0b0111, 0b1110, 0b001>; def : DC<"CISW", 0b01, 0b000, 0b0111, 0b1110, 0b010>; +let Requires = [{ {AArch64::HasV8_2aOps} }] in +def : DC<"CVAP", 0b01, 0b011, 0b0111, 0b1100, 0b001>; + //===----------------------------------------------------------------------===// // IC (instruction cache maintenance) instruction options. //===----------------------------------------------------------------------===// @@ -120,7 +127,7 @@ def : IC<"IALLUIS", 0b000, 0b0111, 0b0001, 0b000, 0>; def : IC<"IALLU", 0b000, 0b0111, 0b0101, 0b000, 0>; -def : IC<"IVAU", 0b000, 0b0111, 0b0001, 0b000, 1>; +def : IC<"IVAU", 0b011, 0b0111, 0b0101, 0b001, 1>; //===----------------------------------------------------------------------===// // ISB (instruction-fetch barrier) instruction options. Index: lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp =================================================================== --- lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -739,7 +739,6 @@ assert(Opcode == AArch64::SYSxt && "Invalid opcode for SYS alias!"); #endif - const char *Asm = nullptr; const MCOperand &Op1 = MI->getOperand(0); const MCOperand &Cn = MI->getOperand(1); const MCOperand &Cm = MI->getOperand(2); @@ -750,230 +749,78 @@ unsigned CmVal = Cm.getImm(); unsigned Op2Val = Op2.getImm(); + uint16_t Encoding = Op2Val; + Encoding |= CmVal << 3; + Encoding |= CnVal << 7; + Encoding |= Op1Val << 11; + + bool NeedsReg; + std::string Ins; + std::string Name; + if (CnVal == 7) { switch (CmVal) { - default: - break; - + default: return false; // IC aliases - case 1: - if (Op1Val == 0 && Op2Val == 0) - Asm = "ic\tialluis"; - break; - case 5: - if (Op1Val == 0 && Op2Val == 0) - Asm = "ic\tiallu"; - else if (Op1Val == 3 && Op2Val == 1) - Asm = "ic\tivau"; - break; - + case 1: case 5: { + // There is no op0, so we do no need to set bit 14 + const AArch64IC::IC *IC = AArch64IC::lookupICByEncoding(Encoding); + if (!IC || !IC->haveFeatures(STI.getFeatureBits())) + return false; + + NeedsReg = IC->NeedsReg; + Ins = "ic\t"; + Name = std::string(IC->Name); + } + break; // DC aliases - case 4: - if (Op1Val == 3 && Op2Val == 1) - Asm = "dc\tzva"; - break; - case 6: - if (Op1Val == 0 && Op2Val == 1) - Asm = "dc\tivac"; - if (Op1Val == 0 && Op2Val == 2) - Asm = "dc\tisw"; - break; - case 10: - if (Op1Val == 3 && Op2Val == 1) - Asm = "dc\tcvac"; - else if (Op1Val == 0 && Op2Val == 2) - Asm = "dc\tcsw"; - break; - case 11: - if (Op1Val == 3 && Op2Val == 1) - Asm = "dc\tcvau"; - break; - case 12: - if (Op1Val == 3 && Op2Val == 1 && - (STI.getFeatureBits()[AArch64::HasV8_2aOps])) - Asm = "dc\tcvap"; - break; - case 14: - if (Op1Val == 3 && Op2Val == 1) - Asm = "dc\tcivac"; - else if (Op1Val == 0 && Op2Val == 2) - Asm = "dc\tcisw"; - break; - + case 4: case 6: case 10: case 11: case 12: case 14: + { + Encoding |= 1 << 14; + const AArch64DC::DC *DC = AArch64DC::lookupDCByEncoding(Encoding); + if (!DC || !DC->haveFeatures(STI.getFeatureBits())) + return false; + + NeedsReg = true; + Ins = "dc\t"; + Name = std::string(DC->Name); + } + break; // AT aliases - case 8: - switch (Op1Val) { - default: - break; - case 0: - switch (Op2Val) { - default: - break; - case 0: Asm = "at\ts1e1r"; break; - case 1: Asm = "at\ts1e1w"; break; - case 2: Asm = "at\ts1e0r"; break; - case 3: Asm = "at\ts1e0w"; break; - } - break; - case 4: - switch (Op2Val) { - default: - break; - case 0: Asm = "at\ts1e2r"; break; - case 1: Asm = "at\ts1e2w"; break; - case 4: Asm = "at\ts12e1r"; break; - case 5: Asm = "at\ts12e1w"; break; - case 6: Asm = "at\ts12e0r"; break; - case 7: Asm = "at\ts12e0w"; break; - } - break; - case 6: - switch (Op2Val) { - default: - break; - case 0: Asm = "at\ts1e3r"; break; - case 1: Asm = "at\ts1e3w"; break; - } - break; - } - break; - case 9: - switch (Op1Val) { - default: - break; - case 0: - if (STI.getFeatureBits()[AArch64::HasV8_2aOps]) { - switch (Op2Val) { - default: - break; - case 0: Asm = "at\ts1e1rp"; break; - case 1: Asm = "at\ts1e1wp"; break; - } - } - break; - } + case 8: case 9: { + Encoding |= 1 << 14; + const AArch64AT::AT *AT = AArch64AT::lookupATByEncoding(Encoding); + if (!AT || !AT->haveFeatures(STI.getFeatureBits())) + return false; + + NeedsReg = true; + Ins = "at\t"; + Name = std::string(AT->Name); + } + break; } } else if (CnVal == 8) { // TLBI aliases - switch (CmVal) { - default: - break; - case 3: - switch (Op1Val) { - default: - break; - case 0: - switch (Op2Val) { - default: - break; - case 0: Asm = "tlbi\tvmalle1is"; break; - case 1: Asm = "tlbi\tvae1is"; break; - case 2: Asm = "tlbi\taside1is"; break; - case 3: Asm = "tlbi\tvaae1is"; break; - case 5: Asm = "tlbi\tvale1is"; break; - case 7: Asm = "tlbi\tvaale1is"; break; - } - break; - case 4: - switch (Op2Val) { - default: - break; - case 0: Asm = "tlbi\talle2is"; break; - case 1: Asm = "tlbi\tvae2is"; break; - case 4: Asm = "tlbi\talle1is"; break; - case 5: Asm = "tlbi\tvale2is"; break; - case 6: Asm = "tlbi\tvmalls12e1is"; break; - } - break; - case 6: - switch (Op2Val) { - default: - break; - case 0: Asm = "tlbi\talle3is"; break; - case 1: Asm = "tlbi\tvae3is"; break; - case 5: Asm = "tlbi\tvale3is"; break; - } - break; - } - break; - case 0: - switch (Op1Val) { - default: - break; - case 4: - switch (Op2Val) { - default: - break; - case 1: Asm = "tlbi\tipas2e1is"; break; - case 5: Asm = "tlbi\tipas2le1is"; break; - } - break; - } - break; - case 4: - switch (Op1Val) { - default: - break; - case 4: - switch (Op2Val) { - default: - break; - case 1: Asm = "tlbi\tipas2e1"; break; - case 5: Asm = "tlbi\tipas2le1"; break; - } - break; - } - break; - case 7: - switch (Op1Val) { - default: - break; - case 0: - switch (Op2Val) { - default: - break; - case 0: Asm = "tlbi\tvmalle1"; break; - case 1: Asm = "tlbi\tvae1"; break; - case 2: Asm = "tlbi\taside1"; break; - case 3: Asm = "tlbi\tvaae1"; break; - case 5: Asm = "tlbi\tvale1"; break; - case 7: Asm = "tlbi\tvaale1"; break; - } - break; - case 4: - switch (Op2Val) { - default: - break; - case 0: Asm = "tlbi\talle2"; break; - case 1: Asm = "tlbi\tvae2"; break; - case 4: Asm = "tlbi\talle1"; break; - case 5: Asm = "tlbi\tvale2"; break; - case 6: Asm = "tlbi\tvmalls12e1"; break; - } - break; - case 6: - switch (Op2Val) { - default: - break; - case 0: Asm = "tlbi\talle3"; break; - case 1: Asm = "tlbi\tvae3"; break; - case 5: Asm = "tlbi\tvale3"; break; - } - break; - } - break; - } + Encoding |= 1 << 14; + const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByEncoding(Encoding); + if (!TLBI || !TLBI->haveFeatures(STI.getFeatureBits())) + return false; + + NeedsReg = TLBI->NeedsReg; + Ins = "tlbi\t"; + Name = std::string(TLBI->Name); } + else + return false; - if (Asm) { - unsigned Reg = MI->getOperand(4).getReg(); + std::string Str = Ins + Name; + std::transform(Str.begin(), Str.end(), Str.begin(), ::tolower); - O << '\t' << Asm; - if (StringRef(Asm).lower().find("all") == StringRef::npos) - O << ", " << getRegisterName(Reg); - } + O << '\t' << Str; + if (NeedsReg) + O << ", " << getRegisterName(MI->getOperand(4).getReg()); - return Asm != nullptr; + return true; } void AArch64InstPrinter::printOperand(const MCInst *MI, unsigned OpNo, Index: lib/Target/AArch64/Utils/AArch64BaseInfo.h =================================================================== --- lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -266,82 +266,84 @@ } } // end namespace AArch64CC +struct SysAlias { + const char *Name; + uint16_t Encoding; + FeatureBitset FeaturesRequired; + + SysAlias (const char *N, uint16_t E) : Name(N), Encoding(E) {}; + SysAlias (const char *N, uint16_t E, FeatureBitset F) : + Name(N), Encoding(E), FeaturesRequired(F) {}; + + bool haveFeatures(FeatureBitset ActiveFeatures) const { + return (FeaturesRequired & ActiveFeatures) == FeaturesRequired; + } +}; + +struct SysAliasReg : SysAlias { + bool NeedsReg; + SysAliasReg(const char *N, uint16_t E, bool R) : SysAlias(N, E), NeedsReg(R) {}; +}; + namespace AArch64AT{ - struct AT { - const char *Name; - uint16_t Encoding; + struct AT : SysAlias { + using SysAlias::SysAlias; }; - #define GET_AT_DECL #include "AArch64GenSystemOperands.inc" - } + namespace AArch64DB { - struct DB { - const char *Name; - uint16_t Encoding; + struct DB : SysAlias { + using SysAlias::SysAlias; }; - #define GET_DB_DECL #include "AArch64GenSystemOperands.inc" } namespace AArch64DC { - struct DC { - const char *Name; - uint16_t Encoding; + struct DC : SysAlias { + using SysAlias::SysAlias; }; - #define GET_DC_DECL #include "AArch64GenSystemOperands.inc" } namespace AArch64IC { - struct IC { - const char *Name; - uint16_t Encoding; - bool NeedsReg; + struct IC : SysAliasReg { + using SysAliasReg::SysAliasReg; }; #define GET_IC_DECL #include "AArch64GenSystemOperands.inc" } namespace AArch64ISB { - struct ISB { - const char *Name; - uint16_t Encoding; + struct ISB : SysAlias { + using SysAlias::SysAlias; }; #define GET_ISB_DECL #include "AArch64GenSystemOperands.inc" } namespace AArch64PRFM { - struct PRFM { - const char *Name; - uint16_t Encoding; + struct PRFM : SysAlias { + using SysAlias::SysAlias; }; #define GET_PRFM_DECL #include "AArch64GenSystemOperands.inc" } namespace AArch64PState { - struct PState { - const char *Name; - uint16_t Encoding; - FeatureBitset FeaturesRequired; - - bool haveFeatures(FeatureBitset ActiveFeatures) const { - return (FeaturesRequired & ActiveFeatures) == FeaturesRequired; - } + struct PState : SysAlias{ + using SysAlias::SysAlias; }; #define GET_PSTATE_DECL #include "AArch64GenSystemOperands.inc" } namespace AArch64PSBHint { - struct PSB { - const char *Name; - uint16_t Encoding; + struct PSB : SysAlias { + using SysAlias::SysAlias; }; #define GET_PSB_DECL #include "AArch64GenSystemOperands.inc" @@ -451,10 +453,8 @@ } namespace AArch64TLBI { - struct TLBI { - const char *Name; - uint16_t Encoding; - bool NeedsReg; + struct TLBI : SysAliasReg { + using SysAliasReg::SysAliasReg; }; #define GET_TLBI_DECL #include "AArch64GenSystemOperands.inc"