def SQDB : UnaryRXE<"sqdb", 0xED15, loadu<fsqrt>, FP64, 8>;
// Round to an integer, with the second operand (modifier M3) specifying
-// the rounding mode.
-//
-// These forms always check for inexact conditions. z196 added versions
-// that allow this to suppressed (as for fnearbyint), but we don't yet
-// support -march=z196.
+// the rounding mode. These forms always check for inexact conditions.
def FIEBR : UnaryRRF<"fieb", 0xB357, FP32, FP32>;
def FIDBR : UnaryRRF<"fidb", 0xB35F, FP64, FP64>;
def FIXBR : UnaryRRF<"fixb", 0xB347, FP128, FP128>;
+// Extended forms of the previous three instructions. M4 can be set to 4
+// to suppress detection of inexact conditions.
+def FIEBRA : UnaryRRF4<"fiebra", 0xB357, FP32, FP32>,
+ Requires<[FeatureFPExtension]>;
+def FIDBRA : UnaryRRF4<"fidbra", 0xB35F, FP64, FP64>,
+ Requires<[FeatureFPExtension]>;
+def FIXBRA : UnaryRRF4<"fixbra", 0xB347, FP128, FP128>,
+ Requires<[FeatureFPExtension]>;
+
// frint rounds according to the current mode (modifier 0) and detects
// inexact conditions.
def : Pat<(frint FP32:$src), (FIEBR 0, FP32:$src)>;
bits<4> R1;
bits<4> R2;
bits<4> R3;
+ bits<4> R4;
let Inst{31-16} = op;
let Inst{15-12} = R3;
- let Inst{11-8} = 0;
+ let Inst{11-8} = R4;
let Inst{7-4} = R1;
let Inst{3-0} = R2;
}
mnemonic#"r\t$R1, $R3, $R2", []> {
let OpKey = mnemonic ## cls1;
let OpType = "reg";
+ let R4 = 0;
}
+class UnaryRRF4<string mnemonic, bits<16> opcode, RegisterOperand cls1,
+ RegisterOperand cls2>
+ : InstRRF<opcode, (outs cls1:$R1), (ins uimm8zx4:$R3, cls2:$R2, uimm8zx4:$R4),
+ mnemonic#"\t$R1, $R3, $R2, $R4", []>;
+
// These instructions are generated by if conversion. The old value of R1
// is added as an implicit use.
class CondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
mnemonic#"r$R3\t$R1, $R2", []>,
Requires<[FeatureLoadStoreOnCond]> {
let CCMaskLast = 1;
+ let R4 = 0;
}
// Like CondUnaryRRF, but used for the raw assembly form. The condition-code
Requires<[FeatureLoadStoreOnCond]> {
let Constraints = "$R1 = $R1src";
let DisableEncoding = "$R1src";
+ let R4 = 0;
}
// Like CondUnaryRRF, but with a fixed CC mask.
let Constraints = "$R1 = $R1src";
let DisableEncoding = "$R1src";
let R3 = ccmask;
+ let R4 = 0;
}
class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
[(set cls1:$R1, (operator cls1:$R3, cls2:$R2))]> {
let OpKey = mnemonic ## cls1;
let OpType = "reg";
+ let R4 = 0;
}
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))]>;
+ [(set cls1:$R1, (operator cls1:$R2, cls2:$R3))]> {
+ let R4 = 0;
+}
multiclass BinaryRRAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
SDPatternOperator operator, RegisterOperand cls1,
"Assume that the high-word facility is installed"
>;
+def FeatureFPExtension : SystemZFeature<
+ "fp-extension", "FPExtension",
+ "Assume that the floating-point extension facility is installed"
+>;
+
def : Processor<"z10", NoItineraries, []>;
def : Processor<"z196", NoItineraries,
- [FeatureDistinctOps, FeatureLoadStoreOnCond, FeatureHighWord]>;
+ [FeatureDistinctOps, FeatureLoadStoreOnCond, FeatureHighWord,
+ FeatureFPExtension]>;
def : Processor<"zEC12", NoItineraries,
- [FeatureDistinctOps, FeatureLoadStoreOnCond, FeatureHighWord]>;
+ [FeatureDistinctOps, FeatureLoadStoreOnCond, FeatureHighWord,
+ FeatureFPExtension]>;
const std::string &CPU,
const std::string &FS)
: SystemZGenSubtargetInfo(TT, CPU, FS), HasDistinctOps(false),
- HasLoadStoreOnCond(false), HasHighWord(false), TargetTriple(TT) {
+ HasLoadStoreOnCond(false), HasHighWord(false), HasFPExtension(false),
+ TargetTriple(TT) {
std::string CPUName = CPU;
if (CPUName.empty())
CPUName = "z10";
bool HasDistinctOps;
bool HasLoadStoreOnCond;
bool HasHighWord;
+ bool HasFPExtension;
private:
Triple TargetTriple;
// Return true if the target has the high-word facility.
bool hasHighWord() const { return HasHighWord; }
+ // Return true if the target has the floating-point extension facility.
+ bool hasFPExtension() const { return HasFPExtension; }
+
// Return true if GV can be accessed using LARL for reloc model RM
// and code model CM.
bool isPC32DBLSymbol(const GlobalValue *GV, Reloc::Model RM,
# CHECK: fidbr %f15, 0, %f0
0xb3 0x5f 0x00 0xf0
+# CHECK: fidbra %f0, 0, %f0, 1
+0xb3 0x5f 0x01 0x00
+
+# CHECK: fidbra %f0, 0, %f0, 15
+0xb3 0x5f 0x0f 0x00
+
+# CHECK: fidbra %f0, 0, %f15, 1
+0xb3 0x5f 0x01 0x0f
+
+# CHECK: fidbra %f0, 15, %f0, 1
+0xb3 0x5f 0xf1 0x00
+
+# CHECK: fidbra %f4, 5, %f6, 7
+0xb3 0x5f 0x57 0x46
+
+# CHECK: fidbra %f15, 0, %f0, 1
+0xb3 0x5f 0x01 0xf0
+
# CHECK: fiebr %f0, 0, %f0
0xb3 0x57 0x00 0x00
# CHECK: fiebr %f15, 0, %f0
0xb3 0x57 0x00 0xf0
+# CHECK: fiebra %f0, 0, %f0, 1
+0xb3 0x57 0x01 0x00
+
+# CHECK: fiebra %f0, 0, %f0, 15
+0xb3 0x57 0x0f 0x00
+
+# CHECK: fiebra %f0, 0, %f15, 1
+0xb3 0x57 0x01 0x0f
+
+# CHECK: fiebra %f0, 15, %f0, 1
+0xb3 0x57 0xf1 0x00
+
+# CHECK: fiebra %f4, 5, %f6, 7
+0xb3 0x57 0x57 0x46
+
+# CHECK: fiebra %f15, 0, %f0, 1
+0xb3 0x57 0x01 0xf0
+
# CHECK: fixbr %f0, 0, %f0
0xb3 0x47 0x00 0x00
# CHECK: fixbr %f13, 0, %f0
0xb3 0x47 0x00 0xd0
+# CHECK: fixbra %f0, 0, %f0, 1
+0xb3 0x47 0x01 0x00
+
+# CHECK: fixbra %f0, 0, %f0, 15
+0xb3 0x47 0x0f 0x00
+
+# CHECK: fixbra %f0, 0, %f13, 1
+0xb3 0x47 0x01 0x0d
+
+# CHECK: fixbra %f0, 15, %f0, 1
+0xb3 0x47 0xf1 0x00
+
+# CHECK: fixbra %f4, 5, %f8, 9
+0xb3 0x47 0x59 0x48
+
+# CHECK: fixbra %f13, 0, %f0, 1
+0xb3 0x47 0x01 0xd0
+
# CHECK: flogr %r0, %r0
0xb9 0x83 0x00 0x00
ahik %r0, %r1, foo
#CHECK: error: invalid operand
+#CHECK: fidbra %f0, 0, %f0, -1
+#CHECK: error: invalid operand
+#CHECK: fidbra %f0, 0, %f0, 16
+#CHECK: error: invalid operand
+#CHECK: fidbra %f0, -1, %f0, 0
+#CHECK: error: invalid operand
+#CHECK: fidbra %f0, 16, %f0, 0
+
+ fidbra %f0, 0, %f0, -1
+ fidbra %f0, 0, %f0, 16
+ fidbra %f0, -1, %f0, 0
+ fidbra %f0, 16, %f0, 0
+
+#CHECK: error: invalid operand
+#CHECK: fiebra %f0, 0, %f0, -1
+#CHECK: error: invalid operand
+#CHECK: fiebra %f0, 0, %f0, 16
+#CHECK: error: invalid operand
+#CHECK: fiebra %f0, -1, %f0, 0
+#CHECK: error: invalid operand
+#CHECK: fiebra %f0, 16, %f0, 0
+
+ fiebra %f0, 0, %f0, -1
+ fiebra %f0, 0, %f0, 16
+ fiebra %f0, -1, %f0, 0
+ fiebra %f0, 16, %f0, 0
+
+#CHECK: error: invalid operand
+#CHECK: fixbra %f0, 0, %f0, -1
+#CHECK: error: invalid operand
+#CHECK: fixbra %f0, 0, %f0, 16
+#CHECK: error: invalid operand
+#CHECK: fixbra %f0, -1, %f0, 0
+#CHECK: error: invalid operand
+#CHECK: fixbra %f0, 16, %f0, 0
+#CHECK: error: invalid register pair
+#CHECK: fixbra %f0, 0, %f2, 0
+#CHECK: error: invalid register pair
+#CHECK: fixbra %f2, 0, %f0, 0
+
+ fixbra %f0, 0, %f0, -1
+ fixbra %f0, 0, %f0, 16
+ fixbra %f0, -1, %f0, 0
+ fixbra %f0, 16, %f0, 0
+ fixbra %f0, 0, %f2, 0
+ fixbra %f2, 0, %f0, 0
+
+#CHECK: error: invalid operand
#CHECK: loc %r0,0,-1
#CHECK: error: invalid operand
#CHECK: loc %r0,0,16
fidbr %f0, -1, %f0
fidbr %f0, 16, %f0
+#CHECK: error: {{(instruction requires: fp-extension)?}}
+#CHECK: fidbra %f0, 0, %f0, 0
+
+ fidbra %f0, 0, %f0, 0
+
#CHECK: error: invalid operand
#CHECK: fiebr %f0, -1, %f0
#CHECK: error: invalid operand
fiebr %f0, -1, %f0
fiebr %f0, 16, %f0
+#CHECK: error: {{(instruction requires: fp-extension)?}}
+#CHECK: fiebra %f0, 0, %f0, 0
+
+ fiebra %f0, 0, %f0, 0
+
#CHECK: error: invalid operand
#CHECK: fixbr %f0, -1, %f0
#CHECK: error: invalid operand
fixbr %f0, 0, %f2
fixbr %f2, 0, %f0
+#CHECK: error: {{(instruction requires: fp-extension)?}}
+#CHECK: fixbra %f0, 0, %f0, 0
+
+ fixbra %f0, 0, %f0, 0
+
#CHECK: error: invalid register pair
#CHECK: flogr %r1, %r0
ark %r15,%r0,%r0
ark %r7,%r8,%r9
+#CHECK: fidbra %f0, 0, %f0, 0 # encoding: [0xb3,0x5f,0x00,0x00]
+#CHECK: fidbra %f0, 0, %f0, 15 # encoding: [0xb3,0x5f,0x0f,0x00]
+#CHECK: fidbra %f0, 0, %f15, 0 # encoding: [0xb3,0x5f,0x00,0x0f]
+#CHECK: fidbra %f0, 15, %f0, 0 # encoding: [0xb3,0x5f,0xf0,0x00]
+#CHECK: fidbra %f4, 5, %f6, 7 # encoding: [0xb3,0x5f,0x57,0x46]
+#CHECK: fidbra %f15, 0, %f0, 0 # encoding: [0xb3,0x5f,0x00,0xf0]
+
+ fidbra %f0, 0, %f0, 0
+ fidbra %f0, 0, %f0, 15
+ fidbra %f0, 0, %f15, 0
+ fidbra %f0, 15, %f0, 0
+ fidbra %f4, 5, %f6, 7
+ fidbra %f15, 0, %f0, 0
+
+#CHECK: fiebra %f0, 0, %f0, 0 # encoding: [0xb3,0x57,0x00,0x00]
+#CHECK: fiebra %f0, 0, %f0, 15 # encoding: [0xb3,0x57,0x0f,0x00]
+#CHECK: fiebra %f0, 0, %f15, 0 # encoding: [0xb3,0x57,0x00,0x0f]
+#CHECK: fiebra %f0, 15, %f0, 0 # encoding: [0xb3,0x57,0xf0,0x00]
+#CHECK: fiebra %f4, 5, %f6, 7 # encoding: [0xb3,0x57,0x57,0x46]
+#CHECK: fiebra %f15, 0, %f0, 0 # encoding: [0xb3,0x57,0x00,0xf0]
+
+ fiebra %f0, 0, %f0, 0
+ fiebra %f0, 0, %f0, 15
+ fiebra %f0, 0, %f15, 0
+ fiebra %f0, 15, %f0, 0
+ fiebra %f4, 5, %f6, 7
+ fiebra %f15, 0, %f0, 0
+
+#CHECK: fixbra %f0, 0, %f0, 0 # encoding: [0xb3,0x47,0x00,0x00]
+#CHECK: fixbra %f0, 0, %f0, 15 # encoding: [0xb3,0x47,0x0f,0x00]
+#CHECK: fixbra %f0, 0, %f13, 0 # encoding: [0xb3,0x47,0x00,0x0d]
+#CHECK: fixbra %f0, 15, %f0, 0 # encoding: [0xb3,0x47,0xf0,0x00]
+#CHECK: fixbra %f4, 5, %f8, 9 # encoding: [0xb3,0x47,0x59,0x48]
+#CHECK: fixbra %f13, 0, %f0, 0 # encoding: [0xb3,0x47,0x00,0xd0]
+
+ fixbra %f0, 0, %f0, 0
+ fixbra %f0, 0, %f0, 15
+ fixbra %f0, 0, %f13, 0
+ fixbra %f0, 15, %f0, 0
+ fixbra %f4, 5, %f8, 9
+ fixbra %f13, 0, %f0, 0
+
#CHECK: loc %r0, 0, 0 # encoding: [0xeb,0x00,0x00,0x00,0x00,0xf2]
#CHECK: loc %r0, 0, 15 # encoding: [0xeb,0x0f,0x00,0x00,0x00,0xf2]
#CHECK: loc %r0, -524288, 0 # encoding: [0xeb,0x00,0x00,0x00,0x80,0xf2]