diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-10-01 14:53:46 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-10-01 14:53:46 +0000 |
commit | ad366a3f67679a56d25464dc2bcad3a0a6a51780 (patch) | |
tree | 39b7511c4c9ec60d3ce4c5738e98c350e38ce8f3 /lib/Target/SystemZ | |
parent | bd1958d8e99ebd5a885f848b2f688c399cfc9886 (diff) | |
download | external_llvm-ad366a3f67679a56d25464dc2bcad3a0a6a51780.zip external_llvm-ad366a3f67679a56d25464dc2bcad3a0a6a51780.tar.gz external_llvm-ad366a3f67679a56d25464dc2bcad3a0a6a51780.tar.bz2 |
[SystemZ] Add immediate addition involving high words
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191774 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SystemZ')
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrFormats.td | 19 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.cpp | 52 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.h | 2 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 5 |
4 files changed, 76 insertions, 2 deletions
diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td index 9ca1a8a..3b06732 100644 --- a/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/lib/Target/SystemZ/SystemZInstrFormats.td @@ -1386,6 +1386,25 @@ class BinaryRIPseudo<SDPatternOperator operator, RegisterOperand cls, let Constraints = "$R1 = $R1src"; } +// Like BinaryRIE, but expanded after RA depending on the choice of register. +class BinaryRIEPseudo<SDPatternOperator operator, RegisterOperand cls, + Immediate imm> + : Pseudo<(outs cls:$R1), (ins cls:$R3, imm:$I2), + [(set cls:$R1, (operator cls:$R3, imm:$I2))]>; + +// Like BinaryRIAndK, but expanded after RA depending on the choice of register. +multiclass BinaryRIAndKPseudo<string key, SDPatternOperator operator, + RegisterOperand cls, Immediate imm> { + let NumOpsKey = key in { + let NumOpsValue = "3" in + def K : BinaryRIEPseudo<null_frag, cls, imm>, + Requires<[FeatureHighWord, FeatureDistinctOps]>; + let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in + def "" : BinaryRIPseudo<operator, cls, imm>, + Requires<[FeatureHighWord]>; + } +} + // Like CompareRI, but expanded after RA depending on the choice of register. class CompareRIPseudo<SDPatternOperator operator, RegisterOperand cls, Immediate imm> diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 2c48c78..acefd9c 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -107,6 +107,28 @@ void SystemZInstrInfo::expandRIPseudo(MachineInstr *MI, unsigned LowOpcode, MI->getOperand(1).setImm(uint32_t(MI->getOperand(1).getImm())); } +// MI is a three-operand RIE-style pseudo instruction. Replace it with +// LowOpcode3 if the registers are both low GR32s, otherwise use a move +// followed by HighOpcode or LowOpcode, depending on whether the target +// is a high or low GR32. +void SystemZInstrInfo::expandRIEPseudo(MachineInstr *MI, unsigned LowOpcode, + unsigned LowOpcodeK, + unsigned HighOpcode) const { + unsigned DestReg = MI->getOperand(0).getReg(); + unsigned SrcReg = MI->getOperand(1).getReg(); + bool DestIsHigh = isHighReg(DestReg); + bool SrcIsHigh = isHighReg(SrcReg); + if (!DestIsHigh && !SrcIsHigh) + MI->setDesc(get(LowOpcodeK)); + else { + emitGRX32Move(*MI->getParent(), MI, MI->getDebugLoc(), + DestReg, SrcReg, SystemZ::LR, 32, + MI->getOperand(1).isKill()); + MI->setDesc(get(DestIsHigh ? HighOpcode : LowOpcode)); + MI->getOperand(1).setReg(DestReg); + } +} + // MI is an RXY-style pseudo instruction. Replace it with LowOpcode // if the first operand is a low GR32 and HighOpcode if the first operand // is a high GR32. @@ -651,6 +673,7 @@ SystemZInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, LiveVariables *LV) const { MachineInstr *MI = MBBI; MachineBasicBlock *MBB = MI->getParent(); + MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); unsigned Opcode = MI->getOpcode(); unsigned NumOps = MI->getNumOperands(); @@ -660,10 +683,23 @@ SystemZInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, // because it tends to be shorter and because some instructions // have memory forms that can be used during spilling. if (TM.getSubtargetImpl()->hasDistinctOps()) { + MachineOperand &Dest = MI->getOperand(0); + MachineOperand &Src = MI->getOperand(1); + unsigned DestReg = Dest.getReg(); + unsigned SrcReg = Src.getReg(); + // AHIMux is only really a three-operand instruction when both operands + // are low registers. Try to constrain both operands to be low if + // possible. + if (Opcode == SystemZ::AHIMux && + TargetRegisterInfo::isVirtualRegister(DestReg) && + TargetRegisterInfo::isVirtualRegister(SrcReg) && + MRI.getRegClass(DestReg)->contains(SystemZ::R1L) && + MRI.getRegClass(SrcReg)->contains(SystemZ::R1L)) { + MRI.constrainRegClass(DestReg, &SystemZ::GR32BitRegClass); + MRI.constrainRegClass(SrcReg, &SystemZ::GR32BitRegClass); + } int ThreeOperandOpcode = SystemZ::getThreeOperandOpcode(Opcode); if (ThreeOperandOpcode >= 0) { - MachineOperand &Dest = MI->getOperand(0); - MachineOperand &Src = MI->getOperand(1); MachineInstrBuilder MIB = BuildMI(*MBB, MBBI, MI->getDebugLoc(), get(ThreeOperandOpcode)) .addOperand(Dest); @@ -918,6 +954,18 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { expandRIPseudo(MI, SystemZ::TMLH, SystemZ::TMHH, false); return true; + case SystemZ::AHIMux: + expandRIPseudo(MI, SystemZ::AHI, SystemZ::AIH, false); + return true; + + case SystemZ::AHIMuxK: + expandRIEPseudo(MI, SystemZ::AHI, SystemZ::AHIK, SystemZ::AIH); + return true; + + case SystemZ::AFIMux: + expandRIPseudo(MI, SystemZ::AFI, SystemZ::AIH, false); + return true; + case SystemZ::RISBMux: { bool DestIsHigh = isHighReg(MI->getOperand(0).getReg()); bool SrcIsHigh = isHighReg(MI->getOperand(2).getReg()); diff --git a/lib/Target/SystemZ/SystemZInstrInfo.h b/lib/Target/SystemZ/SystemZInstrInfo.h index 06e677a..7978be4 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/lib/Target/SystemZ/SystemZInstrInfo.h @@ -118,6 +118,8 @@ class SystemZInstrInfo : public SystemZGenInstrInfo { void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const; void expandRIPseudo(MachineInstr *MI, unsigned LowOpcode, unsigned HighOpcode, bool ConvertHigh) const; + void expandRIEPseudo(MachineInstr *MI, unsigned LowOpcode, + unsigned LowOpcodeK, unsigned HighOpcode) const; void expandRXYPseudo(MachineInstr *MI, unsigned LowOpcode, unsigned HighOpcode) const; void expandZExtPseudo(MachineInstr *MI, unsigned LowOpcode, diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 340580a..986e77f 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -685,11 +685,16 @@ let Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0x8 in { def AGFR : BinaryRRE<"agf", 0xB918, null_frag, GR64, GR32>; // Addition of signed 16-bit immediates. + defm AHIMux : BinaryRIAndKPseudo<"ahimux", add, GRX32, imm32sx16>; defm AHI : BinaryRIAndK<"ahi", 0xA7A, 0xECD8, add, GR32, imm32sx16>; defm AGHI : BinaryRIAndK<"aghi", 0xA7B, 0xECD9, add, GR64, imm64sx16>; // Addition of signed 32-bit immediates. + def AFIMux : BinaryRIPseudo<add, GRX32, simm32>, + Requires<[FeatureHighWord]>; def AFI : BinaryRIL<"afi", 0xC29, add, GR32, simm32>; + def AIH : BinaryRIL<"aih", 0xCC8, add, GRH32, simm32>, + Requires<[FeatureHighWord]>; def AGFI : BinaryRIL<"agfi", 0xC28, add, GR64, imm64sx32>; // Addition of memory. |