[SystemZ] Add a definition of the CLC instruction
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Mon, 12 Aug 2013 10:17:33 +0000 (10:17 +0000)
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Mon, 12 Aug 2013 10:17:33 +0000 (10:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188162 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SystemZ/SystemZISelLowering.cpp
lib/Target/SystemZ/SystemZISelLowering.h
lib/Target/SystemZ/SystemZInstrFormats.td
lib/Target/SystemZ/SystemZInstrInfo.td
lib/Target/SystemZ/SystemZOperators.td
test/MC/Disassembler/SystemZ/insns.txt
test/MC/SystemZ/insn-bad.s
test/MC/SystemZ/insn-good.s

index 6acdcd4bef0ce45df48708f7fed87c978e61e3dc..a51f0168a9e5c91c2e8a18f28d87c51291c850f5 100644 (file)
@@ -1701,6 +1701,7 @@ const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
     OPCODE(UDIVREM32);
     OPCODE(UDIVREM64);
     OPCODE(MVC);
+    OPCODE(CLC);
     OPCODE(ATOMIC_SWAPW);
     OPCODE(ATOMIC_LOADW_ADD);
     OPCODE(ATOMIC_LOADW_SUB);
index c0dbe493c0f5abf34c81164f1f48fa1f6989f1c4..4098ff34b38125dac199e88a282d478d9e7ca352 100644 (file)
@@ -80,6 +80,10 @@ namespace SystemZISD {
     // MachineMemOperands rather than one.
     MVC,
 
+    // Use CLC to compare two blocks of memory, with the same comments
+    // as for MVC.
+    CLC,
+
     // Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or
     // ATOMIC_LOAD_<op>.
     //
index 2af8e83aed5b2867bf3754fdfba89a1ba88f79a2..2d18e03eb505489078ead0bb2929828c266786b2 100644 (file)
@@ -1386,3 +1386,22 @@ class AtomicLoadWBinaryReg<SDPatternOperator operator>
   : AtomicLoadWBinary<operator, (i32 GR32:$src2), GR32>;
 class AtomicLoadWBinaryImm<SDPatternOperator operator, Immediate imm>
   : AtomicLoadWBinary<operator, (i32 imm:$src2), imm>;
+
+// Define an instruction that operates on two fixed-length blocks of memory.
+// The real instruction uses a bdladdr12onlylen8 for the first operand and a
+// bdaddr12only for the second, with the length of the second operand being
+// implicitly the same as the first.  This arrangement matches the underlying
+// assembly syntax.  However, for instruction selection it's easier to have
+// two normal bdaddr12onlys and a separate length operand, so define a pseudo
+// instruction for that too.
+multiclass MemorySS<string mnemonic, bits<8> opcode,
+                    SDPatternOperator operator> {
+  def "" : InstSS<opcode, (outs), (ins bdladdr12onlylen8:$BDL1,
+                                       bdaddr12only:$BD2),
+                  mnemonic##"\t$BDL1, $BD2", []>;
+  let usesCustomInserter = 1 in
+    def Wrapper : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src,
+                                      imm32len8:$length),
+                         [(operator bdaddr12only:$dest, bdaddr12only:$src,
+                                    imm32len8:$length)]>;
+}
index 5371e8ad4db810ce35a34ae31ba057d34702c1dc..a7181d68a7f01f621caa0694eb3ab8af6f3c9351 100644 (file)
@@ -334,15 +334,7 @@ def MVGHI : StoreSIL<"mvghi", 0xE548, store,         imm64sx16>;
 
 // Memory-to-memory moves.
 let mayLoad = 1, mayStore = 1 in
-  def MVC : InstSS<0xD2, (outs), (ins bdladdr12onlylen8:$BDL1,
-                                      bdaddr12only:$BD2),
-                   "mvc\t$BDL1, $BD2", []>;
-
-let mayLoad = 1, mayStore = 1, usesCustomInserter = 1 in
-  def MVCWrapper : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src,
-                                       imm32len8:$length),
-                          [(z_mvc bdaddr12only:$dest, bdaddr12only:$src,
-                                  imm32len8:$length)]>;
+  defm MVC : MemorySS<"mvc", 0xD2, z_mvc>;
 
 defm LoadStore8_32  : MVCLoadStore<anyextloadi8, truncstorei8, i32,
                                    MVCWrapper, 1>;
@@ -1000,6 +992,10 @@ let Defs = [CC], CCValues = 0xE, IsLogical = 1 in {
 }
 defm : ZXB<z_ucmp, GR64, CLGFR>;
 
+// Memory-to-memory comparison.
+let mayLoad = 1, Defs = [CC] in
+  defm CLC : MemorySS<"clc", 0xD5, z_clc>;
+
 //===----------------------------------------------------------------------===//
 // Atomic operations
 //===----------------------------------------------------------------------===//
index 6a3af2b89053355f7db60248c23afa7bf948071c..dae04de02b726582aae7f110e2c8b0a4667f3d74 100644 (file)
@@ -54,7 +54,7 @@ def SDT_ZAtomicCmpSwapW     : SDTypeProfile<1, 6,
                                              SDTCisVT<4, i32>,
                                              SDTCisVT<5, i32>,
                                              SDTCisVT<6, i32>]>;
