| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |