[SystemZ] Add NRK, ORK and XRK

The atomic tests assume the two-operand forms, so I've restricted them to z10.

Running and-01.ll, or-01.ll and xor-01.ll for z196 as well as z10 shows why
using convertToThreeAddress() is better than exposing the three-operand forms
first and then converting back to two operands where possible (which is what
I'd originally tried).  Using the three-operand form first stops us from
taking advantage of NG, OG and XG for spills.

llvm-svn: 186683
This commit is contained in:
Richard Sandiford 2013-07-19 16:21:55 +00:00
parent 34869503cb
commit 0175b4a353
15 changed files with 163 additions and 10 deletions

View File

@ -729,6 +729,24 @@ class BinaryRRF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
let OpType = "reg";
}
class BinaryRRFK<string mnemonic, bits<16> opcode, SDPatternOperator operator,
RegisterOperand cls1, RegisterOperand cls2>
: InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R2, cls2:$R3),
mnemonic#"rk\t$R1, $R2, $R3",
[(set cls1:$R1, (operator cls1:$R2, cls2:$R3))]>;
multiclass BinaryRRAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
SDPatternOperator operator, RegisterOperand cls1,
RegisterOperand cls2> {
let NumOpsKey = mnemonic in {
let NumOpsValue = "3" in
def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>,
Requires<[FeatureDistinctOps]>;
let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
def "" : BinaryRR<mnemonic, opcode1, operator, cls1, cls2>;
}
}
class BinaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
RegisterOperand cls, Immediate imm>
: InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),

View File

