OLD | NEW |
---|---|
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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 static_assert( \ | 116 static_assert( \ |
117 _table1_##tag == _table2_##tag, \ | 117 _table1_##tag == _table2_##tag, \ |
118 "Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE"); | 118 "Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE"); |
119 ICEINSTICMP_TABLE | 119 ICEINSTICMP_TABLE |
120 #undef X | 120 #undef X |
121 } // end of namespace dummy1 | 121 } // end of namespace dummy1 |
122 | 122 |
123 // The maximum number of arguments to pass in GPR registers. | 123 // The maximum number of arguments to pass in GPR registers. |
124 const uint32_t ARM32_MAX_GPR_ARG = 4; | 124 const uint32_t ARM32_MAX_GPR_ARG = 4; |
125 | 125 |
126 // Stack alignment | |
127 const uint32_t ARM32_STACK_ALIGNMENT_BYTES = 16; | |
128 | |
126 } // end of anonymous namespace | 129 } // end of anonymous namespace |
127 | 130 |
128 TargetARM32::TargetARM32(Cfg *Func) | 131 TargetARM32::TargetARM32(Cfg *Func) |
129 : TargetLowering(Func), UsesFramePointer(false) { | 132 : TargetLowering(Func), UsesFramePointer(false) { |
130 // TODO: Don't initialize IntegerRegisters and friends every time. | 133 // TODO: Don't initialize IntegerRegisters and friends every time. |
131 // Instead, initialize in some sort of static initializer for the | 134 // Instead, initialize in some sort of static initializer for the |
132 // class. | 135 // class. |
133 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); | 136 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); |
134 llvm::SmallBitVector FloatRegisters(RegARM32::Reg_NUM); | 137 llvm::SmallBitVector FloatRegisters(RegARM32::Reg_NUM); |
135 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); | 138 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
600 } | 603 } |
601 | 604 |
602 void TargetARM32::lowerAlloca(const InstAlloca *Inst) { | 605 void TargetARM32::lowerAlloca(const InstAlloca *Inst) { |
603 UsesFramePointer = true; | 606 UsesFramePointer = true; |
604 // Conservatively require the stack to be aligned. Some stack | 607 // Conservatively require the stack to be aligned. Some stack |
605 // adjustment operations implemented below assume that the stack is | 608 // adjustment operations implemented below assume that the stack is |
606 // aligned before the alloca. All the alloca code ensures that the | 609 // aligned before the alloca. All the alloca code ensures that the |
607 // stack alignment is preserved after the alloca. The stack alignment | 610 // stack alignment is preserved after the alloca. The stack alignment |
608 // restriction can be relaxed in some cases. | 611 // restriction can be relaxed in some cases. |
609 NeedsStackAlignment = true; | 612 NeedsStackAlignment = true; |
610 (void)Inst; | 613 |
611 UnimplementedError(Func->getContext()->getFlags()); | 614 // TODO(sehr,stichnot): minimize the number of adjustments of SP, etc. |
Jim Stichnoth
2015/05/26 16:58:55
Can probably remove sehr... :)
jvoung (off chromium)
2015/05/26 20:53:46
Done -- darn =)
| |
615 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); | |
616 Variable *Dest = Inst->getDest(); | |
617 uint32_t AlignmentParam = Inst->getAlignInBytes(); | |
618 // For default align=0, set it to the real value 1, to avoid any | |
619 // bit-manipulation problems below. | |
620 AlignmentParam = std::max(AlignmentParam, 1u); | |
621 | |
622 // LLVM enforces power of 2 alignment. | |
623 assert(llvm::isPowerOf2_32(AlignmentParam)); | |
624 assert(llvm::isPowerOf2_32(ARM32_STACK_ALIGNMENT_BYTES)); | |
625 | |
626 uint32_t Alignment = std::max(AlignmentParam, ARM32_STACK_ALIGNMENT_BYTES); | |
627 if (Alignment > ARM32_STACK_ALIGNMENT_BYTES) { | |
628 alignRegisterPow2(SP, Alignment); | |
629 } | |
630 Operand *TotalSize = Inst->getSizeInBytes(); | |
631 if (ConstantInteger32 *ConstantTotalSize = | |
Jim Stichnoth
2015/05/26 16:58:55
const auto *ConstantTotalSize
?
jvoung (off chromium)
2015/05/26 20:53:46
Done.
| |
632 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { | |
633 uint32_t Value = ConstantTotalSize->getValue(); | |
634 Value = Utils::applyAlignment(Value, Alignment); | |
635 Operand *SubAmount = legalize(Ctx->getConstantInt32(Value)); | |
636 _sub(SP, SP, SubAmount); | |
637 } else { | |
638 // Non-constant sizes need to be adjusted to the next highest | |
639 // multiple of the required alignment at runtime. | |
640 TotalSize = legalize(TotalSize); | |
641 Variable *T = makeReg(IceType_i32); | |
642 _mov(T, TotalSize); | |
643 Operand *AddAmount = legalize(Ctx->getConstantInt32(Alignment - 1)); | |
644 _add(T, T, AddAmount); | |
645 alignRegisterPow2(T, Alignment); | |
646 _sub(SP, SP, T); | |
647 } | |
648 _mov(Dest, SP); | |
612 } | 649 } |
613 | 650 |
614 void TargetARM32::lowerArithmetic(const InstArithmetic *Inst) { | 651 void TargetARM32::lowerArithmetic(const InstArithmetic *Inst) { |
615 Variable *Dest = Inst->getDest(); | 652 Variable *Dest = Inst->getDest(); |
616 // TODO(jvoung): Should be able to flip Src0 and Src1 if it is easier | 653 // TODO(jvoung): Should be able to flip Src0 and Src1 if it is easier |
617 // to legalize Src0 to flex or Src1 to flex and there is a reversible | 654 // to legalize Src0 to flex or Src1 to flex and there is a reversible |
618 // instruction. E.g., reverse subtract with immediate, register vs | 655 // instruction. E.g., reverse subtract with immediate, register vs |
619 // register, immediate. | 656 // register, immediate. |
620 // Or it may be the case that the operands aren't swapped, but the | 657 // Or it may be the case that the operands aren't swapped, but the |
621 // bits can be flipped and a different operation applied. | 658 // bits can be flipped and a different operation applied. |
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1521 // There aren't any 64-bit integer registers for ARM32. | 1558 // There aren't any 64-bit integer registers for ARM32. |
1522 assert(Type != IceType_i64); | 1559 assert(Type != IceType_i64); |
1523 Variable *Reg = Func->makeVariable(Type); | 1560 Variable *Reg = Func->makeVariable(Type); |
1524 if (RegNum == Variable::NoRegister) | 1561 if (RegNum == Variable::NoRegister) |
1525 Reg->setWeightInfinite(); | 1562 Reg->setWeightInfinite(); |
1526 else | 1563 else |
1527 Reg->setRegNum(RegNum); | 1564 Reg->setRegNum(RegNum); |
1528 return Reg; | 1565 return Reg; |
1529 } | 1566 } |
1530 | 1567 |
1568 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align) { | |
1569 assert(llvm::isPowerOf2_32(Align)); | |
1570 uint32_t RotateAmt = 0; | |
1571 uint32_t Immed_8; | |
1572 Operand *Mask; | |
1573 // Use AND or BIC to mask off the bits, depending on which immediate fits | |
1574 // (if it fits at all). Assume Align is usually small, in which case BIC | |
1575 // works better. | |
1576 if (OperandARM32FlexImm::canHoldImm(Align - 1, &RotateAmt, &Immed_8)) { | |
1577 Mask = legalize(Ctx->getConstantInt32(Align - 1), Legal_Reg | Legal_Flex); | |
1578 _bic(Reg, Reg, Mask); | |
1579 } else { | |
1580 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex); | |
1581 _and(Reg, Reg, Mask); | |
1582 } | |
1583 } | |
1584 | |
1531 void TargetARM32::postLower() { | 1585 void TargetARM32::postLower() { |
1532 if (Ctx->getFlags().getOptLevel() == Opt_m1) | 1586 if (Ctx->getFlags().getOptLevel() == Opt_m1) |
1533 return; | 1587 return; |
1534 inferTwoAddress(); | 1588 inferTwoAddress(); |
1535 } | 1589 } |
1536 | 1590 |
1537 void TargetARM32::makeRandomRegisterPermutation( | 1591 void TargetARM32::makeRandomRegisterPermutation( |
1538 llvm::SmallVectorImpl<int32_t> &Permutation, | 1592 llvm::SmallVectorImpl<int32_t> &Permutation, |
1539 const llvm::SmallBitVector &ExcludeRegisters) const { | 1593 const llvm::SmallBitVector &ExcludeRegisters) const { |
1540 (void)Permutation; | 1594 (void)Permutation; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1595 } | 1649 } |
1596 } | 1650 } |
1597 | 1651 |
1598 void TargetDataARM32::lowerConstants() const { | 1652 void TargetDataARM32::lowerConstants() const { |
1599 if (Ctx->getFlags().getDisableTranslation()) | 1653 if (Ctx->getFlags().getDisableTranslation()) |
1600 return; | 1654 return; |
1601 UnimplementedError(Ctx->getFlags()); | 1655 UnimplementedError(Ctx->getFlags()); |
1602 } | 1656 } |
1603 | 1657 |
1604 } // end of namespace Ice | 1658 } // end of namespace Ice |
OLD | NEW |