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