Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 93f9010

Browse files
committed
[SystemZ] Support CL(G)T instructions
This adds support for the compare logical and trap (memory) instructions that were added as part of the miscellaneous instruction extensions feature with zEC12. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@286587 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 864946f commit 93f9010

File tree

10 files changed

+346
-3
lines changed

10 files changed

+346
-3
lines changed

lib/Target/SystemZ/SystemZElimCompare.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ bool SystemZElimCompare::fuseCompareOperations(
403403
return false;
404404

405405
// Make sure that the operands are available at the branch.
406+
// SrcReg2 is the register if the source operand is a register,
407+
// 0 if the source operand is immediate, and the base register
408+
// if the source operand is memory (index is not supported).
406409
unsigned SrcReg = Compare.getOperand(0).getReg();
407410
unsigned SrcReg2 =
408411
Compare.getOperand(1).isReg() ? Compare.getOperand(1).getReg() : 0;
@@ -435,11 +438,16 @@ bool SystemZElimCompare::fuseCompareOperations(
435438
Branch->RemoveOperand(0);
436439

437440
// Rebuild Branch as a fused compare and branch.
441+
// SrcNOps is the number of MI operands of the compare instruction
442+
// that we need to copy over.
443+
unsigned SrcNOps = 2;
444+
if (FusedOpcode == SystemZ::CLT || FusedOpcode == SystemZ::CLGT)
445+
SrcNOps = 3;
438446
Branch->setDesc(TII->get(FusedOpcode));
439447
MachineInstrBuilder MIB(*Branch->getParent()->getParent(), Branch);
440-
MIB.addOperand(Compare.getOperand(0))
441-
.addOperand(Compare.getOperand(1))
442-
.addOperand(CCMask);
448+
for (unsigned I = 0; I < SrcNOps; I++)
449+
MIB.addOperand(Compare.getOperand(I));
450+
MIB.addOperand(CCMask);
443451

444452
if (Type == SystemZII::CompareAndBranch) {
445453
// Only conditional branches define CC, as they may be converted back

lib/Target/SystemZ/SystemZInstrFormats.td

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,31 @@ multiclass CmpBranchRISPair<string mnemonic, bits<16> opcode,
18791879
def Asm : AsmCmpBranchRIS<mnemonic, opcode, cls, imm>;
18801880
}
18811881

1882+
class CmpBranchRSYb<string mnemonic, bits<16> opcode,
1883+
RegisterOperand cls>
1884+
: InstRSYb<opcode, (outs), (ins cls:$R1, bdaddr20only:$BD2, cond4:$M3),
1885+
mnemonic#"$M3\t$R1, $BD2", []>;
1886+
1887+
class AsmCmpBranchRSYb<string mnemonic, bits<16> opcode,
1888+
RegisterOperand cls>
1889+
: InstRSYb<opcode, (outs), (ins cls:$R1, bdaddr20only:$BD2, imm32zx4:$M3),
1890+
mnemonic#"\t$R1, $M3, $BD2", []>;
1891+
1892+
multiclass CmpBranchRSYbPair<string mnemonic, bits<16> opcode,
1893+
RegisterOperand cls> {
1894+
let isCodeGenOnly = 1 in
1895+
def "" : CmpBranchRSYb<mnemonic, opcode, cls>;
1896+
def Asm : AsmCmpBranchRSYb<mnemonic, opcode, cls>;
1897+
}
1898+
1899+
class FixedCmpBranchRSYb<CondVariant V, string mnemonic, bits<16> opcode,
1900+
RegisterOperand cls>
1901+
: InstRSYb<opcode, (outs), (ins cls:$R1, bdaddr20only:$BD2),
1902+
mnemonic#V.suffix#"\t$R1, $BD2", []> {
1903+
let isAsmParserOnly = V.alternate;
1904+
let M3 = V.ccmask;
1905+
}
1906+
18821907
class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls>
18831908
: InstRIb<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget16:$RI2),
18841909
mnemonic##"\t$R1, $RI2", []> {

