Chromium Code Reviews

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: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
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...)
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...)
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 109 matching lines...)
1193 << " " << *SrcType << " to " << *CastType; 1291 << " " << *SrcType << " to " << *CastType;
1194 Error(StrBuf.str()); 1292 Error(StrBuf.str());
1195 return; 1293 return;
1196 } 1294 }
1197 Ice::Variable *Dest = NextInstVar(Context->convertToIceType(CastType)); 1295 Ice::Variable *Dest = NextInstVar(Context->convertToIceType(CastType));
1198 Inst = Ice::InstCast::create(Func, CastKind, Dest, Src); 1296 Inst = Ice::InstCast::create(Func, CastKind, Dest, Src);
1199 break; 1297 break;
1200 } 1298 }
1201 case naclbitc::FUNC_CODE_INST_EXTRACTELT: { 1299 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
1202 // EXTRACTELT: [opval, opval] 1300 // EXTRACTELT: [opval, opval]
1301 if (!isValidRecordSize(2, "function block extract element"))
1302 return;
1203 Ice::Operand *Vec = getRelativeOperand(Values[0]); 1303 Ice::Operand *Vec = getRelativeOperand(Values[0]);
1204 Ice::Type VecType = Vec->getType(); 1304 Ice::Type VecType = Vec->getType();
1205 if (!Ice::isVectorType(VecType)) { 1305 if (!Ice::isVectorType(VecType)) {
1206 std::string Buffer; 1306 std::string Buffer;
1207 raw_string_ostream StrBuf(Buffer); 1307 raw_string_ostream StrBuf(Buffer);
1208 StrBuf << "Extractelement not on vector. Found: " << Vec; 1308 StrBuf << "Extractelement not on vector. Found: " << Vec;
1209 Error(StrBuf.str()); 1309 Error(StrBuf.str());
1210 } 1310 }
1211 Ice::Operand *Index = getRelativeOperand(Values[1]); 1311 Ice::Operand *Index = getRelativeOperand(Values[1]);
1212 if (Index->getType() != Ice::IceType_i32) { 1312 if (Index->getType() != Ice::IceType_i32) {
1213 std::string Buffer; 1313 std::string Buffer;
1214 raw_string_ostream StrBuf(Buffer); 1314 raw_string_ostream StrBuf(Buffer);
1215 StrBuf << "Extractelement index not i32. Found: " << Index; 1315 StrBuf << "Extractelement index not i32. Found: " << Index;
1216 Error(StrBuf.str()); 1316 Error(StrBuf.str());
1217 } 1317 }
1218 // TODO(kschimpf): Restrict index to a legal constant index (once 1318 // TODO(kschimpf): Restrict index to a legal constant index (once
1219 // constants can be defined). 1319 // constants can be defined).
1220 Ice::Variable *Dest = NextInstVar(typeElementType(VecType)); 1320 Ice::Variable *Dest = NextInstVar(typeElementType(VecType));
1221 Inst = Ice::InstExtractElement::create(Func, Dest, Vec, Index); 1321 Inst = Ice::InstExtractElement::create(Func, Dest, Vec, Index);
1222 break; 1322 break;
1223 } 1323 }
1224 case naclbitc::FUNC_CODE_INST_INSERTELT: { 1324 case naclbitc::FUNC_CODE_INST_INSERTELT: {
1225 // INSERTELT: [opval, opval, opval] 1325 // INSERTELT: [opval, opval, opval]
1326 if (!isValidRecordSize(3, "function block insert element"))
1327 return;
1226 Ice::Operand *Vec = getRelativeOperand(Values[0]); 1328 Ice::Operand *Vec = getRelativeOperand(Values[0]);
1227 Ice::Type VecType = Vec->getType(); 1329 Ice::Type VecType = Vec->getType();
1228 if (!Ice::isVectorType(VecType)) { 1330 if (!Ice::isVectorType(VecType)) {
1229 std::string Buffer; 1331 std::string Buffer;
1230 raw_string_ostream StrBuf(Buffer); 1332 raw_string_ostream StrBuf(Buffer);
1231 StrBuf << "Insertelement not on vector. Found: " << Vec; 1333 StrBuf << "Insertelement not on vector. Found: " << Vec;
1232 Error(StrBuf.str()); 1334 Error(StrBuf.str());
1233 } 1335 }
1234 Ice::Operand *Elt = getRelativeOperand(Values[1]); 1336 Ice::Operand *Elt = getRelativeOperand(Values[1]);
1235 Ice::Type EltType = Elt->getType(); 1337 Ice::Type EltType = Elt->getType();
(...skipping 10 matching lines...)
1246 raw_string_ostream StrBuf(Buffer); 1348 raw_string_ostream StrBuf(Buffer);
1247 StrBuf << "Insertelement index not i32. Found: " << Index; 1349 StrBuf << "Insertelement index not i32. Found: " << Index;
1248 Error(StrBuf.str()); 1350 Error(StrBuf.str());
1249 } 1351 }
1250 // TODO(kschimpf): Restrict index to a legal constant index (once 1352 // TODO(kschimpf): Restrict index to a legal constant index (once
1251 // constants can be defined). 1353 // constants can be defined).
1252 Ice::Variable *Dest = NextInstVar(EltType); 1354 Ice::Variable *Dest = NextInstVar(EltType);
1253 Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index); 1355 Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index);
1254 break; 1356 break;
1255 } 1357 }
1358 case naclbitc::FUNC_CODE_INST_CMP2: {
1359 // CMP2: [opval, opval, pred]
1360 if (!isValidRecordSize(3, "function block compare"))
1361 return;
1362 Ice::Operand *Op1 = getRelativeOperand(Values[0]);
1363 Ice::Operand *Op2 = getRelativeOperand(Values[1]);
1364 Ice::Type Op1Type = Op1->getType();
1365 Ice::Type Op2Type = Op2->getType();
1366 if (Op1Type != Op2Type) {
1367 std::string Buffer;
1368 raw_string_ostream StrBuf(Buffer);
1369 StrBuf << "Compare argument types differ: " << Op1Type
1370 << " and " << Op2Type;
1371 Error(StrBuf.str());
1372 // TODO(kschimpf) Remove error recovery once implementation complete.
1373 Op2 = Op1;
1374 }
1375 Ice::Type DestType = getCompareResultType(Op1Type);
1376 if (DestType == Ice::IceType_void) {
1377 std::string Buffer;
1378 raw_string_ostream StrBuf(Buffer);
1379 StrBuf << "Compare not defined for type " << Op1Type;
1380 Error(StrBuf.str());
1381 return;
1382 }
1383 Ice::Variable *Dest = NextInstVar(DestType);
1384 if (isIntegerType(Op1Type)) {
1385 Ice::InstIcmp::ICond Cond;
1386 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
1387 std::string Buffer;
1388 raw_string_ostream StrBuf(Buffer);
1389 StrBuf << "Compare record contains unknown integer predicate index: "
1390 << Values[2];
1391 Error(StrBuf.str());
1392 // TODO(kschimpf) Remove error recovery once implementation complete.
1393 Cond = Ice::InstIcmp::Eq;
1394 }
1395 Inst = Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2);
1396 } else if (isFloatingType(Op1Type)){
1397 Ice::InstFcmp::FCond Cond;
1398 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
1399 std::string Buffer;
1400 raw_string_ostream StrBuf(Buffer);
1401 StrBuf << "Compare record contains unknown float predicate index: "
1402 << Values[2];
1403 Error(StrBuf.str());
1404 // TODO(kschimpf) Remove error recovery once implementation complete.
1405 Cond = Ice::InstFcmp::False;
1406 }
1407 Inst = Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2);
1408 } else {
1409 // Not sure this can happen, but be safe.
1410 std::string Buffer;
1411 raw_string_ostream StrBuf(Buffer);
1412 StrBuf << "Compare on type not understood: " << Op1Type;
1413 Error(StrBuf.str());
1414 return;
1415 }
1416 break;
1417 }
1256 case naclbitc::FUNC_CODE_INST_RET: { 1418 case naclbitc::FUNC_CODE_INST_RET: {
1257 // RET: [opval?] 1419 // RET: [opval?]
1258 InstIsTerminating = true; 1420 InstIsTerminating = true;
1259 if (!isValidRecordSizeInRange(0, 1, "function block ret")) 1421 if (!isValidRecordSizeInRange(0, 1, "function block ret"))
1260 return; 1422 return;
1261 if (Values.size() == 0) { 1423 if (Values.size() == 0) {
1262 Inst = Ice::InstRet::create(Func); 1424 Inst = Ice::InstRet::create(Func);
1263 } else { 1425 } else {
1264 Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0])); 1426 Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0]));
1265 } 1427 }
(...skipping 166 matching lines...)
1432 if (TopLevelBlocks != 1) { 1594 if (TopLevelBlocks != 1) {
1433 errs() << IRFilename 1595 errs() << IRFilename
1434 << ": Contains more than one module. Found: " << TopLevelBlocks 1596 << ": Contains more than one module. Found: " << TopLevelBlocks
1435 << "\n"; 1597 << "\n";
1436 ErrorStatus = true; 1598 ErrorStatus = true;
1437 } 1599 }
1438 return; 1600 return;
1439 } 1601 }
1440 1602
1441 } // end of namespace Ice 1603 } // end of namespace Ice
OLDNEW
« src/IceTypes.def ('K') | « src/IceTypes.def ('k') | tests_lit/reader_tests/compare.ll » ('j') | no next file with comments »

Powered by Google App Engine