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 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 GPRegsUsed |= RegisterAliases[*Reg]; | 552 GPRegsUsed |= RegisterAliases[*Reg]; |
553 return true; | 553 return true; |
554 } | 554 } |
555 | 555 |
556 inline void TargetMIPS32::CallingConv::discardNextGPRAndItsAliases( | 556 inline void TargetMIPS32::CallingConv::discardNextGPRAndItsAliases( |
557 CfgVector<RegNumT> *Regs) { | 557 CfgVector<RegNumT> *Regs) { |
558 GPRegsUsed |= RegisterAliases[Regs->back()]; | 558 GPRegsUsed |= RegisterAliases[Regs->back()]; |
559 Regs->pop_back(); | 559 Regs->pop_back(); |
560 } | 560 } |
561 | 561 |
| 562 inline void TargetMIPS32::CallingConv::alignGPR(CfgVector<RegNumT> *Regs) { |
| 563 if (Regs->back() == RegMIPS32::Reg_A1 || Regs->back() == RegMIPS32::Reg_A3) |
| 564 discardNextGPRAndItsAliases(Regs); |
| 565 } |
| 566 |
562 // GPR are not packed when passing parameters. Thus, a function foo(i32, i64, | 567 // GPR are not packed when passing parameters. Thus, a function foo(i32, i64, |
563 // i32) will have the first argument in a0, the second in a2-a3, and the third | 568 // i32) will have the first argument in a0, the second in a2-a3, and the third |
564 // on the stack. To model this behavior, whenever we pop a register from Regs, | 569 // on the stack. To model this behavior, whenever we pop a register from Regs, |
565 // we remove all of its aliases from the pool of available GPRs. This has the | 570 // we remove all of its aliases from the pool of available GPRs. This has the |
566 // effect of computing the "closure" on the GPR registers. | 571 // effect of computing the "closure" on the GPR registers. |
567 void TargetMIPS32::CallingConv::discardUnavailableGPRsAndTheirAliases( | 572 void TargetMIPS32::CallingConv::discardUnavailableGPRsAndTheirAliases( |
568 CfgVector<RegNumT> *Regs) { | 573 CfgVector<RegNumT> *Regs) { |
569 while (!Regs->empty() && GPRegsUsed[Regs->back()]) { | 574 while (!Regs->empty() && GPRegsUsed[Regs->back()]) { |
570 discardNextGPRAndItsAliases(Regs); | 575 discardNextGPRAndItsAliases(Regs); |
571 } | 576 } |
(...skipping 24 matching lines...) Expand all Loading... |
596 | 601 |
597 *Reg = Source->back(); | 602 *Reg = Source->back(); |
598 VFPRegsUsed |= RegisterAliases[*Reg]; | 603 VFPRegsUsed |= RegisterAliases[*Reg]; |
599 | 604 |
600 // In MIPS O32 abi if fun arguments are (f32, i32) then one can not use reg_a0 | 605 // In MIPS O32 abi if fun arguments are (f32, i32) then one can not use reg_a0 |
601 // for second argument even though it's free. f32 arg goes in reg_f12, i32 arg | 606 // for second argument even though it's free. f32 arg goes in reg_f12, i32 arg |
602 // goes in reg_a1. Similarly if arguments are (f64, i32) second argument goes | 607 // goes in reg_a1. Similarly if arguments are (f64, i32) second argument goes |
603 // in reg_a3 and a0, a1 are not used. | 608 // in reg_a3 and a0, a1 are not used. |
604 Source = &GPRArgs; | 609 Source = &GPRArgs; |
605 // Discard one GPR reg for f32(4 bytes), two for f64(4 + 4 bytes) | 610 // Discard one GPR reg for f32(4 bytes), two for f64(4 + 4 bytes) |
| 611 if (Ty == IceType_f64) { |
| 612 // In MIPS o32 abi, when we use GPR argument pairs to store F64 values, pair |
| 613 // must be aligned at even register. Similarly when we discard GPR registers |
| 614 // when some arguments from starting 16 bytes goes in FPR, we must take care |
| 615 // of alignment. For example if fun args are (f32, f64, f32), for first f32 |
| 616 // we discard a0, now for f64 argument, which will go in F14F15, we must |
| 617 // first align GPR vector to even register by discarding a1, then discard |
| 618 // two GPRs a2 and a3. Now last f32 argument will go on stack. |
| 619 alignGPR(Source); |
| 620 discardNextGPRAndItsAliases(Source); |
| 621 } |
606 discardNextGPRAndItsAliases(Source); | 622 discardNextGPRAndItsAliases(Source); |
607 if (Ty == IceType_f64) | |
608 discardNextGPRAndItsAliases(Source); | |
609 | |
610 return true; | 623 return true; |
611 } | 624 } |
612 | 625 |
613 void TargetMIPS32::CallingConv::discardUnavailableVFPRegsAndTheirAliases( | 626 void TargetMIPS32::CallingConv::discardUnavailableVFPRegsAndTheirAliases( |
614 CfgVector<RegNumT> *Regs) { | 627 CfgVector<RegNumT> *Regs) { |
615 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) { | 628 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) { |
616 Regs->pop_back(); | 629 Regs->pop_back(); |
617 } | 630 } |
618 } | 631 } |
619 | 632 |
(...skipping 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2328 Str << "\t.set\t" | 2341 Str << "\t.set\t" |
2329 << "nomips16\n"; | 2342 << "nomips16\n"; |
2330 } | 2343 } |
2331 | 2344 |
2332 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 2345 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
2333 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 2346 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
2334 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 2347 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
2335 | 2348 |
2336 } // end of namespace MIPS32 | 2349 } // end of namespace MIPS32 |
2337 } // end of namespace Ice | 2350 } // end of namespace Ice |
OLD | NEW |