[SystemZ] Add LOC and LOCG
As with the stores, these instructions can trap when the condition is false,
so they are only used for things like (cond ? x : *ptr).
llvm-svn: 187112
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
index b92c350..8199c17 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -704,6 +704,46 @@
let AddedComplexity = 7;
}
+class CondUnaryRSY<string mnemonic, bits<16> opcode,
+ RegisterOperand cls, bits<5> bytes,
+ AddressingMode mode = bdaddr20only>
+ : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, cond4:$R3),
+ mnemonic#"$R3\t$R1, $BD2", []>,
+ Requires<[FeatureLoadStoreOnCond]> {
+ let Constraints = "$R1 = $R1src";
+ let DisableEncoding = "$R1src";
+ let mayLoad = 1;
+ let AccessBytes = bytes;
+}
+
+// Like CondUnaryRSY, but used for the raw assembly form. The condition-code
+// mask is the third operand rather than being part of the mnemonic.
+class AsmCondUnaryRSY<string mnemonic, bits<16> opcode,
+ RegisterOperand cls, bits<5> bytes,
+ AddressingMode mode = bdaddr20only>
+ : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, uimm8zx4:$R3),
+ mnemonic#"\t$R1, $BD2, $R3", []>,
+ Requires<[FeatureLoadStoreOnCond]> {
+ let mayLoad = 1;
+ let AccessBytes = bytes;
+ let Constraints = "$R1 = $R1src";
+ let DisableEncoding = "$R1src";
+}
+
+// Like CondUnaryRSY, but with a fixed CC mask.
+class FixedCondUnaryRSY<string mnemonic, bits<16> opcode,
+ RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
+ AddressingMode mode = bdaddr20only>
+ : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2),
+ mnemonic#"\t$R1, $BD2", []>,
+ Requires<[FeatureLoadStoreOnCond]> {
+ let Constraints = "$R1 = $R1src";
+ let DisableEncoding = "$R1src";
+ let R3 = ccmask;
+ let mayLoad = 1;
+ let AccessBytes = bytes;
+}
+
class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
RegisterOperand cls, bits<5> bytes,
AddressingMode mode = bdxaddr12only>
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
index bda34df..46cd764 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -112,6 +112,8 @@
def JG : InstRIL<0xC04, (outs), (ins brtarget32:$I2),
"jg"##name##"\t$I2", []>;
}
+ def LOC : FixedCondUnaryRSY<"loc"##name, 0xEBF2, GR32, ccmask, 4>;
+ def LOCG : FixedCondUnaryRSY<"locg"##name, 0xEBE2, GR64, ccmask, 8>;
def STOC : FixedCondStoreRSY<"stoc"##name, 0xEBF3, GR32, ccmask, 4>;
def STOCG : FixedCondStoreRSY<"stocg"##name, 0xEBE3, GR64, ccmask, 8>;
}
@@ -259,6 +261,18 @@
def LGRL : UnaryRILPC<"lgrl", 0xC48, aligned_load, GR64>;
}
+// Load on condition.
+let isCodeGenOnly = 1, Uses = [CC] in {
+ def LOC : CondUnaryRSY<"loc", 0xEBF2, GR32, 4>;
+ def LOCG : CondUnaryRSY<"locg", 0xEBE2, GR64, 8>;
+}
+let Uses = [CC] in {
+ def AsmLOC : AsmCondUnaryRSY<"loc", 0xEBF2, GR32, 4>;
+ def AsmLOCG : AsmCondUnaryRSY<"locg", 0xEBE2, GR64, 8>;
+}
+defm : CondLoad<LOC, GR32, nonvolatile_load>;
+defm : CondLoad<LOCG, GR64, nonvolatile_load>;
+
// Register stores.
let SimpleBDXStore = 1 in {
let isCodeGenOnly = 1 in
diff --git a/llvm/lib/Target/SystemZ/SystemZOperands.td b/llvm/lib/Target/SystemZ/SystemZOperands.td
index 9d79439..696ec4f 100644
--- a/llvm/lib/Target/SystemZ/SystemZOperands.td
+++ b/llvm/lib/Target/SystemZ/SystemZOperands.td
@@ -111,6 +111,15 @@
!cast<Immediate>("imm"##bitsize))>;
//===----------------------------------------------------------------------===//
+// Manipulating CC masks
+//===----------------------------------------------------------------------===//
+
+def INVCC : SDNodeXForm<imm, [{
+ unsigned Value = N->getZExtValue() ^ SystemZ::CCMASK_ANY;
+ return CurDAG->getTargetConstant(Value, MVT::i8);
+}]>;
+
+//===----------------------------------------------------------------------===//
// Extracting immediate operands from nodes
// These all create MVT::i64 nodes to ensure the value is not sign-extended
// when converted from an SDNode to a MachineOperand later on.
diff --git a/llvm/lib/Target/SystemZ/SystemZPatterns.td b/llvm/lib/Target/SystemZ/SystemZPatterns.td
index 74cc5f0..4e4386a 100644
--- a/llvm/lib/Target/SystemZ/SystemZPatterns.td
+++ b/llvm/lib/Target/SystemZ/SystemZPatterns.td
@@ -54,6 +54,18 @@
def : RMWI<anyextloadi8, operator, truncstorei8, mode, imm64, insn>;
}
+// Record that INSN conditionally performs load operation LOAD into a
+// register of class CLS. The load may trap even if the condition is false.
+multiclass CondLoad<Instruction insn, RegisterOperand cls,
+ SDPatternOperator load> {
+ def : Pat<(z_select_ccmask (load bdaddr20only:$addr), cls:$new, uimm8zx4:$cc),
+ (insn cls:$new, bdaddr20only:$addr, uimm8zx4:$cc)>,
+ Requires<[FeatureLoadStoreOnCond]>;
+ def : Pat<(z_select_ccmask cls:$new, (load bdaddr20only:$addr), uimm8zx4:$cc),
+ (insn cls:$new, bdaddr20only:$addr, (INVCC uimm8zx4:$cc))>,
+ Requires<[FeatureLoadStoreOnCond]>;
+}
+
// Record that INSN performs insertion TYPE into a register of class CLS.
// The inserted operand is loaded using LOAD from an address of mode MODE.
multiclass InsertMem<string type, Instruction insn, RegisterOperand cls,