aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-10-01 14:08:44 +0000
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-10-01 14:08:44 +0000
commit1ff62e182e648c72e6fce4f9d7911f2edfd914d2 (patch)
tree713f6f25e06617b6df62022247d59ecf0b2392b5
parent8819c84aed10777ba91d4e862229882b8da0b272 (diff)
downloadexternal_llvm-1ff62e182e648c72e6fce4f9d7911f2edfd914d2.zip
external_llvm-1ff62e182e648c72e6fce4f9d7911f2edfd914d2.tar.gz
external_llvm-1ff62e182e648c72e6fce4f9d7911f2edfd914d2.tar.bz2
[SystemZ] Allow integer XOR involving high words
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191759 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/SystemZ/SystemZAsmPrinter.cpp1
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.cpp4
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.cpp4
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.td11
-rw-r--r--test/CodeGen/SystemZ/asm-18.ll42
5 files changed, 57 insertions, 5 deletions
diff --git a/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 64ff46b..b256ac5 100644
--- a/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -130,6 +130,7 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
LOWER_HIGH(OIHL);
LOWER_HIGH(OIHH);
LOWER_HIGH(OIHF);
+ LOWER_HIGH(XIHF);
#undef LOWER_HIGH
diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp
index 19020c8..4d3c22c 100644
--- a/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -3011,8 +3011,8 @@ EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const {
return emitAtomicLoadBinary(MI, MBB, SystemZ::XGR, 64);
case SystemZ::ATOMIC_LOAD_XILF64:
return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF64, 64);
- case SystemZ::ATOMIC_LOAD_XIHF:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::XIHF, 64);
+ case SystemZ::ATOMIC_LOAD_XIHF64:
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::XIHF64, 64);
case SystemZ::ATOMIC_LOADW_NRi:
return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 0, true);
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 5705489..8749f48 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -901,6 +901,10 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
expandRIPseudo(MI, SystemZ::OILH, SystemZ::OIHH, false);
return true;
+ case SystemZ::XIFMux:
+ expandRIPseudo(MI, SystemZ::XILF, SystemZ::XIHF, 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 4cdf128..c468b88 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -900,10 +900,15 @@ let Defs = [CC] in {
// XORs 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 XILF or XIHF, depending on the choice of register.
+ def XIFMux : BinaryRIPseudo<xor, GRX32, uimm32>,
+ Requires<[FeatureHighWord]>;
def XILF : BinaryRIL<"xilf", 0xC07, xor, GR32, uimm32>;
+ def XIHF : BinaryRIL<"xihf", 0xC06, xor, GRH32, uimm32>;
+ }
def XILF64 : BinaryAliasRIL<xor, GR64, imm64lf32>;
- def XIHF : BinaryRIL<"xihf", 0xC06, xor, GR64, imm64hf32>;
+ def XIHF64 : BinaryAliasRIL<xor, GR64, imm64hf32>;
// XORs of memory.
let CCValues = 0xC, CompareZeroCCMask = 0x8 in {
@@ -1186,7 +1191,7 @@ def ATOMIC_LOAD_XR : AtomicLoadBinaryReg32<atomic_load_xor_32>;
def ATOMIC_LOAD_XILF : AtomicLoadBinaryImm32<atomic_load_xor_32, uimm32>;
def ATOMIC_LOAD_XGR : AtomicLoadBinaryReg64<atomic_load_xor_64>;
def ATOMIC_LOAD_XILF64 : AtomicLoadBinaryImm64<atomic_load_xor_64, imm64lf32>;
-def ATOMIC_LOAD_XIHF : AtomicLoadBinaryImm64<atomic_load_xor_64, imm64hf32>;
+def ATOMIC_LOAD_XIHF64 : AtomicLoadBinaryImm64<atomic_load_xor_64, imm64hf32>;
def ATOMIC_LOADW_NRi : AtomicLoadWBinaryReg<z_atomic_loadw_nand>;
def ATOMIC_LOADW_NILHi : AtomicLoadWBinaryImm<z_atomic_loadw_nand,
diff --git a/test/CodeGen/SystemZ/asm-18.ll b/test/CodeGen/SystemZ/asm-18.ll
index 4d0547f..bec8dee 100644
--- a/test/CodeGen/SystemZ/asm-18.ll
+++ b/test/CodeGen/SystemZ/asm-18.ll
@@ -395,3 +395,45 @@ define void @f18() {
call void asm sideeffect "stepd $0", "r"(i32 %or3)
ret void
}
+
+; Test immediate XOR involving high registers.
+define void @f19() {
+; CHECK-LABEL: f19:
+; CHECK: stepa [[REG:%r[0-5]]]
+; CHECK: xihf [[REG]], 305397760
+; CHECK: stepb [[REG]]
+; CHECK: xihf [[REG]], 34661
+; CHECK: stepc [[REG]]
+; CHECK: xihf [[REG]], 12345678
+; CHECK: stepd [[REG]]
+; CHECK: br %r14
+ %res1 = call i32 asm "stepa $0", "=h"()
+ %xor1 = xor i32 %res1, 305397760
+ %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %xor1)
+ %xor2 = xor i32 %res2, 34661
+ %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %xor2)
+ %xor3 = xor i32 %res3, 12345678
+ call void asm sideeffect "stepd $0", "h"(i32 %xor3)
+ ret void
+}
+
+; Test immediate XOR involving low registers.
+define void @f20() {
+; CHECK-LABEL: f20:
+; CHECK: stepa [[REG:%r[0-5]]]
+; CHECK: xilf [[REG]], 305397760
+; CHECK: stepb [[REG]]
+; CHECK: xilf [[REG]], 34661
+; CHECK: stepc [[REG]]
+; CHECK: xilf [[REG]], 12345678
+; CHECK: stepd [[REG]]
+; CHECK: br %r14
+ %res1 = call i32 asm "stepa $0", "=r"()
+ %xor1 = xor i32 %res1, 305397760
+ %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %xor1)
+ %xor2 = xor i32 %res2, 34661
+ %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %xor2)
+ %xor3 = xor i32 %res3, 12345678
+ call void asm sideeffect "stepd $0", "r"(i32 %xor3)
+ ret void
+}