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

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1245063003: Rename legalizeToVar to the more accurate legalizeToReg. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: 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 | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringX86Base.h » ('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 /// \file 10 /// \file
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 _add(T, T, AddAmount); 1020 _add(T, T, AddAmount);
1021 alignRegisterPow2(T, Alignment); 1021 alignRegisterPow2(T, Alignment);
1022 _sub(SP, SP, T); 1022 _sub(SP, SP, T);
1023 } 1023 }
1024 _mov(Dest, SP); 1024 _mov(Dest, SP);
1025 } 1025 }
1026 1026
1027 void TargetARM32::div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi) { 1027 void TargetARM32::div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi) {
1028 if (isGuaranteedNonzeroInt(SrcLo) || isGuaranteedNonzeroInt(SrcHi)) 1028 if (isGuaranteedNonzeroInt(SrcLo) || isGuaranteedNonzeroInt(SrcHi))
1029 return; 1029 return;
1030 Variable *SrcLoReg = legalizeToVar(SrcLo); 1030 Variable *SrcLoReg = legalizeToReg(SrcLo);
1031 switch (Ty) { 1031 switch (Ty) {
1032 default: 1032 default:
1033 llvm_unreachable("Unexpected type"); 1033 llvm_unreachable("Unexpected type");
1034 case IceType_i8: { 1034 case IceType_i8: {
1035 Operand *Mask = 1035 Operand *Mask =
1036 legalize(Ctx->getConstantInt32(0xFF), Legal_Reg | Legal_Flex); 1036 legalize(Ctx->getConstantInt32(0xFF), Legal_Reg | Legal_Flex);
1037 _tst(SrcLoReg, Mask); 1037 _tst(SrcLoReg, Mask);
1038 break; 1038 break;
1039 } 1039 }
1040 case IceType_i16: { 1040 case IceType_i16: {
(...skipping 18 matching lines...) Expand all
1059 _br(Label, CondARM32::NE); 1059 _br(Label, CondARM32::NE);
1060 _trap(); 1060 _trap();
1061 Context.insert(Label); 1061 Context.insert(Label);
1062 } 1062 }
1063 1063
1064 void TargetARM32::lowerIDivRem(Variable *Dest, Variable *T, Variable *Src0R, 1064 void TargetARM32::lowerIDivRem(Variable *Dest, Variable *T, Variable *Src0R,
1065 Operand *Src1, ExtInstr ExtFunc, 1065 Operand *Src1, ExtInstr ExtFunc,
1066 DivInstr DivFunc, const char *DivHelperName, 1066 DivInstr DivFunc, const char *DivHelperName,
1067 bool IsRemainder) { 1067 bool IsRemainder) {
1068 div0Check(Dest->getType(), Src1, nullptr); 1068 div0Check(Dest->getType(), Src1, nullptr);
1069 Variable *Src1R = legalizeToVar(Src1); 1069 Variable *Src1R = legalizeToReg(Src1);
1070 Variable *T0R = Src0R; 1070 Variable *T0R = Src0R;
1071 Variable *T1R = Src1R; 1071 Variable *T1R = Src1R;
1072 if (Dest->getType() != IceType_i32) { 1072 if (Dest->getType() != IceType_i32) {
1073 T0R = makeReg(IceType_i32); 1073 T0R = makeReg(IceType_i32);
1074 (this->*ExtFunc)(T0R, Src0R, CondARM32::AL); 1074 (this->*ExtFunc)(T0R, Src0R, CondARM32::AL);
1075 T1R = makeReg(IceType_i32); 1075 T1R = makeReg(IceType_i32);
1076 (this->*ExtFunc)(T1R, Src1R, CondARM32::AL); 1076 (this->*ExtFunc)(T1R, Src1R, CondARM32::AL);
1077 } 1077 }
1078 if (hasCPUFeature(TargetARM32Features::HWDivArm)) { 1078 if (hasCPUFeature(TargetARM32Features::HWDivArm)) {
1079 (this->*DivFunc)(T, T0R, T1R, CondARM32::AL); 1079 (this->*DivFunc)(T, T0R, T1R, CondARM32::AL);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 constexpr SizeT MaxSrcs = 2; 1156 constexpr SizeT MaxSrcs = 2;
1157 InstCall *Call = makeHelperCall(HelperName, Dest, MaxSrcs); 1157 InstCall *Call = makeHelperCall(HelperName, Dest, MaxSrcs);
1158 Call->addArg(Src0); 1158 Call->addArg(Src0);
1159 Call->addArg(Src1); 1159 Call->addArg(Src1);
1160 lowerCall(Call); 1160 lowerCall(Call);
1161 return; 1161 return;
1162 } 1162 }
1163 } 1163 }
1164 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1164 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1165 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1165 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1166 Variable *Src0RLo = legalizeToVar(loOperand(Src0)); 1166 Variable *Src0RLo = legalizeToReg(loOperand(Src0));
1167 Variable *Src0RHi = legalizeToVar(hiOperand(Src0)); 1167 Variable *Src0RHi = legalizeToReg(hiOperand(Src0));
1168 Operand *Src1Lo = loOperand(Src1); 1168 Operand *Src1Lo = loOperand(Src1);
1169 Operand *Src1Hi = hiOperand(Src1); 1169 Operand *Src1Hi = hiOperand(Src1);
1170 Variable *T_Lo = makeReg(DestLo->getType()); 1170 Variable *T_Lo = makeReg(DestLo->getType());
1171 Variable *T_Hi = makeReg(DestHi->getType()); 1171 Variable *T_Hi = makeReg(DestHi->getType());
1172 switch (Inst->getOp()) { 1172 switch (Inst->getOp()) {
1173 case InstArithmetic::_num: 1173 case InstArithmetic::_num:
1174 llvm_unreachable("Unknown arithmetic operator"); 1174 llvm_unreachable("Unknown arithmetic operator");
1175 return; 1175 return;
1176 case InstArithmetic::Add: 1176 case InstArithmetic::Add:
1177 Src1Lo = legalize(Src1Lo, Legal_Reg | Legal_Flex); 1177 Src1Lo = legalize(Src1Lo, Legal_Reg | Legal_Flex);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 // t.hi =(mla) (b.hi * c.lo) + t.hi 1229 // t.hi =(mla) (b.hi * c.lo) + t.hi
1230 // a.lo = t.lo 1230 // a.lo = t.lo
1231 // a.hi = t.hi 1231 // a.hi = t.hi
1232 // 1232 //
1233 // LLVM's lowering has fewer instructions, but more register pressure: 1233 // LLVM's lowering has fewer instructions, but more register pressure:
1234 // t.lo is live from beginning to end, while GCC delays the two-dest 1234 // t.lo is live from beginning to end, while GCC delays the two-dest
1235 // instruction till the end, and kills c.hi immediately. 1235 // instruction till the end, and kills c.hi immediately.
1236 Variable *T_Acc = makeReg(IceType_i32); 1236 Variable *T_Acc = makeReg(IceType_i32);
1237 Variable *T_Acc1 = makeReg(IceType_i32); 1237 Variable *T_Acc1 = makeReg(IceType_i32);
1238 Variable *T_Hi1 = makeReg(IceType_i32); 1238 Variable *T_Hi1 = makeReg(IceType_i32);
1239 Variable *Src1RLo = legalizeToVar(Src1Lo); 1239 Variable *Src1RLo = legalizeToReg(Src1Lo);
1240 Variable *Src1RHi = legalizeToVar(Src1Hi); 1240 Variable *Src1RHi = legalizeToReg(Src1Hi);
1241 _mul(T_Acc, Src0RLo, Src1RHi); 1241 _mul(T_Acc, Src0RLo, Src1RHi);
1242 _mla(T_Acc1, Src1RLo, Src0RHi, T_Acc); 1242 _mla(T_Acc1, Src1RLo, Src0RHi, T_Acc);
1243 _umull(T_Lo, T_Hi1, Src0RLo, Src1RLo); 1243 _umull(T_Lo, T_Hi1, Src0RLo, Src1RLo);
1244 _add(T_Hi, T_Hi1, T_Acc1); 1244 _add(T_Hi, T_Hi1, T_Acc1);
1245 _mov(DestLo, T_Lo); 1245 _mov(DestLo, T_Lo);
1246 _mov(DestHi, T_Hi); 1246 _mov(DestHi, T_Hi);
1247 return; 1247 return;
1248 } 1248 }
1249 case InstArithmetic::Shl: { 1249 case InstArithmetic::Shl: {
1250 // a=b<<c ==> 1250 // a=b<<c ==>
1251 // GCC 4.8 does: 1251 // GCC 4.8 does:
1252 // sub t_c1, c.lo, #32 1252 // sub t_c1, c.lo, #32
1253 // lsl t_hi, b.hi, c.lo 1253 // lsl t_hi, b.hi, c.lo
1254 // orr t_hi, t_hi, b.lo, lsl t_c1 1254 // orr t_hi, t_hi, b.lo, lsl t_c1
1255 // rsb t_c2, c.lo, #32 1255 // rsb t_c2, c.lo, #32
1256 // orr t_hi, t_hi, b.lo, lsr t_c2 1256 // orr t_hi, t_hi, b.lo, lsr t_c2
1257 // lsl t_lo, b.lo, c.lo 1257 // lsl t_lo, b.lo, c.lo
1258 // a.lo = t_lo 1258 // a.lo = t_lo
1259 // a.hi = t_hi 1259 // a.hi = t_hi
1260 // Can be strength-reduced for constant-shifts, but we don't do 1260 // Can be strength-reduced for constant-shifts, but we don't do
1261 // that for now. 1261 // that for now.
1262 // Given the sub/rsb T_C, C.lo, #32, one of the T_C will be negative. 1262 // Given the sub/rsb T_C, C.lo, #32, one of the T_C will be negative.
1263 // On ARM, shifts only take the lower 8 bits of the shift register, 1263 // On ARM, shifts only take the lower 8 bits of the shift register,
1264 // and saturate to the range 0-32, so the negative value will 1264 // and saturate to the range 0-32, so the negative value will
1265 // saturate to 32. 1265 // saturate to 32.
1266 Variable *T_Hi = makeReg(IceType_i32); 1266 Variable *T_Hi = makeReg(IceType_i32);
1267 Variable *Src1RLo = legalizeToVar(Src1Lo); 1267 Variable *Src1RLo = legalizeToReg(Src1Lo);
1268 Constant *ThirtyTwo = Ctx->getConstantInt32(32); 1268 Constant *ThirtyTwo = Ctx->getConstantInt32(32);
1269 Variable *T_C1 = makeReg(IceType_i32); 1269 Variable *T_C1 = makeReg(IceType_i32);
1270 Variable *T_C2 = makeReg(IceType_i32); 1270 Variable *T_C2 = makeReg(IceType_i32);
1271 _sub(T_C1, Src1RLo, ThirtyTwo); 1271 _sub(T_C1, Src1RLo, ThirtyTwo);
1272 _lsl(T_Hi, Src0RHi, Src1RLo); 1272 _lsl(T_Hi, Src0RHi, Src1RLo);
1273 _orr(T_Hi, T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, Src0RLo, 1273 _orr(T_Hi, T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, Src0RLo,
1274 OperandARM32::LSL, T_C1)); 1274 OperandARM32::LSL, T_C1));
1275 _rsb(T_C2, Src1RLo, ThirtyTwo); 1275 _rsb(T_C2, Src1RLo, ThirtyTwo);
1276 _orr(T_Hi, T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, Src0RLo, 1276 _orr(T_Hi, T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, Src0RLo,
1277 OperandARM32::LSR, T_C2)); 1277 OperandARM32::LSR, T_C2));
(...skipping 18 matching lines...) Expand all
1296 // lsr t_hi, b.hi, c.lo 1296 // lsr t_hi, b.hi, c.lo
1297 // a.lo = t_lo 1297 // a.lo = t_lo
1298 // a.hi = t_hi 1298 // a.hi = t_hi
1299 case InstArithmetic::Ashr: { 1299 case InstArithmetic::Ashr: {
1300 // a=b>>c (signed) ==> ... 1300 // a=b>>c (signed) ==> ...
1301 // Ashr is similar, but the sub t_c2, c.lo, #32 should set flags, 1301 // Ashr is similar, but the sub t_c2, c.lo, #32 should set flags,
1302 // and the next orr should be conditioned on PLUS. The last two 1302 // and the next orr should be conditioned on PLUS. The last two
1303 // right shifts should also be arithmetic. 1303 // right shifts should also be arithmetic.
1304 bool IsAshr = Inst->getOp() == InstArithmetic::Ashr; 1304 bool IsAshr = Inst->getOp() == InstArithmetic::Ashr;
1305 Variable *T_Lo = makeReg(IceType_i32); 1305 Variable *T_Lo = makeReg(IceType_i32);
1306 Variable *Src1RLo = legalizeToVar(Src1Lo); 1306 Variable *Src1RLo = legalizeToReg(Src1Lo);
1307 Constant *ThirtyTwo = Ctx->getConstantInt32(32); 1307 Constant *ThirtyTwo = Ctx->getConstantInt32(32);
1308 Variable *T_C1 = makeReg(IceType_i32); 1308 Variable *T_C1 = makeReg(IceType_i32);
1309 Variable *T_C2 = makeReg(IceType_i32); 1309 Variable *T_C2 = makeReg(IceType_i32);
1310 _rsb(T_C1, Src1RLo, ThirtyTwo); 1310 _rsb(T_C1, Src1RLo, ThirtyTwo);
1311 _lsr(T_Lo, Src0RLo, Src1RLo); 1311 _lsr(T_Lo, Src0RLo, Src1RLo);
1312 _orr(T_Lo, T_Lo, OperandARM32FlexReg::create(Func, IceType_i32, Src0RHi, 1312 _orr(T_Lo, T_Lo, OperandARM32FlexReg::create(Func, IceType_i32, Src0RHi,
1313 OperandARM32::LSL, T_C1)); 1313 OperandARM32::LSL, T_C1));
1314 OperandARM32::ShiftKind RShiftKind; 1314 OperandARM32::ShiftKind RShiftKind;
1315 CondARM32::Cond Pred; 1315 CondARM32::Cond Pred;
1316 if (IsAshr) { 1316 if (IsAshr) {
(...skipping 29 matching lines...) Expand all
1346 llvm_unreachable("Call-helper-involved instruction for i64 type " 1346 llvm_unreachable("Call-helper-involved instruction for i64 type "
1347 "should have already been handled before"); 1347 "should have already been handled before");
1348 return; 1348 return;
1349 } 1349 }
1350 return; 1350 return;
1351 } else if (isVectorType(Dest->getType())) { 1351 } else if (isVectorType(Dest->getType())) {
1352 UnimplementedError(Func->getContext()->getFlags()); 1352 UnimplementedError(Func->getContext()->getFlags());
1353 return; 1353 return;
1354 } 1354 }
1355 // Dest->getType() is a non-i64 scalar. 1355 // Dest->getType() is a non-i64 scalar.
1356 Variable *Src0R = legalizeToVar(Src0); 1356 Variable *Src0R = legalizeToReg(Src0);
1357 Variable *T = makeReg(Dest->getType()); 1357 Variable *T = makeReg(Dest->getType());
1358 // Handle div/rem separately. They require a non-legalized Src1 to inspect 1358 // Handle div/rem separately. They require a non-legalized Src1 to inspect
1359 // whether or not Src1 is a non-zero constant. Once legalized it is more 1359 // whether or not Src1 is a non-zero constant. Once legalized it is more
1360 // difficult to determine (constant may be moved to a register). 1360 // difficult to determine (constant may be moved to a register).
1361 switch (Inst->getOp()) { 1361 switch (Inst->getOp()) {
1362 default: 1362 default:
1363 break; 1363 break;
1364 case InstArithmetic::Udiv: { 1364 case InstArithmetic::Udiv: {
1365 constexpr bool IsRemainder = false; 1365 constexpr bool IsRemainder = false;
1366 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_uxt, &TargetARM32::_udiv, 1366 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_uxt, &TargetARM32::_udiv,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 return; 1406 return;
1407 case InstArithmetic::Xor: 1407 case InstArithmetic::Xor:
1408 _eor(T, Src0R, Src1RF); 1408 _eor(T, Src0R, Src1RF);
1409 _mov(Dest, T); 1409 _mov(Dest, T);
1410 return; 1410 return;
1411 case InstArithmetic::Sub: 1411 case InstArithmetic::Sub:
1412 _sub(T, Src0R, Src1RF); 1412 _sub(T, Src0R, Src1RF);
1413 _mov(Dest, T); 1413 _mov(Dest, T);
1414 return; 1414 return;
1415 case InstArithmetic::Mul: { 1415 case InstArithmetic::Mul: {
1416 Variable *Src1R = legalizeToVar(Src1RF); 1416 Variable *Src1R = legalizeToReg(Src1RF);
1417 _mul(T, Src0R, Src1R); 1417 _mul(T, Src0R, Src1R);
1418 _mov(Dest, T); 1418 _mov(Dest, T);
1419 return; 1419 return;
1420 } 1420 }
1421 case InstArithmetic::Shl: 1421 case InstArithmetic::Shl:
1422 _lsl(T, Src0R, Src1RF); 1422 _lsl(T, Src0R, Src1RF);
1423 _mov(Dest, T); 1423 _mov(Dest, T);
1424 return; 1424 return;
1425 case InstArithmetic::Lshr: 1425 case InstArithmetic::Lshr:
1426 _lsr(T, Src0R, Src1RF); 1426 _lsr(T, Src0R, Src1RF);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 } 1495 }
1496 1496
1497 void TargetARM32::lowerBr(const InstBr *Inst) { 1497 void TargetARM32::lowerBr(const InstBr *Inst) {
1498 if (Inst->isUnconditional()) { 1498 if (Inst->isUnconditional()) {
1499 _br(Inst->getTargetUnconditional()); 1499 _br(Inst->getTargetUnconditional());
1500 return; 1500 return;
1501 } 1501 }
1502 Operand *Cond = Inst->getCondition(); 1502 Operand *Cond = Inst->getCondition();
1503 // TODO(jvoung): Handle folding opportunities. 1503 // TODO(jvoung): Handle folding opportunities.
1504 1504
1505 Variable *Src0R = legalizeToVar(Cond); 1505 Variable *Src0R = legalizeToReg(Cond);
1506 Constant *Zero = Ctx->getConstantZero(IceType_i32); 1506 Constant *Zero = Ctx->getConstantZero(IceType_i32);
1507 _cmp(Src0R, Zero); 1507 _cmp(Src0R, Zero);
1508 _br(Inst->getTargetTrue(), Inst->getTargetFalse(), CondARM32::NE); 1508 _br(Inst->getTargetTrue(), Inst->getTargetFalse(), CondARM32::NE);
1509 } 1509 }
1510 1510
1511 void TargetARM32::lowerCall(const InstCall *Instr) { 1511 void TargetARM32::lowerCall(const InstCall *Instr) {
1512 MaybeLeafFunc = false; 1512 MaybeLeafFunc = false;
1513 NeedsStackAlignment = true; 1513 NeedsStackAlignment = true;
1514 1514
1515 // Assign arguments to registers and stack. Also reserve stack. 1515 // Assign arguments to registers and stack. Also reserve stack.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 Variable *NewBase = Func->makeVariable(SP->getType()); 1589 Variable *NewBase = Func->makeVariable(SP->getType());
1590 lowerArithmetic( 1590 lowerArithmetic(
1591 InstArithmetic::create(Func, InstArithmetic::Add, NewBase, SP, Loc)); 1591 InstArithmetic::create(Func, InstArithmetic::Add, NewBase, SP, Loc));
1592 Addr = formMemoryOperand(NewBase, Ty); 1592 Addr = formMemoryOperand(NewBase, Ty);
1593 } 1593 }
1594 lowerStore(InstStore::create(Func, StackArg.first, Addr)); 1594 lowerStore(InstStore::create(Func, StackArg.first, Addr));
1595 } 1595 }
1596 1596
1597 // Copy arguments to be passed in registers to the appropriate registers. 1597 // Copy arguments to be passed in registers to the appropriate registers.
1598 for (auto &GPRArg : GPRArgs) { 1598 for (auto &GPRArg : GPRArgs) {
1599 Variable *Reg = legalizeToVar(GPRArg.first, GPRArg.second); 1599 Variable *Reg = legalizeToReg(GPRArg.first, GPRArg.second);
1600 // Generate a FakeUse of register arguments so that they do not get 1600 // Generate a FakeUse of register arguments so that they do not get
1601 // dead code eliminated as a result of the FakeKill of scratch 1601 // dead code eliminated as a result of the FakeKill of scratch
1602 // registers after the call. 1602 // registers after the call.
1603 Context.insert(InstFakeUse::create(Func, Reg)); 1603 Context.insert(InstFakeUse::create(Func, Reg));
1604 } 1604 }
1605 1605
1606 // Generate the call instruction. Assign its result to a temporary 1606 // Generate the call instruction. Assign its result to a temporary
1607 // with high register allocation weight. 1607 // with high register allocation weight.
1608 Variable *Dest = Instr->getDest(); 1608 Variable *Dest = Instr->getDest();
1609 // ReturnReg doubles as ReturnRegLo as necessary. 1609 // ReturnReg doubles as ReturnRegLo as necessary.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1715 } else if (Dest->getType() == IceType_i64) { 1715 } else if (Dest->getType() == IceType_i64) {
1716 // t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2 1716 // t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2
1717 Constant *ShiftAmt = Ctx->getConstantInt32(31); 1717 Constant *ShiftAmt = Ctx->getConstantInt32(31);
1718 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1718 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1719 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1719 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1720 Variable *T_Lo = makeReg(DestLo->getType()); 1720 Variable *T_Lo = makeReg(DestLo->getType());
1721 if (Src0->getType() == IceType_i32) { 1721 if (Src0->getType() == IceType_i32) {
1722 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); 1722 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex);
1723 _mov(T_Lo, Src0RF); 1723 _mov(T_Lo, Src0RF);
1724 } else if (Src0->getType() == IceType_i1) { 1724 } else if (Src0->getType() == IceType_i1) {
1725 Variable *Src0R = legalizeToVar(Src0); 1725 Variable *Src0R = legalizeToReg(Src0);
1726 _lsl(T_Lo, Src0R, ShiftAmt); 1726 _lsl(T_Lo, Src0R, ShiftAmt);
1727 _asr(T_Lo, T_Lo, ShiftAmt); 1727 _asr(T_Lo, T_Lo, ShiftAmt);
1728 } else { 1728 } else {
1729 Variable *Src0R = legalizeToVar(Src0); 1729 Variable *Src0R = legalizeToReg(Src0);
1730 _sxt(T_Lo, Src0R); 1730 _sxt(T_Lo, Src0R);
1731 } 1731 }
1732 _mov(DestLo, T_Lo); 1732 _mov(DestLo, T_Lo);
1733 Variable *T_Hi = makeReg(DestHi->getType()); 1733 Variable *T_Hi = makeReg(DestHi->getType());
1734 if (Src0->getType() != IceType_i1) { 1734 if (Src0->getType() != IceType_i1) {
1735 _mov(T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, T_Lo, 1735 _mov(T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, T_Lo,
1736 OperandARM32::ASR, ShiftAmt)); 1736 OperandARM32::ASR, ShiftAmt));
1737 } else { 1737 } else {
1738 // For i1, the asr instruction is already done above. 1738 // For i1, the asr instruction is already done above.
1739 _mov(T_Hi, T_Lo); 1739 _mov(T_Hi, T_Lo);
1740 } 1740 }
1741 _mov(DestHi, T_Hi); 1741 _mov(DestHi, T_Hi);
1742 } else if (Src0->getType() == IceType_i1) { 1742 } else if (Src0->getType() == IceType_i1) {
1743 // GPR registers are 32-bit, so just use 31 as dst_bitwidth - 1. 1743 // GPR registers are 32-bit, so just use 31 as dst_bitwidth - 1.
1744 // lsl t1, src_reg, 31 1744 // lsl t1, src_reg, 31
1745 // asr t1, t1, 31 1745 // asr t1, t1, 31
1746 // dst = t1 1746 // dst = t1
1747 Variable *Src0R = legalizeToVar(Src0); 1747 Variable *Src0R = legalizeToReg(Src0);
1748 Constant *ShiftAmt = Ctx->getConstantInt32(31); 1748 Constant *ShiftAmt = Ctx->getConstantInt32(31);
1749 Variable *T = makeReg(Dest->getType()); 1749 Variable *T = makeReg(Dest->getType());
1750 _lsl(T, Src0R, ShiftAmt); 1750 _lsl(T, Src0R, ShiftAmt);
1751 _asr(T, T, ShiftAmt); 1751 _asr(T, T, ShiftAmt);
1752 _mov(Dest, T); 1752 _mov(Dest, T);
1753 } else { 1753 } else {
1754 // t1 = sxt src; dst = t1 1754 // t1 = sxt src; dst = t1
1755 Variable *Src0R = legalizeToVar(Src0); 1755 Variable *Src0R = legalizeToReg(Src0);
1756 Variable *T = makeReg(Dest->getType()); 1756 Variable *T = makeReg(Dest->getType());
1757 _sxt(T, Src0R); 1757 _sxt(T, Src0R);
1758 _mov(Dest, T); 1758 _mov(Dest, T);
1759 } 1759 }
1760 break; 1760 break;
1761 } 1761 }
1762 case InstCast::Zext: { 1762 case InstCast::Zext: {
1763 if (isVectorType(Dest->getType())) { 1763 if (isVectorType(Dest->getType())) {
1764 UnimplementedError(Func->getContext()->getFlags()); 1764 UnimplementedError(Func->getContext()->getFlags());
1765 } else if (Dest->getType() == IceType_i64) { 1765 } else if (Dest->getType() == IceType_i64) {
1766 // t1=uxtb src; dst.lo=t1; dst.hi=0 1766 // t1=uxtb src; dst.lo=t1; dst.hi=0
1767 Constant *Zero = Ctx->getConstantZero(IceType_i32); 1767 Constant *Zero = Ctx->getConstantZero(IceType_i32);
1768 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1768 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1769 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1769 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1770 Variable *T_Lo = makeReg(DestLo->getType()); 1770 Variable *T_Lo = makeReg(DestLo->getType());
1771 // i32 and i1 can just take up the whole register. 1771 // i32 and i1 can just take up the whole register.
1772 // i32 doesn't need uxt, while i1 will have an and mask later anyway. 1772 // i32 doesn't need uxt, while i1 will have an and mask later anyway.
1773 if (Src0->getType() == IceType_i32 || Src0->getType() == IceType_i1) { 1773 if (Src0->getType() == IceType_i32 || Src0->getType() == IceType_i1) {
1774 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); 1774 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex);
1775 _mov(T_Lo, Src0RF); 1775 _mov(T_Lo, Src0RF);
1776 } else { 1776 } else {
1777 Variable *Src0R = legalizeToVar(Src0); 1777 Variable *Src0R = legalizeToReg(Src0);
1778 _uxt(T_Lo, Src0R); 1778 _uxt(T_Lo, Src0R);
1779 } 1779 }
1780 if (Src0->getType() == IceType_i1) { 1780 if (Src0->getType() == IceType_i1) {
1781 Constant *One = Ctx->getConstantInt32(1); 1781 Constant *One = Ctx->getConstantInt32(1);
1782 _and(T_Lo, T_Lo, One); 1782 _and(T_Lo, T_Lo, One);
1783 } 1783 }
1784 _mov(DestLo, T_Lo); 1784 _mov(DestLo, T_Lo);
1785 Variable *T_Hi = makeReg(DestLo->getType()); 1785 Variable *T_Hi = makeReg(DestLo->getType());
1786 _mov(T_Hi, Zero); 1786 _mov(T_Hi, Zero);
1787 _mov(DestHi, T_Hi); 1787 _mov(DestHi, T_Hi);
1788 } else if (Src0->getType() == IceType_i1) { 1788 } else if (Src0->getType() == IceType_i1) {
1789 // t = Src0; t &= 1; Dest = t 1789 // t = Src0; t &= 1; Dest = t
1790 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); 1790 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex);
1791 Constant *One = Ctx->getConstantInt32(1); 1791 Constant *One = Ctx->getConstantInt32(1);
1792 Variable *T = makeReg(Dest->getType()); 1792 Variable *T = makeReg(Dest->getType());
1793 // Just use _mov instead of _uxt since all registers are 32-bit. 1793 // Just use _mov instead of _uxt since all registers are 32-bit.
1794 // _uxt requires the source to be a register so could have required 1794 // _uxt requires the source to be a register so could have required
1795 // a _mov from legalize anyway. 1795 // a _mov from legalize anyway.
1796 _mov(T, Src0RF); 1796 _mov(T, Src0RF);
1797 _and(T, T, One); 1797 _and(T, T, One);
1798 _mov(Dest, T); 1798 _mov(Dest, T);
1799 } else { 1799 } else {
1800 // t1 = uxt src; dst = t1 1800 // t1 = uxt src; dst = t1
1801 Variable *Src0R = legalizeToVar(Src0); 1801 Variable *Src0R = legalizeToReg(Src0);
1802 Variable *T = makeReg(Dest->getType()); 1802 Variable *T = makeReg(Dest->getType());
1803 _uxt(T, Src0R); 1803 _uxt(T, Src0R);
1804 _mov(Dest, T); 1804 _mov(Dest, T);
1805 } 1805 }
1806 break; 1806 break;
1807 } 1807 }
1808 case InstCast::Trunc: { 1808 case InstCast::Trunc: {
1809 if (isVectorType(Dest->getType())) { 1809 if (isVectorType(Dest->getType())) {
1810 UnimplementedError(Func->getContext()->getFlags()); 1810 UnimplementedError(Func->getContext()->getFlags());
1811 } else { 1811 } else {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 // perhaps for eq/ne). We could revisit special-casing eq/ne later. 1905 // perhaps for eq/ne). We could revisit special-casing eq/ne later.
1906 Constant *Zero = Ctx->getConstantZero(IceType_i32); 1906 Constant *Zero = Ctx->getConstantZero(IceType_i32);
1907 Constant *One = Ctx->getConstantInt32(1); 1907 Constant *One = Ctx->getConstantInt32(1);
1908 if (Src0->getType() == IceType_i64) { 1908 if (Src0->getType() == IceType_i64) {
1909 InstIcmp::ICond Conditon = Inst->getCondition(); 1909 InstIcmp::ICond Conditon = Inst->getCondition();
1910 size_t Index = static_cast<size_t>(Conditon); 1910 size_t Index = static_cast<size_t>(Conditon);
1911 assert(Index < TableIcmp64Size); 1911 assert(Index < TableIcmp64Size);
1912 Variable *Src0Lo, *Src0Hi; 1912 Variable *Src0Lo, *Src0Hi;
1913 Operand *Src1LoRF, *Src1HiRF; 1913 Operand *Src1LoRF, *Src1HiRF;
1914 if (TableIcmp64[Index].Swapped) { 1914 if (TableIcmp64[Index].Swapped) {
1915 Src0Lo = legalizeToVar(loOperand(Src1)); 1915 Src0Lo = legalizeToReg(loOperand(Src1));
1916 Src0Hi = legalizeToVar(hiOperand(Src1)); 1916 Src0Hi = legalizeToReg(hiOperand(Src1));
1917 Src1LoRF = legalize(loOperand(Src0), Legal_Reg | Legal_Flex); 1917 Src1LoRF = legalize(loOperand(Src0), Legal_Reg | Legal_Flex);
1918 Src1HiRF = legalize(hiOperand(Src0), Legal_Reg | Legal_Flex); 1918 Src1HiRF = legalize(hiOperand(Src0), Legal_Reg | Legal_Flex);
1919 } else { 1919 } else {
1920 Src0Lo = legalizeToVar(loOperand(Src0)); 1920 Src0Lo = legalizeToReg(loOperand(Src0));
1921 Src0Hi = legalizeToVar(hiOperand(Src0)); 1921 Src0Hi = legalizeToReg(hiOperand(Src0));
1922 Src1LoRF = legalize(loOperand(Src1), Legal_Reg | Legal_Flex); 1922 Src1LoRF = legalize(loOperand(Src1), Legal_Reg | Legal_Flex);
1923 Src1HiRF = legalize(hiOperand(Src1), Legal_Reg | Legal_Flex); 1923 Src1HiRF = legalize(hiOperand(Src1), Legal_Reg | Legal_Flex);
1924 } 1924 }
1925 Variable *T = makeReg(IceType_i32); 1925 Variable *T = makeReg(IceType_i32);
1926 if (TableIcmp64[Index].IsSigned) { 1926 if (TableIcmp64[Index].IsSigned) {
1927 Variable *ScratchReg = makeReg(IceType_i32); 1927 Variable *ScratchReg = makeReg(IceType_i32);
1928 _cmp(Src0Lo, Src1LoRF); 1928 _cmp(Src0Lo, Src1LoRF);
1929 _sbcs(ScratchReg, Src0Hi, Src1HiRF); 1929 _sbcs(ScratchReg, Src0Hi, Src1HiRF);
1930 // ScratchReg isn't going to be used, but we need the 1930 // ScratchReg isn't going to be used, but we need the
1931 // side-effect of setting flags from this operation. 1931 // side-effect of setting flags from this operation.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1970 // We'll go with the LLVM way for now, since it's shorter and has just as 1970 // We'll go with the LLVM way for now, since it's shorter and has just as
1971 // few dependencies. 1971 // few dependencies.
1972 int32_t ShiftAmt = 32 - getScalarIntBitWidth(Src0->getType()); 1972 int32_t ShiftAmt = 32 - getScalarIntBitWidth(Src0->getType());
1973 assert(ShiftAmt >= 0); 1973 assert(ShiftAmt >= 0);
1974 Constant *ShiftConst = nullptr; 1974 Constant *ShiftConst = nullptr;
1975 Variable *Src0R = nullptr; 1975 Variable *Src0R = nullptr;
1976 Variable *T = makeReg(IceType_i32); 1976 Variable *T = makeReg(IceType_i32);
1977 if (ShiftAmt) { 1977 if (ShiftAmt) {
1978 ShiftConst = Ctx->getConstantInt32(ShiftAmt); 1978 ShiftConst = Ctx->getConstantInt32(ShiftAmt);
1979 Src0R = makeReg(IceType_i32); 1979 Src0R = makeReg(IceType_i32);
1980 _lsl(Src0R, legalizeToVar(Src0), ShiftConst); 1980 _lsl(Src0R, legalizeToReg(Src0), ShiftConst);
1981 } else { 1981 } else {
1982 Src0R = legalizeToVar(Src0); 1982 Src0R = legalizeToReg(Src0);
1983 } 1983 }
1984 _mov(T, Zero); 1984 _mov(T, Zero);
1985 if (ShiftAmt) { 1985 if (ShiftAmt) {
1986 Variable *Src1R = legalizeToVar(Src1); 1986 Variable *Src1R = legalizeToReg(Src1);
1987 OperandARM32FlexReg *Src1RShifted = OperandARM32FlexReg::create( 1987 OperandARM32FlexReg *Src1RShifted = OperandARM32FlexReg::create(
1988 Func, IceType_i32, Src1R, OperandARM32::LSL, ShiftConst); 1988 Func, IceType_i32, Src1R, OperandARM32::LSL, ShiftConst);
1989 _cmp(Src0R, Src1RShifted); 1989 _cmp(Src0R, Src1RShifted);
1990 } else { 1990 } else {
1991 Operand *Src1RF = legalize(Src1, Legal_Reg | Legal_Flex); 1991 Operand *Src1RF = legalize(Src1, Legal_Reg | Legal_Flex);
1992 _cmp(Src0R, Src1RF); 1992 _cmp(Src0R, Src1RF);
1993 } 1993 }
1994 _mov_nonkillable(T, One, getIcmp32Mapping(Inst->getCondition())); 1994 _mov_nonkillable(T, One, getIcmp32Mapping(Inst->getCondition()));
1995 _mov(Dest, T); 1995 _mov(Dest, T);
1996 return; 1996 return;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2030 case Intrinsics::AtomicStore: { 2030 case Intrinsics::AtomicStore: {
2031 UnimplementedError(Func->getContext()->getFlags()); 2031 UnimplementedError(Func->getContext()->getFlags());
2032 return; 2032 return;
2033 } 2033 }
2034 case Intrinsics::Bswap: { 2034 case Intrinsics::Bswap: {
2035 Variable *Dest = Instr->getDest(); 2035 Variable *Dest = Instr->getDest();
2036 Operand *Val = Instr->getArg(0); 2036 Operand *Val = Instr->getArg(0);
2037 Type Ty = Val->getType(); 2037 Type Ty = Val->getType();
2038 if (Ty == IceType_i64) { 2038 if (Ty == IceType_i64) {
2039 Val = legalizeUndef(Val); 2039 Val = legalizeUndef(Val);
2040 Variable *Val_Lo = legalizeToVar(loOperand(Val)); 2040 Variable *Val_Lo = legalizeToReg(loOperand(Val));
2041 Variable *Val_Hi = legalizeToVar(hiOperand(Val)); 2041 Variable *Val_Hi = legalizeToReg(hiOperand(Val));
2042 Variable *T_Lo = makeReg(IceType_i32); 2042 Variable *T_Lo = makeReg(IceType_i32);
2043 Variable *T_Hi = makeReg(IceType_i32); 2043 Variable *T_Hi = makeReg(IceType_i32);
2044 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2044 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2045 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2045 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
2046 _rev(T_Lo, Val_Lo); 2046 _rev(T_Lo, Val_Lo);
2047 _rev(T_Hi, Val_Hi); 2047 _rev(T_Hi, Val_Hi);
2048 _mov(DestLo, T_Hi); 2048 _mov(DestLo, T_Hi);
2049 _mov(DestHi, T_Lo); 2049 _mov(DestHi, T_Lo);
2050 } else { 2050 } else {
2051 assert(Ty == IceType_i32 || Ty == IceType_i16); 2051 assert(Ty == IceType_i32 || Ty == IceType_i16);
2052 Variable *ValR = legalizeToVar(Val); 2052 Variable *ValR = legalizeToReg(Val);
2053 Variable *T = makeReg(Ty); 2053 Variable *T = makeReg(Ty);
2054 _rev(T, ValR); 2054 _rev(T, ValR);
2055 if (Val->getType() == IceType_i16) { 2055 if (Val->getType() == IceType_i16) {
2056 Operand *Sixteen = 2056 Operand *Sixteen =
2057 legalize(Ctx->getConstantInt32(16), Legal_Reg | Legal_Flex); 2057 legalize(Ctx->getConstantInt32(16), Legal_Reg | Legal_Flex);
2058 _lsr(T, T, Sixteen); 2058 _lsr(T, T, Sixteen);
2059 } 2059 }
2060 _mov(Dest, T); 2060 _mov(Dest, T);
2061 } 2061 }
2062 return; 2062 return;
(...skipping 20 matching lines...) Expand all
2083 return; 2083 return;
2084 } 2084 }
2085 case Intrinsics::Ctlz: { 2085 case Intrinsics::Ctlz: {
2086 // The "is zero undef" parameter is ignored and we always return 2086 // The "is zero undef" parameter is ignored and we always return
2087 // a well-defined value. 2087 // a well-defined value.
2088 Operand *Val = Instr->getArg(0); 2088 Operand *Val = Instr->getArg(0);
2089 Variable *ValLoR; 2089 Variable *ValLoR;
2090 Variable *ValHiR = nullptr; 2090 Variable *ValHiR = nullptr;
2091 if (Val->getType() == IceType_i64) { 2091 if (Val->getType() == IceType_i64) {
2092 Val = legalizeUndef(Val); 2092 Val = legalizeUndef(Val);
2093 ValLoR = legalizeToVar(loOperand(Val)); 2093 ValLoR = legalizeToReg(loOperand(Val));
2094 ValHiR = legalizeToVar(hiOperand(Val)); 2094 ValHiR = legalizeToReg(hiOperand(Val));
2095 } else { 2095 } else {
2096 ValLoR = legalizeToVar(Val); 2096 ValLoR = legalizeToReg(Val);
2097 } 2097 }
2098 lowerCLZ(Instr->getDest(), ValLoR, ValHiR); 2098 lowerCLZ(Instr->getDest(), ValLoR, ValHiR);
2099 return; 2099 return;
2100 } 2100 }
2101 case Intrinsics::Cttz: { 2101 case Intrinsics::Cttz: {
2102 // Essentially like Clz, but reverse the bits first. 2102 // Essentially like Clz, but reverse the bits first.
2103 Operand *Val = Instr->getArg(0); 2103 Operand *Val = Instr->getArg(0);
2104 Variable *ValLoR; 2104 Variable *ValLoR;
2105 Variable *ValHiR = nullptr; 2105 Variable *ValHiR = nullptr;
2106 if (Val->getType() == IceType_i64) { 2106 if (Val->getType() == IceType_i64) {
2107 Val = legalizeUndef(Val); 2107 Val = legalizeUndef(Val);
2108 ValLoR = legalizeToVar(loOperand(Val)); 2108 ValLoR = legalizeToReg(loOperand(Val));
2109 ValHiR = legalizeToVar(hiOperand(Val)); 2109 ValHiR = legalizeToReg(hiOperand(Val));
2110 Variable *TLo = makeReg(IceType_i32); 2110 Variable *TLo = makeReg(IceType_i32);
2111 Variable *THi = makeReg(IceType_i32); 2111 Variable *THi = makeReg(IceType_i32);
2112 _rbit(TLo, ValLoR); 2112 _rbit(TLo, ValLoR);
2113 _rbit(THi, ValHiR); 2113 _rbit(THi, ValHiR);
2114 ValLoR = THi; 2114 ValLoR = THi;
2115 ValHiR = TLo; 2115 ValHiR = TLo;
2116 } else { 2116 } else {
2117 ValLoR = legalizeToVar(Val); 2117 ValLoR = legalizeToReg(Val);
2118 Variable *T = makeReg(IceType_i32); 2118 Variable *T = makeReg(IceType_i32);
2119 _rbit(T, ValLoR); 2119 _rbit(T, ValLoR);
2120 ValLoR = T; 2120 ValLoR = T;
2121 } 2121 }
2122 lowerCLZ(Instr->getDest(), ValLoR, ValHiR); 2122 lowerCLZ(Instr->getDest(), ValLoR, ValHiR);
2123 return; 2123 return;
2124 } 2124 }
2125 case Intrinsics::Fabs: { 2125 case Intrinsics::Fabs: {
2126 UnimplementedError(Func->getContext()->getFlags()); 2126 UnimplementedError(Func->getContext()->getFlags());
2127 return; 2127 return;
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
2265 void TargetARM32::lowerPhi(const InstPhi * /*Inst*/) { 2265 void TargetARM32::lowerPhi(const InstPhi * /*Inst*/) {
2266 Func->setError("Phi found in regular instruction list"); 2266 Func->setError("Phi found in regular instruction list");
2267 } 2267 }
2268 2268
2269 void TargetARM32::lowerRet(const InstRet *Inst) { 2269 void TargetARM32::lowerRet(const InstRet *Inst) {
2270 Variable *Reg = nullptr; 2270 Variable *Reg = nullptr;
2271 if (Inst->hasRetValue()) { 2271 if (Inst->hasRetValue()) {
2272 Operand *Src0 = Inst->getRetValue(); 2272 Operand *Src0 = Inst->getRetValue();
2273 if (Src0->getType() == IceType_i64) { 2273 if (Src0->getType() == IceType_i64) {
2274 Src0 = legalizeUndef(Src0); 2274 Src0 = legalizeUndef(Src0);
2275 Variable *R0 = legalizeToVar(loOperand(Src0), RegARM32::Reg_r0); 2275 Variable *R0 = legalizeToReg(loOperand(Src0), RegARM32::Reg_r0);
2276 Variable *R1 = legalizeToVar(hiOperand(Src0), RegARM32::Reg_r1); 2276 Variable *R1 = legalizeToReg(hiOperand(Src0), RegARM32::Reg_r1);
2277 Reg = R0; 2277 Reg = R0;
2278 Context.insert(InstFakeUse::create(Func, R1)); 2278 Context.insert(InstFakeUse::create(Func, R1));
2279 } else if (isScalarFloatingType(Src0->getType())) { 2279 } else if (isScalarFloatingType(Src0->getType())) {
2280 UnimplementedError(Func->getContext()->getFlags()); 2280 UnimplementedError(Func->getContext()->getFlags());
2281 } else if (isVectorType(Src0->getType())) { 2281 } else if (isVectorType(Src0->getType())) {
2282 UnimplementedError(Func->getContext()->getFlags()); 2282 UnimplementedError(Func->getContext()->getFlags());
2283 } else { 2283 } else {
2284 Operand *Src0F = legalize(Src0, Legal_Reg | Legal_Flex); 2284 Operand *Src0F = legalize(Src0, Legal_Reg | Legal_Flex);
2285 _mov(Reg, Src0F, CondARM32::AL, RegARM32::Reg_r0); 2285 _mov(Reg, Src0F, CondARM32::AL, RegARM32::Reg_r0);
2286 } 2286 }
(...skipping 23 matching lines...) Expand all
2310 if (isVectorType(DestTy)) { 2310 if (isVectorType(DestTy)) {
2311 UnimplementedError(Func->getContext()->getFlags()); 2311 UnimplementedError(Func->getContext()->getFlags());
2312 return; 2312 return;
2313 } 2313 }
2314 if (isFloatingType(DestTy)) { 2314 if (isFloatingType(DestTy)) {
2315 UnimplementedError(Func->getContext()->getFlags()); 2315 UnimplementedError(Func->getContext()->getFlags());
2316 return; 2316 return;
2317 } 2317 }
2318 // TODO(jvoung): handle folding opportunities. 2318 // TODO(jvoung): handle folding opportunities.
2319 // cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t 2319 // cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t
2320 Variable *CmpOpnd0 = legalizeToVar(Condition); 2320 Variable *CmpOpnd0 = legalizeToReg(Condition);
2321 Operand *CmpOpnd1 = Ctx->getConstantZero(IceType_i32); 2321 Operand *CmpOpnd1 = Ctx->getConstantZero(IceType_i32);
2322 _cmp(CmpOpnd0, CmpOpnd1); 2322 _cmp(CmpOpnd0, CmpOpnd1);
2323 CondARM32::Cond Cond = CondARM32::NE; 2323 CondARM32::Cond Cond = CondARM32::NE;
2324 if (DestTy == IceType_i64) { 2324 if (DestTy == IceType_i64) {
2325 SrcT = legalizeUndef(SrcT); 2325 SrcT = legalizeUndef(SrcT);
2326 SrcF = legalizeUndef(SrcF); 2326 SrcF = legalizeUndef(SrcF);
2327 // Set the low portion. 2327 // Set the low portion.
2328 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2328 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2329 Variable *TLo = nullptr; 2329 Variable *TLo = nullptr;
2330 Operand *SrcFLo = legalize(loOperand(SrcF), Legal_Reg | Legal_Flex); 2330 Operand *SrcFLo = legalize(loOperand(SrcF), Legal_Reg | Legal_Flex);
(...skipping 20 matching lines...) Expand all
2351 } 2351 }
2352 2352
2353 void TargetARM32::lowerStore(const InstStore *Inst) { 2353 void TargetARM32::lowerStore(const InstStore *Inst) {
2354 Operand *Value = Inst->getData(); 2354 Operand *Value = Inst->getData();
2355 Operand *Addr = Inst->getAddr(); 2355 Operand *Addr = Inst->getAddr();
2356 OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType()); 2356 OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType());
2357 Type Ty = NewAddr->getType(); 2357 Type Ty = NewAddr->getType();
2358 2358
2359 if (Ty == IceType_i64) { 2359 if (Ty == IceType_i64) {
2360 Value = legalizeUndef(Value); 2360 Value = legalizeUndef(Value);
2361 Variable *ValueHi = legalizeToVar(hiOperand(Value)); 2361 Variable *ValueHi = legalizeToReg(hiOperand(Value));
2362 Variable *ValueLo = legalizeToVar(loOperand(Value)); 2362 Variable *ValueLo = legalizeToReg(loOperand(Value));
2363 _str(ValueHi, llvm::cast<OperandARM32Mem>(hiOperand(NewAddr))); 2363 _str(ValueHi, llvm::cast<OperandARM32Mem>(hiOperand(NewAddr)));
2364 _str(ValueLo, llvm::cast<OperandARM32Mem>(loOperand(NewAddr))); 2364 _str(ValueLo, llvm::cast<OperandARM32Mem>(loOperand(NewAddr)));
2365 } else if (isVectorType(Ty)) { 2365 } else if (isVectorType(Ty)) {
2366 UnimplementedError(Func->getContext()->getFlags()); 2366 UnimplementedError(Func->getContext()->getFlags());
2367 } else { 2367 } else {
2368 Variable *ValueR = legalizeToVar(Value); 2368 Variable *ValueR = legalizeToReg(Value);
2369 _str(ValueR, NewAddr); 2369 _str(ValueR, NewAddr);
2370 } 2370 }
2371 } 2371 }
2372 2372
2373 void TargetARM32::doAddressOptStore() { 2373 void TargetARM32::doAddressOptStore() {
2374 UnimplementedError(Func->getContext()->getFlags()); 2374 UnimplementedError(Func->getContext()->getFlags());
2375 } 2375 }
2376 2376
2377 void TargetARM32::lowerSwitch(const InstSwitch *Inst) { 2377 void TargetARM32::lowerSwitch(const InstSwitch *Inst) {
2378 // This implements the most naive possible lowering. 2378 // This implements the most naive possible lowering.
2379 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default 2379 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default
2380 Operand *Src0 = Inst->getComparison(); 2380 Operand *Src0 = Inst->getComparison();
2381 SizeT NumCases = Inst->getNumCases(); 2381 SizeT NumCases = Inst->getNumCases();
2382 if (Src0->getType() == IceType_i64) { 2382 if (Src0->getType() == IceType_i64) {
2383 Src0 = legalizeUndef(Src0); 2383 Src0 = legalizeUndef(Src0);
2384 Variable *Src0Lo = legalizeToVar(loOperand(Src0)); 2384 Variable *Src0Lo = legalizeToReg(loOperand(Src0));
2385 Variable *Src0Hi = legalizeToVar(hiOperand(Src0)); 2385 Variable *Src0Hi = legalizeToReg(hiOperand(Src0));
2386 for (SizeT I = 0; I < NumCases; ++I) { 2386 for (SizeT I = 0; I < NumCases; ++I) {
2387 Operand *ValueLo = Ctx->getConstantInt32(Inst->getValue(I)); 2387 Operand *ValueLo = Ctx->getConstantInt32(Inst->getValue(I));
2388 Operand *ValueHi = Ctx->getConstantInt32(Inst->getValue(I) >> 32); 2388 Operand *ValueHi = Ctx->getConstantInt32(Inst->getValue(I) >> 32);
2389 ValueLo = legalize(ValueLo, Legal_Reg | Legal_Flex); 2389 ValueLo = legalize(ValueLo, Legal_Reg | Legal_Flex);
2390 ValueHi = legalize(ValueHi, Legal_Reg | Legal_Flex); 2390 ValueHi = legalize(ValueHi, Legal_Reg | Legal_Flex);
2391 _cmp(Src0Lo, ValueLo); 2391 _cmp(Src0Lo, ValueLo);
2392 _cmp(Src0Hi, ValueHi, CondARM32::EQ); 2392 _cmp(Src0Hi, ValueHi, CondARM32::EQ);
2393 _br(Inst->getLabel(I), CondARM32::EQ); 2393 _br(Inst->getLabel(I), CondARM32::EQ);
2394 } 2394 }
2395 _br(Inst->getLabelDefault()); 2395 _br(Inst->getLabelDefault());
2396 return; 2396 return;
2397 } 2397 }
2398 2398
2399 // 32 bit integer 2399 // 32 bit integer
2400 Variable *Src0Var = legalizeToVar(Src0); 2400 Variable *Src0Var = legalizeToReg(Src0);
2401 for (SizeT I = 0; I < NumCases; ++I) { 2401 for (SizeT I = 0; I < NumCases; ++I) {
2402 Operand *Value = Ctx->getConstantInt32(Inst->getValue(I)); 2402 Operand *Value = Ctx->getConstantInt32(Inst->getValue(I));
2403 Value = legalize(Value, Legal_Reg | Legal_Flex); 2403 Value = legalize(Value, Legal_Reg | Legal_Flex);
2404 _cmp(Src0Var, Value); 2404 _cmp(Src0Var, Value);
2405 _br(Inst->getLabel(I), CondARM32::EQ); 2405 _br(Inst->getLabel(I), CondARM32::EQ);
2406 } 2406 }
2407 _br(Inst->getLabelDefault()); 2407 _br(Inst->getLabelDefault());
2408 } 2408 }
2409 2409
2410 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Inst*/) { 2410 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Inst*/) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 // (e.g., OperandARM32Mem and !Legal_Mem), we can always copy 2458 // (e.g., OperandARM32Mem and !Legal_Mem), we can always copy
2459 // to a register. 2459 // to a register.
2460 if (auto Mem = llvm::dyn_cast<OperandARM32Mem>(From)) { 2460 if (auto Mem = llvm::dyn_cast<OperandARM32Mem>(From)) {
2461 // Before doing anything with a Mem operand, we need to ensure 2461 // Before doing anything with a Mem operand, we need to ensure
2462 // that the Base and Index components are in physical registers. 2462 // that the Base and Index components are in physical registers.
2463 Variable *Base = Mem->getBase(); 2463 Variable *Base = Mem->getBase();
2464 Variable *Index = Mem->getIndex(); 2464 Variable *Index = Mem->getIndex();
2465 Variable *RegBase = nullptr; 2465 Variable *RegBase = nullptr;
2466 Variable *RegIndex = nullptr; 2466 Variable *RegIndex = nullptr;
2467 if (Base) { 2467 if (Base) {
2468 RegBase = legalizeToVar(Base); 2468 RegBase = legalizeToReg(Base);
2469 } 2469 }
2470 if (Index) { 2470 if (Index) {
2471 RegIndex = legalizeToVar(Index); 2471 RegIndex = legalizeToReg(Index);
2472 } 2472 }
2473 // Create a new operand if there was a change. 2473 // Create a new operand if there was a change.
2474 if (Base != RegBase || Index != RegIndex) { 2474 if (Base != RegBase || Index != RegIndex) {
2475 // There is only a reg +/- reg or reg + imm form. 2475 // There is only a reg +/- reg or reg + imm form.
2476 // Figure out which to re-create. 2476 // Figure out which to re-create.
2477 if (Mem->isRegReg()) { 2477 if (Mem->isRegReg()) {
2478 Mem = OperandARM32Mem::create(Func, Ty, RegBase, RegIndex, 2478 Mem = OperandARM32Mem::create(Func, Ty, RegBase, RegIndex,
2479 Mem->getShiftOp(), Mem->getShiftAmt(), 2479 Mem->getShiftOp(), Mem->getShiftAmt(),
2480 Mem->getAddrMode()); 2480 Mem->getAddrMode());
2481 } else { 2481 } else {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2576 From = copyToReg(From, RegNum); 2576 From = copyToReg(From, RegNum);
2577 } 2577 }
2578 return From; 2578 return From;
2579 } 2579 }
2580 llvm_unreachable("Unhandled operand kind in legalize()"); 2580 llvm_unreachable("Unhandled operand kind in legalize()");
2581 2581
2582 return From; 2582 return From;
2583 } 2583 }
2584 2584
2585 /// Provide a trivial wrapper to legalize() for this common usage. 2585 /// Provide a trivial wrapper to legalize() for this common usage.
2586 Variable *TargetARM32::legalizeToVar(Operand *From, int32_t RegNum) { 2586 Variable *TargetARM32::legalizeToReg(Operand *From, int32_t RegNum) {
2587 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); 2587 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum));
2588 } 2588 }
2589 2589
2590 /// Legalize undef values to concrete values. 2590 /// Legalize undef values to concrete values.
2591 Operand *TargetARM32::legalizeUndef(Operand *From, int32_t RegNum) { 2591 Operand *TargetARM32::legalizeUndef(Operand *From, int32_t RegNum) {
2592 Type Ty = From->getType(); 2592 Type Ty = From->getType();
2593 if (llvm::isa<ConstantUndef>(From)) { 2593 if (llvm::isa<ConstantUndef>(From)) {
2594 // Lower undefs to zero. Another option is to lower undefs to an 2594 // Lower undefs to zero. Another option is to lower undefs to an
2595 // uninitialized register; however, using an uninitialized register 2595 // uninitialized register; however, using an uninitialized register
2596 // results in less predictable code. 2596 // results in less predictable code.
(...skipping 16 matching lines...) Expand all
2613 OperandARM32Mem *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand); 2613 OperandARM32Mem *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand);
2614 // It may be the case that address mode optimization already creates 2614 // It may be the case that address mode optimization already creates
2615 // an OperandARM32Mem, so in that case it wouldn't need another level 2615 // an OperandARM32Mem, so in that case it wouldn't need another level
2616 // of transformation. 2616 // of transformation.
2617 if (Mem) { 2617 if (Mem) {
2618 return llvm::cast<OperandARM32Mem>(legalize(Mem)); 2618 return llvm::cast<OperandARM32Mem>(legalize(Mem));
2619 } 2619 }
2620 // If we didn't do address mode optimization, then we only 2620 // If we didn't do address mode optimization, then we only
2621 // have a base/offset to work with. ARM always requires a base 2621 // have a base/offset to work with. ARM always requires a base
2622 // register, so just use that to hold the operand. 2622 // register, so just use that to hold the operand.
2623 Variable *Base = legalizeToVar(Operand); 2623 Variable *Base = legalizeToReg(Operand);
2624 return OperandARM32Mem::create( 2624 return OperandARM32Mem::create(
2625 Func, Ty, Base, 2625 Func, Ty, Base,
2626 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))); 2626 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32)));
2627 } 2627 }
2628 2628
2629 Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) { 2629 Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) {
2630 // There aren't any 64-bit integer registers for ARM32. 2630 // There aren't any 64-bit integer registers for ARM32.
2631 assert(Type != IceType_i64); 2631 assert(Type != IceType_i64);
2632 Variable *Reg = Func->makeVariable(Type); 2632 Variable *Reg = Func->makeVariable(Type);
2633 if (RegNum == Variable::NoRegister) 2633 if (RegNum == Variable::NoRegister)
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2764 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; 2764 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n";
2765 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { 2765 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) {
2766 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; 2766 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n";
2767 } 2767 }
2768 // Technically R9 is used for TLS with Sandboxing, and we reserve it. 2768 // Technically R9 is used for TLS with Sandboxing, and we reserve it.
2769 // However, for compatibility with current NaCl LLVM, don't claim that. 2769 // However, for compatibility with current NaCl LLVM, don't claim that.
2770 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 2770 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
2771 } 2771 }
2772 2772
2773 } // end of namespace Ice 2773 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringX86Base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698