diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -3175,6 +3175,11 @@ case SP::SELECT_CC_DFP_ICC: case SP::SELECT_CC_QFP_ICC: return expandSelectCC(MI, BB, SP::BCOND); + case SP::SELECT_CC_Int_XCC: + case SP::SELECT_CC_FP_XCC: + case SP::SELECT_CC_DFP_XCC: + case SP::SELECT_CC_QFP_XCC: + return expandSelectCC(MI, BB, SP::BPXCC); case SP::SELECT_CC_Int_FCC: case SP::SELECT_CC_FP_FCC: case SP::SELECT_CC_DFP_FCC: diff --git a/llvm/lib/Target/Sparc/SparcInstr64Bit.td b/llvm/lib/Target/Sparc/SparcInstr64Bit.td --- a/llvm/lib/Target/Sparc/SparcInstr64Bit.td +++ b/llvm/lib/Target/Sparc/SparcInstr64Bit.td @@ -336,6 +336,7 @@ "fmovd$cond %xcc, $rs2, $rd", [(set f64:$rd, (SPselectxcc f64:$rs2, f64:$f, imm:$cond))]>; +let Predicates = [Is64Bit, HasHardQuad] in def FMOVQ_XCC : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), "fmovq$cond %xcc, $rs2, $rd", @@ -436,11 +437,11 @@ (outs DFPRegs:$rd), (ins DFPRegs:$rs2), "fxtod $rs2, $rd", [(set DFPRegs:$rd, (SPxtof DFPRegs:$rs2))]>; +let Predicates = [Is64Bit, HasHardQuad] in def FXTOQ : F3_3u<2, 0b110100, 0b010001100, (outs QFPRegs:$rd), (ins DFPRegs:$rs2), "fxtoq $rs2, $rd", - [(set QFPRegs:$rd, (SPxtof DFPRegs:$rs2))]>, - Requires<[HasHardQuad]>; + [(set QFPRegs:$rd, (SPxtof DFPRegs:$rs2))]>; def FSTOX : F3_3u<2, 0b110100, 0b010000001, (outs DFPRegs:$rd), (ins FPRegs:$rs2), @@ -450,11 +451,11 @@ (outs DFPRegs:$rd), (ins DFPRegs:$rs2), "fdtox $rs2, $rd", [(set DFPRegs:$rd, (SPftox DFPRegs:$rs2))]>; +let Predicates = [Is64Bit, HasHardQuad] in def FQTOX : F3_3u<2, 0b110100, 0b010000011, (outs DFPRegs:$rd), (ins QFPRegs:$rs2), "fqtox $rs2, $rd", - [(set DFPRegs:$rd, (SPftox QFPRegs:$rs2))]>, - Requires<[HasHardQuad]>; + [(set DFPRegs:$rd, (SPftox QFPRegs:$rs2))]>; } // Predicates = [Is64Bit] diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -488,6 +488,27 @@ [(set f128:$dst, (SPselecticc f128:$T, f128:$F, imm:$Cond))]>; } +let Uses = [ICC], usesCustomInserter = 1 in { + def SELECT_CC_Int_XCC + : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond), + "; SELECT_CC_Int_XCC PSEUDO!", + [(set i32:$dst, (SPselectxcc i32:$T, i32:$F, imm:$Cond))]>; + def SELECT_CC_FP_XCC + : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond), + "; SELECT_CC_FP_XCC PSEUDO!", + [(set f32:$dst, (SPselectxcc f32:$T, f32:$F, imm:$Cond))]>; + + def SELECT_CC_DFP_XCC + : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), + "; SELECT_CC_DFP_XCC PSEUDO!", + [(set f64:$dst, (SPselectxcc f64:$T, f64:$F, imm:$Cond))]>; + + def SELECT_CC_QFP_XCC + : Pseudo<(outs QFPRegs:$dst), (ins QFPRegs:$T, QFPRegs:$F, i32imm:$Cond), + "; SELECT_CC_QFP_XCC PSEUDO!", + [(set f128:$dst, (SPselectxcc f128:$T, f128:$F, imm:$Cond))]>; +} + let usesCustomInserter = 1, Uses = [FCC0] in { def SELECT_CC_Int_FCC @@ -1444,12 +1465,12 @@ (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), "fmovd$cond %icc, $rs2, $rd", [(set f64:$rd, (SPselecticc f64:$rs2, f64:$f, imm:$cond))]>; + let Predicates = [HasV9, HasHardQuad] in def FMOVQ_ICC : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), "fmovq$cond %icc, $rs2, $rd", - [(set f128:$rd, (SPselecticc f128:$rs2, f128:$f, imm:$cond))]>, - Requires<[HasHardQuad]>; + [(set f128:$rd, (SPselecticc f128:$rs2, f128:$f, imm:$cond))]>; } let Uses = [FCC0], intcc = 0, opf_cc = 0b00 in { @@ -1463,12 +1484,12 @@ (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), "fmovd$cond %fcc0, $rs2, $rd", [(set f64:$rd, (SPselectfcc f64:$rs2, f64:$f, imm:$cond))]>; + let Predicates = [HasV9, HasHardQuad] in def FMOVQ_FCC : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), "fmovq$cond %fcc0, $rs2, $rd", - [(set f128:$rd, (SPselectfcc f128:$rs2, f128:$f, imm:$cond))]>, - Requires<[HasHardQuad]>; + [(set f128:$rd, (SPselectfcc f128:$rs2, f128:$f, imm:$cond))]>; } } @@ -1478,28 +1499,28 @@ def FMOVD : F3_3u<2, 0b110100, 0b000000010, (outs DFPRegs:$rd), (ins DFPRegs:$rs2), "fmovd $rs2, $rd", []>; + let Predicates = [HasV9, HasHardQuad] in def FMOVQ : F3_3u<2, 0b110100, 0b000000011, (outs QFPRegs:$rd), (ins QFPRegs:$rs2), - "fmovq $rs2, $rd", []>, - Requires<[HasHardQuad]>; + "fmovq $rs2, $rd", []>; def FNEGD : F3_3u<2, 0b110100, 0b000000110, (outs DFPRegs:$rd), (ins DFPRegs:$rs2), "fnegd $rs2, $rd", [(set f64:$rd, (fneg f64:$rs2))]>; + let Predicates = [HasV9, HasHardQuad] in def FNEGQ : F3_3u<2, 0b110100, 0b000000111, (outs QFPRegs:$rd), (ins QFPRegs:$rs2), "fnegq $rs2, $rd", - [(set f128:$rd, (fneg f128:$rs2))]>, - Requires<[HasHardQuad]>; + [(set f128:$rd, (fneg f128:$rs2))]>; def FABSD : F3_3u<2, 0b110100, 0b000001010, (outs DFPRegs:$rd), (ins DFPRegs:$rs2), "fabsd $rs2, $rd", [(set f64:$rd, (fabs f64:$rs2))]>; + let Predicates = [HasV9, HasHardQuad] in def FABSQ : F3_3u<2, 0b110100, 0b000001011, (outs QFPRegs:$rd), (ins QFPRegs:$rs2), "fabsq $rs2, $rd", - [(set f128:$rd, (fabs f128:$rs2))]>, - Requires<[HasHardQuad]>; + [(set f128:$rd, (fabs f128:$rs2))]>; } // Floating-point compare instruction with %fcc0-%fcc3. @@ -1546,11 +1567,11 @@ : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd), (ins FCCRegs:$opf_cc, DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond), "fmovd$cond $opf_cc, $rs2, $rd", []>; + let Predicates = [HasV9, HasHardQuad] in def V9FMOVQ_FCC : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd), (ins FCCRegs:$opf_cc, QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond), - "fmovq$cond $opf_cc, $rs2, $rd", []>, - Requires<[HasHardQuad]>; + "fmovq$cond $opf_cc, $rs2, $rd", []>; } // Constraints = "$f = $rd", ... } // let Predicates = [hasV9] diff --git a/llvm/test/CodeGen/SPARC/hard-quad-float.ll b/llvm/test/CodeGen/SPARC/hard-quad-float.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/SPARC/hard-quad-float.ll @@ -0,0 +1,38 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=sparc64-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC64 + +define fp128 @fpselect_softfloat(i32 signext %0, fp128 %1, fp128 %2) #0 { +; SPARC64-LABEL: fpselect_softfloat: +; SPARC64: .cfi_startproc +; SPARC64-NEXT: ! %bb.0: +; SPARC64-NEXT: cmp %o0, 0 +; SPARC64-NEXT: fmovd %f8, %f0 +; SPARC64-NEXT: fmovd %f10, %f2 +; SPARC64-NEXT: be .LBB0_2 +; SPARC64-NEXT: nop +; SPARC64-NEXT: ! %bb.1: +; SPARC64-NEXT: fmovd %f4, %f0 +; SPARC64-NEXT: fmovd %f6, %f2 +; SPARC64-NEXT: .LBB0_2: +; SPARC64-NEXT: retl +; SPARC64-NEXT: nop + %a = icmp eq i32 %0, 0 + %b = select i1 %a, fp128 %2, fp128 %1 + ret fp128 %b +} + +define fp128 @fpselect_hardfloat(i32 signext %0, fp128 %1, fp128 %2) #1 { +; SPARC64-LABEL: fpselect_hardfloat: +; SPARC64: .cfi_startproc +; SPARC64-NEXT: ! %bb.0: +; SPARC64-NEXT: fmovq %f4, %f0 +; SPARC64-NEXT: cmp %o0, 0 +; SPARC64-NEXT: retl +; SPARC64-NEXT: fmovqe %icc, %f8, %f0 + %a = icmp eq i32 %0, 0 + %b = select i1 %a, fp128 %2, fp128 %1 + ret fp128 %b +} + +attributes #0 = { "target-features"="-hard-quad-float" } +attributes #1 = { "target-features"="+hard-quad-float" }