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, | |
| 1052 Operand *Src0Lo, Operand *Src0Hi, | |
| 1053 Operand *Src1Lo, Variable *DestLo, | |
| 1054 Variable *DestHi) { | |
| 1055 // TODO: Refactor the similarities between Shl, Lshr, and Ashr. | |
| 1056 Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr; | |
| 1057 Constant *Zero = Ctx->getConstantZero(IceType_i32); | |
| 1058 Constant *SignExtend = Ctx->getConstantInt32(0x1f); | |
| 1059 if (auto *ConstantShiftAmount = llvm::dyn_cast<ConstantInteger32>(Src1Lo)) { | |
| 1060 uint32_t ShiftAmount = ConstantShiftAmount->getValue(); | |
| 1061 if (ShiftAmount > 32) { | |
| 1062 Constant *ReducedShift = Ctx->getConstantInt32(ShiftAmount - 32); | |
| 1063 switch (Op) { | |
| 1064 default: | |
| 1065 assert(0 && "non-shift op"); | |
|
Jim Stichnoth
2015/09/23 20:19:47
Here and below, I would add an explicit "break;" a
| |
| 1066 case InstArithmetic::Shl: { | |
| 1067 // a=b<<c ==> | |
| 1068 // t2 = b.lo | |
| 1069 // t2 = shl t2, ShiftAmount-32 | |
| 1070 // t3 = t2 | |
| 1071 // t2 = 0 | |
| 1072 _mov(T_2, Src0Lo); | |
| 1073 _shl(T_2, ReducedShift); | |
| 1074 _mov(DestHi, T_2); | |
| 1075 _mov(DestLo, Zero); | |
| 1076 } break; | |
| 1077 case InstArithmetic::Lshr: { | |
| 1078 // a=b>>c (unsigned) ==> | |
| 1079 // t2 = b.hi | |
| 1080 // t2 = shr t2, ShiftAmount-32 | |
| 1081 // a.lo = t2 | |
| 1082 // a.hi = 0 | |
| 1083 _mov(T_2, Src0Hi); | |
| 1084 _shr(T_2, ReducedShift); | |
| 1085 _mov(DestLo, T_2); | |
| 1086 _mov(DestHi, Zero); | |
| 1087 } break; | |
| 1088 case InstArithmetic::Ashr: { | |
| 1089 // a=b>>c (signed) ==> | |
| 1090 // t3 = b.hi | |
| 1091 // t3 = sar t3, 0x1f | |
| 1092 // t2 = b.hi | |
| 1093 // t2 = shrd t2, t3, ShiftAmount-32 | |
| 1094 // a.lo = t2 | |
| 1095 // a.hi = t3 | |
| 1096 _mov(T_3, Src0Hi); | |
| 1097 _sar(T_3, SignExtend); | |
| 1098 _mov(T_2, Src0Hi); | |
| 1099 _shrd(T_2, T_3, ReducedShift); | |
| 1100 _mov(DestLo, T_2); | |
| 1101 _mov(DestHi, T_3); | |
| 1102 } break; | |
| 1103 } | |
| 1104 } else if (ShiftAmount == 32) { | |
| 1105 switch (Op) { | |
| 1106 default: | |
| 1107 assert(0 && "non-shift op"); | |
| 1108 case InstArithmetic::Shl: { | |
| 1109 // a=b<<c ==> | |
| 1110 // t2 = b.lo | |
| 1111 // a.hi = t2 | |
| 1112 // a.lo = 0 | |
| 1113 _mov(T_2, Src0Lo); | |
| 1114 _mov(DestHi, T_2); | |
| 1115 _mov(DestLo, Zero); | |
| 1116 } break; | |
| 1117 case InstArithmetic::Lshr: { | |
| 1118 // a=b>>c (unsigned) ==> | |
| 1119 // t2 = b.hi | |
| 1120 // a.lo = t2 | |
| 1121 // a.hi = 0 | |
| 1122 _mov(T_2, Src0Hi); | |
| 1123 _mov(DestLo, T_2); | |
| 1124 _mov(DestHi, Zero); | |
| 1125 } break; | |
| 1126 case InstArithmetic::Ashr: { | |
| 1127 // a=b>>c (signed) ==> | |
| 1128 // t2 = b.hi | |
| 1129 // a.lo = t2 | |
| 1130 // t3 = b.hi | |
| 1131 // t3 = sar t3, 0x1f | |
| 1132 // a.hi = t3 | |
| 1133 _mov(T_2, Src0Hi); | |
| 1134 _mov(DestLo, T_2); | |
| 1135 _mov(T_3, Src0Hi); | |
| 1136 _sar(T_3, SignExtend); | |
| 1137 _mov(DestHi, T_3); | |
| 1138 } break; | |
| 1139 } | |
| 1140 } else { | |
| 1141 // COMMON PREFIX OF: a=b SHIFT_OP c ==> | |
| 1142 // t2 = b.lo | |
| 1143 // t3 = b.hi | |
| 1144 _mov(T_2, Src0Lo); | |
| 1145 _mov(T_3, Src0Hi); | |
| 1146 switch (Op) { | |
| 1147 default: | |
| 1148 assert(0 && "non-shift op"); | |
| 1149 case InstArithmetic::Shl: { | |
| 1150 // a=b<<c ==> | |
| 1151 // t3 = shld t3, t2, ShiftAmount | |
| 1152 // t2 = shl t2, ShiftAmount | |
| 1153 _shld(T_3, T_2, ConstantShiftAmount); | |
| 1154 _shl(T_2, ConstantShiftAmount); | |
| 1155 } break; | |
| 1156 case InstArithmetic::Lshr: { | |
| 1157 // a=b>>c (unsigned) ==> | |
| 1158 // t2 = shrd t2, t3, ShiftAmount | |
| 1159 // t3 = shr t3, ShiftAmount | |
| 1160 _shrd(T_2, T_3, ConstantShiftAmount); | |
| 1161 _shr(T_3, ConstantShiftAmount); | |
| 1162 } break; | |
| 1163 case InstArithmetic::Ashr: { | |
| 1164 // a=b>>c (signed) ==> | |
| 1165 // t2 = shrd t2, t3, ShiftAmount | |
| 1166 // t3 = sar t3, ShiftAmount | |
| 1167 _shrd(T_2, T_3, ConstantShiftAmount); | |
| 1168 _sar(T_3, ConstantShiftAmount); | |
| 1169 } break; | |
| 1170 } | |
| 1171 // COMMON SUFFIX OF: a=b SHIFT_OP c ==> | |
| 1172 // a.lo = t2 | |
| 1173 // a.hi = t3 | |
| 1174 _mov(DestLo, T_2); | |
| 1175 _mov(DestHi, T_3); | |
| 1176 } | |
| 1177 } else { | |
| 1178 // NON-CONSTANT CASES. | |
| 1179 Constant *BitTest = Ctx->getConstantInt32(0x20); | |
| 1180 typename Traits::Insts::Label *Label = | |
| 1181 Traits::Insts::Label::create(Func, this); | |
| 1182 // COMMON PREFIX OF: a=b SHIFT_OP c ==> | |
| 1183 // t1:ecx = c.lo & 0xff | |
| 1184 // t2 = b.lo | |
| 1185 // t3 = b.hi | |
| 1186 _mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx); | |
| 1187 _mov(T_2, Src0Lo); | |
| 1188 _mov(T_3, Src0Hi); | |
| 1189 switch (Op) { | |
| 1190 default: | |
| 1191 assert(0 && "non-shift op"); | |
| 1192 case InstArithmetic::Shl: { | |
| 1193 // a=b<<c ==> | |
| 1194 // t3 = shld t3, t2, t1 | |
| 1195 // t2 = shl t2, t1 | |
| 1196 // test t1, 0x20 | |
| 1197 // je L1 | |
| 1198 // use(t3) | |
| 1199 // t3 = t2 | |
| 1200 // t2 = 0 | |
| 1201 _shld(T_3, T_2, T_1); | |
| 1202 _shl(T_2, T_1); | |
| 1203 _test(T_1, BitTest); | |
| 1204 _br(Traits::Cond::Br_e, Label); | |
| 1205 // T_2 and T_3 are being assigned again because of the intra-block | |
| 1206 // control flow, so we need the _mov_nonkillable variant to avoid | |
| 1207 // liveness problems. | |
| 1208 _mov_nonkillable(T_3, T_2); | |
| 1209 _mov_nonkillable(T_2, Zero); | |
| 1210 } break; | |
| 1211 case InstArithmetic::Lshr: { | |
| 1212 // a=b>>c (unsigned) ==> | |
| 1213 // t2 = shrd t2, t3, t1 | |
| 1214 // t3 = shr t3, t1 | |
| 1215 // test t1, 0x20 | |
| 1216 // je L1 | |
| 1217 // use(t2) | |
| 1218 // t2 = t3 | |
| 1219 // t3 = 0 | |
| 1220 _shrd(T_2, T_3, T_1); | |
| 1221 _shr(T_3, T_1); | |
| 1222 _test(T_1, BitTest); | |
| 1223 _br(Traits::Cond::Br_e, Label); | |
| 1224 // T_2 and T_3 are being assigned again because of the intra-block | |
| 1225 // control flow, so we need the _mov_nonkillable variant to avoid | |
| 1226 // liveness problems. | |
| 1227 _mov_nonkillable(T_2, T_3); | |
| 1228 _mov_nonkillable(T_3, Zero); | |
| 1229 } break; | |
| 1230 case InstArithmetic::Ashr: { | |
| 1231 // a=b>>c (signed) ==> | |
| 1232 // t2 = shrd t2, t3, t1 | |
| 1233 // t3 = sar t3, t1 | |
| 1234 // test t1, 0x20 | |
| 1235 // je L1 | |
| 1236 // use(t2) | |
| 1237 // t2 = t3 | |
| 1238 // t3 = sar t3, 0x1f | |
| 1239 Constant *SignExtend = Ctx->getConstantInt32(0x1f); | |
| 1240 _shrd(T_2, T_3, T_1); | |
| 1241 _sar(T_3, T_1); | |
| 1242 _test(T_1, BitTest); | |
| 1243 _br(Traits::Cond::Br_e, Label); | |
| 1244 // T_2 and T_3 are being assigned again because of the intra-block | |
| 1245 // control flow, so T_2 needs the _mov_nonkillable variant to avoid | |
| 1246 // liveness problems. T_3 doesn't need special treatment because it is | |
| 1247 // reassigned via _sar instead of _mov. | |
| 1248 _mov_nonkillable(T_2, T_3); | |
| 1249 _sar(T_3, SignExtend); | |
| 1250 } break; | |
| 1251 } | |
| 1252 // COMMON SUFFIX OF: a=b SHIFT_OP c ==> | |
| 1253 // L1: | |
| 1254 // a.lo = t2 | |
| 1255 // a.hi = t3 | |
| 1256 Context.insert(Label); | |
| 1257 _mov(DestLo, T_2); | |
| 1258 _mov(DestHi, T_3); | |
| 1259 } | |
| 1260 } | |
| 1261 | |
| 1262 template <class Machine> | |
| 1051 void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) { | 1263 void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) { |
| 1052 Variable *Dest = Inst->getDest(); | 1264 Variable *Dest = Inst->getDest(); |
| 1053 Operand *Src0 = legalize(Inst->getSrc(0)); | 1265 Operand *Src0 = legalize(Inst->getSrc(0)); |
| 1054 Operand *Src1 = legalize(Inst->getSrc(1)); | 1266 Operand *Src1 = legalize(Inst->getSrc(1)); |
| 1055 if (Inst->isCommutative()) { | 1267 if (Inst->isCommutative()) { |
| 1056 if (!llvm::isa<Variable>(Src0) && llvm::isa<Variable>(Src1)) | 1268 if (!llvm::isa<Variable>(Src0) && llvm::isa<Variable>(Src1)) |
| 1057 std::swap(Src0, Src1); | 1269 std::swap(Src0, Src1); |
| 1058 if (llvm::isa<Constant>(Src0) && !llvm::isa<Constant>(Src1)) | 1270 if (llvm::isa<Constant>(Src0) && !llvm::isa<Constant>(Src1)) |
| 1059 std::swap(Src0, Src1); | 1271 std::swap(Src0, Src1); |
| 1060 } | 1272 } |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1176 _mov(T_3, Src0Lo, Traits::RegisterSet::Reg_eax); | 1388 _mov(T_3, Src0Lo, Traits::RegisterSet::Reg_eax); |
| 1177 _mul(T_4Lo, T_3, Src1Lo); | 1389 _mul(T_4Lo, T_3, Src1Lo); |
| 1178 // The mul instruction produces two dest variables, edx:eax. We create a | 1390 // The mul instruction produces two dest variables, edx:eax. We create a |
| 1179 // fake definition of edx to account for this. | 1391 // fake definition of edx to account for this. |
| 1180 Context.insert(InstFakeDef::create(Func, T_4Hi, T_4Lo)); | 1392 Context.insert(InstFakeDef::create(Func, T_4Hi, T_4Lo)); |
| 1181 _mov(DestLo, T_4Lo); | 1393 _mov(DestLo, T_4Lo); |
| 1182 _add(T_4Hi, T_1); | 1394 _add(T_4Hi, T_1); |
| 1183 _add(T_4Hi, T_2); | 1395 _add(T_4Hi, T_2); |
| 1184 _mov(DestHi, T_4Hi); | 1396 _mov(DestHi, T_4Hi); |
| 1185 } break; | 1397 } break; |
| 1186 case InstArithmetic::Shl: { | 1398 case InstArithmetic::Shl: |
| 1187 // TODO: Refactor the similarities between Shl, Lshr, and Ashr. | 1399 case InstArithmetic::Lshr: |
| 1188 Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr; | 1400 case InstArithmetic::Ashr: |
| 1189 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 1401 lowerShift64(Inst->getOp(), Src0Lo, Src0Hi, Src1Lo, DestLo, DestHi); |
| 1190 if (const auto *ConstantShiftAmount = | 1402 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: | 1403 case InstArithmetic::Fadd: |
| 1421 case InstArithmetic::Fsub: | 1404 case InstArithmetic::Fsub: |
| 1422 case InstArithmetic::Fmul: | 1405 case InstArithmetic::Fmul: |
| 1423 case InstArithmetic::Fdiv: | 1406 case InstArithmetic::Fdiv: |
| 1424 case InstArithmetic::Frem: | 1407 case InstArithmetic::Frem: |
| 1425 llvm_unreachable("FP instruction with i64 type"); | 1408 llvm_unreachable("FP instruction with i64 type"); |
| 1426 break; | 1409 break; |
| 1427 case InstArithmetic::Udiv: | 1410 case InstArithmetic::Udiv: |
| 1428 case InstArithmetic::Sdiv: | 1411 case InstArithmetic::Sdiv: |
| 1429 case InstArithmetic::Urem: | 1412 case InstArithmetic::Urem: |
| (...skipping 4044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5474 } | 5457 } |
| 5475 // the offset is not eligible for blinding or pooling, return the original | 5458 // the offset is not eligible for blinding or pooling, return the original |
| 5476 // mem operand | 5459 // mem operand |
| 5477 return MemOperand; | 5460 return MemOperand; |
| 5478 } | 5461 } |
| 5479 | 5462 |
| 5480 } // end of namespace X86Internal | 5463 } // end of namespace X86Internal |
| 5481 } // end of namespace Ice | 5464 } // end of namespace Ice |
| 5482 | 5465 |
| 5483 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 5466 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
| OLD | NEW |