[SystemZ] Add comparisons of high words and memory
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Tue, 1 Oct 2013 15:00:44 +0000 (15:00 +0000)
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Tue, 1 Oct 2013 15:00:44 +0000 (15:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191777 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SystemZ/SystemZInstrFormats.td
lib/Target/SystemZ/SystemZInstrInfo.cpp
lib/Target/SystemZ/SystemZInstrInfo.td
test/CodeGen/SystemZ/asm-18.ll
test/MC/Disassembler/SystemZ/insns.txt
test/MC/SystemZ/insn-bad-z196.s
test/MC/SystemZ/insn-bad.s
test/MC/SystemZ/insn-good-z196.s

index 3b06732da1b2c7087af6fc251d2532e1859922d1..353a0d3f73748cc7030bf35d1cec5def6c237dce 100644 (file)
@@ -1355,7 +1355,7 @@ class UnaryRIPseudo<SDPatternOperator operator, RegisterOperand cls,
   : Pseudo<(outs cls:$R1), (ins imm:$I2),
            [(set cls:$R1, (operator imm:$I2))]>;
 
-// 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<string key, SDPatternOperator operator,
                      RegisterOperand cls, bits<5> bytes,
                      AddressingMode mode = bdxaddr20only>
@@ -1410,7 +1410,19 @@ class CompareRIPseudo<SDPatternOperator operator, RegisterOperand cls,
                       Immediate imm>
   : 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<SDPatternOperator operator, RegisterOperand cls,
+                       SDPatternOperator load, bits<5> 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<SDPatternOperator operator, RegisterOperand cls,
                      bits<5> bytes, AddressingMode mode = bdxaddr20only>
   : Pseudo<(outs), (ins cls:$R1, mode:$XBD2),
index 9b50a3c684c1769574c01ade47f0050e08bf530c..38d0a32d6f7ba97b90bf06cedc395f01d57ab25d 100644 (file)
@@ -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());
index f7dbd094fa0d3f9aa28d00c88a4627ed6171e002..a318aa1b73ade4e0dd8b585405c8d3176b523caa 100644 (file)
@@ -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<z_scmp, GRX32, load, 4>,
+               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<z_ucmp, GRX32, load, 4>,
+                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,
index d39de6d6550bb88b21a1fdea2ef984c8d657de58..d60654b7863d5a6a0e0fc13c7eefce7a59d76ec1 100644 (file)
@@ -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
+}
index f88531b2cdf0a586dd9599506815de6843b10e8f..982b35ffad5a2f1ce00d3fb7611b11708fad3d2b 100644 (file)
 # 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
 
 # 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
 
index e387f149fd122319f8f966f0d3e6087f24c86db6..089d9b5b3e147412ca29e17f5f4c41009baeb07d 100644 (file)
        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
        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
index 8de20612caad016da22cb6a60e5b1cc1df44ed68..64453a55816bed39f5b704b9a54928fd2f5fa298 100644 (file)
        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
        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
index 93687ea81f6e932984a9eb6f12905715838430c4..258e06f99dd193c0b7a3a6b8e607237313572773 100644 (file)
        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]
        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]