@ -648,7 +648,7 @@ let Defs = [CC], Uses = [CC] in {
let Defs = [CC] in {
// ANDs of a register.
let isCommutable = 1 in {
def NR : BinaryRR <"n", 0x14, and, GR32, GR32>;
defm NR : BinaryRRAndK<"n", 0x14, 0xB9F4, and, GR32, GR32>;
def NGR : BinaryRRE<"ng", 0xB980, and, GR64, GR64>;
}
@ -685,7 +685,7 @@ defm : RMWIByte<and, bdaddr20pair, NIY>;
let Defs = [CC] in {
// ORs of a register.
let isCommutable = 1 in {
def OR : BinaryRR <"o", 0x16, or, GR32, GR32>;
defm OR : BinaryRRAndK<"o", 0x16, 0xB9F6, or, GR32, GR32>;
def OGR : BinaryRRE<"og", 0xB981, or, GR64, GR64>;
}
@ -722,7 +722,7 @@ defm : RMWIByte<or, bdaddr20pair, OIY>;
let Defs = [CC] in {
// XORs of a register.
let isCommutable = 1 in {
def XR : BinaryRR <"x", 0x17, xor, GR32, GR32>;
defm XR : BinaryRRAndK<"x", 0x17, 0xB9F7, xor, GR32, GR32>;
def XGR : BinaryRRE<"xg", 0xB982, xor, GR64, GR64>;
}

View File

@ -1,6 +1,7 @@
; Test 32-bit ANDs in which the second operand is variable.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
declare i32 @foo()

View File

@ -0,0 +1,21 @@
; Test the three-operand forms of AND.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
; Check NRK.
define i32 @f1(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: f1:
; CHECK: nrk %r2, %r3, %r4
; CHECK: br %r14
%and = and i32 %b, %c
ret i32 %and
}
; Check that we can still use NR in obvious cases.
define i32 @f2(i32 %a, i32 %b) {
; CHECK-LABEL: f2:
; CHECK: nr %r2, %r3
; CHECK: br %r14
%and = and i32 %a, %b
ret i32 %and
}

View File

@ -1,6 +1,6 @@
; Test 32-bit atomic ANDs.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; Check ANDs of a variable.
define i32 @f1(i32 %dummy, i32 *%src, i32 %b) {

View File

@ -1,6 +1,6 @@
; Test 32-bit atomic NANDs.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; Check NANDs of a variable.
define i32 @f1(i32 %dummy, i32 *%src, i32 %b) {

View File

@ -1,6 +1,6 @@
; Test 32-bit atomic ORs.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; Check ORs of a variable.
define i32 @f1(i32 %dummy, i32 *%src, i32 %b) {

View File

@ -1,6 +1,6 @@
; Test 32-bit atomic XORs.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; Check XORs of a variable.
define i32 @f1(i32 %dummy, i32 *%src, i32 %b) {

View File

@ -1,6 +1,7 @@
; Test 32-bit ORs in which the second operand is variable.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
declare i32 @foo()

View File

@ -0,0 +1,21 @@
; Test the three-operand forms of OR.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
; Check XRK.
define i32 @f1(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: f1:
; CHECK: ork %r2, %r3, %r4
; CHECK: br %r14
%or = or i32 %b, %c
ret i32 %or
}
; Check that we can still use OR in obvious cases.
define i32 @f2(i32 %a, i32 %b) {
; CHECK-LABEL: f2:
; CHECK: or %r2, %r3
; CHECK: br %r14
%or = or i32 %a, %b
ret i32 %or
}

View File

@ -1,6 +1,7 @@
; Test 32-bit XORs in which the second operand is variable.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
declare i32 @foo()

View File

@ -0,0 +1,21 @@
; Test the three-operand forms of XOR.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
; Check XRK.
define i32 @f1(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: f1:
; CHECK: xrk %r2, %r3, %r4
; CHECK: br %r14
%xor = xor i32 %b, %c
ret i32 %xor
}
; Check that we can still use XR in obvious cases.
define i32 @f2(i32 %a, i32 %b) {
; CHECK-LABEL: f2:
; CHECK: xr %r2, %r3
; CHECK: br %r14
%xor = xor i32 %a, %b
ret i32 %xor
}

View File

@ -4363,6 +4363,12 @@
# CHECK: nr %r7, %r8
0x14 0x78
# CHECK: nrk %r0, %r0, %r0
0xb9 0xf4 0x00 0x00
# CHECK: nrk %r2, %r3, %r4
0xb9 0xf4 0x40 0x23
# CHECK: n %r0, 0
0x54 0x00 0x00 0x00
@ -4585,6 +4591,12 @@
# CHECK: or %r7, %r8
0x16 0x78
# CHECK: ork %r0, %r0, %r0
0xb9 0xf6 0x00 0x00
# CHECK: ork %r2, %r3, %r4
0xb9 0xf6 0x40 0x23
# CHECK: o %r0, 0
0x56 0x00 0x00 0x00
@ -6190,6 +6202,12 @@
# CHECK: xr %r7, %r8
0x17 0x78
# CHECK: xrk %r0, %r0, %r0
0xb9 0xf7 0x00 0x00
# CHECK: xrk %r2, %r3, %r4
0xb9 0xf7 0x40 0x23
# CHECK: x %r0, 0
0x57 0x00 0x00 0x00

View File

@ -1982,6 +1982,11 @@
niy 0, -1
niy 0, 256
#CHECK: error: {{(instruction requires: distinct-ops)?}}
#CHECK: nrk %r2,%r3,%r4
nrk %r2,%r3,%r4
#CHECK: error: invalid operand
#CHECK: ny %r0, -524289
#CHECK: error: invalid operand
@ -2088,6 +2093,11 @@
oiy 0, -1
oiy 0, 256
#CHECK: error: {{(instruction requires: distinct-ops)?}}
#CHECK: ork %r2,%r3,%r4
ork %r2,%r3,%r4
#CHECK: error: invalid operand
#CHECK: oy %r0, -524289
#CHECK: error: invalid operand
@ -2686,6 +2696,11 @@
xiy 0, -1
xiy 0, 256
#CHECK: error: {{(instruction requires: distinct-ops)?}}
#CHECK: xrk %r2,%r3,%r4
xrk %r2,%r3,%r4
#CHECK: error: invalid operand
#CHECK: xy %r0, -524289
#CHECK: error: invalid operand

View File

@ -1,6 +1,30 @@
# For z196 and above.
# RUN: llvm-mc -triple s390x-linux-gnu -mcpu=z196 -show-encoding %s | FileCheck %s
#CHECK: nrk %r0, %r0, %r0 # encoding: [0xb9,0xf4,0x00,0x00]
#CHECK: nrk %r0, %r0, %r15 # encoding: [0xb9,0xf4,0xf0,0x00]
#CHECK: nrk %r0, %r15, %r0 # encoding: [0xb9,0xf4,0x00,0x0f]
#CHECK: nrk %r15, %r0, %r0 # encoding: [0xb9,0xf4,0x00,0xf0]
#CHECK: nrk %r7, %r8, %r9 # encoding: [0xb9,0xf4,0x90,0x78]
nrk %r0,%r0,%r0
nrk %r0,%r0,%r15
nrk %r0,%r15,%r0
nrk %r15,%r0,%r0
nrk %r7,%r8,%r9
#CHECK: ork %r0, %r0, %r0 # encoding: [0xb9,0xf6,0x00,0x00]
#CHECK: ork %r0, %r0, %r15 # encoding: [0xb9,0xf6,0xf0,0x00]
#CHECK: ork %r0, %r15, %r0 # encoding: [0xb9,0xf6,0x00,0x0f]
#CHECK: ork %r15, %r0, %r0 # encoding: [0xb9,0xf6,0x00,0xf0]
#CHECK: ork %r7, %r8, %r9 # encoding: [0xb9,0xf6,0x90,0x78]
ork %r0,%r0,%r0
ork %r0,%r0,%r15
ork %r0,%r15,%r0
ork %r15,%r0,%r0
ork %r7,%r8,%r9
#CHECK: sllk %r0, %r0, 0 # encoding: [0xeb,0x00,0x00,0x00,0x00,0xdf]
#CHECK: sllk %r15, %r1, 0 # encoding: [0xeb,0xf1,0x00,0x00,0x00,0xdf]
#CHECK: sllk %r1, %r15, 0 # encoding: [0xeb,0x1f,0x00,0x00,0x00,0xdf]
@ -78,3 +102,15 @@
srlk %r0,%r0,0(%r15)
srlk %r0,%r0,524287(%r1)
srlk %r0,%r0,524287(%r15)
#CHECK: xrk %r0, %r0, %r0 # encoding: [0xb9,0xf7,0x00,0x00]
#CHECK: xrk %r0, %r0, %r15 # encoding: [0xb9,0xf7,0xf0,0x00]
#CHECK: xrk %r0, %r15, %r0 # encoding: [0xb9,0xf7,0x00,0x0f]
#CHECK: xrk %r15, %r0, %r0 # encoding: [0xb9,0xf7,0x00,0xf0]
#CHECK: xrk %r7, %r8, %r9 # encoding: [0xb9,0xf7,0x90,0x78]
xrk %r0,%r0,%r0
xrk %r0,%r0,%r15
xrk %r0,%r15,%r0
xrk %r15,%r0,%r0
xrk %r7,%r8,%r9