diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-10-01 13:18:56 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-10-01 13:18:56 +0000 |
commit | 645d250b84fe0d097e7813b980ae58daeca2c2e6 (patch) | |
tree | 546e722390d56140fee454cc642a0d234d85291c /lib/Target/SystemZ | |
parent | 2e1625475fab156b98204fa73c168ca4a828b775 (diff) | |
download | external_llvm-645d250b84fe0d097e7813b980ae58daeca2c2e6.zip external_llvm-645d250b84fe0d097e7813b980ae58daeca2c2e6.tar.gz external_llvm-645d250b84fe0d097e7813b980ae58daeca2c2e6.tar.bz2 |
[SystemZ] Allow integer insertions with a high-word destination
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191753 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SystemZ')
-rw-r--r-- | lib/Target/SystemZ/SystemZAsmPrinter.cpp | 17 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrFormats.td | 8 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.cpp | 8 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 12 |
4 files changed, 43 insertions, 2 deletions
diff --git a/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 0a89a96..cb01949 100644 --- a/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -36,6 +36,15 @@ static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) { } // Return an RI instruction like MI with opcode Opcode, but with the +// GR64 register operands turned into GRH32s. +static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) { + return MCInstBuilder(Opcode) + .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) + .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg())) + .addImm(MI->getOperand(2).getImm()); +} + +// Return an RI instruction like MI with opcode Opcode, but with the // R2 register turned into a GR64. static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) { return MCInstBuilder(Opcode) @@ -113,6 +122,14 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) { #undef LOWER_LOW +#define LOWER_HIGH(NAME) \ + case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break + + LOWER_HIGH(IIHL); + LOWER_HIGH(IIHH); + +#undef LOWER_HIGH + default: Lower.lower(MI, LoweredMI); break; diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td index c74091f..aa15ebd 100644 --- a/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/lib/Target/SystemZ/SystemZInstrFormats.td @@ -1378,6 +1378,14 @@ class UnaryRRPseudo<string key, SDPatternOperator operator, let OpType = "reg"; } +// Like BinaryRI, but expanded after RA depending on the choice of register. +class BinaryRIPseudo<SDPatternOperator operator, RegisterOperand cls, + Immediate imm> + : Pseudo<(outs cls:$R1), (ins cls:$R1src, imm:$I2), + [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> { + let Constraints = "$R1 = $R1src"; +} + // Like StoreRXY, but expanded after RA depending on the choice of registers. class StoreRXYPseudo<SDPatternOperator operator, RegisterOperand cls, bits<5> bytes, AddressingMode mode = bdxaddr20only> diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 3abecf6..90de3da 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -881,6 +881,14 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { expandRIPseudo(MI, SystemZ::IILF, SystemZ::IIHF, false); return true; + case SystemZ::IILMux: + expandRIPseudo(MI, SystemZ::IILL, SystemZ::IIHL, false); + return true; + + case SystemZ::IIHMux: + expandRIPseudo(MI, SystemZ::IILH, SystemZ::IIHH, false); + return true; + case SystemZ::ADJDYNALLOC: splitAdjDynAlloc(MI); return true; diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index ac1ca3c..e19cc27 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -629,12 +629,20 @@ defm : InsertMem<"inserti8", ICY, GR64, azextloadi8, bdxaddr20pair>; // Insertions of a 16-bit immediate, leaving other bits unaffected. // We don't have or_as_insert equivalents of these operations because // OI is available instead. +// +// IIxMux expands to II[LH]x, depending on the choice of register. +def IILMux : BinaryRIPseudo<insertll, GRX32, imm32ll16>, + Requires<[FeatureHighWord]>; +def IIHMux : BinaryRIPseudo<insertlh, GRX32, imm32lh16>, + Requires<[FeatureHighWord]>; def IILL : BinaryRI<"iill", 0xA53, insertll, GR32, imm32ll16>; def IILH : BinaryRI<"iilh", 0xA52, insertlh, GR32, imm32lh16>; +def IIHL : BinaryRI<"iihl", 0xA51, insertll, GRH32, imm32ll16>; +def IIHH : BinaryRI<"iihh", 0xA50, insertlh, GRH32, imm32lh16>; def IILL64 : BinaryAliasRI<insertll, GR64, imm64ll16>; def IILH64 : BinaryAliasRI<insertlh, GR64, imm64lh16>; -def IIHL : BinaryRI<"iihl", 0xA51, inserthl, GR64, imm64hl16>; -def IIHH : BinaryRI<"iihh", 0xA50, inserthh, GR64, imm64hh16>; +def IIHL64 : BinaryAliasRI<inserthl, GR64, imm64hl16>; +def IIHH64 : BinaryAliasRI<inserthh, GR64, imm64hh16>; // ...likewise for 32-bit immediates. For GR32s this is a general // full-width move. (We use IILF rather than something like LLILF |