llvm.org GIT mirror llvm / fcb25e6
Add an I64Regs register class for 64-bit registers. We are going to use the same registers for 32-bit and 64-bit values, but in two different register classes. The I64Regs register class has a larger spill size and alignment. The addition of an i64 register class confuses TableGen's type inference, so it is necessary to clarify the type of some immediates and the G0 register. In 64-bit mode, pointers are i64 and should use the I64Regs register class. Implement getPointerRegClass() to dynamically provide the pointer register class depending on the subtarget. Use ptr_rc and iPTR for memory operands. Finally, add the i64 type to the IntRegs register class. This register class is not used to hold i64 values, I64Regs is for that. The type is required to appease TableGen's type checking in output patterns like this: def : Pat<(add i64:$a, i64:$b), (ADDrr $a, $b)>; SPARC v9 uses the same ADDrr instruction for i32 and i64 additions, and TableGen doesn't know to check the type of register sub-classes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178522 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 6 years ago
6 changed file(s) with 37 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
688688
689689 SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
690690 : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
691 Subtarget = &TM.getSubtarget();
691692
692693 // Set up the register classes.
693694 addRegisterClass(MVT::i32, &SP::IntRegsRegClass);
694695 addRegisterClass(MVT::f32, &SP::FPRegsRegClass);
695696 addRegisterClass(MVT::f64, &SP::DFPRegsRegClass);
697 if (Subtarget->is64Bit())
698 addRegisterClass(MVT::i64, &SP::I64RegsRegClass);
696699
697700 // Turn FP extload into load/fextend
698701 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
1818 #include "llvm/Target/TargetLowering.h"
1919
2020 namespace llvm {
21 class SparcSubtarget;
22
2123 namespace SPISD {
2224 enum {
2325 FIRST_NUMBER = ISD::BUILTIN_OP_END,
4143 }
4244
4345 class SparcTargetLowering : public TargetLowering {
46 const SparcSubtarget *Subtarget;
4447 public:
4548 SparcTargetLowering(TargetMachine &TM);
4649 virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
6262 }], HI22>;
6363
6464 // Addressing modes.
65 def ADDRrr : ComplexPattern;
66 def ADDRri : ComplexPattern], []>;
65 def ADDRrr : ComplexPattern], []>;
66 def ADDRri : ComplexPattern;
6767
6868 // Address operands
69 def MEMrr : Operand32> {
69 def MEMrr : OperandPTR> {
7070 let PrintMethod = "printMemOperand";
71 let MIOperandInfo = (ops IntRegs, IntRegs);
72 }
73 def MEMri : Operand {
71 let MIOperandInfo = (ops ptr_rc, ptr_rc);
72 }
73 def MEMri : Operand {
7474 let PrintMethod = "printMemOperand";
75 let MIOperandInfo = (ops IntRegs, i32imm);
75 let MIOperandInfo = (ops ptr_rc, i32imm);
7676 }
7777
7878 // Branch targets have OtherVT type.
185185 def ri : F3_2<2, Op3Val,
186186 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
187187 !strconcat(OpcStr, " $b, $c, $dst"),
188 [(set i32:$dst, (OpNode i32:$b, simm13:$c))]>;
188 [(set i32:$dst, (OpNode i32:$b, (i32 simm13:$c)))]>;
189189 }
190190
191191 /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no
769769
770770 // Small immediates.
771771 def : Pat<(i32 simm13:$val),
772 (ORri G0, imm:$val)>;
772 (ORri (i32 G0), imm:$val)>;
773773 // Arbitrary immediates.
774774 def : Pat<(i32 imm:$val),
775775 (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;
782782
783783 // Global addresses, constant pool entries
784784 def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>;
785 def : Pat<(SPlo tglobaladdr:$in), (ORri G0, tglobaladdr:$in)>;
785 def : Pat<(SPlo tglobaladdr:$in), (ORri (i32 G0), tglobaladdr:$in)>;
786786 def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>;
787 def : Pat<(SPlo tconstpool:$in), (ORri G0, tconstpool:$in)>;
787 def : Pat<(SPlo tconstpool:$in), (ORri (i32 G0), tconstpool:$in)>;
788788
789789 // Add reg, lo. This is used when taking the addr of a global/constpool entry.
790790 def : Pat<(add i32:$r, (SPlo tglobaladdr:$in)),
5555 return Reserved;
5656 }
5757
58 const TargetRegisterClass*
59 SparcRegisterInfo::getPointerRegClass(const MachineFunction &MF,
60 unsigned Kind) const {
61 return Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
62 }
63
5864 void
5965 SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
6066 int SPAdj, unsigned FIOperandNum,
3535
3636 BitVector getReservedRegs(const MachineFunction &MF) const;
3737
38 const TargetRegisterClass *getPointerRegClass(const MachineFunction &MF,
39 unsigned Kind) const;
40
3841 void eliminateFrameIndex(MachineBasicBlock::iterator II,
3942 int SPAdj, unsigned FIOperandNum,
4043 RegScavenger *RS = NULL) const;
139139 // FIXME: the register order should be defined in terms of the preferred
140140 // allocation order...
141141 //
142 def IntRegs : RegisterClass<"SP", [i32], 32,
142 // This register class should not be used to hold i64 values, use the I64Regs
143 // register class for that. The i64 type is included here to allow i64 patterns
144 // using the integer instructions.
145 def IntRegs : RegisterClass<"SP", [i32, i64], 32,
143146 (add L0, L1, L2, L3, L4, L5, L6,
144147 L7, I0, I1, I2, I3, I4, I5,
145148 O0, O1, O2, O3, O4, O5, O7,
154157 G5, G6, G7 // reserved for kernel
155158 )>;
156159
160 // Register class for 64-bit mode, with a 64-bit spill slot size.
161 // These are the same as the 32-bit registers, so TableGen will consider this
162 // to be a sub-class of IntRegs. That works out because requiring a 64-bit
163 // spill slot is a stricter constraint than only requiring a 32-bit spill slot.
164 def I64Regs : RegisterClass<"SP", [i64], 64, (add IntRegs)>;
165
166 // Floating point register classes.
157167 def FPRegs : RegisterClass<"SP", [f32], 32, (sequence "F%u", 0, 31)>;
158168
159169 def DFPRegs : RegisterClass<"SP", [f64], 64, (sequence "D%u", 0, 15)>;