From 8e92c389e405c0fa5951e35c58eeb20ebb67eba9 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 21 Aug 2013 08:58:08 +0000 Subject: [PATCH] [SystemZ] Add FI[EDX]BRA These are extensions of the existing FI[EDX]BR instructions, but use a spare bit to suppress inexact conditions. llvm-svn: 188894 --- llvm/lib/Target/SystemZ/SystemZInstrFP.td | 15 ++++-- .../lib/Target/SystemZ/SystemZInstrFormats.td | 17 +++++- llvm/lib/Target/SystemZ/SystemZProcessors.td | 11 +++- llvm/lib/Target/SystemZ/SystemZSubtarget.cpp | 3 +- llvm/lib/Target/SystemZ/SystemZSubtarget.h | 4 ++ llvm/test/MC/Disassembler/SystemZ/insns.txt | 54 +++++++++++++++++++ llvm/test/MC/SystemZ/insn-bad-z196.s | 48 +++++++++++++++++ llvm/test/MC/SystemZ/insn-bad.s | 15 ++++++ llvm/test/MC/SystemZ/insn-good-z196.s | 42 +++++++++++++++ 9 files changed, 199 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFP.td b/llvm/lib/Target/SystemZ/SystemZInstrFP.td index 9f5279e63a28..b407b86c2bd0 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrFP.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrFP.td @@ -212,15 +212,20 @@ def SQEB : UnaryRXE<"sqeb", 0xED14, loadu, FP32, 4>; def SQDB : UnaryRXE<"sqdb", 0xED15, loadu, 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)>; diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td index 1f80c27fe7df..39b763970544 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -308,10 +308,11 @@ class InstRRF op, dag outs, dag ins, string asmstr, list pattern> 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; } @@ -719,8 +720,14 @@ class UnaryRRF opcode, RegisterOperand cls1, mnemonic#"r\t$R1, $R3, $R2", []> { let OpKey = mnemonic ## cls1; let OpType = "reg"; + let R4 = 0; } +class UnaryRRF4 opcode, RegisterOperand cls1, + RegisterOperand cls2> + : InstRRF; + // These instructions are generated by if conversion. The old value of R1 // is added as an implicit use. class CondUnaryRRF opcode, RegisterOperand cls1, @@ -729,6 +736,7 @@ class CondUnaryRRF 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 @@ -740,6 +748,7 @@ class AsmCondUnaryRRF opcode, RegisterOperand cls1, Requires<[FeatureLoadStoreOnCond]> { let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; + let R4 = 0; } // Like CondUnaryRRF, but with a fixed CC mask. @@ -751,6 +760,7 @@ class FixedCondUnaryRRF opcode, RegisterOperand cls1, let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; let R3 = ccmask; + let R4 = 0; } class UnaryRI opcode, SDPatternOperator operator, @@ -898,13 +908,16 @@ class BinaryRRF opcode, SDPatternOperator operator, [(set cls1:$R1, (operator cls1:$R3, cls2:$R2))]> { let OpKey = mnemonic ## cls1; let OpType = "reg"; + let R4 = 0; } class BinaryRRFK opcode, SDPatternOperator operator, RegisterOperand cls1, RegisterOperand cls2> : InstRRF; + [(set cls1:$R1, (operator cls1:$R2, cls2:$R3))]> { + let R4 = 0; +} multiclass BinaryRRAndK opcode1, bits<16> opcode2, SDPatternOperator operator, RegisterOperand cls1, diff --git a/llvm/lib/Target/SystemZ/SystemZProcessors.td b/llvm/lib/Target/SystemZ/SystemZProcessors.td index 7e14aa75862f..00d4338af55b 100644 --- a/llvm/lib/Target/SystemZ/SystemZProcessors.td +++ b/llvm/lib/Target/SystemZ/SystemZProcessors.td @@ -31,8 +31,15 @@ def FeatureHighWord : SystemZFeature< "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]>; diff --git a/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp b/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp index 036ec05d93a8..b6a63923cf5c 100644 --- a/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp +++ b/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp @@ -21,7 +21,8 @@ SystemZSubtarget::SystemZSubtarget(const std::string &TT, 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"; diff --git a/llvm/lib/Target/SystemZ/SystemZSubtarget.h b/llvm/lib/Target/SystemZ/SystemZSubtarget.h index 4efb58d097b1..f321cb258a2d 100644 --- a/llvm/lib/Target/SystemZ/SystemZSubtarget.h +++ b/llvm/lib/Target/SystemZ/SystemZSubtarget.h @@ -30,6 +30,7 @@ protected: bool HasDistinctOps; bool HasLoadStoreOnCond; bool HasHighWord; + bool HasFPExtension; private: Triple TargetTriple; @@ -50,6 +51,9 @@ public: // 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, diff --git a/llvm/test/MC/Disassembler/SystemZ/insns.txt b/llvm/test/MC/Disassembler/SystemZ/insns.txt index 15eaf7b43c37..3f4f6c3dd178 100644 --- a/llvm/test/MC/Disassembler/SystemZ/insns.txt +++ b/llvm/test/MC/Disassembler/SystemZ/insns.txt @@ -2149,6 +2149,24 @@ # 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 @@ -2164,6 +2182,24 @@ # 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 @@ -2179,6 +2215,24 @@ # 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 diff --git a/llvm/test/MC/SystemZ/insn-bad-z196.s b/llvm/test/MC/SystemZ/insn-bad-z196.s index ec90c89b4c20..477dac2d269c 100644 --- a/llvm/test/MC/SystemZ/insn-bad-z196.s +++ b/llvm/test/MC/SystemZ/insn-bad-z196.s @@ -24,6 +24,54 @@ ahik %r0, %r1, 32768 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 diff --git a/llvm/test/MC/SystemZ/insn-bad.s b/llvm/test/MC/SystemZ/insn-bad.s index 228467004b19..aa3f4c9d83b9 100644 --- a/llvm/test/MC/SystemZ/insn-bad.s +++ b/llvm/test/MC/SystemZ/insn-bad.s @@ -1142,6 +1142,11 @@ 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 @@ -1150,6 +1155,11 @@ 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 @@ -1164,6 +1174,11 @@ 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 diff --git a/llvm/test/MC/SystemZ/insn-good-z196.s b/llvm/test/MC/SystemZ/insn-good-z196.s index 5f7c27785d78..4b12265f7302 100644 --- a/llvm/test/MC/SystemZ/insn-good-z196.s +++ b/llvm/test/MC/SystemZ/insn-good-z196.s @@ -121,6 +121,48 @@ 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]