Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1210073017: Subzero: Avoid unused insts for ARM Om1 lowering for arithmetic (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: change break to return where useful to make it obvious Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/64bit.pnacl.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===//
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 TargetLoweringARM32 class, which consists almost 10 // This file implements the TargetLoweringARM32 class, which consists almost
(...skipping 1085 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 // TODO(jvoung): Should be able to flip Src0 and Src1 if it is easier 1096 // TODO(jvoung): Should be able to flip Src0 and Src1 if it is easier
1097 // to legalize Src0 to flex or Src1 to flex and there is a reversible 1097 // to legalize Src0 to flex or Src1 to flex and there is a reversible
1098 // instruction. E.g., reverse subtract with immediate, register vs 1098 // instruction. E.g., reverse subtract with immediate, register vs
1099 // register, immediate. 1099 // register, immediate.
1100 // Or it may be the case that the operands aren't swapped, but the 1100 // Or it may be the case that the operands aren't swapped, but the
1101 // bits can be flipped and a different operation applied. 1101 // bits can be flipped and a different operation applied.
1102 // E.g., use BIC (bit clear) instead of AND for some masks. 1102 // E.g., use BIC (bit clear) instead of AND for some masks.
1103 Operand *Src0 = Inst->getSrc(0); 1103 Operand *Src0 = Inst->getSrc(0);
1104 Operand *Src1 = Inst->getSrc(1); 1104 Operand *Src1 = Inst->getSrc(1);
1105 if (Dest->getType() == IceType_i64) { 1105 if (Dest->getType() == IceType_i64) {
1106 // These helper-call-involved instructions are lowered in this
1107 // separate switch. This is because we would otherwise assume that
1108 // we need to legalize Src0 to Src0RLo and Src0Hi. However, those go unused
1109 // with helper calls, and such unused/redundant instructions will fail
1110 // liveness analysis under -Om1 setting.
Jim Stichnoth 2015/07/07 11:50:29 Hmm, I wonder if that Om1 validation check should
1111 switch (Inst->getOp()) {
1112 default:
1113 break;
1114 case InstArithmetic::Udiv:
1115 case InstArithmetic::Sdiv:
1116 case InstArithmetic::Urem:
1117 case InstArithmetic::Srem: {
1118 // Check for divide by 0 (ARM normally doesn't trap, but we want it
1119 // to trap for NaCl). Src1Lo and Src1Hi may have already been legalized
1120 // to a register, which will hide a constant source operand.
1121 // Instead, check the not-yet-legalized Src1 to optimize-out a divide
1122 // by 0 check.
1123 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src1)) {
1124 if (C64->getValue() == 0) {
1125 _trap();
1126 return;
1127 }
1128 } else {
1129 Operand *Src1Lo = legalize(loOperand(Src1), Legal_Reg | Legal_Flex);
1130 Operand *Src1Hi = legalize(hiOperand(Src1), Legal_Reg | Legal_Flex);
1131 div0Check(IceType_i64, Src1Lo, Src1Hi);
1132 }
1133 // Technically, ARM has their own aeabi routines, but we can use the
1134 // non-aeabi routine as well. LLVM uses __aeabi_ldivmod for div,
1135 // but uses the more standard __moddi3 for rem.
1136 const char *HelperName = "";
1137 switch (Inst->getOp()) {
1138 default:
1139 llvm_unreachable("Should have only matched div ops.");
1140 break;
1141 case InstArithmetic::Udiv:
1142 HelperName = H_udiv_i64;
1143 break;
1144 case InstArithmetic::Sdiv:
1145 HelperName = H_sdiv_i64;
1146 break;
1147 case InstArithmetic::Urem:
1148 HelperName = H_urem_i64;
1149 break;
1150 case InstArithmetic::Srem:
1151 HelperName = H_srem_i64;
1152 break;
1153 }
1154 constexpr SizeT MaxSrcs = 2;
1155 InstCall *Call = makeHelperCall(HelperName, Dest, MaxSrcs);
1156 Call->addArg(Src0);
1157 Call->addArg(Src1);
1158 lowerCall(Call);
1159 return;
1160 }
1161 }
1106 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1162 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1107 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1163 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1108 Variable *Src0RLo = legalizeToVar(loOperand(Src0)); 1164 Variable *Src0RLo = legalizeToVar(loOperand(Src0));
1109 Variable *Src0RHi = legalizeToVar(hiOperand(Src0)); 1165 Variable *Src0RHi = legalizeToVar(hiOperand(Src0));
1110 Operand *Src1Lo = legalize(loOperand(Src1), Legal_Reg | Legal_Flex); 1166 Operand *Src1Lo = loOperand(Src1);
1111 Operand *Src1Hi = legalize(hiOperand(Src1), Legal_Reg | Legal_Flex); 1167 Operand *Src1Hi = hiOperand(Src1);
1112 Variable *T_Lo = makeReg(DestLo->getType()); 1168 Variable *T_Lo = makeReg(DestLo->getType());
1113 Variable *T_Hi = makeReg(DestHi->getType()); 1169 Variable *T_Hi = makeReg(DestHi->getType());
1114 switch (Inst->getOp()) { 1170 switch (Inst->getOp()) {
1115 case InstArithmetic::_num: 1171 case InstArithmetic::_num:
1116 llvm_unreachable("Unknown arithmetic operator"); 1172 llvm_unreachable("Unknown arithmetic operator");
1117 break; 1173 return;
1118 case InstArithmetic::Add: 1174 case InstArithmetic::Add:
1175 Src1Lo = legalize(Src1Lo, Legal_Reg | Legal_Flex);
1176 Src1Hi = legalize(Src1Hi, Legal_Reg | Legal_Flex);
1119 _adds(T_Lo, Src0RLo, Src1Lo); 1177 _adds(T_Lo, Src0RLo, Src1Lo);
1120 _mov(DestLo, T_Lo); 1178 _mov(DestLo, T_Lo);
1121 _adc(T_Hi, Src0RHi, Src1Hi); 1179 _adc(T_Hi, Src0RHi, Src1Hi);
1122 _mov(DestHi, T_Hi); 1180 _mov(DestHi, T_Hi);
1123 break; 1181 return;
1124 case InstArithmetic::And: 1182 case InstArithmetic::And:
1183 Src1Lo = legalize(Src1Lo, Legal_Reg | Legal_Flex);
1184 Src1Hi = legalize(Src1Hi, Legal_Reg | Legal_Flex);
1125 _and(T_Lo, Src0RLo, Src1Lo); 1185 _and(T_Lo, Src0RLo, Src1Lo);
1126 _mov(DestLo, T_Lo); 1186 _mov(DestLo, T_Lo);
1127 _and(T_Hi, Src0RHi, Src1Hi); 1187 _and(T_Hi, Src0RHi, Src1Hi);
1128 _mov(DestHi, T_Hi); 1188 _mov(DestHi, T_Hi);
1129 break; 1189 return;
1130 case InstArithmetic::Or: 1190 case InstArithmetic::Or:
1191 Src1Lo = legalize(Src1Lo, Legal_Reg | Legal_Flex);
1192 Src1Hi = legalize(Src1Hi, Legal_Reg | Legal_Flex);
1131 _orr(T_Lo, Src0RLo, Src1Lo); 1193 _orr(T_Lo, Src0RLo, Src1Lo);
1132 _mov(DestLo, T_Lo); 1194 _mov(DestLo, T_Lo);
1133 _orr(T_Hi, Src0RHi, Src1Hi); 1195 _orr(T_Hi, Src0RHi, Src1Hi);
1134 _mov(DestHi, T_Hi); 1196 _mov(DestHi, T_Hi);
1135 break; 1197 return;
1136 case InstArithmetic::Xor: 1198 case InstArithmetic::Xor:
1199 Src1Lo = legalize(Src1Lo, Legal_Reg | Legal_Flex);
1200 Src1Hi = legalize(Src1Hi, Legal_Reg | Legal_Flex);
1137 _eor(T_Lo, Src0RLo, Src1Lo); 1201 _eor(T_Lo, Src0RLo, Src1Lo);
1138 _mov(DestLo, T_Lo); 1202 _mov(DestLo, T_Lo);
1139 _eor(T_Hi, Src0RHi, Src1Hi); 1203 _eor(T_Hi, Src0RHi, Src1Hi);
1140 _mov(DestHi, T_Hi); 1204 _mov(DestHi, T_Hi);
1141 break; 1205 return;
1142 case InstArithmetic::Sub: 1206 case InstArithmetic::Sub:
1207 Src1Lo = legalize(Src1Lo, Legal_Reg | Legal_Flex);
1208 Src1Hi = legalize(Src1Hi, Legal_Reg | Legal_Flex);
1143 _subs(T_Lo, Src0RLo, Src1Lo); 1209 _subs(T_Lo, Src0RLo, Src1Lo);
1144 _mov(DestLo, T_Lo); 1210 _mov(DestLo, T_Lo);
1145 _sbc(T_Hi, Src0RHi, Src1Hi); 1211 _sbc(T_Hi, Src0RHi, Src1Hi);
1146 _mov(DestHi, T_Hi); 1212 _mov(DestHi, T_Hi);
1147 break; 1213 return;
1148 case InstArithmetic::Mul: { 1214 case InstArithmetic::Mul: {
1149 // GCC 4.8 does: 1215 // GCC 4.8 does:
1150 // a=b*c ==> 1216 // a=b*c ==>
1151 // t_acc =(mul) (b.lo * c.hi) 1217 // t_acc =(mul) (b.lo * c.hi)
1152 // t_acc =(mla) (c.lo * b.hi) + t_acc 1218 // t_acc =(mla) (c.lo * b.hi) + t_acc
1153 // t.hi,t.lo =(umull) b.lo * c.lo 1219 // t.hi,t.lo =(umull) b.lo * c.lo
1154 // t.hi += t_acc 1220 // t.hi += t_acc
1155 // a.lo = t.lo 1221 // a.lo = t.lo
1156 // a.hi = t.hi 1222 // a.hi = t.hi
1157 // 1223 //
(...skipping 11 matching lines...) Expand all
1169 Variable *T_Acc1 = makeReg(IceType_i32); 1235 Variable *T_Acc1 = makeReg(IceType_i32);
1170 Variable *T_Hi1 = makeReg(IceType_i32); 1236 Variable *T_Hi1 = makeReg(IceType_i32);
1171 Variable *Src1RLo = legalizeToVar(Src1Lo); 1237 Variable *Src1RLo = legalizeToVar(Src1Lo);
1172 Variable *Src1RHi = legalizeToVar(Src1Hi); 1238 Variable *Src1RHi = legalizeToVar(Src1Hi);
1173 _mul(T_Acc, Src0RLo, Src1RHi); 1239 _mul(T_Acc, Src0RLo, Src1RHi);
1174 _mla(T_Acc1, Src1RLo, Src0RHi, T_Acc); 1240 _mla(T_Acc1, Src1RLo, Src0RHi, T_Acc);
1175 _umull(T_Lo, T_Hi1, Src0RLo, Src1RLo); 1241 _umull(T_Lo, T_Hi1, Src0RLo, Src1RLo);
1176 _add(T_Hi, T_Hi1, T_Acc1); 1242 _add(T_Hi, T_Hi1, T_Acc1);
1177 _mov(DestLo, T_Lo); 1243 _mov(DestLo, T_Lo);
1178 _mov(DestHi, T_Hi); 1244 _mov(DestHi, T_Hi);
1179 } break; 1245 return;
1246 }
1180 case InstArithmetic::Shl: { 1247 case InstArithmetic::Shl: {
1181 // a=b<<c ==> 1248 // a=b<<c ==>
1182 // GCC 4.8 does: 1249 // GCC 4.8 does:
1183 // sub t_c1, c.lo, #32 1250 // sub t_c1, c.lo, #32
1184 // lsl t_hi, b.hi, c.lo 1251 // lsl t_hi, b.hi, c.lo
1185 // orr t_hi, t_hi, b.lo, lsl t_c1 1252 // orr t_hi, t_hi, b.lo, lsl t_c1
1186 // rsb t_c2, c.lo, #32 1253 // rsb t_c2, c.lo, #32
1187 // orr t_hi, t_hi, b.lo, lsr t_c2 1254 // orr t_hi, t_hi, b.lo, lsr t_c2
1188 // lsl t_lo, b.lo, c.lo 1255 // lsl t_lo, b.lo, c.lo
1189 // a.lo = t_lo 1256 // a.lo = t_lo
(...skipping 17 matching lines...) Expand all
1207 _orr(T_Hi, T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, Src0RLo, 1274 _orr(T_Hi, T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, Src0RLo,
1208 OperandARM32::LSR, T_C2)); 1275 OperandARM32::LSR, T_C2));
1209 _mov(DestHi, T_Hi); 1276 _mov(DestHi, T_Hi);
1210 Variable *T_Lo = makeReg(IceType_i32); 1277 Variable *T_Lo = makeReg(IceType_i32);
1211 // _mov seems to sometimes have better register preferencing than lsl. 1278 // _mov seems to sometimes have better register preferencing than lsl.
1212 // Otherwise mov w/ lsl shifted register is a pseudo-instruction 1279 // Otherwise mov w/ lsl shifted register is a pseudo-instruction
1213 // that maps to lsl. 1280 // that maps to lsl.
1214 _mov(T_Lo, OperandARM32FlexReg::create(Func, IceType_i32, Src0RLo, 1281 _mov(T_Lo, OperandARM32FlexReg::create(Func, IceType_i32, Src0RLo,
1215 OperandARM32::LSL, Src1RLo)); 1282 OperandARM32::LSL, Src1RLo));
1216 _mov(DestLo, T_Lo); 1283 _mov(DestLo, T_Lo);
1217 } break; 1284 return;
1285 }
1218 case InstArithmetic::Lshr: 1286 case InstArithmetic::Lshr:
1219 // a=b>>c (unsigned) ==> 1287 // a=b>>c (unsigned) ==>
1220 // GCC 4.8 does: 1288 // GCC 4.8 does:
1221 // rsb t_c1, c.lo, #32 1289 // rsb t_c1, c.lo, #32
1222 // lsr t_lo, b.lo, c.lo 1290 // lsr t_lo, b.lo, c.lo
1223 // orr t_lo, t_lo, b.hi, lsl t_c1 1291 // orr t_lo, t_lo, b.hi, lsl t_c1
1224 // sub t_c2, c.lo, #32 1292 // sub t_c2, c.lo, #32
1225 // orr t_lo, t_lo, b.hi, lsr t_c2 1293 // orr t_lo, t_lo, b.hi, lsr t_c2
1226 // lsr t_hi, b.hi, c.lo 1294 // lsr t_hi, b.hi, c.lo
1227 // a.lo = t_lo 1295 // a.lo = t_lo
(...skipping 25 matching lines...) Expand all
1253 Pred = CondARM32::AL; 1321 Pred = CondARM32::AL;
1254 } 1322 }
1255 _orr(T_Lo, T_Lo, OperandARM32FlexReg::create(Func, IceType_i32, Src0RHi, 1323 _orr(T_Lo, T_Lo, OperandARM32FlexReg::create(Func, IceType_i32, Src0RHi,
1256 RShiftKind, T_C2), 1324 RShiftKind, T_C2),
1257 Pred); 1325 Pred);
1258 _mov(DestLo, T_Lo); 1326 _mov(DestLo, T_Lo);
1259 Variable *T_Hi = makeReg(IceType_i32); 1327 Variable *T_Hi = makeReg(IceType_i32);
1260 _mov(T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, Src0RHi, 1328 _mov(T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, Src0RHi,
1261 RShiftKind, Src1RLo)); 1329 RShiftKind, Src1RLo));
1262 _mov(DestHi, T_Hi); 1330 _mov(DestHi, T_Hi);
1263 } break;
1264 case InstArithmetic::Udiv:
1265 case InstArithmetic::Sdiv:
1266 case InstArithmetic::Urem:
1267 case InstArithmetic::Srem: {
1268 // Check for divide by 0 (ARM normally doesn't trap, but we want it
1269 // to trap for NaCl). Src1Lo and Src1Hi may have already been legalized
1270 // to a register, which will hide a constant source operand.
1271 // Instead, check the not-yet-legalized Src1 to optimize-out a divide
1272 // by 0 check.
1273 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src1)) {
1274 if (C64->getValue() == 0) {
1275 div0Check(IceType_i64, Src1Lo, Src1Hi);
1276 }
1277 } else {
1278 div0Check(IceType_i64, Src1Lo, Src1Hi);
1279 }
1280 // Technically, ARM has their own aeabi routines, but we can use the
1281 // non-aeabi routine as well. LLVM uses __aeabi_ldivmod for div,
1282 // but uses the more standard __moddi3 for rem.
1283 const char *HelperName = "";
1284 switch (Inst->getOp()) {
1285 case InstArithmetic::Udiv:
1286 HelperName = H_udiv_i64;
1287 break;
1288 case InstArithmetic::Sdiv:
1289 HelperName = H_sdiv_i64;
1290 break;
1291 case InstArithmetic::Urem:
1292 HelperName = H_urem_i64;
1293 break;
1294 case InstArithmetic::Srem:
1295 HelperName = H_srem_i64;
1296 break;
1297 default:
1298 llvm_unreachable("Should have only matched div ops.");
1299 break;
1300 }
1301 constexpr SizeT MaxSrcs = 2;
1302 InstCall *Call = makeHelperCall(HelperName, Dest, MaxSrcs);
1303 Call->addArg(Inst->getSrc(0));
1304 Call->addArg(Inst->getSrc(1));
1305 lowerCall(Call);
1306 return; 1331 return;
1307 } 1332 }
1308 case InstArithmetic::Fadd: 1333 case InstArithmetic::Fadd:
1309 case InstArithmetic::Fsub: 1334 case InstArithmetic::Fsub:
1310 case InstArithmetic::Fmul: 1335 case InstArithmetic::Fmul:
1311 case InstArithmetic::Fdiv: 1336 case InstArithmetic::Fdiv:
1312 case InstArithmetic::Frem: 1337 case InstArithmetic::Frem:
1313 llvm_unreachable("FP instruction with i64 type"); 1338 llvm_unreachable("FP instruction with i64 type");
1314 break; 1339 return;
1340 case InstArithmetic::Udiv:
1341 case InstArithmetic::Sdiv:
1342 case InstArithmetic::Urem:
1343 case InstArithmetic::Srem:
1344 llvm_unreachable("Call-helper-involved instruction for i64 type "
1345 "should have already been handled before");
1346 return;
1315 } 1347 }
1348 return;
1316 } else if (isVectorType(Dest->getType())) { 1349 } else if (isVectorType(Dest->getType())) {
1317 UnimplementedError(Func->getContext()->getFlags()); 1350 UnimplementedError(Func->getContext()->getFlags());
1318 } else { // Dest->getType() is non-i64 scalar 1351 return;
1319 Variable *Src0R = legalizeToVar(Inst->getSrc(0)); 1352 }
1320 Operand *Src1RF = legalize(Inst->getSrc(1), Legal_Reg | Legal_Flex); 1353 // Dest->getType() is a non-i64 scalar.
1321 Variable *T = makeReg(Dest->getType()); 1354 Variable *Src0R = legalizeToVar(Src0);
1322 switch (Inst->getOp()) { 1355 Variable *T = makeReg(Dest->getType());
1323 case InstArithmetic::_num: 1356 // Handle div/rem separately. They require a non-legalized Src1 to inspect
1324 llvm_unreachable("Unknown arithmetic operator"); 1357 // whether or not Src1 is a non-zero constant. Once legalized it is more
1325 break; 1358 // difficult to determine (constant may be moved to a register).
1326 case InstArithmetic::Add: { 1359 switch (Inst->getOp()) {
1327 _add(T, Src0R, Src1RF); 1360 default:
1328 _mov(Dest, T); 1361 break;
1329 } break; 1362 case InstArithmetic::Udiv: {
1330 case InstArithmetic::And: { 1363 constexpr bool IsRemainder = false;
1331 _and(T, Src0R, Src1RF); 1364 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_uxt, &TargetARM32::_udiv,
1332 _mov(Dest, T); 1365 H_udiv_i32, IsRemainder);
1333 } break; 1366 return;
1334 case InstArithmetic::Or: { 1367 }
1335 _orr(T, Src0R, Src1RF); 1368 case InstArithmetic::Sdiv: {
1336 _mov(Dest, T); 1369 constexpr bool IsRemainder = false;
1337 } break; 1370 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_sxt, &TargetARM32::_sdiv,
1338 case InstArithmetic::Xor: { 1371 H_sdiv_i32, IsRemainder);
1339 _eor(T, Src0R, Src1RF); 1372 return;
1340 _mov(Dest, T); 1373 }
1341 } break; 1374 case InstArithmetic::Urem: {
1342 case InstArithmetic::Sub: { 1375 constexpr bool IsRemainder = true;
1343 _sub(T, Src0R, Src1RF); 1376 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_uxt, &TargetARM32::_udiv,
1344 _mov(Dest, T); 1377 H_urem_i32, IsRemainder);
1345 } break; 1378 return;
1346 case InstArithmetic::Mul: { 1379 }
1347 Variable *Src1R = legalizeToVar(Src1RF); 1380 case InstArithmetic::Srem: {
1348 _mul(T, Src0R, Src1R); 1381 constexpr bool IsRemainder = true;
1349 _mov(Dest, T); 1382 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_sxt, &TargetARM32::_sdiv,
1350 } break; 1383 H_srem_i32, IsRemainder);
1351 case InstArithmetic::Shl: 1384 return;
1352 _lsl(T, Src0R, Src1RF); 1385 }
1353 _mov(Dest, T); 1386 }
1354 break; 1387
1355 case InstArithmetic::Lshr: 1388 Operand *Src1RF = legalize(Src1, Legal_Reg | Legal_Flex);
1356 _lsr(T, Src0R, Src1RF); 1389 switch (Inst->getOp()) {
1357 _mov(Dest, T); 1390 case InstArithmetic::_num:
1358 break; 1391 llvm_unreachable("Unknown arithmetic operator");
1359 case InstArithmetic::Ashr: 1392 return;
1360 _asr(T, Src0R, Src1RF); 1393 case InstArithmetic::Add:
1361 _mov(Dest, T); 1394 _add(T, Src0R, Src1RF);
1362 break; 1395 _mov(Dest, T);
1363 case InstArithmetic::Udiv: { 1396 return;
1364 constexpr bool IsRemainder = false; 1397 case InstArithmetic::And:
1365 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_uxt, 1398 _and(T, Src0R, Src1RF);
1366 &TargetARM32::_udiv, H_udiv_i32, IsRemainder); 1399 _mov(Dest, T);
1367 return; 1400 return;
1368 } 1401 case InstArithmetic::Or:
1369 case InstArithmetic::Sdiv: { 1402 _orr(T, Src0R, Src1RF);
1370 constexpr bool IsRemainder = false; 1403 _mov(Dest, T);
1371 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_sxt, 1404 return;
1372 &TargetARM32::_sdiv, H_sdiv_i32, IsRemainder); 1405 case InstArithmetic::Xor:
1373 return; 1406 _eor(T, Src0R, Src1RF);
1374 } 1407 _mov(Dest, T);
1375 case InstArithmetic::Urem: { 1408 return;
1376 constexpr bool IsRemainder = true; 1409 case InstArithmetic::Sub:
1377 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_uxt, 1410 _sub(T, Src0R, Src1RF);
1378 &TargetARM32::_udiv, H_urem_i32, IsRemainder); 1411 _mov(Dest, T);
1379 return; 1412 return;
1380 } 1413 case InstArithmetic::Mul: {
1381 case InstArithmetic::Srem: { 1414 Variable *Src1R = legalizeToVar(Src1RF);
1382 constexpr bool IsRemainder = true; 1415 _mul(T, Src0R, Src1R);
1383 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_sxt, 1416 _mov(Dest, T);
1384 &TargetARM32::_sdiv, H_srem_i32, IsRemainder); 1417 return;
1385 return; 1418 }
1386 } 1419 case InstArithmetic::Shl:
1387 case InstArithmetic::Fadd: 1420 _lsl(T, Src0R, Src1RF);
1388 UnimplementedError(Func->getContext()->getFlags()); 1421 _mov(Dest, T);
1389 break; 1422 return;
1390 case InstArithmetic::Fsub: 1423 case InstArithmetic::Lshr:
1391 UnimplementedError(Func->getContext()->getFlags()); 1424 _lsr(T, Src0R, Src1RF);
1392 break; 1425 _mov(Dest, T);
1393 case InstArithmetic::Fmul: 1426 return;
1394 UnimplementedError(Func->getContext()->getFlags()); 1427 case InstArithmetic::Ashr:
1395 break; 1428 _asr(T, Src0R, Src1RF);
1396 case InstArithmetic::Fdiv: 1429 _mov(Dest, T);
1397 UnimplementedError(Func->getContext()->getFlags()); 1430 return;
1398 break; 1431 case InstArithmetic::Udiv:
1399 case InstArithmetic::Frem: 1432 case InstArithmetic::Sdiv:
1400 UnimplementedError(Func->getContext()->getFlags()); 1433 case InstArithmetic::Urem:
1401 break; 1434 case InstArithmetic::Srem:
1402 } 1435 llvm_unreachable("Integer div/rem should have been handled earlier.");
1436 return;
1437 case InstArithmetic::Fadd:
1438 UnimplementedError(Func->getContext()->getFlags());
1439 return;
1440 case InstArithmetic::Fsub:
1441 UnimplementedError(Func->getContext()->getFlags());
1442 return;
1443 case InstArithmetic::Fmul:
1444 UnimplementedError(Func->getContext()->getFlags());
1445 return;
1446 case InstArithmetic::Fdiv:
1447 UnimplementedError(Func->getContext()->getFlags());
1448 return;
1449 case InstArithmetic::Frem:
1450 UnimplementedError(Func->getContext()->getFlags());
1451 return;
1403 } 1452 }
1404 } 1453 }
1405 1454
1406 void TargetARM32::lowerAssign(const InstAssign *Inst) { 1455 void TargetARM32::lowerAssign(const InstAssign *Inst) {
1407 Variable *Dest = Inst->getDest(); 1456 Variable *Dest = Inst->getDest();
1408 Operand *Src0 = Inst->getSrc(0); 1457 Operand *Src0 = Inst->getSrc(0);
1409 assert(Dest->getType() == Src0->getType()); 1458 assert(Dest->getType() == Src0->getType());
1410 if (Dest->getType() == IceType_i64) { 1459 if (Dest->getType() == IceType_i64) {
1411 Src0 = legalize(Src0); 1460 Src0 = legalize(Src0);
1412 Operand *Src0Lo = loOperand(Src0); 1461 Operand *Src0Lo = loOperand(Src0);
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2590 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; 2639 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n";
2591 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { 2640 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) {
2592 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; 2641 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n";
2593 } 2642 }
2594 // Technically R9 is used for TLS with Sandboxing, and we reserve it. 2643 // Technically R9 is used for TLS with Sandboxing, and we reserve it.
2595 // However, for compatibility with current NaCl LLVM, don't claim that. 2644 // However, for compatibility with current NaCl LLVM, don't claim that.
2596 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 2645 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
2597 } 2646 }
2598 2647
2599 } // end of namespace Ice 2648 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/64bit.pnacl.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698