Skip to content

Commit

Permalink
[SystemZ] Add optional argument to some vector string instructions
Browse files Browse the repository at this point in the history
The vfee[bhf], vfene[bhf], and vistr[bhf] assembler mnemonics are
documented in the Principles of Operation to have an optional last
operand to encode arbitrary values in a mask field.

This commit adds support for those optional operands, and cleans up
the patterns to generate vector string instruction as bit.  No change
to code generation intended.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284585 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
uweigand committed Oct 19, 2016
1 parent 7b63453 commit a91221a
Show file tree
Hide file tree
Showing 5 changed files with 566 additions and 175 deletions.
96 changes: 69 additions & 27 deletions lib/Target/SystemZ/SystemZInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -1770,15 +1770,25 @@ class UnaryVRRa<string mnemonic, bits<16> opcode, SDPatternOperator operator,
let M5 = m5;
}

multiclass UnaryVRRaSPair<string mnemonic, bits<16> opcode,
SDPatternOperator operator,
SDPatternOperator operator_cc, TypedReg tr1,
TypedReg tr2, bits<4> type, bits<4> modifier = 0,
bits<4> modifier_cc = 1> {
def "" : UnaryVRRa<mnemonic, opcode, operator, tr1, tr2, type, 0, modifier>;
// Declare a pair of instructions, one which sets CC and one which doesn't.
// The CC-setting form ends with "S" and sets the low bit of M5.
// The form that does not set CC has an extra operand to optionally allow
// specifying arbitrary M5 values in assembler.
multiclass UnaryExtraVRRaSPair<string mnemonic, bits<16> opcode,
SDPatternOperator operator,
SDPatternOperator operator_cc,
TypedReg tr1, TypedReg tr2, bits<4> type> {
let M3 = type, M4 = 0 in
def "" : InstVRRa<opcode, (outs tr1.op:$V1),
(ins tr2.op:$V2, imm32zx4:$M5),
mnemonic#"\t$V1, $V2, $M5", []>;
def : Pat<(tr1.vt (operator (tr2.vt tr2.op:$V2))),
(!cast<Instruction>(NAME) tr2.op:$V2, 0)>;
def : InstAlias<mnemonic#"\t$V1, $V2",
(!cast<Instruction>(NAME) tr1.op:$V1, tr2.op:$V2, 0)>;
let Defs = [CC] in
def S : UnaryVRRa<mnemonic##"s", opcode, operator_cc, tr1, tr2, type, 0,
modifier_cc>;
def S : UnaryVRRa<mnemonic##"s", opcode, operator_cc, tr1, tr2,
type, 0, 1>;
}

class UnaryVRX<string mnemonic, bits<16> opcode, SDPatternOperator operator,
Expand Down Expand Up @@ -2053,12 +2063,33 @@ class BinaryVRRb<string mnemonic, bits<16> opcode, SDPatternOperator operator,
multiclass BinaryVRRbSPair<string mnemonic, bits<16> opcode,
SDPatternOperator operator,
SDPatternOperator operator_cc, TypedReg tr1,
TypedReg tr2, bits<4> type,
bits<4> modifier = 0, bits<4> modifier_cc = 1> {
def "" : BinaryVRRb<mnemonic, opcode, operator, tr1, tr2, type, modifier>;
TypedReg tr2, bits<4> type, bits<4> modifier = 0> {
def "" : BinaryVRRb<mnemonic, opcode, operator, tr1, tr2, type,
!and (modifier, 14)>;
let Defs = [CC] in
def S : BinaryVRRb<mnemonic##"s", opcode, operator_cc, tr1, tr2, type,
modifier_cc>;
!add (!and (modifier, 14), 1)>;
}

// Declare a pair of instructions, one which sets CC and one which doesn't.
// The CC-setting form ends with "S" and sets the low bit of M5.
// The form that does not set CC has an extra operand to optionally allow
// specifying arbitrary M5 values in assembler.
multiclass BinaryExtraVRRbSPair<string mnemonic, bits<16> opcode,
SDPatternOperator operator,
SDPatternOperator operator_cc,
TypedReg tr1, TypedReg tr2, bits<4> type> {
let M4 = type in
def "" : InstVRRb<opcode, (outs tr1.op:$V1),
(ins tr2.op:$V2, tr2.op:$V3, imm32zx4:$M5),
mnemonic#"\t$V1, $V2, $V3, $M5", []>;
def : Pat<(tr1.vt (operator (tr2.vt tr2.op:$V2), (tr2.vt tr2.op:$V3))),
(!cast<Instruction>(NAME) tr2.op:$V2, tr2.op:$V3, 0)>;
def : InstAlias<mnemonic#"\t$V1, $V2, $V3",
(!cast<Instruction>(NAME) tr1.op:$V1, tr2.op:$V2,
tr2.op:$V3, 0)>;
let Defs = [CC] in
def S : BinaryVRRb<mnemonic##"s", opcode, operator_cc, tr1, tr2, type, 1>;
}

class BinaryVRRc<string mnemonic, bits<16> opcode, SDPatternOperator operator,
Expand All @@ -2073,15 +2104,18 @@ class BinaryVRRc<string mnemonic, bits<16> opcode, SDPatternOperator operator,
let M6 = m6;
}

// Declare a pair of instructions, one which sets CC and one which doesn't.
// The CC-setting form ends with "S" and sets the low bit of M5.
multiclass BinaryVRRcSPair<string mnemonic, bits<16> opcode,
SDPatternOperator operator,
SDPatternOperator operator_cc, TypedReg tr1,
TypedReg tr2, bits<4> type, bits<4> m5,
bits<4> modifier = 0, bits<4> modifier_cc = 1> {
def "" : BinaryVRRc<mnemonic, opcode, operator, tr1, tr2, type, m5, modifier>;
bits<4> modifier = 0> {
def "" : BinaryVRRc<mnemonic, opcode, operator, tr1, tr2, type,
m5, !and (modifier, 14)>;
let Defs = [CC] in
def S : BinaryVRRc<mnemonic##"s", opcode, operator_cc, tr1, tr2, type,
m5, modifier_cc>;
m5, !add (!and (modifier, 14), 1)>;
}

class BinaryVRRf<string mnemonic, bits<16> opcode, SDPatternOperator operator,
Expand Down Expand Up @@ -2412,18 +2446,22 @@ class TernaryVRRb<string mnemonic, bits<16> opcode, SDPatternOperator operator,
let M4 = type;
}

multiclass TernaryVRRbSPair<string mnemonic, bits<16> opcode,
SDPatternOperator operator,
SDPatternOperator operator_cc, TypedReg tr1,
TypedReg tr2, bits<4> type, bits<4> m5or> {
// Declare a pair of instructions, one which sets CC and one which doesn't.
// The CC-setting form ends with "S" and sets the low bit of M5.
// Also create aliases to make use of M5 operand optional in assembler.
multiclass TernaryOptVRRbSPair<string mnemonic, bits<16> opcode,
SDPatternOperator operator,
SDPatternOperator operator_cc,
TypedReg tr1, TypedReg tr2, bits<4> type,
bits<4> modifier = 0> {
def "" : TernaryVRRb<mnemonic, opcode, operator, tr1, tr2, type,
imm32zx4even, !and (m5or, 14)>;
imm32zx4even, !and (modifier, 14)>;
def : InstAlias<mnemonic#"\t$V1, $V2, $V3",
(!cast<Instruction>(NAME) tr1.op:$V1, tr2.op:$V2,
tr2.op:$V3, 0)>;
let Defs = [CC] in
def S : TernaryVRRb<mnemonic##"s", opcode, operator_cc, tr1, tr2, type,
imm32zx4even, !add(!and (m5or, 14), 1)>;
imm32zx4even, !add(!and (modifier, 14), 1)>;
def : InstAlias<mnemonic#"s\t$V1, $V2, $V3",
(!cast<Instruction>(NAME#"S") tr1.op:$V1, tr2.op:$V2,
tr2.op:$V3, 0)>;
Expand Down Expand Up @@ -2531,18 +2569,22 @@ class QuaternaryVRRd<string mnemonic, bits<16> opcode,
let M5 = type;
}

multiclass QuaternaryVRRdSPair<string mnemonic, bits<16> opcode,
SDPatternOperator operator,
SDPatternOperator operator_cc, TypedReg tr1,
TypedReg tr2, bits<4> type, bits<4> m6or> {
// Declare a pair of instructions, one which sets CC and one which doesn't.
// The CC-setting form ends with "S" and sets the low bit of M6.
// Also create aliases to make use of M6 operand optional in assembler.
multiclass QuaternaryOptVRRdSPair<string mnemonic, bits<16> opcode,
SDPatternOperator operator,
SDPatternOperator operator_cc,
TypedReg tr1, TypedReg tr2, bits<4> type,
bits<4> modifier = 0> {
def "" : QuaternaryVRRd<mnemonic, opcode, operator, tr1, tr2, type,
imm32zx4even, !and (m6or, 14)>;
imm32zx4even, !and (modifier, 14)>;
def : InstAlias<mnemonic#"\t$V1, $V2, $V3, $V4",
(!cast<Instruction>(NAME) tr1.op:$V1, tr2.op:$V2,
tr2.op:$V3, tr2.op:$V4, 0)>;
let Defs = [CC] in
def S : QuaternaryVRRd<mnemonic##"s", opcode, operator_cc, tr1, tr2, type,
imm32zx4even, !add (!and (m6or, 14), 1)>;
imm32zx4even, !add (!and (modifier, 14), 1)>;
def : InstAlias<mnemonic#"s\t$V1, $V2, $V3, $V4",
(!cast<Instruction>(NAME#"S") tr1.op:$V1, tr2.op:$V2,
tr2.op:$V3, tr2.op:$V4, 0)>;
Expand Down
110 changes: 55 additions & 55 deletions lib/Target/SystemZ/SystemZInstrVector.td
Original file line number Diff line number Diff line change
Expand Up @@ -1036,62 +1036,62 @@ let AddedComplexity = 4 in {
//===----------------------------------------------------------------------===//

let Predicates = [FeatureVector] in {
defm VFAEB : TernaryVRRbSPair<"vfaeb", 0xE782, int_s390_vfaeb, z_vfae_cc,
v128b, v128b, 0, 0>;
defm VFAEH : TernaryVRRbSPair<"vfaeh", 0xE782, int_s390_vfaeh, z_vfae_cc,
v128h, v128h, 1, 0>;
defm VFAEF : TernaryVRRbSPair<"vfaef", 0xE782, int_s390_vfaef, z_vfae_cc,
v128f, v128f, 2, 0>;
defm VFAEZB : TernaryVRRbSPair<"vfaezb", 0xE782, int_s390_vfaezb, z_vfaez_cc,
v128b, v128b, 0, 2>;
defm VFAEZH : TernaryVRRbSPair<"vfaezh", 0xE782, int_s390_vfaezh, z_vfaez_cc,
v128h, v128h, 1, 2>;
defm VFAEZF : TernaryVRRbSPair<"vfaezf", 0xE782, int_s390_vfaezf, z_vfaez_cc,
v128f, v128f, 2, 2>;

defm VFEEB : BinaryVRRbSPair<"vfeeb", 0xE780, int_s390_vfeeb, z_vfee_cc,
v128b, v128b, 0, 0, 1>;
defm VFEEH : BinaryVRRbSPair<"vfeeh", 0xE780, int_s390_vfeeh, z_vfee_cc,
v128h, v128h, 1, 0, 1>;
defm VFEEF : BinaryVRRbSPair<"vfeef", 0xE780, int_s390_vfeef, z_vfee_cc,
v128f, v128f, 2, 0, 1>;
defm VFEEZB : BinaryVRRbSPair<"vfeezb", 0xE780, int_s390_vfeezb, z_vfeez_cc,
v128b, v128b, 0, 2, 3>;
defm VFEEZH : BinaryVRRbSPair<"vfeezh", 0xE780, int_s390_vfeezh, z_vfeez_cc,
v128h, v128h, 1, 2, 3>;
defm VFEEZF : BinaryVRRbSPair<"vfeezf", 0xE780, int_s390_vfeezf, z_vfeez_cc,
v128f, v128f, 2, 2, 3>;

defm VFENEB : BinaryVRRbSPair<"vfeneb", 0xE781, int_s390_vfeneb, z_vfene_cc,
v128b, v128b, 0, 0, 1>;
defm VFENEH : BinaryVRRbSPair<"vfeneh", 0xE781, int_s390_vfeneh, z_vfene_cc,
v128h, v128h, 1, 0, 1>;
defm VFENEF : BinaryVRRbSPair<"vfenef", 0xE781, int_s390_vfenef, z_vfene_cc,
v128f, v128f, 2, 0, 1>;
defm VFAEB : TernaryOptVRRbSPair<"vfaeb", 0xE782, int_s390_vfaeb,
z_vfae_cc, v128b, v128b, 0>;
defm VFAEH : TernaryOptVRRbSPair<"vfaeh", 0xE782, int_s390_vfaeh,
z_vfae_cc, v128h, v128h, 1>;
defm VFAEF : TernaryOptVRRbSPair<"vfaef", 0xE782, int_s390_vfaef,
z_vfae_cc, v128f, v128f, 2>;
defm VFAEZB : TernaryOptVRRbSPair<"vfaezb", 0xE782, int_s390_vfaezb,
z_vfaez_cc, v128b, v128b, 0, 2>;
defm VFAEZH : TernaryOptVRRbSPair<"vfaezh", 0xE782, int_s390_vfaezh,
z_vfaez_cc, v128h, v128h, 1, 2>;
defm VFAEZF : TernaryOptVRRbSPair<"vfaezf", 0xE782, int_s390_vfaezf,
z_vfaez_cc, v128f, v128f, 2, 2>;

defm VFEEB : BinaryExtraVRRbSPair<"vfeeb", 0xE780, int_s390_vfeeb,
z_vfee_cc, v128b, v128b, 0>;
defm VFEEH : BinaryExtraVRRbSPair<"vfeeh", 0xE780, int_s390_vfeeh,
z_vfee_cc, v128h, v128h, 1>;
defm VFEEF : BinaryExtraVRRbSPair<"vfeef", 0xE780, int_s390_vfeef,
z_vfee_cc, v128f, v128f, 2>;
defm VFEEZB : BinaryVRRbSPair<"vfeezb", 0xE780, int_s390_vfeezb,
z_vfeez_cc, v128b, v128b, 0, 2>;
defm VFEEZH : BinaryVRRbSPair<"vfeezh", 0xE780, int_s390_vfeezh,
z_vfeez_cc, v128h, v128h, 1, 2>;
defm VFEEZF : BinaryVRRbSPair<"vfeezf", 0xE780, int_s390_vfeezf,
z_vfeez_cc, v128f, v128f, 2, 2>;

defm VFENEB : BinaryExtraVRRbSPair<"vfeneb", 0xE781, int_s390_vfeneb,
z_vfene_cc, v128b, v128b, 0>;
defm VFENEH : BinaryExtraVRRbSPair<"vfeneh", 0xE781, int_s390_vfeneh,
z_vfene_cc, v128h, v128h, 1>;
defm VFENEF : BinaryExtraVRRbSPair<"vfenef", 0xE781, int_s390_vfenef,
z_vfene_cc, v128f, v128f, 2>;
defm VFENEZB : BinaryVRRbSPair<"vfenezb", 0xE781, int_s390_vfenezb,
z_vfenez_cc, v128b, v128b, 0, 2, 3>;
z_vfenez_cc, v128b, v128b, 0, 2>;
defm VFENEZH : BinaryVRRbSPair<"vfenezh", 0xE781, int_s390_vfenezh,
z_vfenez_cc, v128h, v128h, 1, 2, 3>;
z_vfenez_cc, v128h, v128h, 1, 2>;
defm VFENEZF : BinaryVRRbSPair<"vfenezf", 0xE781, int_s390_vfenezf,
z_vfenez_cc, v128f, v128f, 2, 2, 3>;

defm VISTRB : UnaryVRRaSPair<"vistrb", 0xE75C, int_s390_vistrb, z_vistr_cc,
v128b, v128b, 0>;
defm VISTRH : UnaryVRRaSPair<"vistrh", 0xE75C, int_s390_vistrh, z_vistr_cc,
v128h, v128h, 1>;
defm VISTRF : UnaryVRRaSPair<"vistrf", 0xE75C, int_s390_vistrf, z_vistr_cc,
v128f, v128f, 2>;

defm VSTRCB : QuaternaryVRRdSPair<"vstrcb", 0xE78A, int_s390_vstrcb,
z_vstrc_cc, v128b, v128b, 0, 0>;
defm VSTRCH : QuaternaryVRRdSPair<"vstrch", 0xE78A, int_s390_vstrch,
z_vstrc_cc, v128h, v128h, 1, 0>;
defm VSTRCF : QuaternaryVRRdSPair<"vstrcf", 0xE78A, int_s390_vstrcf,
z_vstrc_cc, v128f, v128f, 2, 0>;
defm VSTRCZB : QuaternaryVRRdSPair<"vstrczb", 0xE78A, int_s390_vstrczb,
z_vstrcz_cc, v128b, v128b, 0, 2>;
defm VSTRCZH : QuaternaryVRRdSPair<"vstrczh", 0xE78A, int_s390_vstrczh,
z_vstrcz_cc, v128h, v128h, 1, 2>;
defm VSTRCZF : QuaternaryVRRdSPair<"vstrczf", 0xE78A, int_s390_vstrczf,
z_vstrcz_cc, v128f, v128f, 2, 2>;
z_vfenez_cc, v128f, v128f, 2, 2>;

defm VISTRB : UnaryExtraVRRaSPair<"vistrb", 0xE75C, int_s390_vistrb,
z_vistr_cc, v128b, v128b, 0>;
defm VISTRH : UnaryExtraVRRaSPair<"vistrh", 0xE75C, int_s390_vistrh,
z_vistr_cc, v128h, v128h, 1>;
defm VISTRF : UnaryExtraVRRaSPair<"vistrf", 0xE75C, int_s390_vistrf,
z_vistr_cc, v128f, v128f, 2>;

defm VSTRCB : QuaternaryOptVRRdSPair<"vstrcb", 0xE78A, int_s390_vstrcb,
z_vstrc_cc, v128b, v128b, 0>;
defm VSTRCH : QuaternaryOptVRRdSPair<"vstrch", 0xE78A, int_s390_vstrch,
z_vstrc_cc, v128h, v128h, 1>;
defm VSTRCF : QuaternaryOptVRRdSPair<"vstrcf", 0xE78A, int_s390_vstrcf,
z_vstrc_cc, v128f, v128f, 2>;
defm VSTRCZB : QuaternaryOptVRRdSPair<"vstrczb", 0xE78A, int_s390_vstrczb,
z_vstrcz_cc, v128b, v128b, 0, 2>;
defm VSTRCZH : QuaternaryOptVRRdSPair<"vstrczh", 0xE78A, int_s390_vstrczh,
z_vstrcz_cc, v128h, v128h, 1, 2>;
defm VSTRCZF : QuaternaryOptVRRdSPair<"vstrczf", 0xE78A, int_s390_vstrczf,
z_vstrcz_cc, v128f, v128f, 2, 2>;
}
Loading

0 comments on commit a91221a

Please sign in to comment.