From 8ac2bcbe80e2b943856490509afc72c86b01945c Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 1 Oct 2013 15:00:44 +0000 Subject: [PATCH] [SystemZ] Add comparisons of high words and memory llvm-svn: 191777 --- lib/Target/SystemZ/SystemZInstrFormats.td | 16 +++++- lib/Target/SystemZ/SystemZInstrInfo.cpp | 8 +++ lib/Target/SystemZ/SystemZInstrInfo.td | 8 +++ test/CodeGen/SystemZ/asm-18.ll | 40 +++++++++++++++ test/MC/Disassembler/SystemZ/insns.txt | 60 +++++++++++++++++++++++ test/MC/SystemZ/insn-bad-z196.s | 16 ++++++ test/MC/SystemZ/insn-bad.s | 10 ++++ test/MC/SystemZ/insn-good-z196.s | 44 +++++++++++++++++ 8 files changed, 200 insertions(+), 2 deletions(-) diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td index 3b06732da1b..353a0d3f737 100644 --- a/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/lib/Target/SystemZ/SystemZInstrFormats.td @@ -1355,7 +1355,7 @@ class UnaryRIPseudo; -// Like UnaryRXY, but expanded after RA depending on the choice of registers. +// Like UnaryRXY, but expanded after RA depending on the choice of register. class UnaryRXYPseudo bytes, AddressingMode mode = bdxaddr20only> @@ -1410,7 +1410,19 @@ class CompareRIPseudo : Pseudo<(outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]>; -// Like StoreRXY, but expanded after RA depending on the choice of registers. +// Like CompareRXY, but expanded after RA depending on the choice of register. +class CompareRXYPseudo bytes, + AddressingMode mode = bdxaddr20only> + : Pseudo<(outs), (ins cls:$R1, mode:$XBD2), + [(operator cls:$R1, (load mode:$XBD2))]> { + let mayLoad = 1; + let Has20BitOffset = 1; + let HasIndex = 1; + let AccessBytes = bytes; +} + +// Like StoreRXY, but expanded after RA depending on the choice of register. class StoreRXYPseudo bytes, AddressingMode mode = bdxaddr20only> : Pseudo<(outs), (ins cls:$R1, mode:$XBD2), diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 9b50a3c684c..38d0a32d6f7 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -974,6 +974,14 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { expandRIPseudo(MI, SystemZ::CLFI, SystemZ::CLIH, false); return true; + case SystemZ::CMux: + expandRXYPseudo(MI, SystemZ::C, SystemZ::CHF); + return true; + + case SystemZ::CLMux: + expandRXYPseudo(MI, SystemZ::CL, SystemZ::CLHF); + 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.td b/lib/Target/SystemZ/SystemZInstrInfo.td index f7dbd094fa0..a318aa1b73a 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -1087,7 +1087,11 @@ let Defs = [CC], CCValues = 0xE in { // Comparison with memory. defm CH : CompareRXPair<"ch", 0x49, 0xE379, z_scmp, GR32, asextloadi16, 2>; + def CMux : CompareRXYPseudo, + Requires<[FeatureHighWord]>; defm C : CompareRXPair<"c", 0x59, 0xE359, z_scmp, GR32, load, 4>; + def CHF : CompareRXY<"chf", 0xE3CD, z_scmp, GRH32, load, 4>, + Requires<[FeatureHighWord]>; def CGH : CompareRXY<"cgh", 0xE334, z_scmp, GR64, asextloadi16, 2>; def CGF : CompareRXY<"cgf", 0xE330, z_scmp, GR64, asextloadi32, 4>; def CG : CompareRXY<"cg", 0xE320, z_scmp, GR64, load, 8>; @@ -1121,7 +1125,11 @@ let Defs = [CC], CCValues = 0xE, IsLogical = 1 in { def CLGFI : CompareRIL<"clgfi", 0xC2E, z_ucmp, GR64, imm64zx32>; // Comparison with memory. + def CLMux : CompareRXYPseudo, + Requires<[FeatureHighWord]>; defm CL : CompareRXPair<"cl", 0x55, 0xE355, z_ucmp, GR32, load, 4>; + def CLHF : CompareRXY<"clhf", 0xE3CF, z_ucmp, GRH32, load, 4>, + Requires<[FeatureHighWord]>; def CLGF : CompareRXY<"clgf", 0xE331, z_ucmp, GR64, azextloadi32, 4>; def CLG : CompareRXY<"clg", 0xE321, z_ucmp, GR64, load, 8>; def CLHRL : CompareRILPC<"clhrl", 0xC67, z_ucmp, GR32, diff --git a/test/CodeGen/SystemZ/asm-18.ll b/test/CodeGen/SystemZ/asm-18.ll index d39de6d6550..d60654b7863 100644 --- a/test/CodeGen/SystemZ/asm-18.ll +++ b/test/CodeGen/SystemZ/asm-18.ll @@ -703,3 +703,43 @@ define i32 @f32() { %sel2 = select i1 %cmp2, i32 0, i32 1 ret i32 %sel2 } + +; Test memory comparison involving high registers. +define void @f33(i32 *%ptr1, i32 *%ptr2) { +; CHECK-LABEL: f33: +; CHECK: stepa [[REG1:%r[0-5]]] +; CHECK: chf [[REG1]], 0(%r2) +; CHECK: stepb [[REG2:%r[0-5]]] +; CHECK: clhf [[REG2]], 0(%r3) +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=h"() + %load1 = load i32 *%ptr1 + %cmp1 = icmp sle i32 %res1, %load1 + %sel1 = select i1 %cmp1, i32 0, i32 1 + %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1) + %load2 = load i32 *%ptr2 + %cmp2 = icmp ule i32 %res2, %load2 + %sel2 = select i1 %cmp2, i32 0, i32 1 + store i32 %sel2, i32 *%ptr1 + ret void +} + +; Test memory comparison involving low registers. +define void @f34(i32 *%ptr1, i32 *%ptr2) { +; CHECK-LABEL: f34: +; CHECK: stepa [[REG1:%r[0-5]]] +; CHECK: c [[REG1]], 0(%r2) +; CHECK: stepb [[REG2:%r[0-5]]] +; CHECK: cl [[REG2]], 0(%r3) +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=r"() + %load1 = load i32 *%ptr1 + %cmp1 = icmp sle i32 %res1, %load1 + %sel1 = select i1 %cmp1, i32 0, i32 1 + %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1) + %load2 = load i32 *%ptr2 + %cmp2 = icmp ule i32 %res2, %load2 + %sel2 = select i1 %cmp2, i32 0, i32 1 + store i32 %sel2, i32 *%ptr1 + ret void +} diff --git a/test/MC/Disassembler/SystemZ/insns.txt b/test/MC/Disassembler/SystemZ/insns.txt index f88531b2cdf..982b35ffad5 100644 --- a/test/MC/Disassembler/SystemZ/insns.txt +++ b/test/MC/Disassembler/SystemZ/insns.txt @@ -1216,6 +1216,36 @@ # CHECK: cgxbr %r15, 0, %f0 0xb3 0xaa 0x00 0xf0 +# CHECK: chf %r0, -524288 +0xe3 0x00 0x00 0x00 0x80 0xcd + +# CHECK: chf %r0, -1 +0xe3 0x00 0x0f 0xff 0xff 0xcd + +# CHECK: chf %r0, 0 +0xe3 0x00 0x00 0x00 0x00 0xcd + +# CHECK: chf %r0, 1 +0xe3 0x00 0x00 0x01 0x00 0xcd + +# CHECK: chf %r0, 524287 +0xe3 0x00 0x0f 0xff 0x7f 0xcd + +# CHECK: chf %r0, 0(%r1) +0xe3 0x00 0x10 0x00 0x00 0xcd + +# CHECK: chf %r0, 0(%r15) +0xe3 0x00 0xf0 0x00 0x00 0xcd + +# CHECK: chf %r0, 524287(%r1,%r15) +0xe3 0x01 0xff 0xff 0x7f 0xcd + +# CHECK: chf %r0, 524287(%r15,%r1) +0xe3 0x0f 0x1f 0xff 0x7f 0xcd + +# CHECK: chf %r15, 0 +0xe3 0xf0 0x00 0x00 0x00 0xcd + # CHECK: chhsi 0, 0 0xe5 0x54 0x00 0x00 0x00 0x00 @@ -1549,6 +1579,36 @@ # CHECK: clg %r15, 0 0xe3 0xf0 0x00 0x00 0x00 0x21 +# CHECK: clhf %r0, -524288 +0xe3 0x00 0x00 0x00 0x80 0xcf + +# CHECK: clhf %r0, -1 +0xe3 0x00 0x0f 0xff 0xff 0xcf + +# CHECK: clhf %r0, 0 +0xe3 0x00 0x00 0x00 0x00 0xcf + +# CHECK: clhf %r0, 1 +0xe3 0x00 0x00 0x01 0x00 0xcf + +# CHECK: clhf %r0, 524287 +0xe3 0x00 0x0f 0xff 0x7f 0xcf + +# CHECK: clhf %r0, 0(%r1) +0xe3 0x00 0x10 0x00 0x00 0xcf + +# CHECK: clhf %r0, 0(%r15) +0xe3 0x00 0xf0 0x00 0x00 0xcf + +# CHECK: clhf %r0, 524287(%r1,%r15) +0xe3 0x01 0xff 0xff 0x7f 0xcf + +# CHECK: clhf %r0, 524287(%r15,%r1) +0xe3 0x0f 0x1f 0xff 0x7f 0xcf + +# CHECK: clhf %r15, 0 +0xe3 0xf0 0x00 0x00 0x00 0xcf + # CHECK: clhhsi 0, 0 0xe5 0x55 0x00 0x00 0x00 0x00 diff --git a/test/MC/SystemZ/insn-bad-z196.s b/test/MC/SystemZ/insn-bad-z196.s index e387f149fd1..089d9b5b3e1 100644 --- a/test/MC/SystemZ/insn-bad-z196.s +++ b/test/MC/SystemZ/insn-bad-z196.s @@ -32,6 +32,14 @@ aih %r0, (-1 << 31) - 1 aih %r0, (1 << 31) +#CHECK: error: invalid operand +#CHECK: chf %r0, -524289 +#CHECK: error: invalid operand +#CHECK: chf %r0, 524288 + + chf %r0, -524289 + chf %r0, 524288 + #CHECK: error: invalid operand #CHECK: cih %r0, (-1 << 31) - 1 #CHECK: error: invalid operand @@ -40,6 +48,14 @@ cih %r0, (-1 << 31) - 1 cih %r0, (1 << 31) +#CHECK: error: invalid operand +#CHECK: clhf %r0, -524289 +#CHECK: error: invalid operand +#CHECK: clhf %r0, 524288 + + clhf %r0, -524289 + clhf %r0, 524288 + #CHECK: error: invalid operand #CHECK: clih %r0, -1 #CHECK: error: invalid operand diff --git a/test/MC/SystemZ/insn-bad.s b/test/MC/SystemZ/insn-bad.s index 8de20612caa..64453a55816 100644 --- a/test/MC/SystemZ/insn-bad.s +++ b/test/MC/SystemZ/insn-bad.s @@ -612,6 +612,11 @@ ch %r0, -1 ch %r0, 4096 +#CHECK: error: {{(instruction requires: high-word)?}} +#CHECK: chf %r0, 0 + + chf %r0, 0 + #CHECK: error: invalid operand #CHECK: chhsi -1, 0 #CHECK: error: invalid operand @@ -766,6 +771,11 @@ clc 0(1,%r2), 0(%r1,%r2) clc 0(-), 0 +#CHECK: error: {{(instruction requires: high-word)?}} +#CHECK: clhf %r0, 0 + + clhf %r0, 0 + #CHECK: error: invalid operand #CHECK: clfhsi -1, 0 #CHECK: error: invalid operand diff --git a/test/MC/SystemZ/insn-good-z196.s b/test/MC/SystemZ/insn-good-z196.s index 93687ea81f6..258e06f99dd 100644 --- a/test/MC/SystemZ/insn-good-z196.s +++ b/test/MC/SystemZ/insn-good-z196.s @@ -135,6 +135,28 @@ ark %r15,%r0,%r0 ark %r7,%r8,%r9 +#CHECK: chf %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0xcd] +#CHECK: chf %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0xcd] +#CHECK: chf %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0xcd] +#CHECK: chf %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0xcd] +#CHECK: chf %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0xcd] +#CHECK: chf %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0xcd] +#CHECK: chf %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0xcd] +#CHECK: chf %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0xcd] +#CHECK: chf %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0xcd] +#CHECK: chf %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0xcd] + + chf %r0, -524288 + chf %r0, -1 + chf %r0, 0 + chf %r0, 1 + chf %r0, 524287 + chf %r0, 0(%r1) + chf %r0, 0(%r15) + chf %r0, 524287(%r1,%r15) + chf %r0, 524287(%r15,%r1) + chf %r15, 0 + #CHECK: cih %r0, -2147483648 # encoding: [0xcc,0x0d,0x80,0x00,0x00,0x00] #CHECK: cih %r0, -1 # encoding: [0xcc,0x0d,0xff,0xff,0xff,0xff] #CHECK: cih %r0, 0 # encoding: [0xcc,0x0d,0x00,0x00,0x00,0x00] @@ -149,6 +171,28 @@ cih %r0, (1 << 31) - 1 cih %r15, 0 +#CHECK: clhf %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0xcf] +#CHECK: clhf %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0xcf] +#CHECK: clhf %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0xcf] +#CHECK: clhf %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0xcf] +#CHECK: clhf %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0xcf] +#CHECK: clhf %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0xcf] +#CHECK: clhf %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0xcf] +#CHECK: clhf %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0xcf] +#CHECK: clhf %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0xcf] +#CHECK: clhf %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0xcf] + + clhf %r0, -524288 + clhf %r0, -1 + clhf %r0, 0 + clhf %r0, 1 + clhf %r0, 524287 + clhf %r0, 0(%r1) + clhf %r0, 0(%r15) + clhf %r0, 524287(%r1,%r15) + clhf %r0, 524287(%r15,%r1) + clhf %r15, 0 + #CHECK: clih %r0, 0 # encoding: [0xcc,0x0f,0x00,0x00,0x00,0x00] #CHECK: clih %r0, 1 # encoding: [0xcc,0x0f,0x00,0x00,0x00,0x01] #CHECK: clih %r0, 4294967295 # encoding: [0xcc,0x0f,0xff,0xff,0xff,0xff]