diff options
-rw-r--r-- | lib/Target/SystemZ/SystemZAsmPrinter.cpp | 3 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZISelLowering.cpp | 12 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.cpp | 12 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 27 | ||||
-rw-r--r-- | test/CodeGen/SystemZ/asm-18.ll | 42 |
5 files changed, 83 insertions, 13 deletions
diff --git a/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/SystemZAsmPrinter.cpp index cb01949..64ff46b 100644 --- a/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -127,6 +127,9 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) { LOWER_HIGH(IIHL); LOWER_HIGH(IIHH); + LOWER_HIGH(OIHL); + LOWER_HIGH(OIHH); + LOWER_HIGH(OIHF); #undef LOWER_HIGH diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 46824e6..19020c8 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -2990,14 +2990,14 @@ EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const { return emitAtomicLoadBinary(MI, MBB, SystemZ::OILL64, 64); case SystemZ::ATOMIC_LOAD_OILH64: return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH64, 64); - case SystemZ::ATOMIC_LOAD_OIHL: - return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHL, 64); - case SystemZ::ATOMIC_LOAD_OIHH: - return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHH, 64); + case SystemZ::ATOMIC_LOAD_OIHL64: + return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHL64, 64); + case SystemZ::ATOMIC_LOAD_OIHH64: + return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHH64, 64); case SystemZ::ATOMIC_LOAD_OILF64: return emitAtomicLoadBinary(MI, MBB, SystemZ::OILF64, 64); - case SystemZ::ATOMIC_LOAD_OIHF: - return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHF, 64); + case SystemZ::ATOMIC_LOAD_OIHF64: + return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHF64, 64); case SystemZ::ATOMIC_LOADW_XR: return emitAtomicLoadBinary(MI, MBB, SystemZ::XR, 0); diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 90de3da..5705489 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -889,6 +889,18 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { expandRIPseudo(MI, SystemZ::IILH, SystemZ::IIHH, false); return true; + case SystemZ::OIFMux: + expandRIPseudo(MI, SystemZ::OILF, SystemZ::OIHF, false); + return true; + + case SystemZ::OILMux: + expandRIPseudo(MI, SystemZ::OILL, SystemZ::OIHL, false); + return true; + + case SystemZ::OIHMux: + expandRIPseudo(MI, SystemZ::OILH, SystemZ::OIHH, 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 e19cc27..4cdf128 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -842,20 +842,33 @@ let Defs = [CC] in { // ORs of a 16-bit immediate, leaving other bits unaffected. // The CC result only reflects the 16-bit field, not the full register. + // + // OIxMux expands to OI[LH]x, depending on the choice of register. + def OILMux : BinaryRIPseudo<or, GRX32, imm32ll16>, + Requires<[FeatureHighWord]>; + def OIHMux : BinaryRIPseudo<or, GRX32, imm32lh16>, + Requires<[FeatureHighWord]>; def OILL : BinaryRI<"oill", 0xA5B, or, GR32, imm32ll16>; def OILH : BinaryRI<"oilh", 0xA5A, or, GR32, imm32lh16>; + def OIHL : BinaryRI<"oihl", 0xA59, or, GRH32, imm32ll16>; + def OIHH : BinaryRI<"oihh", 0xA58, or, GRH32, imm32lh16>; def OILL64 : BinaryAliasRI<or, GR64, imm64ll16>; def OILH64 : BinaryAliasRI<or, GR64, imm64lh16>; - def OIHL : BinaryRI<"oihl", 0xA59, or, GR64, imm64hl16>; - def OIHH : BinaryRI<"oihh", 0xA58, or, GR64, imm64hh16>; + def OIHL64 : BinaryAliasRI<or, GR64, imm64hl16>; + def OIHH64 : BinaryAliasRI<or, GR64, imm64hh16>; // ORs of a 32-bit immediate, leaving other bits unaffected. // The CC result only reflects the 32-bit field, which means we can // use it as a zero indicator for i32 operations but not otherwise. - let CCValues = 0xC, CompareZeroCCMask = 0x8 in + let CCValues = 0xC, CompareZeroCCMask = 0x8 in { + // Expands to OILF or OIHF, depending on the choice of register. + def OIFMux : BinaryRIPseudo<or, GRX32, uimm32>, + Requires<[FeatureHighWord]>; def OILF : BinaryRIL<"oilf", 0xC0D, or, GR32, uimm32>; + def OIHF : BinaryRIL<"oihf", 0xC0C, or, GRH32, uimm32>; + } def OILF64 : BinaryAliasRIL<or, GR64, imm64lf32>; - def OIHF : BinaryRIL<"oihf", 0xC0C, or, GR64, imm64hf32>; + def OIHF64 : BinaryAliasRIL<or, GR64, imm64hf32>; // ORs of memory. let CCValues = 0xC, CompareZeroCCMask = 0x8 in { @@ -1162,10 +1175,10 @@ def ATOMIC_LOAD_OILF : AtomicLoadBinaryImm32<atomic_load_or_32, uimm32>; def ATOMIC_LOAD_OGR : AtomicLoadBinaryReg64<atomic_load_or_64>; def ATOMIC_LOAD_OILL64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64ll16>; def ATOMIC_LOAD_OILH64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64lh16>; -def ATOMIC_LOAD_OIHL : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hl16>; -def ATOMIC_LOAD_OIHH : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hh16>; +def ATOMIC_LOAD_OIHL64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hl16>; +def ATOMIC_LOAD_OIHH64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hh16>; def ATOMIC_LOAD_OILF64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64lf32>; -def ATOMIC_LOAD_OIHF : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hf32>; +def ATOMIC_LOAD_OIHF64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hf32>; def ATOMIC_LOADW_XR : AtomicLoadWBinaryReg<z_atomic_loadw_xor>; def ATOMIC_LOADW_XILF : AtomicLoadWBinaryImm<z_atomic_loadw_xor, uimm32>; diff --git a/test/CodeGen/SystemZ/asm-18.ll b/test/CodeGen/SystemZ/asm-18.ll index fc71895..4d0547f 100644 --- a/test/CodeGen/SystemZ/asm-18.ll +++ b/test/CodeGen/SystemZ/asm-18.ll @@ -353,3 +353,45 @@ define void @f16() { call void asm sideeffect "stepc $0", "r"(i32 %or2) ret void } + +; Test immediate OR involving high registers. +define void @f17() { +; CHECK-LABEL: f17: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: oihh [[REG]], 4660 +; CHECK: stepb [[REG]] +; CHECK: oihl [[REG]], 34661 +; CHECK: stepc [[REG]] +; CHECK: oihf [[REG]], 12345678 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=h"() + %or1 = or i32 %res1, 305397760 + %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1) + %or2 = or i32 %res2, 34661 + %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %or2) + %or3 = or i32 %res3, 12345678 + call void asm sideeffect "stepd $0", "h"(i32 %or3) + ret void +} + +; Test immediate OR involving low registers. +define void @f18() { +; CHECK-LABEL: f18: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: oilh [[REG]], 4660 +; CHECK: stepb [[REG]] +; CHECK: oill [[REG]], 34661 +; CHECK: stepc [[REG]] +; CHECK: oilf [[REG]], 12345678 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=r"() + %or1 = or i32 %res1, 305397760 + %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1) + %or2 = or i32 %res2, 34661 + %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %or2) + %or3 = or i32 %res3, 12345678 + call void asm sideeffect "stepd $0", "r"(i32 %or3) + ret void +} |