-def SDT_ZCopy               : SDTypeProfile<0, 3,
+def SDT_ZMemMemLength       : SDTypeProfile<0, 3,
                                             [SDTCisPtrTy<0>,
                                              SDTCisPtrTy<1>,
                                              SDTCisVT<2, i32>]>;
@@ -109,8 +109,10 @@ def z_atomic_loadw_umin : AtomicWOp<"ATOMIC_LOADW_UMIN">;
 def z_atomic_loadw_umax : AtomicWOp<"ATOMIC_LOADW_UMAX">;
 def z_atomic_cmp_swapw  : AtomicWOp<"ATOMIC_CMP_SWAPW", SDT_ZAtomicCmpSwapW>;
 
-def z_mvc               : SDNode<"SystemZISD::MVC", SDT_ZCopy,
+def z_mvc               : SDNode<"SystemZISD::MVC", SDT_ZMemMemLength,
                                  [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
+def z_clc               : SDNode<"SystemZISD::CLC", SDT_ZMemMemLength,
+                                 [SDNPHasChain, SDNPMayLoad]>;
 
 //===----------------------------------------------------------------------===//
 // Pattern fragments
index 97e41fee1216d10a58a6d6f1b8ca5fc4d8229623..f76c83a125241fc71aada90a5b1021f4f68ce16a 100644 (file)
 # CHECK: chy %r15, 0
 0xe3 0xf0 0x00 0x00 0x00 0x79
 
+# CHECK: clc 0(1), 0
+0xd5 0x00 0x00 0x00 0x00 0x00
+
+# CHECK: clc 0(1), 0(%r1)
+0xd5 0x00 0x00 0x00 0x10 0x00
+
+# CHECK: clc 0(1), 0(%r15)
+0xd5 0x00 0x00 0x00 0xf0 0x00
+
+# CHECK: clc 0(1), 4095
+0xd5 0x00 0x00 0x00 0x0f 0xff
+
+# CHECK: clc 0(1), 4095(%r1)
+0xd5 0x00 0x00 0x00 0x1f 0xff
+
+# CHECK: clc 0(1), 4095(%r15)
+0xd5 0x00 0x00 0x00 0xff 0xff
+
+# CHECK: clc 0(1,%r1), 0
+0xd5 0x00 0x10 0x00 0x00 0x00
+
+# CHECK: clc 0(1,%r15), 0
+0xd5 0x00 0xf0 0x00 0x00 0x00
+
+# CHECK: clc 4095(1,%r1), 0
+0xd5 0x00 0x1f 0xff 0x00 0x00
+
+# CHECK: clc 4095(1,%r15), 0
+0xd5 0x00 0xff 0xff 0x00 0x00
+
+# CHECK: clc 0(256,%r1), 0
+0xd5 0xff 0x10 0x00 0x00 0x00
+
+# CHECK: clc 0(256,%r15), 0
+0xd5 0xff 0xf0 0x00 0x00 0x00
+
 # CHECK: clfhsi 0, 0
 0xe5 0x5d 0x00 0x00 0x00 0x00
 
 # CHECK: msy %r15, 0
 0xe3 0xf0 0x00 0x00 0x00 0x51
 
+# CHECK: mvc 0(1), 0
+0xd2 0x00 0x00 0x00 0x00 0x00
+
+# CHECK: mvc 0(1), 0(%r1)
+0xd2 0x00 0x00 0x00 0x10 0x00
+
+# CHECK: mvc 0(1), 0(%r15)
+0xd2 0x00 0x00 0x00 0xf0 0x00
+
+# CHECK: mvc 0(1), 4095
+0xd2 0x00 0x00 0x00 0x0f 0xff
+
+# CHECK: mvc 0(1), 4095(%r1)
+0xd2 0x00 0x00 0x00 0x1f 0xff
+
+# CHECK: mvc 0(1), 4095(%r15)
+0xd2 0x00 0x00 0x00 0xff 0xff
+
+# CHECK: mvc 0(1,%r1), 0
+0xd2 0x00 0x10 0x00 0x00 0x00
+
+# CHECK: mvc 0(1,%r15), 0
+0xd2 0x00 0xf0 0x00 0x00 0x00
+
+# CHECK: mvc 4095(1,%r1), 0
+0xd2 0x00 0x1f 0xff 0x00 0x00
+
+# CHECK: mvc 4095(1,%r15), 0
+0xd2 0x00 0xff 0xff 0x00 0x00
+
+# CHECK: mvc 0(256,%r1), 0
+0xd2 0xff 0x10 0x00 0x00 0x00
+
+# CHECK: mvc 0(256,%r15), 0
+0xd2 0xff 0xf0 0x00 0x00 0x00
+
 # CHECK: mvghi 0, 0
 0xe5 0x48 0x00 0x00 0x00 0x00
 
index b730637cd375ed599ba48835c77cb639c7f01cf4..228467004b190a57c9548ec80a8cd7f602ad03b1 100644 (file)
        cl      %r0, -1
        cl      %r0, 4096
 
+#CHECK: error: missing length in address
+#CHECK: clc    0, 0
+#CHECK: error: missing length in address
+#CHECK: clc    0(%r1), 0(%r1)
+#CHECK: error: invalid use of length addressing
+#CHECK: clc    0(1,%r1), 0(2,%r1)
+#CHECK: error: invalid operand
+#CHECK: clc    0(0,%r1), 0(%r1)
+#CHECK: error: invalid operand
+#CHECK: clc    0(257,%r1), 0(%r1)
+#CHECK: error: invalid operand
+#CHECK: clc    -1(1,%r1), 0(%r1)
+#CHECK: error: invalid operand
+#CHECK: clc    4096(1,%r1), 0(%r1)
+#CHECK: error: invalid operand
+#CHECK: clc    0(1,%r1), -1(%r1)
+#CHECK: error: invalid operand
+#CHECK: clc    0(1,%r1), 4096(%r1)
+#CHECK: error: %r0 used in an address
+#CHECK: clc    0(1,%r0), 0(%r1)
+#CHECK: error: %r0 used in an address
+#CHECK: clc    0(1,%r1), 0(%r0)
+#CHECK: error: invalid use of indexed addressing
+#CHECK: clc    0(%r1,%r2), 0(%r1)
+#CHECK: error: invalid use of indexed addressing
+#CHECK: clc    0(1,%r2), 0(%r1,%r2)
+#CHECK: error: unknown token in expression
+#CHECK: clc    0(-), 0
+
+       clc     0, 0
+       clc     0(%r1), 0(%r1)
+       clc     0(1,%r1), 0(2,%r1)
+       clc     0(0,%r1), 0(%r1)
+       clc     0(257,%r1), 0(%r1)
+       clc     -1(1,%r1), 0(%r1)
+       clc     4096(1,%r1), 0(%r1)
+       clc     0(1,%r1), -1(%r1)
+       clc     0(1,%r1), 4096(%r1)
+       clc     0(1,%r0), 0(%r1)
+       clc     0(1,%r1), 0(%r0)
+       clc     0(%r1,%r2), 0(%r1)
+       clc     0(1,%r2), 0(%r1,%r2)
+       clc     0(-), 0
+
 #CHECK: error: invalid operand
 #CHECK: clfhsi -1, 0
 #CHECK: error: invalid operand
index c4e09e47783a11415db0f048603303c30a1d180a..9fd0d0c7dc7d04ff4740ac086e2835459961c59d 100644 (file)
        cl      %r0, 4095(%r15,%r1)
        cl      %r15, 0
 
+#CHECK: clc    0(1), 0                 # encoding: [0xd5,0x00,0x00,0x00,0x00,0x00]
+#CHECK: clc    0(1), 0(%r1)            # encoding: [0xd5,0x00,0x00,0x00,0x10,0x00]
+#CHECK: clc    0(1), 0(%r15)           # encoding: [0xd5,0x00,0x00,0x00,0xf0,0x00]
+#CHECK: clc    0(1), 4095              # encoding: [0xd5,0x00,0x00,0x00,0x0f,0xff]
+#CHECK: clc    0(1), 4095(%r1)         # encoding: [0xd5,0x00,0x00,0x00,0x1f,0xff]
+#CHECK: clc    0(1), 4095(%r15)        # encoding: [0xd5,0x00,0x00,0x00,0xff,0xff]
+#CHECK: clc    0(1,%r1), 0             # encoding: [0xd5,0x00,0x10,0x00,0x00,0x00]
+#CHECK: clc    0(1,%r15), 0            # encoding: [0xd5,0x00,0xf0,0x00,0x00,0x00]
+#CHECK: clc    4095(1,%r1), 0          # encoding: [0xd5,0x00,0x1f,0xff,0x00,0x00]
+#CHECK: clc    4095(1,%r15), 0         # encoding: [0xd5,0x00,0xff,0xff,0x00,0x00]
+#CHECK: clc    0(256,%r1), 0           # encoding: [0xd5,0xff,0x10,0x00,0x00,0x00]
+#CHECK: clc    0(256,%r15), 0          # encoding: [0xd5,0xff,0xf0,0x00,0x00,0x00]
+
+       clc     0(1), 0
+       clc     0(1), 0(%r1)
+       clc     0(1), 0(%r15)
+       clc     0(1), 4095
+       clc     0(1), 4095(%r1)
+       clc     0(1), 4095(%r15)
+       clc     0(1,%r1), 0
+       clc     0(1,%r15), 0
+       clc     4095(1,%r1), 0
+       clc     4095(1,%r15), 0
+       clc     0(256,%r1), 0
+       clc     0(256,%r15), 0
+
 #CHECK: clfhsi 0, 0                    # encoding: [0xe5,0x5d,0x00,0x00,0x00,0x00]
 #CHECK: clfhsi 4095, 0                 # encoding: [0xe5,0x5d,0x0f,0xff,0x00,0x00]
 #CHECK: clfhsi 0, 65535                # encoding: [0xe5,0x5d,0x00,0x00,0xff,0xff]