diff options
| author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-08-21 08:58:08 +0000 |
|---|---|---|
| committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-08-21 08:58:08 +0000 |
| commit | 8e92c389e405c0fa5951e35c58eeb20ebb67eba9 (patch) | |
| tree | 6e0879addc2462d23b2129defcd04cb2b8975575 /llvm/lib/Target/SystemZ | |
| parent | ec12322a282ca7a3c63339d7aaeb50c0d985b072 (diff) | |
| download | bcm5719-llvm-8e92c389e405c0fa5951e35c58eeb20ebb67eba9.tar.gz bcm5719-llvm-8e92c389e405c0fa5951e35c58eeb20ebb67eba9.zip | |
[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
Diffstat (limited to 'llvm/lib/Target/SystemZ')
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrFP.td | 15 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrFormats.td | 17 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZProcessors.td | 11 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZSubtarget.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZSubtarget.h | 4 |
5 files changed, 40 insertions, 10 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFP.td b/llvm/lib/Target/SystemZ/SystemZInstrFP.td index 9f5279e63a2..b407b86c2bd 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<fsqrt>, FP32, 4>; 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)>; diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td index 1f80c27fe7d..39b76397054 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -308,10 +308,11 @@ class InstRRF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> 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<string mnemonic, bits<16> opcode, RegisterOperand cls1, 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, @@ -729,6 +736,7 @@ 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 @@ -740,6 +748,7 @@ class AsmCondUnaryRRF<string mnemonic, bits<16> 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<string mnemonic, bits<16> opcode, RegisterOperand cls1, let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; let R3 = ccmask; + let R4 = 0; } class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator, @@ -898,13 +908,16 @@ class BinaryRRF<string mnemonic, bits<16> 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, diff --git a/llvm/lib/Target/SystemZ/SystemZProcessors.td b/llvm/lib/Target/SystemZ/SystemZProcessors.td index 7e14aa75862..00d4338af55 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 036ec05d93a..b6a63923cf5 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 4efb58d097b..f321cb258a2 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, |

