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...) 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...) 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 109 matching lines...) Loading... |
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...) Loading... |
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...) Loading... |
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 |
OLD | NEW |