| OLD | NEW |
| 1 // | 1 // |
| 2 // The Subzero Code Generator | 2 // The Subzero Code Generator |
| 3 // | 3 // |
| 4 // This file is distributed under the University of Illinois Open Source | 4 // This file is distributed under the University of Illinois Open Source |
| 5 // License. See LICENSE.TXT for details. | 5 // License. See LICENSE.TXT for details. |
| 6 // | 6 // |
| 7 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
| 8 /// | 8 /// |
| 9 /// \file | 9 /// \file |
| 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost | 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost |
| (...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 // used registers -- and their aliases. Then, we figure out which GPR | 783 // used registers -- and their aliases. Then, we figure out which GPR |
| 784 // registers should be saved. | 784 // registers should be saved. |
| 785 SmallBitVector ToPreserve(RegMIPS32::Reg_NUM); | 785 SmallBitVector ToPreserve(RegMIPS32::Reg_NUM); |
| 786 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { | 786 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { |
| 787 if (CalleeSaves[i] && RegsUsed[i]) { | 787 if (CalleeSaves[i] && RegsUsed[i]) { |
| 788 ToPreserve |= RegisterAliases[i]; | 788 ToPreserve |= RegisterAliases[i]; |
| 789 } | 789 } |
| 790 } | 790 } |
| 791 | 791 |
| 792 uint32_t NumCallee = 0; | 792 uint32_t NumCallee = 0; |
| 793 size_t PreservedRegsSizeBytes = 0; | |
| 794 | 793 |
| 795 // RegClasses is a tuple of | 794 // RegClasses is a tuple of |
| 796 // | 795 // |
| 797 // <First Register in Class, Last Register in Class, Vector of Save Registers> | 796 // <First Register in Class, Last Register in Class, Vector of Save Registers> |
| 798 // | 797 // |
| 799 // We use this tuple to figure out which register we should save/restore | 798 // We use this tuple to figure out which register we should save/restore |
| 800 // during | 799 // during |
| 801 // prolog/epilog. | 800 // prolog/epilog. |
| 802 using RegClassType = std::tuple<uint32_t, uint32_t, VarList *>; | 801 using RegClassType = std::tuple<uint32_t, uint32_t, VarList *>; |
| 803 const RegClassType RegClass = RegClassType( | 802 const RegClassType RegClass = RegClassType( |
| (...skipping 24 matching lines...) Expand all Loading... |
| 828 uint32_t SpillAreaPaddingBytes = 0; | 827 uint32_t SpillAreaPaddingBytes = 0; |
| 829 uint32_t LocalsSlotsPaddingBytes = 0; | 828 uint32_t LocalsSlotsPaddingBytes = 0; |
| 830 alignStackSpillAreas(PreservedRegsSizeBytes, SpillAreaAlignmentBytes, | 829 alignStackSpillAreas(PreservedRegsSizeBytes, SpillAreaAlignmentBytes, |
| 831 GlobalsSize, LocalsSlotsAlignmentBytes, | 830 GlobalsSize, LocalsSlotsAlignmentBytes, |
| 832 &SpillAreaPaddingBytes, &LocalsSlotsPaddingBytes); | 831 &SpillAreaPaddingBytes, &LocalsSlotsPaddingBytes); |
| 833 SpillAreaSizeBytes += SpillAreaPaddingBytes + LocalsSlotsPaddingBytes; | 832 SpillAreaSizeBytes += SpillAreaPaddingBytes + LocalsSlotsPaddingBytes; |
| 834 uint32_t GlobalsAndSubsequentPaddingSize = | 833 uint32_t GlobalsAndSubsequentPaddingSize = |
| 835 GlobalsSize + LocalsSlotsPaddingBytes; | 834 GlobalsSize + LocalsSlotsPaddingBytes; |
| 836 | 835 |
| 837 // Adds the out args space to the stack, and align SP if necessary. | 836 // Adds the out args space to the stack, and align SP if necessary. |
| 838 uint32_t TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes + | 837 TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes + |
| 839 FixedAllocaSizeBytes + MaxOutArgsSizeBytes; | 838 FixedAllocaSizeBytes + MaxOutArgsSizeBytes; |
| 840 | 839 |
| 841 // Generate "addiu sp, sp, -TotalStackSizeBytes" | 840 // Generate "addiu sp, sp, -TotalStackSizeBytes" |
| 842 if (TotalStackSizeBytes) { | 841 if (TotalStackSizeBytes) { |
| 843 // Use the scratch register if needed to legalize the immediate. | 842 // Use the scratch register if needed to legalize the immediate. |
| 844 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 843 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
| 845 _addiu(SP, SP, -(TotalStackSizeBytes)); | 844 _addiu(SP, SP, -(TotalStackSizeBytes)); |
| 846 } | 845 } |
| 847 | 846 |
| 848 Ctx->statsUpdateFrameBytes(TotalStackSizeBytes); | 847 Ctx->statsUpdateFrameBytes(TotalStackSizeBytes); |
| 849 | 848 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 << " spill area alignment = " << SpillAreaAlignmentBytes << " bytes\n" | 918 << " spill area alignment = " << SpillAreaAlignmentBytes << " bytes\n" |
| 920 << " outgoing args size = " << MaxOutArgsSizeBytes << " bytes\n" | 919 << " outgoing args size = " << MaxOutArgsSizeBytes << " bytes\n" |
| 921 << " locals spill area alignment = " << LocalsSlotsAlignmentBytes | 920 << " locals spill area alignment = " << LocalsSlotsAlignmentBytes |
| 922 << " bytes\n" | 921 << " bytes\n" |
| 923 << " is FP based = " << 1 << "\n"; | 922 << " is FP based = " << 1 << "\n"; |
| 924 } | 923 } |
| 925 return; | 924 return; |
| 926 } | 925 } |
| 927 | 926 |
| 928 void TargetMIPS32::addEpilog(CfgNode *Node) { | 927 void TargetMIPS32::addEpilog(CfgNode *Node) { |
| 929 (void)Node; | 928 InstList &Insts = Node->getInsts(); |
| 929 InstList::reverse_iterator RI, E; |
| 930 for (RI = Insts.rbegin(), E = Insts.rend(); RI != E; ++RI) { |
| 931 if (llvm::isa<InstMIPS32Ret>(*RI)) |
| 932 break; |
| 933 } |
| 934 if (RI == E) |
| 935 return; |
| 936 |
| 937 // Convert the reverse_iterator position into its corresponding (forward) |
| 938 // iterator position. |
| 939 InstList::iterator InsertPoint = RI.base(); |
| 940 --InsertPoint; |
| 941 Context.init(Node); |
| 942 Context.setInsertPoint(InsertPoint); |
| 943 |
| 944 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
| 945 if (UsesFramePointer) { |
| 946 Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP); |
| 947 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake |
| 948 // use of SP before the assignment of SP=FP keeps previous SP adjustments |
| 949 // from being dead-code eliminated. |
| 950 Context.insert<InstFakeUse>(SP); |
| 951 _mov(SP, FP); |
| 952 } |
| 953 |
| 954 VarList::reverse_iterator RIter, END; |
| 955 |
| 956 if (!PreservedGPRs.empty()) { |
| 957 uint32_t StackOffset = TotalStackSizeBytes - PreservedRegsSizeBytes; |
| 958 for (RIter = PreservedGPRs.rbegin(), END = PreservedGPRs.rend(); |
| 959 RIter != END; ++RIter) { |
| 960 Variable *PhysicalRegister = getPhysicalRegister((*RIter)->getRegNum()); |
| 961 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
| 962 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( |
| 963 Func, IceType_i32, SP, |
| 964 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); |
| 965 _lw(PhysicalRegister, MemoryLocation); |
| 966 StackOffset += typeWidthInBytesOnStack(PhysicalRegister->getType()); |
| 967 } |
| 968 } |
| 969 |
| 970 if (TotalStackSizeBytes) { |
| 971 _addiu(SP, SP, TotalStackSizeBytes); |
| 972 } |
| 973 |
| 930 return; | 974 return; |
| 931 UnimplementedError(getFlags()); | |
| 932 } | 975 } |
| 933 | 976 |
| 934 Operand *TargetMIPS32::loOperand(Operand *Operand) { | 977 Operand *TargetMIPS32::loOperand(Operand *Operand) { |
| 935 assert(Operand->getType() == IceType_i64); | 978 assert(Operand->getType() == IceType_i64); |
| 936 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand)) | 979 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand)) |
| 937 return Var64On32->getLo(); | 980 return Var64On32->getLo(); |
| 938 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { | 981 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { |
| 939 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())); | 982 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())); |
| 940 } | 983 } |
| 941 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) { | 984 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) { |
| (...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2285 Str << "\t.set\t" | 2328 Str << "\t.set\t" |
| 2286 << "nomips16\n"; | 2329 << "nomips16\n"; |
| 2287 } | 2330 } |
| 2288 | 2331 |
| 2289 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 2332 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 2290 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 2333 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 2291 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 2334 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 2292 | 2335 |
| 2293 } // end of namespace MIPS32 | 2336 } // end of namespace MIPS32 |
| 2294 } // end of namespace Ice | 2337 } // end of namespace Ice |
| OLD | NEW |