llvm.org GIT mirror llvm / 7dcd9e7
AMDGPU: Add R600InstPrinter class Summary: This is step towards separating the GCN and R600 tablegen'd code. This is a little awkward for now, because the R600 functions won't have the MCSubtargetInfo parameter, so we need to have AMDMGPUInstPrinter delegate to R600InstPrinter, but once the tablegen'd code is split, we will be able to drop the delegation and use R600InstPrinter directly. Reviewers: arsenm Subscribers: kzhuravl, wdng, nhaehnle, yaxunl, dstuttard, tpr, t-tye, llvm-commits Differential Revision: https://reviews.llvm.org/D36444 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311128 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 2 years ago
3 changed file(s) with 252 addition(s) and 109 deletion(s). Raw diff Collapse all Expand all
495495 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
496496 const MCSubtargetInfo &STI,
497497 raw_ostream &O) {
498 if (!STI.getFeatureBits()[AMDGPU::FeatureGCN]) {
499 static_cast(this)->printOperand(MI, OpNo, O);
500 return;
501 }
502
498503 if (OpNo >= MI->getNumOperands()) {
499504 O << "/*Missing OP" << OpNo << "*/";
500505 return;
502507
503508 const MCOperand &Op = MI->getOperand(OpNo);
504509 if (Op.isReg()) {
505 switch (Op.getReg()) {
506 // This is the default predicate state, so we don't need to print it.
507 case AMDGPU::PRED_SEL_OFF:
508 break;
509
510 default:
511 printRegOperand(Op.getReg(), O, MRI);
512 break;
513 }
510 printRegOperand(Op.getReg(), O, MRI);
514511 } else if (Op.isImm()) {
515512 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
516513 switch (Desc.OpInfo[OpNo].OperandType) {
945942 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
946943 const MCSubtargetInfo &STI,
947944 raw_ostream &O) {
945 if (!STI.getFeatureBits()[AMDGPU::FeatureGCN]) {
946 static_cast(this)->printMemOperand(MI, OpNo, O);
947 return;
948 }
949
948950 printOperand(MI, OpNo, STI, O);
949951 O << ", ";
950952 printOperand(MI, OpNo + 1, STI, O);
972974
973975 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
974976 const MCSubtargetInfo &STI, raw_ostream &O) {
975 printIfSet(MI, OpNo, O, '|');
977 static_cast(this)->printAbs(MI, OpNo, O);
976978 }
977979
978980 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
979981 const MCSubtargetInfo &STI, raw_ostream &O) {
980 printIfSet(MI, OpNo, O, "_SAT");
982 static_cast(this)->printClamp(MI, OpNo, O);
981983 }
982984
983985 void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo,
10091011 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
10101012 const MCSubtargetInfo &STI,
10111013 raw_ostream &O) {
1012 const MCOperand &Op = MI->getOperand(OpNo);
1013 assert(Op.isImm() || Op.isExpr());
1014 if (Op.isImm()) {
1015 int64_t Imm = Op.getImm();
1016 O << Imm << '(' << BitsToFloat(Imm) << ')';
1017 }
1018 if (Op.isExpr()) {
1019 Op.getExpr()->print(O << '@', &MAI);
1020 }
1014 static_cast(this)->printLiteral(MI, OpNo, O);
10211015 }
10221016
10231017 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
10241018 const MCSubtargetInfo &STI, raw_ostream &O) {
1025 printIfSet(MI, OpNo, O, "*", " ");
1019 static_cast(this)->printLast(MI, OpNo, O);
10261020 }
10271021
10281022 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
10291023 const MCSubtargetInfo &STI, raw_ostream &O) {
1030 printIfSet(MI, OpNo, O, '-');
1024 static_cast(this)->printNeg(MI, OpNo, O);
10311025 }
10321026
10331027 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
10341028 const MCSubtargetInfo &STI, raw_ostream &O) {
1035 switch (MI->getOperand(OpNo).getImm()) {
1036 default: break;
1037 case 1:
1038 O << " * 2.0";
1039 break;
1040 case 2:
1041 O << " * 4.0";
1042 break;
1043 case 3:
1044 O << " / 2.0";
1045 break;
1046 }
1029 static_cast(this)->printOMOD(MI, OpNo, O);
10471030 }
10481031
10491032 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
10501033 const MCSubtargetInfo &STI, raw_ostream &O) {
1051 printIfSet(MI, OpNo, O, '+');
1034 static_cast(this)->printRel(MI, OpNo, O);
10521035 }
10531036
10541037 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
10551038 const MCSubtargetInfo &STI,
10561039 raw_ostream &O) {
1057 printIfSet(MI, OpNo, O, "ExecMask,");
1040 static_cast(this)->printUpdateExecMask(MI, OpNo, O);
10581041 }
10591042
10601043 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
10611044 const MCSubtargetInfo &STI,
10621045 raw_ostream &O) {
1063 printIfSet(MI, OpNo, O, "Pred,");
1046 static_cast(this)->printUpdatePred(MI, OpNo, O);
10641047 }
10651048
10661049 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
10671050 const MCSubtargetInfo &STI, raw_ostream &O) {
1068 const MCOperand &Op = MI->getOperand(OpNo);
1069 if (Op.getImm() == 0) {
1070 O << " (MASKED)";
1071 }
1051 static_cast(this)->printWrite(MI, OpNo, O);
10721052 }
10731053
10741054 void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
10751055 const MCSubtargetInfo &STI,
10761056 raw_ostream &O) {
1077 int BankSwizzle = MI->getOperand(OpNo).getImm();
1078 switch (BankSwizzle) {
1079 case 1:
1080 O << "BS:VEC_021/SCL_122";
1081 break;
1082 case 2:
1083 O << "BS:VEC_120/SCL_212";
1084 break;
1085 case 3:
1086 O << "BS:VEC_102/SCL_221";
1087 break;
1088 case 4:
1089 O << "BS:VEC_201";
1090 break;
1091 case 5:
1092 O << "BS:VEC_210";
1093 break;
1094 default:
1095 break;
1096 }
1057 static_cast(this)->printBankSwizzle(MI, OpNo, O);
10971058 }
10981059
10991060 void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
11001061 const MCSubtargetInfo &STI, raw_ostream &O) {
1101 unsigned Sel = MI->getOperand(OpNo).getImm();
1102 switch (Sel) {
1103 case 0:
1104 O << 'X';
1105 break;
1106 case 1:
1107 O << 'Y';
1108 break;
1109 case 2:
1110 O << 'Z';
1111 break;
1112 case 3:
1113 O << 'W';
1114 break;
1115 case 4:
1116 O << '0';
1117 break;
1118 case 5:
1119 O << '1';
1120 break;
1121 case 7:
1122 O << '_';
1123 break;
1124 default:
1125 break;
1126 }
1062 static_cast(this)->printRSel(MI, OpNo, O);
11271063 }
11281064
11291065 void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo,
11301066 const MCSubtargetInfo &STI, raw_ostream &O) {
1131 unsigned CT = MI->getOperand(OpNo).getImm();
1132 switch (CT) {
1133 case 0:
1134 O << 'U';
1135 break;
1136 case 1:
1137 O << 'N';
1138 break;
1139 default:
1140 break;
1141 }
1067 static_cast(this)->printCT(MI, OpNo, O);
11421068 }
11431069
11441070 void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
11451071 const MCSubtargetInfo &STI, raw_ostream &O) {
1146 int KCacheMode = MI->getOperand(OpNo).getImm();
1147 if (KCacheMode > 0) {
1148 int KCacheBank = MI->getOperand(OpNo - 2).getImm();
1149 O << "CB" << KCacheBank << ':';
1150 int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
1151 int LineSize = (KCacheMode == 1) ? 16 : 32;
1152 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
1153 }
1072 static_cast(this)->printKCache(MI, OpNo, O);
11541073 }
11551074
11561075 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
13531272 }
13541273
13551274 #include "AMDGPUGenAsmWriter.inc"
1275
1276 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
1277 raw_ostream &O) {
1278 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
1279 }
1280
1281 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
1282 raw_ostream &O) {
1283 int BankSwizzle = MI->getOperand(OpNo).getImm();
1284 switch (BankSwizzle) {
1285 case 1:
1286 O << "BS:VEC_021/SCL_122";
1287 break;
1288 case 2:
1289 O << "BS:VEC_120/SCL_212";
1290 break;
1291 case 3:
1292 O << "BS:VEC_102/SCL_221";
1293 break;
1294 case 4:
1295 O << "BS:VEC_201";
1296 break;
1297 case 5:
1298 O << "BS:VEC_210";
1299 break;
1300 default:
1301 break;
1302 }
1303 }
1304
1305 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
1306 raw_ostream &O) {
1307 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
1308 }
1309
1310 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo,
1311 raw_ostream &O) {
1312 unsigned CT = MI->getOperand(OpNo).getImm();
1313 switch (CT) {
1314 case 0:
1315 O << 'U';
1316 break;
1317 case 1:
1318 O << 'N';
1319 break;
1320 default:
1321 break;
1322 }
1323 }
1324
1325 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
1326 raw_ostream &O) {
1327 int KCacheMode = MI->getOperand(OpNo).getImm();
1328 if (KCacheMode > 0) {
1329 int KCacheBank = MI->getOperand(OpNo - 2).getImm();
1330 O << "CB" << KCacheBank << ':';
1331 int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
1332 int LineSize = (KCacheMode == 1) ? 16 : 32;
1333 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
1334 }
1335 }
1336
1337 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
1338 raw_ostream &O) {
1339 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
1340 }
1341
1342 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
1343 raw_ostream &O) {
1344 const MCOperand &Op = MI->getOperand(OpNo);
1345 assert(Op.isImm() || Op.isExpr());
1346 if (Op.isImm()) {
1347 int64_t Imm = Op.getImm();
1348 O << Imm << '(' << BitsToFloat(Imm) << ')';
1349 }
1350 if (Op.isExpr()) {
1351 Op.getExpr()->print(O << '@', &MAI);
1352 }
1353 }
1354
1355 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
1356 raw_ostream &O) {
1357 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
1358 }
1359
1360 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
1361 raw_ostream &O) {
1362 switch (MI->getOperand(OpNo).getImm()) {
1363 default: break;
1364 case 1:
1365 O << " * 2.0";
1366 break;
1367 case 2:
1368 O << " * 4.0";
1369 break;
1370 case 3:
1371 O << " / 2.0";
1372 break;
1373 }
1374 }
1375
1376 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1377 raw_ostream &O) {
1378 printOperand(MI, OpNo, O);
1379 O << ", ";
1380 printOperand(MI, OpNo + 1, O);
1381 }
1382
1383 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
1384 raw_ostream &O) {
1385 if (OpNo >= MI->getNumOperands()) {
1386 O << "/*Missing OP" << OpNo << "*/";
1387 return;
1388 }
1389
1390 const MCOperand &Op = MI->getOperand(OpNo);
1391 if (Op.isReg()) {
1392 switch (Op.getReg()) {
1393 // This is the default predicate state, so we don't need to print it.
1394 case AMDGPU::PRED_SEL_OFF:
1395 break;
1396
1397 default:
1398 O << getRegisterName(Op.getReg());
1399 break;
1400 }
1401 } else if (Op.isImm()) {
1402 O << Op.getImm();
1403 } else if (Op.isFPImm()) {
1404 // We special case 0.0 because otherwise it will be printed as an integer.
1405 if (Op.getFPImm() == 0.0)
1406 O << "0.0";
1407 else {
1408 O << Op.getFPImm();
1409 }
1410 } else if (Op.isExpr()) {
1411 const MCExpr *Exp = Op.getExpr();
1412 Exp->print(O, &MAI);
1413 } else {
1414 O << "/*INV_OP*/";
1415 }
1416 }
1417
1418 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
1419 raw_ostream &O) {
1420 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
1421 }
1422
1423 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
1424 raw_ostream &O) {
1425 unsigned Sel = MI->getOperand(OpNo).getImm();
1426 switch (Sel) {
1427 case 0:
1428 O << 'X';
1429 break;
1430 case 1:
1431 O << 'Y';
1432 break;
1433 case 2:
1434 O << 'Z';
1435 break;
1436 case 3:
1437 O << 'W';
1438 break;
1439 case 4:
1440 O << '0';
1441 break;
1442 case 5:
1443 O << '1';
1444 break;
1445 case 7:
1446 O << '_';
1447 break;
1448 default:
1449 break;
1450 }
1451 }
1452
1453 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
1454 raw_ostream &O) {
1455 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
1456 }
1457
1458 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
1459 raw_ostream &O) {
1460 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
1461 }
1462
1463 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
1464 raw_ostream &O) {
1465 const MCOperand &Op = MI->getOperand(OpNo);
1466 if (Op.getImm() == 0) {
1467 O << " (MASKED)";
1468 }
1469 }
1818
1919 class AMDGPUInstPrinter : public MCInstPrinter {
2020 public:
21 AMDGPUInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
22 const MCRegisterInfo &MRI)
21 AMDGPUInstPrinter(const MCAsmInfo &MAI,
22 const MCInstrInfo &MII, const MCRegisterInfo &MRI)
2323 : MCInstPrinter(MAI, MII, MRI) {}
2424
2525 //Autogenerated by tblgen
163163 void printExpTgt(const MCInst *MI, unsigned OpNo,
164164 const MCSubtargetInfo &STI, raw_ostream &O);
165165
166 public:
166167 static void printIfSet(const MCInst *MI, unsigned OpNo, raw_ostream &O,
167168 StringRef Asm, StringRef Default = "");
168169 static void printIfSet(const MCInst *MI, unsigned OpNo, raw_ostream &O,
169170 char Asm);
171 protected:
170172 void printAbs(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
171173 raw_ostream &O);
172174 void printHigh(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
211213 raw_ostream &O);
212214 };
213215
216 // FIXME: R600 specific parts of AMDGPUInstrPrinter should be moved here, and
217 // MCTargetDesc should be using R600InstPrinter for the R600 target.
218 class R600InstPrinter : public AMDGPUInstPrinter {
219 public:
220 R600InstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
221 const MCRegisterInfo &MRI)
222 : AMDGPUInstPrinter(MAI, MII, MRI) {}
223
224 void printAbs(const MCInst *MI, unsigned OpNo, raw_ostream &O);
225 void printBankSwizzle(const MCInst *MI, unsigned OpNo, raw_ostream &O);
226 void printClamp(const MCInst *MI, unsigned OpNo, raw_ostream &O);
227 void printCT(const MCInst *MI, unsigned OpNo, raw_ostream &O);
228 void printKCache(const MCInst *MI, unsigned OpNo, raw_ostream &O);
229 void printLast(const MCInst *MI, unsigned OpNo, raw_ostream &O);
230 void printLiteral(const MCInst *MI, unsigned OpNo, raw_ostream &O);
231 void printMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
232 void printNeg(const MCInst *MI, unsigned OpNo, raw_ostream &O);
233 void printOMOD(const MCInst *MI, unsigned OpNo, raw_ostream &O);
234 void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
235 void printRel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
236 void printRSel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
237 void printUpdateExecMask(const MCInst *MI, unsigned OpNo, raw_ostream &O);
238 void printUpdatePred(const MCInst *MI, unsigned OpNo, raw_ostream &O);
239 void printWrite(const MCInst *MI, unsigned OpNo, raw_ostream &O);
240 };
241
214242 } // End namespace llvm
215243
216244 #endif
5959 const MCAsmInfo &MAI,
6060 const MCInstrInfo &MII,
6161 const MCRegisterInfo &MRI) {
62 return new AMDGPUInstPrinter(MAI, MII, MRI);
62 return T.getArch() == Triple::r600 ? new R600InstPrinter(MAI, MII, MRI) :
63 new AMDGPUInstPrinter(MAI, MII, MRI);
6364 }
6465
6566 static MCTargetStreamer *createAMDGPUAsmTargetStreamer(MCStreamer &S,