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 |