lib/Target/SystemZ/SystemZInstrInfo.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,14 @@ unsigned SystemZInstrInfo::getFusedCompare(unsigned Opcode,
14161416
case SystemZ::CLGFI:
14171417
if (!(MI && isUInt<8>(MI->getOperand(1).getImm())))
14181418
return 0;
1419+
break;
1420+
case SystemZ::CL:
1421+
case SystemZ::CLG:
1422+
if (!STI.hasMiscellaneousExtensions())
1423+
return 0;
1424+
if (!(MI && MI->getOperand(3).getReg() == 0))
1425+
return 0;
1426+
break;
14191427
}
14201428
switch (Type) {
14211429
case SystemZII::CompareAndBranch:
@@ -1499,6 +1507,10 @@ unsigned SystemZInstrInfo::getFusedCompare(unsigned Opcode,
14991507
return SystemZ::CLFIT;
15001508
case SystemZ::CLGFI:
15011509
return SystemZ::CLGIT;
1510+
case SystemZ::CL:
1511+
return SystemZ::CLT;
1512+
case SystemZ::CLG:
1513+
return SystemZ::CLGT;
15021514
default:
15031515
return 0;
15041516
}

lib/Target/SystemZ/SystemZInstrInfo.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ let isTerminator = 1, hasCtrlDep = 1 in {
192192
defm CGIT : CmpBranchRIEaPair<"cgit", 0xEC70, GR64, imm64sx16>;
193193
defm CLFIT : CmpBranchRIEaPair<"clfit", 0xEC73, GR32, imm32zx16>;
194194
defm CLGIT : CmpBranchRIEaPair<"clgit", 0xEC71, GR64, imm64zx16>;
195+
let Predicates = [FeatureMiscellaneousExtensions] in {
196+
defm CLT : CmpBranchRSYbPair<"clt", 0xEB23, GR32>;
197+
defm CLGT : CmpBranchRSYbPair<"clgt", 0xEB2B, GR64>;
198+
}
195199

196200
foreach V = [ "E", "H", "L", "HE", "LE", "LH",
197201
"NE", "NH", "NL", "NHE", "NLE", "NLH" ] in {
@@ -207,6 +211,10 @@ let isTerminator = 1, hasCtrlDep = 1 in {
207211
imm32zx16>;
208212
def CLGITAsm#V : FixedCmpBranchRIEa<ICV<V>, "clgit", 0xEC71, GR64,
209213
imm64zx16>;
214+
let Predicates = [FeatureMiscellaneousExtensions] in {
215+
def CLTAsm#V : FixedCmpBranchRSYb<ICV<V>, "clt", 0xEB23, GR32>;
216+
def CLGTAsm#V : FixedCmpBranchRSYb<ICV<V>, "clgt", 0xEB2B, GR64>;
217+
}
210218
}
211219
}
212220

lib/Target/SystemZ/SystemZScheduleZ13.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ def : InstRW<[VBU], (instregex "(Cond)?Trap$")>;
134134
def : InstRW<[FXb], (instregex "C(G)?(I|R)T(Asm.*)?$")>;
135135
def : InstRW<[FXb], (instregex "CL(G)?RT(Asm.*)?$")>;
136136
def : InstRW<[FXb], (instregex "CL(F|G)IT(Asm.*)?$")>;
137+
def : InstRW<[FXb, LSU, Lat5], (instregex "CL(G)?T(Asm.*)?$")>;
137138

138139
//===----------------------------------------------------------------------===//
139140
// Call and return instructions

lib/Target/SystemZ/SystemZScheduleZEC12.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def : InstRW<[VBU], (instregex "(Cond)?Trap$")>;
111111
def : InstRW<[FXU], (instregex "C(G)?(I|R)T(Asm.*)?$")>;
112112
def : InstRW<[FXU], (instregex "CL(G)?RT(Asm.*)?$")>;
113113
def : InstRW<[FXU], (instregex "CL(F|G)IT(Asm.*)?$")>;
114+
def : InstRW<[FXU, LSU, Lat5], (instregex "CL(G)?T(Asm.*)?$")>;
114115

115116
//===----------------------------------------------------------------------===//
116117
// Call and return instructions

test/CodeGen/SystemZ/trap-02.ll

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
; Test zE12 conditional traps
2+
;
3+
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 | FileCheck %s
4+
5+
declare void @llvm.trap()
6+
7+
; Check conditional compare logical and trap
8+
define i32 @f1(i32 zeroext %a, i32 *%ptr) {
9+
; CHECK-LABEL: f1:
10+
; CHECK: clth %r2, 0(%r3)
11+
; CHECK: lhi %r2, 0
12+
; CHECK: br %r14
13+
entry:
14+
%b = load i32, i32 *%ptr
15+
%cmp = icmp ugt i32 %a, %b
16+
br i1 %cmp, label %if.then, label %if.end
17+
18+
if.then: ; preds = %entry
19+
tail call void @llvm.trap()
20+
unreachable
21+
22+
if.end: ; preds = %entry
23+
ret i32 0
24+
}
25+
26+
; Check conditional compare logical grande and trap
27+
define i64 @f2(i64 zeroext %a, i64 *%ptr) {
28+
; CHECK-LABEL: f2:
29+
; CHECK: clgtl %r2, 0(%r3)
30+
; CHECK: lghi %r2, 0
31+
; CHECK: br %r14
32+
entry:
33+
%b = load i64, i64 *%ptr
34+
%cmp = icmp ult i64 %a, %b
35+
br i1 %cmp, label %if.then, label %if.end
36+
37+
if.then: ; preds = %entry
38+
tail call void @llvm.trap()
39+
unreachable
40+
41+
if.end: ; preds = %entry
42+
ret i64 0
43+
}
44+
45+
; Verify that we don't attempt to use the compare and trap
46+
; instruction with an index operand.
47+
define i32 @f3(i32 zeroext %a, i32 *%base, i64 %offset) {
48+
; CHECK-LABEL: f3:
49+
; CHECK: cl %r2, 0(%r{{[0-5]}},%r3)
50+
; CHECK-LABEL: .Ltmp0
51+
; CHECK: jh .Ltmp0+2
52+
; CHECK: lhi %r2, 0
53+
; CHECK: br %r14
54+
entry:
55+
%ptr = getelementptr i32, i32 *%base, i64 %offset
56+
%b = load i32, i32 *%ptr
57+
%cmp = icmp ugt i32 %a, %b
58+
br i1 %cmp, label %if.then, label %if.end
59+
60+
if.then: ; preds = %entry
61+
tail call void @llvm.trap()
62+
unreachable
63+
64+
if.end: ; preds = %entry
65+
ret i32 0
66+
}
67+
68+
; Verify that we don't attempt to use the compare and trap grande
69+
; instruction with an index operand.
70+
define i64 @f4(i64 %a, i64 *%base, i64 %offset) {
71+
; CHECK-LABEL: f4:
72+
; CHECK: clg %r2, 0(%r{{[0-5]}},%r3)
73+
; CHECK-LABEL: .Ltmp1
74+
; CHECK: jh .Ltmp1+2
75+
; CHECK: lghi %r2, 0
76+
; CHECK: br %r14
77+
entry:
78+
%ptr = getelementptr i64, i64 *%base, i64 %offset
79+
%b = load i64, i64 *%ptr
80+
%cmp = icmp ugt i64 %a, %b
81+
br i1 %cmp, label %if.then, label %if.end
82+
83+
if.then: ; preds = %entry
84+
tail call void @llvm.trap()
85+
unreachable
86+
87+
if.end: ; preds = %entry
88+
ret i64 0
89+
}
90+

test/MC/Disassembler/SystemZ/insns.txt

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2872,6 +2872,90 @@
28722872
# CHECK: clrtle %r0, %r1
28732873
0xb9 0x73 0xc0 0x01
28742874

2875+
# CHECK: clth %r0, -524288
2876+
0xeb 0x02 0x00 0x00 0x80 0x23
2877+
2878+
# CHECK: clth %r0, -1
2879+
0xeb 0x02 0x0f 0xff 0xff 0x23
2880+
2881+
# CHECK: clth %r0, 0
2882+
0xeb 0x02 0x00 0x00 0x00 0x23
2883+
2884+
# CHECK: clth %r0, 1
2885+
0xeb 0x02 0x00 0x01 0x00 0x23
2886+
2887+
# CHECK: clth %r0, 524287
2888+
0xeb 0x02 0x0f 0xff 0x7f 0x23
2889+
2890+
# CHECK: clth %r0, 0(%r1)
2891+
0xeb 0x02 0x10 0x00 0x00 0x23
2892+
2893+
# CHECK: clth %r0, 0(%r15)
2894+
0xeb 0x02 0xf0 0x00 0x00 0x23
2895+
2896+
# CHECK: clth %r0, 12345(%r6)
2897+
0xeb 0x02 0x60 0x39 0x03 0x23
2898+
2899+
# CHECK: clth %r1, 0
2900+
0xeb 0x12 0x00 0x00 0x00 0x23
2901+
2902+
# CHECK: cltl %r1, 0
2903+
0xeb 0x14 0x00 0x00 0x00 0x23
2904+
2905+
# CHECK: clte %r1, 0
2906+
0xeb 0x18 0x00 0x00 0x00 0x23
2907+
2908+
# CHECK: cltlh %r1, 0
2909+
0xeb 0x16 0x00 0x00 0x00 0x23
2910+
2911+
# CHECK: clthe %r1, 0
2912+
0xeb 0x1a 0x00 0x00 0x00 0x23
2913+
2914+
# CHECK: cltle %r1, 0
2915+
0xeb 0x1c 0x00 0x00 0x00 0x23
2916+
2917+
# CHECK: clgth %r0, -524288
2918+
0xeb 0x02 0x00 0x00 0x80 0x2b
2919+
2920+
# CHECK: clgth %r0, -1
2921+
0xeb 0x02 0x0f 0xff 0xff 0x2b
2922+
2923+
# CHECK: clgth %r0, 0
2924+
0xeb 0x02 0x00 0x00 0x00 0x2b
2925+
2926+
# CHECK: clgth %r0, 1
2927+
0xeb 0x02 0x00 0x01 0x00 0x2b
2928+
2929+
# CHECK: clgth %r0, 524287
2930+
0xeb 0x02 0x0f 0xff 0x7f 0x2b
2931+
2932+
# CHECK: clgth %r0, 0(%r1)
2933+
0xeb 0x02 0x10 0x00 0x00 0x2b
2934+
2935+
# CHECK: clgth %r0, 0(%r15)
2936+
0xeb 0x02 0xf0 0x00 0x00 0x2b
2937+
2938+
# CHECK: clgth %r0, 12345(%r6)
2939+
0xeb 0x02 0x60 0x39 0x03 0x2b
2940+
2941+
# CHECK: clgth %r1, 0
2942+
0xeb 0x12 0x00 0x00 0x00 0x2b
2943+
2944+
# CHECK: clgtl %r1, 0
2945+
0xeb 0x14 0x00 0x00 0x00 0x2b
2946+
2947+
# CHECK: clgte %r1, 0
2948+
0xeb 0x18 0x00 0x00 0x00 0x2b
2949+
2950+
# CHECK: clgtlh %r1, 0
2951+
0xeb 0x16 0x00 0x00 0x00 0x2b
2952+
2953+
# CHECK: clgthe %r1, 0
2954+
0xeb 0x1a 0x00 0x00 0x00 0x2b
2955+
2956+
# CHECK: clgtle %r1, 0
2957+
0xeb 0x1c 0x00 0x00 0x00 0x2b
2958+
28752959
# CHECK: clst %r0, %r0
28762960
0xb2 0x5d 0x00 0x00
28772961

test/MC/SystemZ/insn-bad-zEC12.s

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,56 @@
44
# RUN: not llvm-mc -triple s390x-linux-gnu -mcpu=arch10 < %s 2> %t
55
# RUN: FileCheck < %t %s
66

7+
#CHECK: error: invalid operand
8+
#CHECK: clt %r0, -1, 0
9+
#CHECK: error: invalid operand
10+
#CHECK: clt %r0, 16, 0
11+
#CHECK: error: invalid operand
12+
#CHECK: clt %r0, 12, -524289
13+
#CHECK: error: invalid operand
14+
#CHECK: clt %r0, 12, 524288
15+
#CHECK: error: invalid use of indexed addressing
16+
#CHECK: clt %r0, 12, 0(%r1,%r2)
17+
18+
clt %r0, -1, 0
19+
clt %r0, 16, 0
20+
clt %r0, 12, -524289
21+
clt %r0, 12, 524288
22+
clt %r0, 12, 0(%r1,%r2)
23+
24+
#CHECK: error: invalid instruction
25+
#CHECK: clto %r0, 0
26+
#CHECK: error: invalid instruction
27+
#CHECK: cltno %r0, 0
28+
29+
clto %r0, 0
30+
cltno %r0, 0
31+
32+
#CHECK: error: invalid operand
33+
#CHECK: clgt %r0, -1, 0
34+
#CHECK: error: invalid operand
35+
#CHECK: clgt %r0, 16, 0
36+
#CHECK: error: invalid operand
37+
#CHECK: clgt %r0, 12, -524289
38+
#CHECK: error: invalid operand
39+
#CHECK: clgt %r0, 12, 524288
40+
#CHECK: error: invalid use of indexed addressing
41+
#CHECK: clgt %r0, 12, 0(%r1,%r2)
42+
43+
clgt %r0, -1, 0
44+
clgt %r0, 16, 0
45+
clgt %r0, 12, -524289
46+
clgt %r0, 12, 524288
47+
clgt %r0, 12, 0(%r1,%r2)
48+
49+
#CHECK: error: invalid instruction
50+
#CHECK: clgto %r0, 0
51+
#CHECK: error: invalid instruction
52+
#CHECK: clgtno %r0, 0
53+
54+
clgto %r0, 0
55+
clgtno %r0, 0
56+
757
#CHECK: error: instruction requires: vector
858
#CHECK: lcbb %r0, 0, 0
959

0 commit comments

Comments
 (0)