Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: src/PNaClTranslator.cpp

Issue 543793003: Add icmp and fcmp instructions to Subzero bitcode reader. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nit. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTypes.def ('k') | tests_lit/reader_tests/compare.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file implements the PNaCl bitcode file to Ice, to machine code 10 // This file implements the PNaCl bitcode file to Ice, to machine code
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 case Instruction::Xor: 1027 case Instruction::Xor:
1028 Op = Ice::InstArithmetic::Xor; 1028 Op = Ice::InstArithmetic::Xor;
1029 return isValidIntegerLogicalOp(Op, Ty); 1029 return isValidIntegerLogicalOp(Op, Ty);
1030 } 1030 }
1031 } 1031 }
1032 1032
1033 /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice 1033 /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice
1034 /// cast opcode and assigns to CastKind. Returns true if successful, 1034 /// cast opcode and assigns to CastKind. Returns true if successful,
1035 /// false otherwise. 1035 /// false otherwise.
1036 bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp, 1036 bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp,
1037 Ice::InstCast::OpKind &CastKind) { 1037 Ice::InstCast::OpKind &CastKind) const {
1038 switch (LLVMCastOp) { 1038 switch (LLVMCastOp) {
1039 case Instruction::ZExt: 1039 case Instruction::ZExt:
1040 CastKind = Ice::InstCast::Zext; 1040 CastKind = Ice::InstCast::Zext;
1041 break; 1041 break;
1042 case Instruction::SExt: 1042 case Instruction::SExt:
1043 CastKind = Ice::InstCast::Sext; 1043 CastKind = Ice::InstCast::Sext;
1044 break; 1044 break;
1045 case Instruction::Trunc: 1045 case Instruction::Trunc:
1046 CastKind = Ice::InstCast::Trunc; 1046 CastKind = Ice::InstCast::Trunc;
1047 break; 1047 break;
(...skipping 16 matching lines...) Expand all
1064 CastKind = Ice::InstCast::Uitofp; 1064 CastKind = Ice::InstCast::Uitofp;
1065 break; 1065 break;
1066 case Instruction::BitCast: 1066 case Instruction::BitCast:
1067 CastKind = Ice::InstCast::Bitcast; 1067 CastKind = Ice::InstCast::Bitcast;
1068 break; 1068 break;
1069 default: 1069 default:
1070 return false; 1070 return false;
1071 } 1071 }
1072 return true; 1072 return true;
1073 } 1073 }
1074
1075 // Converts PNaCl bitcode Icmp operator to corresponding ICE op.
1076 // Returns true if able to convert, false otherwise.
1077 bool convertNaClBitcICmpOpToIce(uint64_t Op,
1078 Ice::InstIcmp::ICond &Cond) const {
1079 switch (Op) {
1080 case naclbitc::ICMP_EQ:
1081 Cond = Ice::InstIcmp::Eq;
1082 return true;
1083 case naclbitc::ICMP_NE:
1084 Cond = Ice::InstIcmp::Ne;
1085 return true;
1086 case naclbitc::ICMP_UGT:
1087 Cond = Ice::InstIcmp::Ugt;
1088 return true;
1089 case naclbitc::ICMP_UGE:
1090 Cond = Ice::InstIcmp::Uge;
1091 return true;
1092 case naclbitc::ICMP_ULT:
1093 Cond = Ice::InstIcmp::Ult;
1094 return true;
1095 case naclbitc::ICMP_ULE:
1096 Cond = Ice::InstIcmp::Ule;
1097 return true;
1098 case naclbitc::ICMP_SGT:
1099 Cond = Ice::InstIcmp::Sgt;
1100 return true;
1101 case naclbitc::ICMP_SGE:
1102 Cond = Ice::InstIcmp::Sge;
1103 return true;
1104 case naclbitc::ICMP_SLT:
1105 Cond = Ice::InstIcmp::Slt;
1106 return true;
1107 case naclbitc::ICMP_SLE:
1108 Cond = Ice::InstIcmp::Sle;
1109 return true;
1110 default:
1111 return false;
1112 }
1113 }
1114
1115 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op.
1116 // Returns true if able to convert, false otherwise.
1117 bool convertNaClBitcFCompOpToIce(uint64_t Op,
1118 Ice::InstFcmp::FCond &Cond) const {
1119 switch (Op) {
1120 case naclbitc::FCMP_FALSE:
1121 Cond = Ice::InstFcmp::False;
1122 return true;
1123 case naclbitc::FCMP_OEQ:
1124 Cond = Ice::InstFcmp::Oeq;
1125 return true;
1126 case naclbitc::FCMP_OGT:
1127 Cond = Ice::InstFcmp::Ogt;
1128 return true;
1129 case naclbitc::FCMP_OGE:
1130 Cond = Ice::InstFcmp::Oge;
1131 return true;
1132 case naclbitc::FCMP_OLT:
1133 Cond = Ice::InstFcmp::Olt;
1134 return true;
1135 case naclbitc::FCMP_OLE:
1136 Cond = Ice::InstFcmp::Ole;
1137 return true;
1138 case naclbitc::FCMP_ONE:
1139 Cond = Ice::InstFcmp::One;
1140 return true;
1141 case naclbitc::FCMP_ORD:
1142 Cond = Ice::InstFcmp::Ord;
1143 return true;
1144 case naclbitc::FCMP_UNO:
1145 Cond = Ice::InstFcmp::Uno;
1146 return true;
1147 case naclbitc::FCMP_UEQ:
1148 Cond = Ice::InstFcmp::Ueq;
1149 return true;
1150 case naclbitc::FCMP_UGT:
1151 Cond = Ice::InstFcmp::Ugt;
1152 return true;
1153 case naclbitc::FCMP_UGE:
1154 Cond = Ice::InstFcmp::Uge;
1155 return true;
1156 case naclbitc::FCMP_ULT:
1157 Cond = Ice::InstFcmp::Ult;
1158 return true;
1159 case naclbitc::FCMP_ULE:
1160 Cond = Ice::InstFcmp::Ule;
1161 return true;
1162 case naclbitc::FCMP_UNE:
1163 Cond = Ice::InstFcmp::Une;
1164 return true;
1165 case naclbitc::FCMP_TRUE:
1166 Cond = Ice::InstFcmp::True;
1167 return true;
1168 default:
1169 return false;
1170 }
1171 }
1074 }; 1172 };
1075 1173
1076 FunctionParser::~FunctionParser() { 1174 FunctionParser::~FunctionParser() {
1077 if (getTranslator().getFlags().SubzeroTimingEnabled) { 1175 if (getTranslator().getFlags().SubzeroTimingEnabled) {
1078 errs() << "[Subzero timing] Convert function " << Func->getFunctionName() 1176 errs() << "[Subzero timing] Convert function " << Func->getFunctionName()
1079 << ": " << TConvert.getElapsedSec() << " sec\n"; 1177 << ": " << TConvert.getElapsedSec() << " sec\n";
1080 } 1178 }
1081 } 1179 }
1082 1180
1083 void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) { 1181 void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1231 StrBuf << "Select condition not type i1. Found: " << CondVal->getType(); 1329 StrBuf << "Select condition not type i1. Found: " << CondVal->getType();
1232 Error(StrBuf.str()); 1330 Error(StrBuf.str());
1233 return; 1331 return;
1234 } 1332 }
1235 Ice::Variable *DestVal = NextInstVar(ThenType); 1333 Ice::Variable *DestVal = NextInstVar(ThenType);
1236 Inst = Ice::InstSelect::create(Func, DestVal, CondVal, ThenVal, ElseVal); 1334 Inst = Ice::InstSelect::create(Func, DestVal, CondVal, ThenVal, ElseVal);
1237 break; 1335 break;
1238 } 1336 }
1239 case naclbitc::FUNC_CODE_INST_EXTRACTELT: { 1337 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
1240 // EXTRACTELT: [opval, opval] 1338 // EXTRACTELT: [opval, opval]
1339 if (!isValidRecordSize(2, "function block extract element"))
1340 return;
1241 Ice::Operand *Vec = getRelativeOperand(Values[0]); 1341 Ice::Operand *Vec = getRelativeOperand(Values[0]);
1242 Ice::Type VecType = Vec->getType(); 1342 Ice::Type VecType = Vec->getType();
1243 if (!Ice::isVectorType(VecType)) { 1343 if (!Ice::isVectorType(VecType)) {
1244 std::string Buffer; 1344 std::string Buffer;
1245 raw_string_ostream StrBuf(Buffer); 1345 raw_string_ostream StrBuf(Buffer);
1246 StrBuf << "Extractelement not on vector. Found: " << Vec; 1346 StrBuf << "Extractelement not on vector. Found: " << Vec;
1247 Error(StrBuf.str()); 1347 Error(StrBuf.str());
1248 } 1348 }
1249 Ice::Operand *Index = getRelativeOperand(Values[1]); 1349 Ice::Operand *Index = getRelativeOperand(Values[1]);
1250 if (Index->getType() != Ice::IceType_i32) { 1350 if (Index->getType() != Ice::IceType_i32) {
1251 std::string Buffer; 1351 std::string Buffer;
1252 raw_string_ostream StrBuf(Buffer); 1352 raw_string_ostream StrBuf(Buffer);
1253 StrBuf << "Extractelement index not i32. Found: " << Index; 1353 StrBuf << "Extractelement index not i32. Found: " << Index;
1254 Error(StrBuf.str()); 1354 Error(StrBuf.str());
1255 } 1355 }
1256 // TODO(kschimpf): Restrict index to a legal constant index (once 1356 // TODO(kschimpf): Restrict index to a legal constant index (once
1257 // constants can be defined). 1357 // constants can be defined).
1258 Ice::Variable *Dest = NextInstVar(typeElementType(VecType)); 1358 Ice::Variable *Dest = NextInstVar(typeElementType(VecType));
1259 Inst = Ice::InstExtractElement::create(Func, Dest, Vec, Index); 1359 Inst = Ice::InstExtractElement::create(Func, Dest, Vec, Index);
1260 break; 1360 break;
1261 } 1361 }
1262 case naclbitc::FUNC_CODE_INST_INSERTELT: { 1362 case naclbitc::FUNC_CODE_INST_INSERTELT: {
1263 // INSERTELT: [opval, opval, opval] 1363 // INSERTELT: [opval, opval, opval]
1364 if (!isValidRecordSize(3, "function block insert element"))
1365 return;
1264 Ice::Operand *Vec = getRelativeOperand(Values[0]); 1366 Ice::Operand *Vec = getRelativeOperand(Values[0]);
1265 Ice::Type VecType = Vec->getType(); 1367 Ice::Type VecType = Vec->getType();
1266 if (!Ice::isVectorType(VecType)) { 1368 if (!Ice::isVectorType(VecType)) {
1267 std::string Buffer; 1369 std::string Buffer;
1268 raw_string_ostream StrBuf(Buffer); 1370 raw_string_ostream StrBuf(Buffer);
1269 StrBuf << "Insertelement not on vector. Found: " << Vec; 1371 StrBuf << "Insertelement not on vector. Found: " << Vec;
1270 Error(StrBuf.str()); 1372 Error(StrBuf.str());
1271 } 1373 }
1272 Ice::Operand *Elt = getRelativeOperand(Values[1]); 1374 Ice::Operand *Elt = getRelativeOperand(Values[1]);
1273 Ice::Type EltType = Elt->getType(); 1375 Ice::Type EltType = Elt->getType();
(...skipping 10 matching lines...) Expand all
1284 raw_string_ostream StrBuf(Buffer); 1386 raw_string_ostream StrBuf(Buffer);
1285 StrBuf << "Insertelement index not i32. Found: " << Index; 1387 StrBuf << "Insertelement index not i32. Found: " << Index;
1286 Error(StrBuf.str()); 1388 Error(StrBuf.str());
1287 } 1389 }
1288 // TODO(kschimpf): Restrict index to a legal constant index (once 1390 // TODO(kschimpf): Restrict index to a legal constant index (once
1289 // constants can be defined). 1391 // constants can be defined).
1290 Ice::Variable *Dest = NextInstVar(EltType); 1392 Ice::Variable *Dest = NextInstVar(EltType);
1291 Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index); 1393 Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index);
1292 break; 1394 break;
1293 } 1395 }
1396 case naclbitc::FUNC_CODE_INST_CMP2: {
1397 // CMP2: [opval, opval, pred]
1398 if (!isValidRecordSize(3, "function block compare"))
1399 return;
1400 Ice::Operand *Op1 = getRelativeOperand(Values[0]);
1401 Ice::Operand *Op2 = getRelativeOperand(Values[1]);
1402 Ice::Type Op1Type = Op1->getType();
1403 Ice::Type Op2Type = Op2->getType();
1404 if (Op1Type != Op2Type) {
1405 std::string Buffer;
1406 raw_string_ostream StrBuf(Buffer);
1407 StrBuf << "Compare argument types differ: " << Op1Type
1408 << " and " << Op2Type;
1409 Error(StrBuf.str());
1410 // TODO(kschimpf) Remove error recovery once implementation complete.
1411 Op2 = Op1;
1412 }
1413 Ice::Type DestType = getCompareResultType(Op1Type);
1414 if (DestType == Ice::IceType_void) {
1415 std::string Buffer;
1416 raw_string_ostream StrBuf(Buffer);
1417 StrBuf << "Compare not defined for type " << Op1Type;
1418 Error(StrBuf.str());
1419 return;
1420 }
1421 Ice::Variable *Dest = NextInstVar(DestType);
1422 if (isIntegerType(Op1Type)) {
1423 Ice::InstIcmp::ICond Cond;
1424 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
1425 std::string Buffer;
1426 raw_string_ostream StrBuf(Buffer);
1427 StrBuf << "Compare record contains unknown integer predicate index: "
1428 << Values[2];
1429 Error(StrBuf.str());
1430 // TODO(kschimpf) Remove error recovery once implementation complete.
1431 Cond = Ice::InstIcmp::Eq;
1432 }
1433 Inst = Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2);
1434 } else if (isFloatingType(Op1Type)){
1435 Ice::InstFcmp::FCond Cond;
1436 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
1437 std::string Buffer;
1438 raw_string_ostream StrBuf(Buffer);
1439 StrBuf << "Compare record contains unknown float predicate index: "
1440 << Values[2];
1441 Error(StrBuf.str());
1442 // TODO(kschimpf) Remove error recovery once implementation complete.
1443 Cond = Ice::InstFcmp::False;
1444 }
1445 Inst = Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2);
1446 } else {
1447 // Not sure this can happen, but be safe.
1448 std::string Buffer;
1449 raw_string_ostream StrBuf(Buffer);
1450 StrBuf << "Compare on type not understood: " << Op1Type;
1451 Error(StrBuf.str());
1452 return;
1453 }
1454 break;
1455 }
1294 case naclbitc::FUNC_CODE_INST_RET: { 1456 case naclbitc::FUNC_CODE_INST_RET: {
1295 // RET: [opval?] 1457 // RET: [opval?]
1296 InstIsTerminating = true; 1458 InstIsTerminating = true;
1297 if (!isValidRecordSizeInRange(0, 1, "function block ret")) 1459 if (!isValidRecordSizeInRange(0, 1, "function block ret"))
1298 return; 1460 return;
1299 if (Values.size() == 0) { 1461 if (Values.size() == 0) {
1300 Inst = Ice::InstRet::create(Func); 1462 Inst = Ice::InstRet::create(Func);
1301 } else { 1463 } else {
1302 Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0])); 1464 Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0]));
1303 } 1465 }
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 if (TopLevelBlocks != 1) { 1632 if (TopLevelBlocks != 1) {
1471 errs() << IRFilename 1633 errs() << IRFilename
1472 << ": Contains more than one module. Found: " << TopLevelBlocks 1634 << ": Contains more than one module. Found: " << TopLevelBlocks
1473 << "\n"; 1635 << "\n";
1474 ErrorStatus = true; 1636 ErrorStatus = true;
1475 } 1637 }
1476 return; 1638 return;
1477 } 1639 }
1478 1640
1479 } // end of namespace Ice 1641 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTypes.def ('k') | tests_lit/reader_tests/compare.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698