| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// | 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// |
| 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 /// \file | 10 /// \file |
| (...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 if (Count2) { | 1051 if (Count2) { |
| 1052 _shl(T, Ctx->getConstantInt(Ty, Count2)); | 1052 _shl(T, Ctx->getConstantInt(Ty, Count2)); |
| 1053 } | 1053 } |
| 1054 if (Src1IsNegative) | 1054 if (Src1IsNegative) |
| 1055 _neg(T); | 1055 _neg(T); |
| 1056 _mov(Dest, T); | 1056 _mov(Dest, T); |
| 1057 return true; | 1057 return true; |
| 1058 } | 1058 } |
| 1059 | 1059 |
| 1060 template <class Machine> | 1060 template <class Machine> |
| 1061 void TargetX86Base<Machine>::lowerShift64(InstArithmetic::OpKind Op, |
| 1062 Operand *Src0Lo, Operand *Src0Hi, |
| 1063 Operand *Src1Lo, Variable *DestLo, |
| 1064 Variable *DestHi) { |
| 1065 // TODO: Refactor the similarities between Shl, Lshr, and Ashr. |
| 1066 Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr; |
| 1067 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
| 1068 Constant *SignExtend = Ctx->getConstantInt32(0x1f); |
| 1069 if (auto *ConstantShiftAmount = llvm::dyn_cast<ConstantInteger32>(Src1Lo)) { |
| 1070 uint32_t ShiftAmount = ConstantShiftAmount->getValue(); |
| 1071 if (ShiftAmount > 32) { |
| 1072 Constant *ReducedShift = Ctx->getConstantInt32(ShiftAmount - 32); |
| 1073 switch (Op) { |
| 1074 default: |
| 1075 assert(0 && "non-shift op"); |
| 1076 break; |
| 1077 case InstArithmetic::Shl: { |
| 1078 // a=b<<c ==> |
| 1079 // t2 = b.lo |
| 1080 // t2 = shl t2, ShiftAmount-32 |
| 1081 // t3 = t2 |
| 1082 // t2 = 0 |
| 1083 _mov(T_2, Src0Lo); |
| 1084 _shl(T_2, ReducedShift); |
| 1085 _mov(DestHi, T_2); |
| 1086 _mov(DestLo, Zero); |
| 1087 } break; |
| 1088 case InstArithmetic::Lshr: { |
| 1089 // a=b>>c (unsigned) ==> |
| 1090 // t2 = b.hi |
| 1091 // t2 = shr t2, ShiftAmount-32 |
| 1092 // a.lo = t2 |
| 1093 // a.hi = 0 |
| 1094 _mov(T_2, Src0Hi); |
| 1095 _shr(T_2, ReducedShift); |
| 1096 _mov(DestLo, T_2); |
| 1097 _mov(DestHi, Zero); |
| 1098 } break; |
| 1099 case InstArithmetic::Ashr: { |
| 1100 // a=b>>c (signed) ==> |
| 1101 // t3 = b.hi |
| 1102 // t3 = sar t3, 0x1f |
| 1103 // t2 = b.hi |
| 1104 // t2 = shrd t2, t3, ShiftAmount-32 |
| 1105 // a.lo = t2 |
| 1106 // a.hi = t3 |
| 1107 _mov(T_3, Src0Hi); |
| 1108 _sar(T_3, SignExtend); |
| 1109 _mov(T_2, Src0Hi); |
| 1110 _shrd(T_2, T_3, ReducedShift); |
| 1111 _mov(DestLo, T_2); |
| 1112 _mov(DestHi, T_3); |
| 1113 } break; |
| 1114 } |
| 1115 } else if (ShiftAmount == 32) { |
| 1116 switch (Op) { |
| 1117 default: |
| 1118 assert(0 && "non-shift op"); |
| 1119 break; |
| 1120 case InstArithmetic::Shl: { |
| 1121 // a=b<<c ==> |
| 1122 // t2 = b.lo |
| 1123 // a.hi = t2 |
| 1124 // a.lo = 0 |
| 1125 _mov(T_2, Src0Lo); |
| 1126 _mov(DestHi, T_2); |
| 1127 _mov(DestLo, Zero); |
| 1128 } break; |
| 1129 case InstArithmetic::Lshr: { |
| 1130 // a=b>>c (unsigned) ==> |
| 1131 // t2 = b.hi |
| 1132 // a.lo = t2 |
| 1133 // a.hi = 0 |
| 1134 _mov(T_2, Src0Hi); |
| 1135 _mov(DestLo, T_2); |
| 1136 _mov(DestHi, Zero); |
| 1137 } break; |
| 1138 case InstArithmetic::Ashr: { |
| 1139 // a=b>>c (signed) ==> |
| 1140 // t2 = b.hi |
| 1141 // a.lo = t2 |
| 1142 // t3 = b.hi |
| 1143 // t3 = sar t3, 0x1f |
| 1144 // a.hi = t3 |
| 1145 _mov(T_2, Src0Hi); |
| 1146 _mov(DestLo, T_2); |
| 1147 _mov(T_3, Src0Hi); |
| 1148 _sar(T_3, SignExtend); |
| 1149 _mov(DestHi, T_3); |
| 1150 } break; |
| 1151 } |
| 1152 } else { |
| 1153 // COMMON PREFIX OF: a=b SHIFT_OP c ==> |
| 1154 // t2 = b.lo |
| 1155 // t3 = b.hi |
| 1156 _mov(T_2, Src0Lo); |
| 1157 _mov(T_3, Src0Hi); |
| 1158 switch (Op) { |
| 1159 default: |
| 1160 assert(0 && "non-shift op"); |
| 1161 break; |
| 1162 case InstArithmetic::Shl: { |
| 1163 // a=b<<c ==> |
| 1164 // t3 = shld t3, t2, ShiftAmount |
| 1165 // t2 = shl t2, ShiftAmount |
| 1166 _shld(T_3, T_2, ConstantShiftAmount); |
| 1167 _shl(T_2, ConstantShiftAmount); |
| 1168 } break; |
| 1169 case InstArithmetic::Lshr: { |
| 1170 // a=b>>c (unsigned) ==> |
| 1171 // t2 = shrd t2, t3, ShiftAmount |
| 1172 // t3 = shr t3, ShiftAmount |
| 1173 _shrd(T_2, T_3, ConstantShiftAmount); |
| 1174 _shr(T_3, ConstantShiftAmount); |
| 1175 } break; |
| 1176 case InstArithmetic::Ashr: { |
| 1177 // a=b>>c (signed) ==> |
| 1178 // t2 = shrd t2, t3, ShiftAmount |
| 1179 // t3 = sar t3, ShiftAmount |
| 1180 _shrd(T_2, T_3, ConstantShiftAmount); |
| 1181 _sar(T_3, ConstantShiftAmount); |
| 1182 } break; |
| 1183 } |
| 1184 // COMMON SUFFIX OF: a=b SHIFT_OP c ==> |
| 1185 // a.lo = t2 |
| 1186 // a.hi = t3 |
| 1187 _mov(DestLo, T_2); |
| 1188 _mov(DestHi, T_3); |
| 1189 } |
| 1190 } else { |
| 1191 // NON-CONSTANT CASES. |
| 1192 Constant *BitTest = Ctx->getConstantInt32(0x20); |
| 1193 typename Traits::Insts::Label *Label = |
| 1194 Traits::Insts::Label::create(Func, this); |
| 1195 // COMMON PREFIX OF: a=b SHIFT_OP c ==> |
| 1196 // t1:ecx = c.lo & 0xff |
| 1197 // t2 = b.lo |
| 1198 // t3 = b.hi |
| 1199 _mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx); |
| 1200 _mov(T_2, Src0Lo); |
| 1201 _mov(T_3, Src0Hi); |
| 1202 switch (Op) { |
| 1203 default: |
| 1204 assert(0 && "non-shift op"); |
| 1205 break; |
| 1206 case InstArithmetic::Shl: { |
| 1207 // a=b<<c ==> |
| 1208 // t3 = shld t3, t2, t1 |
| 1209 // t2 = shl t2, t1 |
| 1210 // test t1, 0x20 |
| 1211 // je L1 |
| 1212 // use(t3) |
| 1213 // t3 = t2 |
| 1214 // t2 = 0 |
| 1215 _shld(T_3, T_2, T_1); |
| 1216 _shl(T_2, T_1); |
| 1217 _test(T_1, BitTest); |
| 1218 _br(Traits::Cond::Br_e, Label); |
| 1219 // T_2 and T_3 are being assigned again because of the intra-block |
| 1220 // control flow, so we need the _mov_nonkillable variant to avoid |
| 1221 // liveness problems. |
| 1222 _mov_nonkillable(T_3, T_2); |
| 1223 _mov_nonkillable(T_2, Zero); |
| 1224 } break; |
| 1225 case InstArithmetic::Lshr: { |
| 1226 // a=b>>c (unsigned) ==> |
| 1227 // t2 = shrd t2, t3, t1 |
| 1228 // t3 = shr t3, t1 |
| 1229 // test t1, 0x20 |
| 1230 // je L1 |
| 1231 // use(t2) |
| 1232 // t2 = t3 |
| 1233 // t3 = 0 |
| 1234 _shrd(T_2, T_3, T_1); |
| 1235 _shr(T_3, T_1); |
| 1236 _test(T_1, BitTest); |
| 1237 _br(Traits::Cond::Br_e, Label); |
| 1238 // T_2 and T_3 are being assigned again because of the intra-block |
| 1239 // control flow, so we need the _mov_nonkillable variant to avoid |
| 1240 // liveness problems. |
| 1241 _mov_nonkillable(T_2, T_3); |
| 1242 _mov_nonkillable(T_3, Zero); |
| 1243 } break; |
| 1244 case InstArithmetic::Ashr: { |
| 1245 // a=b>>c (signed) ==> |
| 1246 // t2 = shrd t2, t3, t1 |
| 1247 // t3 = sar t3, t1 |
| 1248 // test t1, 0x20 |
| 1249 // je L1 |
| 1250 // use(t2) |
| 1251 // t2 = t3 |
| 1252 // t3 = sar t3, 0x1f |
| 1253 Constant *SignExtend = Ctx->getConstantInt32(0x1f); |
| 1254 _shrd(T_2, T_3, T_1); |
| 1255 _sar(T_3, T_1); |
| 1256 _test(T_1, BitTest); |
| 1257 _br(Traits::Cond::Br_e, Label); |
| 1258 // T_2 and T_3 are being assigned again because of the intra-block |
| 1259 // control flow, so T_2 needs the _mov_nonkillable variant to avoid |
| 1260 // liveness problems. T_3 doesn't need special treatment because it is |
| 1261 // reassigned via _sar instead of _mov. |
| 1262 _mov_nonkillable(T_2, T_3); |
| 1263 _sar(T_3, SignExtend); |
| 1264 } break; |
| 1265 } |
| 1266 // COMMON SUFFIX OF: a=b SHIFT_OP c ==> |
| 1267 // L1: |
| 1268 // a.lo = t2 |
| 1269 // a.hi = t3 |
| 1270 Context.insert(Label); |
| 1271 _mov(DestLo, T_2); |
| 1272 _mov(DestHi, T_3); |
| 1273 } |
| 1274 } |
| 1275 |
| 1276 template <class Machine> |
| 1061 void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) { | 1277 void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) { |
| 1062 Variable *Dest = Inst->getDest(); | 1278 Variable *Dest = Inst->getDest(); |
| 1063 Operand *Src0 = legalize(Inst->getSrc(0)); | 1279 Operand *Src0 = legalize(Inst->getSrc(0)); |
| 1064 Operand *Src1 = legalize(Inst->getSrc(1)); | 1280 Operand *Src1 = legalize(Inst->getSrc(1)); |
| 1065 if (Inst->isCommutative()) { | 1281 if (Inst->isCommutative()) { |
| 1066 if (!llvm::isa<Variable>(Src0) && llvm::isa<Variable>(Src1)) | 1282 if (!llvm::isa<Variable>(Src0) && llvm::isa<Variable>(Src1)) |
| 1067 std::swap(Src0, Src1); | 1283 std::swap(Src0, Src1); |
| 1068 if (llvm::isa<Constant>(Src0) && !llvm::isa<Constant>(Src1)) | 1284 if (llvm::isa<Constant>(Src0) && !llvm::isa<Constant>(Src1)) |
| 1069 std::swap(Src0, Src1); | 1285 std::swap(Src0, Src1); |
| 1070 } | 1286 } |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1186 _mov(T_3, Src0Lo, Traits::RegisterSet::Reg_eax); | 1402 _mov(T_3, Src0Lo, Traits::RegisterSet::Reg_eax); |
| 1187 _mul(T_4Lo, T_3, Src1Lo); | 1403 _mul(T_4Lo, T_3, Src1Lo); |
| 1188 // The mul instruction produces two dest variables, edx:eax. We create a | 1404 // The mul instruction produces two dest variables, edx:eax. We create a |
| 1189 // fake definition of edx to account for this. | 1405 // fake definition of edx to account for this. |
| 1190 Context.insert(InstFakeDef::create(Func, T_4Hi, T_4Lo)); | 1406 Context.insert(InstFakeDef::create(Func, T_4Hi, T_4Lo)); |
| 1191 _mov(DestLo, T_4Lo); | 1407 _mov(DestLo, T_4Lo); |
| 1192 _add(T_4Hi, T_1); | 1408 _add(T_4Hi, T_1); |
| 1193 _add(T_4Hi, T_2); | 1409 _add(T_4Hi, T_2); |
| 1194 _mov(DestHi, T_4Hi); | 1410 _mov(DestHi, T_4Hi); |
| 1195 } break; | 1411 } break; |
| 1196 case InstArithmetic::Shl: { | 1412 case InstArithmetic::Shl: |
| 1197 // TODO: Refactor the similarities between Shl, Lshr, and Ashr. | 1413 case InstArithmetic::Lshr: |
| 1198 Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr; | 1414 case InstArithmetic::Ashr: |
| 1199 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 1415 lowerShift64(Inst->getOp(), Src0Lo, Src0Hi, Src1Lo, DestLo, DestHi); |
| 1200 if (const auto *ConstantShiftAmount = | 1416 break; |
| 1201 llvm::dyn_cast<ConstantInteger32>(Src1Lo)) { | |
| 1202 uint32_t ShiftAmount = ConstantShiftAmount->getValue(); | |
| 1203 if (ShiftAmount > 32) { | |
| 1204 // a=b<<c ==> | |
| 1205 // t2 = b.lo | |
| 1206 // t2 = shl t2, ShiftAmount-32 | |
| 1207 // t3 = t2 | |
| 1208 // t2 = 0 | |
| 1209 _mov(T_2, Src0Lo); | |
| 1210 _shl(T_2, Ctx->getConstantInt32(ShiftAmount - 32)); | |
| 1211 _mov(DestHi, T_2); | |
| 1212 _mov(DestLo, Zero); | |
| 1213 } else if (ShiftAmount == 32) { | |
| 1214 // a=b<<c ==> | |
| 1215 // t2 = b.lo | |
| 1216 // a.hi = t2 | |
| 1217 // a.lo = 0 | |
| 1218 _mov(T_2, Src0Lo); | |
| 1219 _mov(DestHi, T_2); | |
| 1220 _mov(DestLo, Zero); | |
| 1221 } else { | |
| 1222 // a=b<<c ==> | |
| 1223 // t2 = b.lo | |
| 1224 // t3 = b.hi | |
| 1225 // t3 = shld t3, t2, ShiftAmount | |
| 1226 // t2 = shl t2, ShiftAmount | |
| 1227 // a.lo = t2 | |
| 1228 // a.hi = t3 | |
| 1229 _mov(T_2, Src0Lo); | |
| 1230 _mov(T_3, Src0Hi); | |
| 1231 _shld(T_3, T_2, Ctx->getConstantInt32(ShiftAmount)); | |
| 1232 _shl(T_2, Ctx->getConstantInt32(ShiftAmount)); | |
| 1233 // Move T_2 first to reduce register pressure. | |
| 1234 _mov(DestLo, T_2); | |
| 1235 _mov(DestHi, T_3); | |
| 1236 } | |
| 1237 } else { | |
| 1238 // a=b<<c ==> | |
| 1239 // t1:ecx = c.lo & 0xff | |
| 1240 // t2 = b.lo | |
| 1241 // t3 = b.hi | |
| 1242 // t3 = shld t3, t2, t1 | |
| 1243 // t2 = shl t2, t1 | |
| 1244 // test t1, 0x20 | |
| 1245 // je L1 | |
| 1246 // use(t3) | |
| 1247 // t3 = t2 | |
| 1248 // t2 = 0 | |
| 1249 // L1: | |
| 1250 // a.lo = t2 | |
| 1251 // a.hi = t3 | |
| 1252 Constant *BitTest = Ctx->getConstantInt32(0x20); | |
| 1253 typename Traits::Insts::Label *Label = | |
| 1254 Traits::Insts::Label::create(Func, this); | |
| 1255 _mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx); | |
| 1256 _mov(T_2, Src0Lo); | |
| 1257 _mov(T_3, Src0Hi); | |
| 1258 _shld(T_3, T_2, T_1); | |
| 1259 _shl(T_2, T_1); | |
| 1260 _test(T_1, BitTest); | |
| 1261 _br(Traits::Cond::Br_e, Label); | |
| 1262 // T_2 and T_3 are being assigned again because of the intra-block | |
| 1263 // control flow, so we need the _mov_nonkillable variant to avoid | |
| 1264 // liveness problems. | |
| 1265 _mov_nonkillable(T_3, T_2); | |
| 1266 _mov_nonkillable(T_2, Zero); | |
| 1267 Context.insert(Label); | |
| 1268 _mov(DestLo, T_2); | |
| 1269 _mov(DestHi, T_3); | |
| 1270 } | |
| 1271 } break; | |
| 1272 case InstArithmetic::Lshr: { | |
| 1273 Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr; | |
| 1274 Constant *Zero = Ctx->getConstantZero(IceType_i32); | |
| 1275 if (const auto *ConstantShiftAmount = | |
| 1276 llvm::dyn_cast<ConstantInteger32>(Src1Lo)) { | |
| 1277 uint32_t ShiftAmount = ConstantShiftAmount->getValue(); | |
| 1278 if (ShiftAmount > 32) { | |
| 1279 // a=b>>c (unsigned) ==> | |
| 1280 // t3 = b.hi | |
| 1281 // t3 = shr t3, ShiftAmount-32 | |
| 1282 // a.lo = t3 | |
| 1283 // a.hi = 0 | |
| 1284 _mov(T_3, Src0Hi); | |
| 1285 _shr(T_3, Ctx->getConstantInt32(ShiftAmount - 32)); | |
| 1286 _mov(DestLo, T_3); | |
| 1287 _mov(DestHi, Zero); | |
| 1288 } else if (ShiftAmount == 32) { | |
| 1289 // a=b>>c (unsigned) ==> | |
| 1290 // t3 = b.hi | |
| 1291 // a.lo = t3 | |
| 1292 // a.hi = 0 | |
| 1293 _mov(T_3, Src0Hi); | |
| 1294 _mov(DestLo, T_3); | |
| 1295 _mov(DestHi, Zero); | |
| 1296 } else { | |
| 1297 // a=b>>c (unsigned) ==> | |
| 1298 // t2 = b.lo | |
| 1299 // t3 = b.hi | |
| 1300 // t2 = shrd t2, t3, ShiftAmount | |
| 1301 // t3 = shr t3, ShiftAmount | |
| 1302 // a.lo = t2 | |
| 1303 // a.hi = t3 | |
| 1304 _mov(T_2, Src0Lo); | |
| 1305 _mov(T_3, Src0Hi); | |
| 1306 _shrd(T_2, T_3, Ctx->getConstantInt32(ShiftAmount)); | |
| 1307 _shr(T_3, Ctx->getConstantInt32(ShiftAmount)); | |
| 1308 // Move T_3 first to reduce register pressure. | |
| 1309 _mov(DestHi, T_3); | |
| 1310 _mov(DestLo, T_2); | |
| 1311 } | |
| 1312 } else { | |
| 1313 // a=b>>c (unsigned) ==> | |
| 1314 // t1:ecx = c.lo & 0xff | |
| 1315 // t2 = b.lo | |
| 1316 // t3 = b.hi | |
| 1317 // t2 = shrd t2, t3, t1 | |
| 1318 // t3 = shr t3, t1 | |
| 1319 // test t1, 0x20 | |
| 1320 // je L1 | |
| 1321 // use(t2) | |
| 1322 // t2 = t3 | |
| 1323 // t3 = 0 | |
| 1324 // L1: | |
| 1325 // a.lo = t2 | |
| 1326 // a.hi = t3 | |
| 1327 Constant *BitTest = Ctx->getConstantInt32(0x20); | |
| 1328 typename Traits::Insts::Label *Label = | |
| 1329 Traits::Insts::Label::create(Func, this); | |
| 1330 _mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx); | |
| 1331 _mov(T_2, Src0Lo); | |
| 1332 _mov(T_3, Src0Hi); | |
| 1333 _shrd(T_2, T_3, T_1); | |
| 1334 _shr(T_3, T_1); | |
| 1335 _test(T_1, BitTest); | |
| 1336 _br(Traits::Cond::Br_e, Label); | |
| 1337 // T_2 and T_3 are being assigned again because of the intra-block | |
| 1338 // control flow, so we need the _mov_nonkillable variant to avoid | |
| 1339 // liveness problems. | |
| 1340 _mov_nonkillable(T_2, T_3); | |
| 1341 _mov_nonkillable(T_3, Zero); | |
| 1342 Context.insert(Label); | |
| 1343 _mov(DestLo, T_2); | |
| 1344 _mov(DestHi, T_3); | |
| 1345 } | |
| 1346 } break; | |
| 1347 case InstArithmetic::Ashr: { | |
| 1348 Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr; | |
| 1349 if (const auto *ConstantShiftAmount = | |
| 1350 llvm::dyn_cast<ConstantInteger32>(Src1Lo)) { | |
| 1351 uint32_t ShiftAmount = ConstantShiftAmount->getValue(); | |
| 1352 if (ShiftAmount > 32) { | |
| 1353 // a=b>>c (signed) ==> | |
| 1354 // t2 = b.hi | |
| 1355 // t3 = b.hi | |
| 1356 // t3 = sar t3, 0x1f | |
| 1357 // t2 = shrd t2, t3, ShiftAmount-32 | |
| 1358 // a.lo = t2 | |
| 1359 // a.hi = t3 | |
| 1360 _mov(T_2, Src0Hi); | |
| 1361 _mov(T_3, Src0Hi); | |
| 1362 _sar(T_3, Ctx->getConstantInt32(0x1f)); | |
| 1363 _shrd(T_2, T_3, Ctx->getConstantInt32(ShiftAmount - 32)); | |
| 1364 _mov(DestLo, T_2); | |
| 1365 _mov(DestHi, T_3); | |
| 1366 } else if (ShiftAmount == 32) { | |
| 1367 // a=b>>c (signed) ==> | |
| 1368 // t2 = b.hi | |
| 1369 // a.lo = t2 | |
| 1370 // t3 = b.hi | |
| 1371 // t3 = sar t3, 0x1f | |
| 1372 // a.hi = t3 | |
| 1373 _mov(T_2, Src0Hi); | |
| 1374 _mov(DestLo, T_2); | |
| 1375 _mov(T_3, Src0Hi); | |
| 1376 _sar(T_3, Ctx->getConstantInt32(0x1f)); | |
| 1377 _mov(DestHi, T_3); | |
| 1378 } else { | |
| 1379 // a=b>>c (signed) ==> | |
| 1380 // t2 = b.lo | |
| 1381 // t3 = b.hi | |
| 1382 // t2 = shrd t2, t3, ShiftAmount | |
| 1383 // t3 = sar t3, ShiftAmount | |
| 1384 // a.lo = t2 | |
| 1385 // a.hi = t3 | |
| 1386 _mov(T_2, Src0Lo); | |
| 1387 _mov(T_3, Src0Hi); | |
| 1388 _shrd(T_2, T_3, Ctx->getConstantInt32(ShiftAmount)); | |
| 1389 _sar(T_3, Ctx->getConstantInt32(ShiftAmount)); | |
| 1390 _mov(DestLo, T_2); | |
| 1391 _mov(DestHi, T_3); | |
| 1392 } | |
| 1393 } else { | |
| 1394 // a=b>>c (signed) ==> | |
| 1395 // t1:ecx = c.lo & 0xff | |
| 1396 // t2 = b.lo | |
| 1397 // t3 = b.hi | |
| 1398 // t2 = shrd t2, t3, t1 | |
| 1399 // t3 = sar t3, t1 | |
| 1400 // test t1, 0x20 | |
| 1401 // je L1 | |
| 1402 // use(t2) | |
| 1403 // t2 = t3 | |
| 1404 // t3 = sar t3, 0x1f | |
| 1405 // L1: | |
| 1406 // a.lo = t2 | |
| 1407 // a.hi = t3 | |
| 1408 Constant *BitTest = Ctx->getConstantInt32(0x20); | |
| 1409 Constant *SignExtend = Ctx->getConstantInt32(0x1f); | |
| 1410 typename Traits::Insts::Label *Label = | |
| 1411 Traits::Insts::Label::create(Func, this); | |
| 1412 _mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx); | |
| 1413 _mov(T_2, Src0Lo); | |
| 1414 _mov(T_3, Src0Hi); | |
| 1415 _shrd(T_2, T_3, T_1); | |
| 1416 _sar(T_3, T_1); | |
| 1417 _test(T_1, BitTest); | |
| 1418 _br(Traits::Cond::Br_e, Label); | |
| 1419 // T_2 and T_3 are being assigned again because of the intra-block | |
| 1420 // control flow, so T_2 needs the _mov_nonkillable variant to avoid | |
| 1421 // liveness problems. T_3 doesn't need special treatment because it is | |
| 1422 // reassigned via _sar instead of _mov. | |
| 1423 _mov_nonkillable(T_2, T_3); | |
| 1424 _sar(T_3, SignExtend); | |
| 1425 Context.insert(Label); | |
| 1426 _mov(DestLo, T_2); | |
| 1427 _mov(DestHi, T_3); | |
| 1428 } | |
| 1429 } break; | |
| 1430 case InstArithmetic::Fadd: | 1417 case InstArithmetic::Fadd: |
| 1431 case InstArithmetic::Fsub: | 1418 case InstArithmetic::Fsub: |
| 1432 case InstArithmetic::Fmul: | 1419 case InstArithmetic::Fmul: |
| 1433 case InstArithmetic::Fdiv: | 1420 case InstArithmetic::Fdiv: |
| 1434 case InstArithmetic::Frem: | 1421 case InstArithmetic::Frem: |
| 1435 llvm_unreachable("FP instruction with i64 type"); | 1422 llvm_unreachable("FP instruction with i64 type"); |
| 1436 break; | 1423 break; |
| 1437 case InstArithmetic::Udiv: | 1424 case InstArithmetic::Udiv: |
| 1438 case InstArithmetic::Sdiv: | 1425 case InstArithmetic::Sdiv: |
| 1439 case InstArithmetic::Urem: | 1426 case InstArithmetic::Urem: |
| (...skipping 4044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5484 } | 5471 } |
| 5485 // the offset is not eligible for blinding or pooling, return the original | 5472 // the offset is not eligible for blinding or pooling, return the original |
| 5486 // mem operand | 5473 // mem operand |
| 5487 return MemOperand; | 5474 return MemOperand; |
| 5488 } | 5475 } |
| 5489 | 5476 |
| 5490 } // end of namespace X86Internal | 5477 } // end of namespace X86Internal |
| 5491 } // end of namespace Ice | 5478 } // end of namespace Ice |
| 5492 | 5479 |
| 5493 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 5480 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
| OLD | NEW |