diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r199033-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r199033-sparc.diff | 944 |
1 files changed, 944 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199033-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199033-sparc.diff new file mode 100644 index 0000000..c4b3438 --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r199033-sparc.diff @@ -0,0 +1,944 @@ +Pull in r199033 from upstream llvm trunk (by Venkatraman Govindaraju): + + [Sparc] Add support for parsing floating point instructions. + +Introduced here: http://svn.freebsd.org/changeset/base/262261 + +Index: lib/Target/Sparc/SparcInstrInfo.td +=================================================================== +--- lib/Target/Sparc/SparcInstrInfo.td ++++ lib/Target/Sparc/SparcInstrInfo.td +@@ -601,91 +601,91 @@ let Defs = [Y], rd = 0 in { + } + // Convert Integer to Floating-point Instructions, p. 141 + def FITOS : F3_3u<2, 0b110100, 0b011000100, +- (outs FPRegs:$dst), (ins FPRegs:$src), +- "fitos $src, $dst", +- [(set FPRegs:$dst, (SPitof FPRegs:$src))]>; ++ (outs FPRegs:$rd), (ins FPRegs:$rs2), ++ "fitos $rs2, $rd", ++ [(set FPRegs:$rd, (SPitof FPRegs:$rs2))]>; + def FITOD : F3_3u<2, 0b110100, 0b011001000, +- (outs DFPRegs:$dst), (ins FPRegs:$src), +- "fitod $src, $dst", +- [(set DFPRegs:$dst, (SPitof FPRegs:$src))]>; ++ (outs DFPRegs:$rd), (ins FPRegs:$rs2), ++ "fitod $rs2, $rd", ++ [(set DFPRegs:$rd, (SPitof FPRegs:$rs2))]>; + def FITOQ : F3_3u<2, 0b110100, 0b011001100, +- (outs QFPRegs:$dst), (ins FPRegs:$src), +- "fitoq $src, $dst", +- [(set QFPRegs:$dst, (SPitof FPRegs:$src))]>, ++ (outs QFPRegs:$rd), (ins FPRegs:$rs2), ++ "fitoq $rs2, $rd", ++ [(set QFPRegs:$rd, (SPitof FPRegs:$rs2))]>, + Requires<[HasHardQuad]>; + + // Convert Floating-point to Integer Instructions, p. 142 + def FSTOI : F3_3u<2, 0b110100, 0b011010001, +- (outs FPRegs:$dst), (ins FPRegs:$src), +- "fstoi $src, $dst", +- [(set FPRegs:$dst, (SPftoi FPRegs:$src))]>; ++ (outs FPRegs:$rd), (ins FPRegs:$rs2), ++ "fstoi $rs2, $rd", ++ [(set FPRegs:$rd, (SPftoi FPRegs:$rs2))]>; + def FDTOI : F3_3u<2, 0b110100, 0b011010010, +- (outs FPRegs:$dst), (ins DFPRegs:$src), +- "fdtoi $src, $dst", +- [(set FPRegs:$dst, (SPftoi DFPRegs:$src))]>; ++ (outs FPRegs:$rd), (ins DFPRegs:$rs2), ++ "fdtoi $rs2, $rd", ++ [(set FPRegs:$rd, (SPftoi DFPRegs:$rs2))]>; + def FQTOI : F3_3u<2, 0b110100, 0b011010011, +- (outs FPRegs:$dst), (ins QFPRegs:$src), +- "fqtoi $src, $dst", +- [(set FPRegs:$dst, (SPftoi QFPRegs:$src))]>, ++ (outs FPRegs:$rd), (ins QFPRegs:$rs2), ++ "fqtoi $rs2, $rd", ++ [(set FPRegs:$rd, (SPftoi QFPRegs:$rs2))]>, + Requires<[HasHardQuad]>; + + // Convert between Floating-point Formats Instructions, p. 143 + def FSTOD : F3_3u<2, 0b110100, 0b011001001, +- (outs DFPRegs:$dst), (ins FPRegs:$src), +- "fstod $src, $dst", +- [(set f64:$dst, (fextend f32:$src))]>; ++ (outs DFPRegs:$rd), (ins FPRegs:$rs2), ++ "fstod $rs2, $rd", ++ [(set f64:$rd, (fextend f32:$rs2))]>; + def FSTOQ : F3_3u<2, 0b110100, 0b011001101, +- (outs QFPRegs:$dst), (ins FPRegs:$src), +- "fstoq $src, $dst", +- [(set f128:$dst, (fextend f32:$src))]>, ++ (outs QFPRegs:$rd), (ins FPRegs:$rs2), ++ "fstoq $rs2, $rd", ++ [(set f128:$rd, (fextend f32:$rs2))]>, + Requires<[HasHardQuad]>; + def FDTOS : F3_3u<2, 0b110100, 0b011000110, +- (outs FPRegs:$dst), (ins DFPRegs:$src), +- "fdtos $src, $dst", +- [(set f32:$dst, (fround f64:$src))]>; +-def FDTOQ : F3_3u<2, 0b110100, 0b01101110, +- (outs QFPRegs:$dst), (ins DFPRegs:$src), +- "fdtoq $src, $dst", +- [(set f128:$dst, (fextend f64:$src))]>, ++ (outs FPRegs:$rd), (ins DFPRegs:$rs2), ++ "fdtos $rs2, $rd", ++ [(set f32:$rd, (fround f64:$rs2))]>; ++def FDTOQ : F3_3u<2, 0b110100, 0b011001110, ++ (outs QFPRegs:$rd), (ins DFPRegs:$rs2), ++ "fdtoq $rs2, $rd", ++ [(set f128:$rd, (fextend f64:$rs2))]>, + Requires<[HasHardQuad]>; + def FQTOS : F3_3u<2, 0b110100, 0b011000111, +- (outs FPRegs:$dst), (ins QFPRegs:$src), +- "fqtos $src, $dst", +- [(set f32:$dst, (fround f128:$src))]>, ++ (outs FPRegs:$rd), (ins QFPRegs:$rs2), ++ "fqtos $rs2, $rd", ++ [(set f32:$rd, (fround f128:$rs2))]>, + Requires<[HasHardQuad]>; + def FQTOD : F3_3u<2, 0b110100, 0b011001011, +- (outs DFPRegs:$dst), (ins QFPRegs:$src), +- "fqtod $src, $dst", +- [(set f64:$dst, (fround f128:$src))]>, ++ (outs DFPRegs:$rd), (ins QFPRegs:$rs2), ++ "fqtod $rs2, $rd", ++ [(set f64:$rd, (fround f128:$rs2))]>, + Requires<[HasHardQuad]>; + + // Floating-point Move Instructions, p. 144 + def FMOVS : F3_3u<2, 0b110100, 0b000000001, +- (outs FPRegs:$dst), (ins FPRegs:$src), +- "fmovs $src, $dst", []>; ++ (outs FPRegs:$rd), (ins FPRegs:$rs2), ++ "fmovs $rs2, $rd", []>; + def FNEGS : F3_3u<2, 0b110100, 0b000000101, +- (outs FPRegs:$dst), (ins FPRegs:$src), +- "fnegs $src, $dst", +- [(set f32:$dst, (fneg f32:$src))]>; ++ (outs FPRegs:$rd), (ins FPRegs:$rs2), ++ "fnegs $rs2, $rd", ++ [(set f32:$rd, (fneg f32:$rs2))]>; + def FABSS : F3_3u<2, 0b110100, 0b000001001, +- (outs FPRegs:$dst), (ins FPRegs:$src), +- "fabss $src, $dst", +- [(set f32:$dst, (fabs f32:$src))]>; ++ (outs FPRegs:$rd), (ins FPRegs:$rs2), ++ "fabss $rs2, $rd", ++ [(set f32:$rd, (fabs f32:$rs2))]>; + + + // Floating-point Square Root Instructions, p.145 + def FSQRTS : F3_3u<2, 0b110100, 0b000101001, +- (outs FPRegs:$dst), (ins FPRegs:$src), +- "fsqrts $src, $dst", +- [(set f32:$dst, (fsqrt f32:$src))]>; ++ (outs FPRegs:$rd), (ins FPRegs:$rs2), ++ "fsqrts $rs2, $rd", ++ [(set f32:$rd, (fsqrt f32:$rs2))]>; + def FSQRTD : F3_3u<2, 0b110100, 0b000101010, +- (outs DFPRegs:$dst), (ins DFPRegs:$src), +- "fsqrtd $src, $dst", +- [(set f64:$dst, (fsqrt f64:$src))]>; ++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2), ++ "fsqrtd $rs2, $rd", ++ [(set f64:$rd, (fsqrt f64:$rs2))]>; + def FSQRTQ : F3_3u<2, 0b110100, 0b000101011, +- (outs QFPRegs:$dst), (ins QFPRegs:$src), +- "fsqrtq $src, $dst", +- [(set f128:$dst, (fsqrt f128:$src))]>, ++ (outs QFPRegs:$rd), (ins QFPRegs:$rs2), ++ "fsqrtq $rs2, $rd", ++ [(set f128:$rd, (fsqrt f128:$rs2))]>, + Requires<[HasHardQuad]>; + + +@@ -692,73 +692,73 @@ def FSQRTQ : F3_3u<2, 0b110100, 0b000101011, + + // Floating-point Add and Subtract Instructions, p. 146 + def FADDS : F3_3<2, 0b110100, 0b001000001, +- (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2), +- "fadds $src1, $src2, $dst", +- [(set f32:$dst, (fadd f32:$src1, f32:$src2))]>; ++ (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), ++ "fadds $rs1, $rs2, $rd", ++ [(set f32:$rd, (fadd f32:$rs1, f32:$rs2))]>; + def FADDD : F3_3<2, 0b110100, 0b001000010, +- (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2), +- "faddd $src1, $src2, $dst", +- [(set f64:$dst, (fadd f64:$src1, f64:$src2))]>; ++ (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), ++ "faddd $rs1, $rs2, $rd", ++ [(set f64:$rd, (fadd f64:$rs1, f64:$rs2))]>; + def FADDQ : F3_3<2, 0b110100, 0b001000011, +- (outs QFPRegs:$dst), (ins QFPRegs:$src1, QFPRegs:$src2), +- "faddq $src1, $src2, $dst", +- [(set f128:$dst, (fadd f128:$src1, f128:$src2))]>, ++ (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), ++ "faddq $rs1, $rs2, $rd", ++ [(set f128:$rd, (fadd f128:$rs1, f128:$rs2))]>, + Requires<[HasHardQuad]>; + + def FSUBS : F3_3<2, 0b110100, 0b001000101, +- (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2), +- "fsubs $src1, $src2, $dst", +- [(set f32:$dst, (fsub f32:$src1, f32:$src2))]>; ++ (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), ++ "fsubs $rs1, $rs2, $rd", ++ [(set f32:$rd, (fsub f32:$rs1, f32:$rs2))]>; + def FSUBD : F3_3<2, 0b110100, 0b001000110, +- (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2), +- "fsubd $src1, $src2, $dst", +- [(set f64:$dst, (fsub f64:$src1, f64:$src2))]>; ++ (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), ++ "fsubd $rs1, $rs2, $rd", ++ [(set f64:$rd, (fsub f64:$rs1, f64:$rs2))]>; + def FSUBQ : F3_3<2, 0b110100, 0b001000111, +- (outs QFPRegs:$dst), (ins QFPRegs:$src1, QFPRegs:$src2), +- "fsubq $src1, $src2, $dst", +- [(set f128:$dst, (fsub f128:$src1, f128:$src2))]>, ++ (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), ++ "fsubq $rs1, $rs2, $rd", ++ [(set f128:$rd, (fsub f128:$rs1, f128:$rs2))]>, + Requires<[HasHardQuad]>; + + + // Floating-point Multiply and Divide Instructions, p. 147 + def FMULS : F3_3<2, 0b110100, 0b001001001, +- (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2), +- "fmuls $src1, $src2, $dst", +- [(set f32:$dst, (fmul f32:$src1, f32:$src2))]>; ++ (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), ++ "fmuls $rs1, $rs2, $rd", ++ [(set f32:$rd, (fmul f32:$rs1, f32:$rs2))]>; + def FMULD : F3_3<2, 0b110100, 0b001001010, +- (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2), +- "fmuld $src1, $src2, $dst", +- [(set f64:$dst, (fmul f64:$src1, f64:$src2))]>; ++ (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), ++ "fmuld $rs1, $rs2, $rd", ++ [(set f64:$rd, (fmul f64:$rs1, f64:$rs2))]>; + def FMULQ : F3_3<2, 0b110100, 0b001001011, +- (outs QFPRegs:$dst), (ins QFPRegs:$src1, QFPRegs:$src2), +- "fmulq $src1, $src2, $dst", +- [(set f128:$dst, (fmul f128:$src1, f128:$src2))]>, ++ (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), ++ "fmulq $rs1, $rs2, $rd", ++ [(set f128:$rd, (fmul f128:$rs1, f128:$rs2))]>, + Requires<[HasHardQuad]>; + + def FSMULD : F3_3<2, 0b110100, 0b001101001, +- (outs DFPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2), +- "fsmuld $src1, $src2, $dst", +- [(set f64:$dst, (fmul (fextend f32:$src1), +- (fextend f32:$src2)))]>; ++ (outs DFPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), ++ "fsmuld $rs1, $rs2, $rd", ++ [(set f64:$rd, (fmul (fextend f32:$rs1), ++ (fextend f32:$rs2)))]>; + def FDMULQ : F3_3<2, 0b110100, 0b001101110, +- (outs QFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2), +- "fdmulq $src1, $src2, $dst", +- [(set f128:$dst, (fmul (fextend f64:$src1), +- (fextend f64:$src2)))]>, ++ (outs QFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), ++ "fdmulq $rs1, $rs2, $rd", ++ [(set f128:$rd, (fmul (fextend f64:$rs1), ++ (fextend f64:$rs2)))]>, + Requires<[HasHardQuad]>; + + def FDIVS : F3_3<2, 0b110100, 0b001001101, +- (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2), +- "fdivs $src1, $src2, $dst", +- [(set f32:$dst, (fdiv f32:$src1, f32:$src2))]>; ++ (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2), ++ "fdivs $rs1, $rs2, $rd", ++ [(set f32:$rd, (fdiv f32:$rs1, f32:$rs2))]>; + def FDIVD : F3_3<2, 0b110100, 0b001001110, +- (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2), +- "fdivd $src1, $src2, $dst", +- [(set f64:$dst, (fdiv f64:$src1, f64:$src2))]>; ++ (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2), ++ "fdivd $rs1, $rs2, $rd", ++ [(set f64:$rd, (fdiv f64:$rs1, f64:$rs2))]>; + def FDIVQ : F3_3<2, 0b110100, 0b001001111, +- (outs QFPRegs:$dst), (ins QFPRegs:$src1, QFPRegs:$src2), +- "fdivq $src1, $src2, $dst", +- [(set f128:$dst, (fdiv f128:$src1, f128:$src2))]>, ++ (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2), ++ "fdivq $rs1, $rs2, $rd", ++ [(set f128:$rd, (fdiv f128:$rs1, f128:$rs2))]>, + Requires<[HasHardQuad]>; + + // Floating-point Compare Instructions, p. 148 +@@ -770,17 +770,17 @@ def FDIVQ : F3_3<2, 0b110100, 0b001001111, + + let Defs = [FCC] in { + def FCMPS : F3_3c<2, 0b110101, 0b001010001, +- (outs), (ins FPRegs:$src1, FPRegs:$src2), +- "fcmps $src1, $src2", +- [(SPcmpfcc f32:$src1, f32:$src2)]>; ++ (outs), (ins FPRegs:$rs1, FPRegs:$rs2), ++ "fcmps $rs1, $rs2", ++ [(SPcmpfcc f32:$rs1, f32:$rs2)]>; + def FCMPD : F3_3c<2, 0b110101, 0b001010010, +- (outs), (ins DFPRegs:$src1, DFPRegs:$src2), +- "fcmpd $src1, $src2", +- [(SPcmpfcc f64:$src1, f64:$src2)]>; ++ (outs), (ins DFPRegs:$rs1, DFPRegs:$rs2), ++ "fcmpd $rs1, $rs2", ++ [(SPcmpfcc f64:$rs1, f64:$rs2)]>; + def FCMPQ : F3_3c<2, 0b110101, 0b001010011, +- (outs), (ins QFPRegs:$src1, QFPRegs:$src2), +- "fcmpq $src1, $src2", +- [(SPcmpfcc f128:$src1, f128:$src2)]>, ++ (outs), (ins QFPRegs:$rs1, QFPRegs:$rs2), ++ "fcmpq $rs1, $rs2", ++ [(SPcmpfcc f128:$rs1, f128:$rs2)]>, + Requires<[HasHardQuad]>; + } + +@@ -892,29 +892,29 @@ let Predicates = [HasV9], Constraints = "$f = $rd" + // Floating-Point Move Instructions, p. 164 of the V9 manual. + let Predicates = [HasV9] in { + def FMOVD : F3_3u<2, 0b110100, 0b000000010, +- (outs DFPRegs:$dst), (ins DFPRegs:$src), +- "fmovd $src, $dst", []>; ++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2), ++ "fmovd $rs2, $rd", []>; + def FMOVQ : F3_3u<2, 0b110100, 0b000000011, +- (outs QFPRegs:$dst), (ins QFPRegs:$src), +- "fmovq $src, $dst", []>, ++ (outs QFPRegs:$rd), (ins QFPRegs:$rs2), ++ "fmovq $rs2, $rd", []>, + Requires<[HasHardQuad]>; + def FNEGD : F3_3u<2, 0b110100, 0b000000110, +- (outs DFPRegs:$dst), (ins DFPRegs:$src), +- "fnegd $src, $dst", +- [(set f64:$dst, (fneg f64:$src))]>; ++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2), ++ "fnegd $rs2, $rd", ++ [(set f64:$rd, (fneg f64:$rs2))]>; + def FNEGQ : F3_3u<2, 0b110100, 0b000000111, +- (outs QFPRegs:$dst), (ins QFPRegs:$src), +- "fnegq $src, $dst", +- [(set f128:$dst, (fneg f128:$src))]>, ++ (outs QFPRegs:$rd), (ins QFPRegs:$rs2), ++ "fnegq $rs2, $rd", ++ [(set f128:$rd, (fneg f128:$rs2))]>, + Requires<[HasHardQuad]>; + def FABSD : F3_3u<2, 0b110100, 0b000001010, +- (outs DFPRegs:$dst), (ins DFPRegs:$src), +- "fabsd $src, $dst", +- [(set f64:$dst, (fabs f64:$src))]>; ++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2), ++ "fabsd $rs2, $rd", ++ [(set f64:$rd, (fabs f64:$rs2))]>; + def FABSQ : F3_3u<2, 0b110100, 0b000001011, +- (outs QFPRegs:$dst), (ins QFPRegs:$src), +- "fabsq $src, $dst", +- [(set f128:$dst, (fabs f128:$src))]>, ++ (outs QFPRegs:$rd), (ins QFPRegs:$rs2), ++ "fabsq $rs2, $rd", ++ [(set f128:$rd, (fabs f128:$rs2))]>, + Requires<[HasHardQuad]>; + } + +Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +=================================================================== +--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp ++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +@@ -54,6 +54,8 @@ class SparcAsmParser : public MCTargetAsmParser { + SmallVectorImpl<MCParsedAsmOperand*> &Operands); + bool ParseDirective(AsmToken DirectiveID); + ++ virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, ++ unsigned Kind); + + // Custom parse functions for Sparc specific operands. + OperandMatchResultTy +@@ -67,8 +69,9 @@ class SparcAsmParser : public MCTargetAsmParser { + parseSparcAsmOperand(SparcOperand *&Operand); + + // returns true if Tok is matched to a register and returns register in RegNo. +- bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP, +- bool isQFP); ++ bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, ++ unsigned &RegKind); ++ + bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc); + + public: +@@ -178,6 +181,16 @@ class SparcOperand : public MCParsedAsmOperand { + bool isMEMrr() const { return Kind == k_MemoryReg; } + bool isMEMri() const { return Kind == k_MemoryImm; } + ++ bool isFloatReg() const { ++ return (Kind == k_Register && Reg.Kind == rk_FloatReg); ++ } ++ ++ bool isFloatOrDoubleReg() const { ++ return (Kind == k_Register && (Reg.Kind == rk_FloatReg ++ || Reg.Kind == rk_DoubleReg)); ++ } ++ ++ + StringRef getToken() const { + assert(Kind == k_Token && "Invalid access!"); + return StringRef(Tok.Data, Tok.Length); +@@ -280,11 +293,11 @@ class SparcOperand : public MCParsedAsmOperand { + } + + static SparcOperand *CreateReg(unsigned RegNum, +- SparcOperand::RegisterKind Kind, ++ unsigned Kind, + SMLoc S, SMLoc E) { + SparcOperand *Op = new SparcOperand(k_Register); + Op->Reg.RegNum = RegNum; +- Op->Reg.Kind = Kind; ++ Op->Reg.Kind = (SparcOperand::RegisterKind)Kind; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; +@@ -298,6 +311,40 @@ class SparcOperand : public MCParsedAsmOperand { + return Op; + } + ++ static SparcOperand *MorphToDoubleReg(SparcOperand *Op) { ++ unsigned Reg = Op->getReg(); ++ assert(Op->Reg.Kind == rk_FloatReg); ++ unsigned regIdx = Reg - Sparc::F0; ++ if (regIdx % 2 || regIdx > 31) ++ return 0; ++ Op->Reg.RegNum = DoubleRegs[regIdx / 2]; ++ Op->Reg.Kind = rk_DoubleReg; ++ return Op; ++ } ++ ++ static SparcOperand *MorphToQuadReg(SparcOperand *Op) { ++ unsigned Reg = Op->getReg(); ++ unsigned regIdx = 0; ++ switch (Op->Reg.Kind) { ++ default: assert(0 && "Unexpected register kind!"); ++ case rk_FloatReg: ++ regIdx = Reg - Sparc::F0; ++ if (regIdx % 4 || regIdx > 31) ++ return 0; ++ Reg = QuadFPRegs[regIdx / 4]; ++ break; ++ case rk_DoubleReg: ++ regIdx = Reg - Sparc::D0; ++ if (regIdx % 2 || regIdx > 31) ++ return 0; ++ Reg = QuadFPRegs[regIdx / 2]; ++ break; ++ } ++ Op->Reg.RegNum = Reg; ++ Op->Reg.Kind = rk_QuadReg; ++ return Op; ++ } ++ + static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) { + unsigned offsetReg = Op->getReg(); + Op->Kind = k_MemoryReg; +@@ -383,7 +430,8 @@ ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SM + if (getLexer().getKind() != AsmToken::Percent) + return false; + Parser.Lex(); +- if (matchRegisterName(Tok, RegNo, false, false)) { ++ unsigned regKind = SparcOperand::rk_None; ++ if (matchRegisterName(Tok, RegNo, regKind)) { + Parser.Lex(); + return false; + } +@@ -537,13 +585,14 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand + case AsmToken::Percent: + Parser.Lex(); // Eat the '%'. + unsigned RegNo; +- if (matchRegisterName(Parser.getTok(), RegNo, false, false)) { ++ unsigned RegKind; ++ if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) { + StringRef name = Parser.getTok().getString(); + Parser.Lex(); // Eat the identifier token. + E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + switch (RegNo) { + default: +- Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E); ++ Op = SparcOperand::CreateReg(RegNo, RegKind, S, E); + break; + case Sparc::Y: + Op = SparcOperand::CreateToken("%y", S); +@@ -593,11 +642,11 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand + + bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, + unsigned &RegNo, +- bool isDFP, +- bool isQFP) ++ unsigned &RegKind) + { + int64_t intVal = 0; + RegNo = 0; ++ RegKind = SparcOperand::rk_None; + if (Tok.is(AsmToken::Identifier)) { + StringRef name = Tok.getString(); + +@@ -604,21 +653,25 @@ bool SparcAsmParser::matchRegisterName(const AsmTo + // %fp + if (name.equals("fp")) { + RegNo = Sparc::I6; ++ RegKind = SparcOperand::rk_IntReg; + return true; + } + // %sp + if (name.equals("sp")) { + RegNo = Sparc::O6; ++ RegKind = SparcOperand::rk_IntReg; + return true; + } + + if (name.equals("y")) { + RegNo = Sparc::Y; ++ RegKind = SparcOperand::rk_Y; + return true; + } + + if (name.equals("icc")) { + RegNo = Sparc::ICC; ++ RegKind = SparcOperand::rk_CCReg; + return true; + } + +@@ -625,6 +678,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo + if (name.equals("xcc")) { + // FIXME:: check 64bit. + RegNo = Sparc::ICC; ++ RegKind = SparcOperand::rk_CCReg; + return true; + } + +@@ -634,6 +688,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo + && intVal < 4) { + // FIXME: check 64bit and handle %fcc1 - %fcc3 + RegNo = Sparc::FCC; ++ RegKind = SparcOperand::rk_CCReg; + return true; + } + +@@ -642,6 +697,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo + && !name.substr(1).getAsInteger(10, intVal) + && intVal < 8) { + RegNo = IntRegs[intVal]; ++ RegKind = SparcOperand::rk_IntReg; + return true; + } + // %o0 - %o7 +@@ -649,6 +705,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo + && !name.substr(1).getAsInteger(10, intVal) + && intVal < 8) { + RegNo = IntRegs[8 + intVal]; ++ RegKind = SparcOperand::rk_IntReg; + return true; + } + if (name.substr(0, 1).equals_lower("l") +@@ -655,6 +712,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo + && !name.substr(1).getAsInteger(10, intVal) + && intVal < 8) { + RegNo = IntRegs[16 + intVal]; ++ RegKind = SparcOperand::rk_IntReg; + return true; + } + if (name.substr(0, 1).equals_lower("i") +@@ -661,18 +719,14 @@ bool SparcAsmParser::matchRegisterName(const AsmTo + && !name.substr(1).getAsInteger(10, intVal) + && intVal < 8) { + RegNo = IntRegs[24 + intVal]; ++ RegKind = SparcOperand::rk_IntReg; + return true; + } + // %f0 - %f31 + if (name.substr(0, 1).equals_lower("f") + && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) { +- if (isDFP && (intVal%2 == 0)) { +- RegNo = DoubleRegs[intVal/2]; +- } else if (isQFP && (intVal%4 == 0)) { +- RegNo = QuadFPRegs[intVal/4]; +- } else { +- RegNo = FloatRegs[intVal]; +- } ++ RegNo = FloatRegs[intVal]; ++ RegKind = SparcOperand::rk_FloatReg; + return true; + } + // %f32 - %f62 +@@ -679,13 +733,9 @@ bool SparcAsmParser::matchRegisterName(const AsmTo + if (name.substr(0, 1).equals_lower("f") + && !name.substr(1, 2).getAsInteger(10, intVal) + && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) { +- if (isDFP) { +- RegNo = DoubleRegs[16 + intVal/2]; +- } else if (isQFP && (intVal % 4 == 0)) { +- RegNo = QuadFPRegs[8 + intVal/4]; +- } else { +- return false; +- } ++ // FIXME: Check V9 ++ RegNo = DoubleRegs[16 + intVal/2]; ++ RegKind = SparcOperand::rk_DoubleReg; + return true; + } + +@@ -693,6 +743,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo + if (name.substr(0, 1).equals_lower("r") + && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) { + RegNo = IntRegs[intVal]; ++ RegKind = SparcOperand::rk_IntReg; + return true; + } + } +@@ -735,3 +786,26 @@ extern "C" void LLVMInitializeSparcAsmParser() { + #define GET_REGISTER_MATCHER + #define GET_MATCHER_IMPLEMENTATION + #include "SparcGenAsmMatcher.inc" ++ ++ ++ ++unsigned SparcAsmParser:: ++validateTargetOperandClass(MCParsedAsmOperand *GOp, ++ unsigned Kind) ++{ ++ SparcOperand *Op = (SparcOperand*)GOp; ++ if (Op->isFloatOrDoubleReg()) { ++ switch (Kind) { ++ default: break; ++ case MCK_DFPRegs: ++ if (!Op->isFloatReg() || SparcOperand::MorphToDoubleReg(Op)) ++ return MCTargetAsmParser::Match_Success; ++ break; ++ case MCK_QFPRegs: ++ if (SparcOperand::MorphToQuadReg(Op)) ++ return MCTargetAsmParser::Match_Success; ++ break; ++ } ++ } ++ return Match_InvalidOperand; ++} +Index: lib/Target/Sparc/SparcInstr64Bit.td +=================================================================== +--- lib/Target/Sparc/SparcInstr64Bit.td ++++ lib/Target/Sparc/SparcInstr64Bit.td +@@ -358,31 +358,31 @@ def FMOVQ_XCC : F4_3<0b110101, 0b000011, (outs QFP + let Predicates = [Is64Bit] in { + + def FXTOS : F3_3u<2, 0b110100, 0b010000100, +- (outs FPRegs:$dst), (ins DFPRegs:$src), +- "fxtos $src, $dst", +- [(set FPRegs:$dst, (SPxtof DFPRegs:$src))]>; ++ (outs FPRegs:$rd), (ins DFPRegs:$rs2), ++ "fxtos $rs2, $rd", ++ [(set FPRegs:$rd, (SPxtof DFPRegs:$rs2))]>; + def FXTOD : F3_3u<2, 0b110100, 0b010001000, +- (outs DFPRegs:$dst), (ins DFPRegs:$src), +- "fxtod $src, $dst", +- [(set DFPRegs:$dst, (SPxtof DFPRegs:$src))]>; ++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2), ++ "fxtod $rs2, $rd", ++ [(set DFPRegs:$rd, (SPxtof DFPRegs:$rs2))]>; + def FXTOQ : F3_3u<2, 0b110100, 0b010001100, +- (outs QFPRegs:$dst), (ins DFPRegs:$src), +- "fxtoq $src, $dst", +- [(set QFPRegs:$dst, (SPxtof DFPRegs:$src))]>, ++ (outs QFPRegs:$rd), (ins DFPRegs:$rs2), ++ "fxtoq $rs2, $rd", ++ [(set QFPRegs:$rd, (SPxtof DFPRegs:$rs2))]>, + Requires<[HasHardQuad]>; + + def FSTOX : F3_3u<2, 0b110100, 0b010000001, +- (outs DFPRegs:$dst), (ins FPRegs:$src), +- "fstox $src, $dst", +- [(set DFPRegs:$dst, (SPftox FPRegs:$src))]>; ++ (outs DFPRegs:$rd), (ins FPRegs:$rs2), ++ "fstox $rs2, $rd", ++ [(set DFPRegs:$rd, (SPftox FPRegs:$rs2))]>; + def FDTOX : F3_3u<2, 0b110100, 0b010000010, +- (outs DFPRegs:$dst), (ins DFPRegs:$src), +- "fdtox $src, $dst", +- [(set DFPRegs:$dst, (SPftox DFPRegs:$src))]>; ++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2), ++ "fdtox $rs2, $rd", ++ [(set DFPRegs:$rd, (SPftox DFPRegs:$rs2))]>; + def FQTOX : F3_3u<2, 0b110100, 0b010000011, +- (outs DFPRegs:$dst), (ins QFPRegs:$src), +- "fqtox $src, $dst", +- [(set DFPRegs:$dst, (SPftox QFPRegs:$src))]>, ++ (outs DFPRegs:$rd), (ins QFPRegs:$rs2), ++ "fqtox $rs2, $rd", ++ [(set DFPRegs:$rd, (SPftox QFPRegs:$rs2))]>, + Requires<[HasHardQuad]>; + + } // Predicates = [Is64Bit] +Index: test/MC/Disassembler/Sparc/sparc-fp.txt +=================================================================== +--- test/MC/Disassembler/Sparc/sparc-fp.txt ++++ test/MC/Disassembler/Sparc/sparc-fp.txt +@@ -0,0 +1,142 @@ ++# RUN: llvm-mc --disassemble %s -triple=sparc64-linux-gnu | FileCheck %s ++ ++ ++# CHECK: fitos %f0, %f4 ++0x89 0xa0 0x18 0x80 ++ ++# CHECK: fitod %f0, %f4 ++0x89 0xa0 0x19 0x00 ++ ++# CHECK: fitoq %f0, %f4 ++0x89 0xa0 0x19 0x80 ++ ++# CHECK: fstoi %f0, %f4 ++0x89 0xa0 0x1a 0x20 ++ ++# CHECK: fdtoi %f0, %f4 ++0x89 0xa0 0x1a 0x40 ++ ++# CHECK: fqtoi %f0, %f4 ++0x89 0xa0 0x1a 0x60 ++ ++# CHECK: fstod %f0, %f4 ++0x89 0xa0 0x19 0x20 ++# CHECK: fstoq %f0, %f4 ++0x89 0xa0 0x19 0xa0 ++ ++# CHECK: fdtos %f0, %f4 ++0x89 0xa0 0x18 0xc0 ++ ++# CHECK: fdtoq %f0, %f4 ++0x89 0xa0 0x19 0xc0 ++ ++# CHECK: fqtos %f0, %f4 ++0x89 0xa0 0x18 0xe0 ++ ++# CHECK: fqtod %f0, %f4 ++0x89 0xa0 0x19 0x60 ++ ++# CHECK: fmovs %f0, %f4 ++0x89 0xa0 0x00 0x20 ++ ++# CHECK: fmovd %f0, %f4 ++0x89 0xa0 0x00 0x40 ++ ++# CHECK: fmovq %f0, %f4 ++0x89 0xa0 0x00 0x60 ++ ++# CHECK: fnegs %f0, %f4 ++0x89 0xa0 0x00 0xa0 ++ ++# CHECK: fnegd %f0, %f4 ++0x89 0xa0 0x00 0xc0 ++ ++# CHECK: fnegq %f0, %f4 ++0x89 0xa0 0x00 0xe0 ++ ++# CHECK: fabss %f0, %f4 ++0x89 0xa0 0x01 0x20 ++ ++# CHECK: fabsd %f0, %f4 ++0x89 0xa0 0x01 0x40 ++ ++# CHECK: fabsq %f0, %f4 ++0x89 0xa0 0x01 0x60 ++ ++# CHECK: fsqrts %f0, %f4 ++0x89 0xa0 0x05 0x20 ++ ++# CHECK: fsqrtd %f0, %f4 ++0x89 0xa0 0x05 0x40 ++ ++# CHECK: fsqrtq %f0, %f4 ++0x89 0xa0 0x05 0x60 ++ ++# CHECK: fadds %f0, %f4, %f8 ++0x91 0xa0 0x08 0x24 ++ ++# CHECK: faddd %f0, %f4, %f8 ++0x91 0xa0 0x08 0x44 ++ ++# CHECK: faddq %f0, %f4, %f8 ++0x91 0xa0 0x08 0x64 ++ ++# CHECK: fsubs %f0, %f4, %f8 ++0x91 0xa0 0x08 0xa4 ++ ++# CHECK: fsubd %f0, %f4, %f8 ++0x91 0xa0 0x08 0xc4 ++ ++# CHECK: fsubq %f0, %f4, %f8 ++0x91 0xa0 0x08 0xe4 ++ ++# CHECK: fmuls %f0, %f4, %f8 ++0x91 0xa0 0x09 0x24 ++ ++# CHECK: fmuld %f0, %f4, %f8 ++0x91 0xa0 0x09 0x44 ++ ++# CHECK: fmulq %f0, %f4, %f8 ++0x91 0xa0 0x09 0x64 ++ ++# CHECK: fsmuld %f0, %f4, %f8 ++0x91 0xa0 0x0d 0x24 ++ ++# CHECK: fdmulq %f0, %f4, %f8 ++0x91 0xa0 0x0d 0xc4 ++ ++# CHECK: fdivs %f0, %f4, %f8 ++0x91 0xa0 0x09 0xa4 ++ ++# CHECK: fdivd %f0, %f4, %f8 ++0x91 0xa0 0x09 0xc4 ++ ++# CHECK: fdivq %f0, %f4, %f8 ++0x91 0xa0 0x09 0xe4 ++ ++# CHECK: fcmps %f0, %f4 ++0x81 0xa8 0x0a 0x24 ++ ++# CHECK: fcmpd %f0, %f4 ++0x81 0xa8 0x0a 0x44 ++ ++# CHECK: fcmpq %f0, %f4 ++0x81 0xa8 0x0a 0x64 ++ ++# CHECK: fxtos %f0, %f4 ++0x89 0xa0 0x10 0x80 ++ ++# CHECK: fxtod %f0, %f4 ++0x89 0xa0 0x11 0x00 ++ ++# CHECK: fxtoq %f0, %f4 ++0x89 0xa0 0x11 0x80 ++ ++# CHECK: fstox %f0, %f4 ++0x89 0xa0 0x10 0x20 ++ ++# CHECK: fdtox %f0, %f4 ++0x89 0xa0 0x10 0x40 ++ ++# CHECK: fqtox %f0, %f4 ++0x89 0xa0 0x10 0x60 +Index: test/MC/Sparc/sparc-fp-instructions.s +=================================================================== +--- test/MC/Sparc/sparc-fp-instructions.s ++++ test/MC/Sparc/sparc-fp-instructions.s +@@ -0,0 +1,113 @@ ++! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s ++ ++ ! CHECK: fitos %f0, %f4 ! encoding: [0x89,0xa0,0x18,0x80] ++ ! CHECK: fitod %f0, %f4 ! encoding: [0x89,0xa0,0x19,0x00] ++ ! CHECK: fitoq %f0, %f4 ! encoding: [0x89,0xa0,0x19,0x80] ++ fitos %f0, %f4 ++ fitod %f0, %f4 ++ fitoq %f0, %f4 ++ ++ ! CHECK: fstoi %f0, %f4 ! encoding: [0x89,0xa0,0x1a,0x20] ++ ! CHECK: fdtoi %f0, %f4 ! encoding: [0x89,0xa0,0x1a,0x40] ++ ! CHECK: fqtoi %f0, %f4 ! encoding: [0x89,0xa0,0x1a,0x60] ++ fstoi %f0, %f4 ++ fdtoi %f0, %f4 ++ fqtoi %f0, %f4 ++ ++ ! CHECK: fstod %f0, %f4 ! encoding: [0x89,0xa0,0x19,0x20] ++ ! CHECK: fstoq %f0, %f4 ! encoding: [0x89,0xa0,0x19,0xa0] ++ fstod %f0, %f4 ++ fstoq %f0, %f4 ++ ++ ! CHECK: fdtos %f0, %f4 ! encoding: [0x89,0xa0,0x18,0xc0] ++ ! CHECK: fdtoq %f0, %f4 ! encoding: [0x89,0xa0,0x19,0xc0] ++ fdtos %f0, %f4 ++ fdtoq %f0, %f4 ++ ++ ! CHECK: fqtos %f0, %f4 ! encoding: [0x89,0xa0,0x18,0xe0] ++ ! CHECK: fqtod %f0, %f4 ! encoding: [0x89,0xa0,0x19,0x60] ++ fqtos %f0, %f4 ++ fqtod %f0, %f4 ++ ++ ! CHECK: fmovs %f0, %f4 ! encoding: [0x89,0xa0,0x00,0x20] ++ ! CHECK: fmovd %f0, %f4 ! encoding: [0x89,0xa0,0x00,0x40] ++ ! CHECK: fmovq %f0, %f4 ! encoding: [0x89,0xa0,0x00,0x60] ++ fmovs %f0, %f4 ++ fmovd %f0, %f4 ++ fmovq %f0, %f4 ++ ++ ! CHECK: fnegs %f0, %f4 ! encoding: [0x89,0xa0,0x00,0xa0] ++ ! CHECK: fnegd %f0, %f4 ! encoding: [0x89,0xa0,0x00,0xc0] ++ ! CHECK: fnegq %f0, %f4 ! encoding: [0x89,0xa0,0x00,0xe0] ++ fnegs %f0, %f4 ++ fnegd %f0, %f4 ++ fnegq %f0, %f4 ++ ++ ! CHECK: fabss %f0, %f4 ! encoding: [0x89,0xa0,0x01,0x20] ++ ! CHECK: fabsd %f0, %f4 ! encoding: [0x89,0xa0,0x01,0x40] ++ ! CHECK: fabsq %f0, %f4 ! encoding: [0x89,0xa0,0x01,0x60] ++ fabss %f0, %f4 ++ fabsd %f0, %f4 ++ fabsq %f0, %f4 ++ ++ ! CHECK: fsqrts %f0, %f4 ! encoding: [0x89,0xa0,0x05,0x20] ++ ! CHECK: fsqrtd %f0, %f4 ! encoding: [0x89,0xa0,0x05,0x40] ++ ! CHECK: fsqrtq %f0, %f4 ! encoding: [0x89,0xa0,0x05,0x60] ++ fsqrts %f0, %f4 ++ fsqrtd %f0, %f4 ++ fsqrtq %f0, %f4 ++ ++ ! CHECK: fadds %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0x24] ++ ! CHECK: faddd %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0x44] ++ ! CHECK: faddq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0x64] ++ fadds %f0, %f4, %f8 ++ faddd %f0, %f4, %f8 ++ faddq %f0, %f4, %f8 ++ ++ ! CHECK: fsubs %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0xa4] ++ ! CHECK: fsubd %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0xc4] ++ ! CHECK: fsubq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0xe4] ++ fsubs %f0, %f4, %f8 ++ fsubd %f0, %f4, %f8 ++ fsubq %f0, %f4, %f8 ++ ++ ! CHECK: fmuls %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0x24] ++ ! CHECK: fmuld %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0x44] ++ ! CHECK: fmulq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0x64] ++ fmuls %f0, %f4, %f8 ++ fmuld %f0, %f4, %f8 ++ fmulq %f0, %f4, %f8 ++ ++ ! CHECK: fsmuld %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x0d,0x24] ++ ! CHECK: fdmulq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x0d,0xc4] ++ fsmuld %f0, %f4, %f8 ++ fdmulq %f0, %f4, %f8 ++ ++ ! CHECK: fdivs %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0xa4] ++ ! CHECK: fdivd %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0xc4] ++ ! CHECK: fdivq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0xe4] ++ fdivs %f0, %f4, %f8 ++ fdivd %f0, %f4, %f8 ++ fdivq %f0, %f4, %f8 ++ ++ ! CHECK: fcmps %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x24] ++ ! CHECK: fcmpd %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x44] ++ ! CHECK: fcmpq %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x64] ++ fcmps %f0, %f4 ++ fcmpd %f0, %f4 ++ fcmpq %f0, %f4 ++ ++ ! CHECK: fxtos %f0, %f4 ! encoding: [0x89,0xa0,0x10,0x80] ++ ! CHECK: fxtod %f0, %f4 ! encoding: [0x89,0xa0,0x11,0x00] ++ ! CHECK: fxtoq %f0, %f4 ! encoding: [0x89,0xa0,0x11,0x80] ++ fxtos %f0, %f4 ++ fxtod %f0, %f4 ++ fxtoq %f0, %f4 ++ ++ ! CHECK: fstox %f0, %f4 ! encoding: [0x89,0xa0,0x10,0x20] ++ ! CHECK: fdtox %f0, %f4 ! encoding: [0x89,0xa0,0x10,0x40] ++ ! CHECK: fqtox %f0, %f4 ! encoding: [0x89,0xa0,0x10,0x60] ++ fstox %f0, %f4 ++ fdtox %f0, %f4 ++ fqtox %f0, %f4 ++ |