summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-08-05 11:07:38 +0000
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-08-05 11:07:38 +0000
commitccdf5cc7bc443726425dd1ad498d44768332d49c (patch)
treeba6ba8530fea0b0d41dff8638f24d06bd3997035
parent9b05c709c65ba05645853ca49bc2a1ea8b554f37 (diff)
downloadllvm-ccdf5cc7bc443726425dd1ad498d44768332d49c.tar.gz
llvm-ccdf5cc7bc443726425dd1ad498d44768332d49c.tar.bz2
llvm-ccdf5cc7bc443726425dd1ad498d44768332d49c.tar.xz
[SystemZ] Add definitions for BRCT and BRCTG
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187721 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/SystemZ/SystemZInstrFormats.td15
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.td7
-rw-r--r--test/MC/Disassembler/SystemZ/insns-pcrel.txt32
-rw-r--r--test/MC/SystemZ/insn-bad.s28
-rw-r--r--test/MC/SystemZ/insn-good.s32
5 files changed, 114 insertions, 0 deletions
diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td
index 9883714903..534ed88652 100644
--- a/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -489,6 +489,12 @@ class InstSS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
// Inherent:
// One register output operand and no input operands.
//
+// BranchUnary:
+// One register output operand, one register input operand and
+// one branch displacement. The instructions stores a modified
+// form of the source register in the destination register and
+// branches on the result.
+//
// Store:
// One register or immediate input operand and one address input operand.
// The instruction stores the first operand to the address.
@@ -555,6 +561,15 @@ class InherentRRE<string mnemonic, bits<16> opcode, RegisterOperand cls,
let R2 = 0;
}
+class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls>
+ : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget16:$I2),
+ mnemonic##"\t$R1, $I2", []> {
+ let isBranch = 1;
+ let isTerminator = 1;
+ let Constraints = "$R1 = $R1src";
+ let DisableEncoding = "$R1src";
+}
+
class LoadMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
: InstRSY<opcode, (outs cls:$R1, cls:$R3), (ins bdaddr20only:$BD2),
mnemonic#"\t$R1, $R3, $BD2", []> {
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td
index 58fb662efd..73a6126f03 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -166,6 +166,13 @@ defm AsmJE : IntCondExtendedMnemonic<8, "e", "nlh">;
defm AsmJHE : IntCondExtendedMnemonic<10, "he", "nl">;
defm AsmJLE : IntCondExtendedMnemonic<12, "le", "nh">;
+// Decrement a register and branch if it is nonzero. These don't clobber CC,
+// but we might need to split long branches into sequences that do.
+let Defs = [CC] in {
+ def BRCT : BranchUnaryRI<"brct", 0xA76, GR32>;
+ def BRCTG : BranchUnaryRI<"brctg", 0xA77, GR64>;
+}
+
//===----------------------------------------------------------------------===//
// Select instructions
//===----------------------------------------------------------------------===//
diff --git a/test/MC/Disassembler/SystemZ/insns-pcrel.txt b/test/MC/Disassembler/SystemZ/insns-pcrel.txt
index f9e7774cbd..c565b6e47b 100644
--- a/test/MC/Disassembler/SystemZ/insns-pcrel.txt
+++ b/test/MC/Disassembler/SystemZ/insns-pcrel.txt
@@ -1298,3 +1298,35 @@
# 0x0000075a:
# CHECK: cij %r0, 0, 15, 0x75a
0xec 0x0f 0x00 0x00 0x00 0x7e
+
+# 0x00000760:
+# CHECK: brct %r0, 0x760
+0xa7 0x06 0x00 0x00
+
+# 0x00000764:
+# CHECK: brct %r1, 0x762
+0xa7 0x16 0xff 0xff
+
+# 0x00000768:
+# CHECK: brct %r9, 0xffffffffffff0768
+0xa7 0x96 0x80 0x00
+
+# 0x0000076c:
+# CHECK: brct %r15, 0x1076a
+0xa7 0xf6 0x7f 0xff
+
+# 0x00000770:
+# CHECK: brctg %r0, 0x770
+0xa7 0x07 0x00 0x00
+
+# 0x00000774:
+# CHECK: brctg %r1, 0x772
+0xa7 0x17 0xff 0xff
+
+# 0x00000778:
+# CHECK: brctg %r9, 0xffffffffffff0778
+0xa7 0x97 0x80 0x00
+
+# 0x0000077c:
+# CHECK: brctg %r15, 0x1077a
+0xa7 0xf7 0x7f 0xff
diff --git a/test/MC/SystemZ/insn-bad.s b/test/MC/SystemZ/insn-bad.s
index a3218edb94..246f5ce661 100644
--- a/test/MC/SystemZ/insn-bad.s
+++ b/test/MC/SystemZ/insn-bad.s
@@ -329,6 +329,34 @@
brcl -1, bar
brcl 16, bar
+#CHECK: error: offset out of range
+#CHECK: brct %r0, -0x100002
+#CHECK: error: offset out of range
+#CHECK: brct %r0, -1
+#CHECK: error: offset out of range
+#CHECK: brct %r0, 1
+#CHECK: error: offset out of range
+#CHECK: brct %r0, 0x10000
+
+ brct %r0, -0x100002
+ brct %r0, -1
+ brct %r0, 1
+ brct %r0, 0x10000
+
+#CHECK: error: offset out of range
+#CHECK: brctg %r0, -0x100002
+#CHECK: error: offset out of range
+#CHECK: brctg %r0, -1
+#CHECK: error: offset out of range
+#CHECK: brctg %r0, 1
+#CHECK: error: offset out of range
+#CHECK: brctg %r0, 0x10000
+
+ brctg %r0, -0x100002
+ brctg %r0, -1
+ brctg %r0, 1
+ brctg %r0, 0x10000
+
#CHECK: error: invalid operand
#CHECK: c %r0, -1
#CHECK: error: invalid operand
diff --git a/test/MC/SystemZ/insn-good.s b/test/MC/SystemZ/insn-good.s
index 5ddae83a7a..7686238da4 100644
--- a/test/MC/SystemZ/insn-good.s
+++ b/test/MC/SystemZ/insn-good.s
@@ -1122,6 +1122,38 @@
#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC32DBL
jg bar@PLT
+#CHECK: brct %r0, .[[LAB:L.*]]-65536 # encoding: [0xa7,0x06,A,A]
+#CHECK: fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL
+ brct %r0, -0x10000
+#CHECK: brct %r0, .[[LAB:L.*]]-2 # encoding: [0xa7,0x06,A,A]
+#CHECK: fixup A - offset: 2, value: (.[[LAB]]-2)+2, kind: FK_390_PC16DBL
+ brct %r0, -2
+#CHECK: brct %r0, .[[LAB:L.*]] # encoding: [0xa7,0x06,A,A]
+#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL
+ brct %r0, 0
+#CHECK: brct %r0, .[[LAB:L.*]]+65534 # encoding: [0xa7,0x06,A,A]
+#CHECK: fixup A - offset: 2, value: (.[[LAB]]+65534)+2, kind: FK_390_PC16DBL
+ brct %r0, 0xfffe
+#CHECK: brct %r15, .[[LAB:L.*]] # encoding: [0xa7,0xf6,A,A]
+#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL
+ brct %r15, 0
+
+#CHECK: brctg %r0, .[[LAB:L.*]]-65536 # encoding: [0xa7,0x07,A,A]
+#CHECK: fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL
+ brctg %r0, -0x10000
+#CHECK: brctg %r0, .[[LAB:L.*]]-2 # encoding: [0xa7,0x07,A,A]
+#CHECK: fixup A - offset: 2, value: (.[[LAB]]-2)+2, kind: FK_390_PC16DBL
+ brctg %r0, -2
+#CHECK: brctg %r0, .[[LAB:L.*]] # encoding: [0xa7,0x07,A,A]
+#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL
+ brctg %r0, 0
+#CHECK: brctg %r0, .[[LAB:L.*]]+65534 # encoding: [0xa7,0x07,A,A]
+#CHECK: fixup A - offset: 2, value: (.[[LAB]]+65534)+2, kind: FK_390_PC16DBL
+ brctg %r0, 0xfffe
+#CHECK: brctg %r15, .[[LAB:L.*]] # encoding: [0xa7,0xf7,A,A]
+#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL
+ brctg %r15, 0
+
#CHECK: c %r0, 0 # encoding: [0x59,0x00,0x00,0x00]
#CHECK: c %r0, 4095 # encoding: [0x59,0x00,0x0f,0xff]
#CHECK: c %r0, 0(%r1) # encoding: [0x59,0x00,0x10,0x00]