llvm.org GIT mirror llvm / 45a3149
Condition codes AL and NV are invalid in the aliases that use inverted condition codes (CINC, CINV, CNEG, CSET, and CSETM). Matching aliases based on "immediate classes", when disassembling, wasn't previously supported, hence adding MCOperandPredicate into class Operand, and implementing the support for it in AsmWriterEmitter. The parsing for those aliases was already custom, so just adding the missing condition into AArch64AsmParser::parseCondCode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210528 91177308-0d34-0410-b5e6-96231b3b80d8 Artyom Skrobov 5 years ago
6 changed file(s) with 101 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
586586 string OperandType = "OPERAND_UNKNOWN";
587587 dag MIOperandInfo = (ops);
588588
589 // MCOperandPredicate - Optionally, a code fragment operating on
590 // const MCOperand &MCOp, and returning a bool, to indicate if
591 // the value of MCOp is valid for the specific subclass of Operand
592 code MCOperandPredicate;
593
589594 // ParserMatchClass - The "match class" that operands of this type fit
590595 // in. Match classes are used to define the order in which instructions are
591596 // match, to ensure that which instructions gets matched is deterministic.
962962 let ParserMatchClass = CondCode;
963963 }
964964 def inv_ccode : Operand {
965 // AL and NV are invalid in the aliases which use inv_ccode
965966 let PrintMethod = "printInverseCondCode";
966967 let ParserMatchClass = CondCode;
968 let MCOperandPredicate = [{
969 return MCOp.isImm() &&
970 MCOp.getImm() != AArch64CC::AL &&
971 MCOp.getImm() != AArch64CC::NV;
972 }];
967973 }
968974
969975 // Conditional branch target. 19-bit immediate. The low two bits of the target
21832183 return TokError("invalid condition code");
21842184 Parser.Lex(); // Eat identifier token.
21852185
2186 if (invertCondCode)
2186 if (invertCondCode) {
2187 if (CC == AArch64CC::AL || CC == AArch64CC::NV)
2188 return TokError("condition codes AL and NV are invalid for this instruction");
21872189 CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC));
2190 }
21882191
21892192 Operands.push_back(
21902193 AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
13441344
13451345 cset wsp, lt
13461346 csetm sp, ge
1347 cset w1, al
1348 csetm x6, nv
13471349 // CHECK-ERROR: error: invalid operand for instruction
13481350 // CHECK-ERROR-NEXT: cset wsp, lt
13491351 // CHECK-ERROR-NEXT: ^
13501352 // CHECK-ERROR-NEXT: error: invalid operand for instruction
13511353 // CHECK-ERROR-NEXT: csetm sp, ge
13521354 // CHECK-ERROR-NEXT: ^
1355 // CHECK-ERROR-NEXT: error: condition codes AL and NV are invalid for this instruction
1356 // CHECK-ERROR-NEXT: cset w1, al
1357 // CHECK-ERROR-NEXT: ^
1358 // CHECK-ERROR-NEXT: error: condition codes AL and NV are invalid for this instruction
1359 // CHECK-ERROR-NEXT: csetm x6, nv
1360 // CHECK-ERROR-NEXT: ^
13531361
13541362 cinc w3, wsp, ne
13551363 cinc sp, x9, eq
1364 cinc x2, x0, nv
13561365 // CHECK-ERROR: error: invalid operand for instruction
13571366 // CHECK-ERROR-NEXT: cinc w3, wsp, ne
13581367 // CHECK-ERROR-NEXT: ^
13591368 // CHECK-ERROR-NEXT: error: invalid operand for instruction
13601369 // CHECK-ERROR-NEXT: cinc sp, x9, eq
13611370 // CHECK-ERROR-NEXT: ^
1371 // CHECK-ERROR-NEXT: error: condition codes AL and NV are invalid for this instruction
1372 // CHECK-ERROR-NEXT: cinc x2, x0, nv
1373 // CHECK-ERROR-NEXT: ^
13621374
13631375 cinv w3, wsp, ne
13641376 cinv sp, x9, eq
1377 cinv w8, x7, nv
13651378 // CHECK-ERROR: error: invalid operand for instruction
13661379 // CHECK-ERROR-NEXT: cinv w3, wsp, ne
13671380 // CHECK-ERROR-NEXT: ^
13681381 // CHECK-ERROR-NEXT: error: invalid operand for instruction
13691382 // CHECK-ERROR-NEXT: cinv sp, x9, eq
13701383 // CHECK-ERROR-NEXT: ^
1384 // CHECK-ERROR-NEXT: error: condition codes AL and NV are invalid for this instruction
1385 // CHECK-ERROR-NEXT: cinv w8, x7, nv
1386 // CHECK-ERROR-NEXT: ^
13711387
13721388 cneg w3, wsp, ne
13731389 cneg sp, x9, eq
1390 cneg x4, x5, al
13741391 // CHECK-ERROR: error: invalid operand for instruction
13751392 // CHECK-ERROR-NEXT: cneg w3, wsp, ne
13761393 // CHECK-ERROR-NEXT: ^
13771394 // CHECK-ERROR-NEXT: error: invalid operand for instruction
13781395 // CHECK-ERROR-NEXT: cneg sp, x9, eq
13791396 // CHECK-ERROR-NEXT: ^
1397 // CHECK-ERROR-NEXT: error: condition codes AL and NV are invalid for this instruction
1398 // CHECK-ERROR-NEXT: cneg x4, x5, al
1399 // CHECK-ERROR-NEXT: ^
13801400
13811401 //------------------------------------------------------------------------------
13821402 // Data Processing (1 source)
944944 # CHECK: cset x9, pl
945945 # CHECK: csetm w20, ne
946946 # CHECK: csetm x30, ge
947 # "cset w2, nv" and "csetm x3, al" are invalid aliases for these two
948 # CHECK: csinc w2, wzr, wzr, al
949 # CHECK: csinv x3, xzr, xzr, nv
947950 0xe3 0x17 0x9f 0x1a
948951 0xe9 0x47 0x9f 0x9a
949952 0xf4 0x3 0x9f 0x5a
950953 0xfe 0xb3 0x9f 0xda
954 0xe2,0xe7,0x9f,0x1a
955 0xe3,0xf3,0x9f,0xda
951956
952957 # CHECK: cinc w3, w5, gt
953958 # CHECK: cinc wzr, w4, le
955960 # CHECK: cinc x3, x5, gt
956961 # CHECK: cinc xzr, x4, le
957962 # CHECK: cset x9, lt
963 # "cinc w5, w6, al" and "cinc x1, x2, nv" are invalid aliases for these two
964 # CHECK: csinc w5, w6, w6, nv
965 # CHECK: csinc x1, x2, x2, al
958966 0xa3 0xd4 0x85 0x1a
959967 0x9f 0xc4 0x84 0x1a
960968 0xe9 0xa7 0x9f 0x1a
961969 0xa3 0xd4 0x85 0x9a
962970 0x9f 0xc4 0x84 0x9a
963971 0xe9 0xa7 0x9f 0x9a
972 0xc5,0xf4,0x86,0x1a
973 0x41,0xe4,0x82,0x9a
964974
965975 # CHECK: cinv w3, w5, gt
966976 # CHECK: cinv wzr, w4, le
968978 # CHECK: cinv x3, x5, gt
969979 # CHECK: cinv xzr, x4, le
970980 # CHECK: csetm x9, lt
971 # CHECK: cinv x0, x0, nv
981 # "cinv x1, x0, nv" and "cinv w9, w8, al" are invalid aliases for these two
982 # CHECK: csinv x1, x0, x0, al
983 # CHECK: csinv w9, w8, w8, nv
972984 0xa3 0xd0 0x85 0x5a
973985 0x9f 0xc0 0x84 0x5a
974986 0xe9 0xa3 0x9f 0x5a
975987 0xa3 0xd0 0x85 0xda
976988 0x9f 0xc0 0x84 0xda
977989 0xe9 0xa3 0x9f 0xda
978 0x00 0xe0 0x80 0xda
990 0x01 0xe0 0x80 0xda
991 0x09,0xf1,0x88,0x5a
979992
980993 # CHECK: cneg w3, w5, gt
981994 # CHECK: cneg wzr, w4, le
983996 # CHECK: cneg x3, x5, gt
984997 # CHECK: cneg xzr, x4, le
985998 # CHECK: cneg x9, xzr, lt
999 # "cneg x4, x8, nv" and "cneg w5, w6, al" are invalid aliases for these two
1000 # CHECK: csneg x4, x8, x8, al
1001 # CHECK: csinv w9, w8, w8, nv
9861002 0xa3 0xd4 0x85 0x5a
9871003 0x9f 0xc4 0x84 0x5a
9881004 0xe9 0xa7 0x9f 0x5a
9891005 0xa3 0xd4 0x85 0xda
9901006 0x9f 0xc4 0x84 0xda
9911007 0xe9 0xa7 0x9f 0xda
1008 0x04,0xe5,0x88,0xda
1009 0x09,0xf1,0x88,0x5a
9921010
9931011 #------------------------------------------------------------------------------
9941012 # Data-processing (1 source)
805805 // before it can be matched to the mnemonic.
806806 std::map > IAPrinterMap;
807807
808 // A list of MCOperandPredicates for all operands in use, and the reverse map
809 std::vector MCOpPredicates;
810 DenseMap MCOpPredicateMap;
811
808812 for (auto &Aliases : AliasMap) {
809813 for (auto &Alias : Aliases.second) {
810814 const CodeGenInstAlias *CGA = Alias.first;
869873 Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" +
870874 R->getName() + "RegClassID)"
871875 ".contains(" + Op + ".getReg())";
872 IAP->addCond(Cond);
873876 } else {
874877 Cond = Op + ".getReg() == MI->getOperand(" +
875878 llvm::utostr(IAP->getOpIndex(ROName)) + ").getReg()";
876 IAP->addCond(Cond);
877879 }
878880 } else {
879881 // Assume all printable operands are desired for now. This can be
880882 // overridden in the InstAlias instantiation if necessary.
881883 IAP->addOperand(ROName, MIOpNum, PrintMethodIdx);
884
885 // There might be an additional predicate on the MCOperand
886 unsigned Entry = MCOpPredicateMap[Rec];
887 if (!Entry) {
888 if (!Rec->isValueUnset("MCOperandPredicate")) {
889 MCOpPredicates.push_back(Rec);
890 Entry = MCOpPredicates.size();
891 MCOpPredicateMap[Rec] = Entry;
892 } else
893 break; // No conditions on this operand at all
894 }
895 Cond = Target.getName() + ClassName + "ValidateMCOperand(" +
896 Op + ", " + llvm::utostr(Entry) + ")";
882897 }
883
898 // for all subcases of ResultOperand::K_Record:
899 IAP->addCond(Cond);
884900 break;
885901 }
886902 case CodeGenInstAlias::ResultOperand::K_Imm: {
973989 O << "#endif // PRINT_ALIAS_INSTR\n";
974990 return;
975991 }
992
993 if (MCOpPredicates.size())
994 O << "static bool " << Target.getName() << ClassName
995 << "ValidateMCOperand(\n"
996 << " const MCOperand &MCOp, unsigned PredicateIndex);\n";
976997
977998 O << HeaderO.str();
978999 O.indent(2) << "const char *AsmString;\n";
10351056 }
10361057 O << "}\n\n";
10371058
1059 if (MCOpPredicates.size()) {
1060 O << "static bool " << Target.getName() << ClassName
1061 << "ValidateMCOperand(\n"
1062 << " const MCOperand &MCOp, unsigned PredicateIndex) {\n"
1063 << " switch (PredicateIndex) {\n"
1064 << " default:\n"
1065 << " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n"
1066 << " break;\n";
1067
1068 for (unsigned i = 0; i < MCOpPredicates.size(); ++i) {
1069 Init *MCOpPred = MCOpPredicates[i]->getValueInit("MCOperandPredicate");
1070 if (StringInit *SI = dyn_cast(MCOpPred)) {
1071 O << " case " << i + 1 << ": {\n"
1072 << SI->getValue() << "\n"
1073 << " }\n";
1074 } else
1075 llvm_unreachable("Unexpected MCOperandPredicate field!");
1076 }
1077 O << " }\n"
1078 << "}\n\n";
1079 }
1080
10381081 O << "#endif // PRINT_ALIAS_INSTR\n";
10391082 }
10401083