summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-08-12 10:17:33 +0000
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-08-12 10:17:33 +0000
commite03a56d62fc623e2f72d623b816f91b293d5904b (patch)
treea44f78deb25219ad36468a9d206b887fab879389
parentf37c8feb468a0e1876c08bdeb449bdb5999c0534 (diff)
downloadllvm-e03a56d62fc623e2f72d623b816f91b293d5904b.tar.gz
llvm-e03a56d62fc623e2f72d623b816f91b293d5904b.tar.bz2
llvm-e03a56d62fc623e2f72d623b816f91b293d5904b.tar.xz
[SystemZ] Add a definition of the CLC instruction
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188162 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.cpp1
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.h4
-rw-r--r--lib/Target/SystemZ/SystemZInstrFormats.td19
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.td14
-rw-r--r--lib/Target/SystemZ/SystemZOperators.td6
-rw-r--r--test/MC/Disassembler/SystemZ/insns.txt72
-rw-r--r--test/MC/SystemZ/insn-bad.s44
-rw-r--r--test/MC/SystemZ/insn-good.s26
8 files changed, 175 insertions, 11 deletions
diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp
index 6acdcd4bef..a51f0168a9 100644
--- a/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -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);
diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h
index c0dbe493c0..4098ff34b3 100644
--- a/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/lib/Target/SystemZ/SystemZISelLowering.h
@@ -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>.
//
diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td
index 2af8e83aed..2d18e03eb5 100644
--- a/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -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)]>;
+}
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td
index 5371e8ad4d..a7181d68a7 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -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
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/SystemZ/SystemZOperators.td b/lib/Target/SystemZ/SystemZOperators.td
index 6a3af2b890..dae04de02b 100644
--- a/lib/Target/SystemZ/SystemZOperators.td
+++ b/lib/Target/SystemZ/SystemZOperators.td
@@ -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
diff --git a/test/MC/Disassembler/SystemZ/insns.txt b/test/MC/Disassembler/SystemZ/insns.txt
index 97e41fee12..f76c83a125 100644
--- a/test/MC/Disassembler/SystemZ/insns.txt
+++ b/test/MC/Disassembler/SystemZ/insns.txt
@@ -1333,6 +1333,42 @@
# 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
@@ -4444,6 +4480,42 @@
# 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
diff --git a/test/MC/SystemZ/insn-bad.s b/test/MC/SystemZ/insn-bad.s
index b730637cd3..228467004b 100644
--- a/test/MC/SystemZ/insn-bad.s
+++ b/test/MC/SystemZ/insn-bad.s
@@ -712,6 +712,50 @@
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
diff --git a/test/MC/SystemZ/insn-good.s b/test/MC/SystemZ/insn-good.s
index c4e09e4778..9fd0d0c7dc 100644
--- a/test/MC/SystemZ/insn-good.s
+++ b/test/MC/SystemZ/insn-good.s
@@ -2454,6 +2454,32 @@
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]