Index: llvm/lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -1480,6 +1480,7 @@ setTruncStoreAction(MVT::f32, MVT::f16, Expand); setTruncStoreAction(MVT::f64, MVT::f16, Expand); setTruncStoreAction(MVT::f64, MVT::f32, Expand); + setTruncStoreAction(MVT::f128, MVT::f16, Expand); setTruncStoreAction(MVT::f128, MVT::f32, Expand); setTruncStoreAction(MVT::f128, MVT::f64, Expand); @@ -1525,6 +1526,8 @@ setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand); setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand); setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand); + setOperationAction(ISD::FP16_TO_FP, MVT::f128, Expand); + setOperationAction(ISD::FP_TO_FP16, MVT::f128, Expand); setOperationAction(ISD::BITCAST, MVT::f32, Expand); setOperationAction(ISD::BITCAST, MVT::i32, Expand); Index: llvm/test/CodeGen/SPARC/fp16-promote.ll =================================================================== --- llvm/test/CodeGen/SPARC/fp16-promote.ll +++ llvm/test/CodeGen/SPARC/fp16-promote.ll @@ -77,6 +77,90 @@ ret double %r } +define void @test_fpextend_fp128(half* %p, fp128* %out) nounwind { +; V8-OPT-LABEL: test_fpextend_fp128: +; V8-OPT: ! %bb.0: +; V8-OPT-NEXT: save %sp, -112, %sp +; V8-OPT-NEXT: call __gnu_h2f_ieee +; V8-OPT-NEXT: lduh [%i0], %o0 +; V8-OPT-NEXT: st %f0, [%fp+-20] +; V8-OPT-NEXT: add %fp, -16, %i0 +; V8-OPT-NEXT: st %i0, [%sp+64] +; V8-OPT-NEXT: call _Q_stoq +; V8-OPT-NEXT: ld [%fp+-20], %o0 +; V8-OPT-NEXT: unimp 16 +; V8-OPT-NEXT: ldd [%fp+-16], %f0 +; V8-OPT-NEXT: ldd [%fp+-8], %f2 +; V8-OPT-NEXT: std %f2, [%i1+8] +; V8-OPT-NEXT: std %f0, [%i1] +; V8-OPT-NEXT: ret +; V8-OPT-NEXT: restore +; +; V8-UNOPT-LABEL: test_fpextend_fp128: +; V8-UNOPT: ! %bb.0: +; V8-UNOPT-NEXT: save %sp, -112, %sp +; V8-UNOPT-NEXT: call __gnu_h2f_ieee +; V8-UNOPT-NEXT: lduh [%i0], %o0 +; V8-UNOPT-NEXT: st %f0, [%fp+-20] +; V8-UNOPT-NEXT: add %fp, -16, %i0 +; V8-UNOPT-NEXT: st %i0, [%sp+64] +; V8-UNOPT-NEXT: call _Q_stoq +; V8-UNOPT-NEXT: ld [%fp+-20], %o0 +; V8-UNOPT-NEXT: unimp 16 +; V8-UNOPT-NEXT: ldd [%fp+-16], %f4 +; V8-UNOPT-NEXT: ! implicit-def: $q0 +; V8-UNOPT-NEXT: fmovs %f4, %f0 +; V8-UNOPT-NEXT: fmovs %f5, %f1 +; V8-UNOPT-NEXT: ldd [%fp+-8], %f4 +; V8-UNOPT-NEXT: fmovs %f4, %f2 +; V8-UNOPT-NEXT: fmovs %f5, %f3 +; V8-UNOPT-NEXT: fmovs %f2, %f4 +; V8-UNOPT-NEXT: fmovs %f3, %f5 +; V8-UNOPT-NEXT: std %f4, [%i1+8] +; V8-UNOPT-NEXT: ! kill: def $d0 killed $d0 killed $q0 +; V8-UNOPT-NEXT: std %f0, [%i1] +; V8-UNOPT-NEXT: ret +; V8-UNOPT-NEXT: restore +; +; V9-LABEL: test_fpextend_fp128: +; V9: ! %bb.0: +; V9-NEXT: save %sp, -112, %sp +; V9-NEXT: call __gnu_h2f_ieee +; V9-NEXT: lduh [%i0], %o0 +; V9-NEXT: st %f0, [%fp+-20] +; V9-NEXT: add %fp, -16, %i0 +; V9-NEXT: st %i0, [%sp+64] +; V9-NEXT: call _Q_stoq +; V9-NEXT: ld [%fp+-20], %o0 +; V9-NEXT: unimp 16 +; V9-NEXT: ldd [%fp+-16], %f0 +; V9-NEXT: ldd [%fp+-8], %f2 +; V9-NEXT: std %f2, [%i1+8] +; V9-NEXT: std %f0, [%i1] +; V9-NEXT: ret +; V9-NEXT: restore +; +; SPARC64-LABEL: test_fpextend_fp128: +; SPARC64: ! %bb.0: +; SPARC64-NEXT: save %sp, -192, %sp +; SPARC64-NEXT: call __gnu_h2f_ieee +; SPARC64-NEXT: lduh [%i0], %o0 +; SPARC64-NEXT: add %fp, 2031, %o0 +; SPARC64-NEXT: fmovs %f0, %f3 +; SPARC64-NEXT: call _Qp_stoq +; SPARC64-NEXT: nop +; SPARC64-NEXT: ldd [%fp+2031], %f0 +; SPARC64-NEXT: ldd [%fp+2039], %f2 +; SPARC64-NEXT: std %f2, [%i1+8] +; SPARC64-NEXT: std %f0, [%i1] +; SPARC64-NEXT: ret +; SPARC64-NEXT: restore + %a = load half, half* %p + %r = fpext half %a to fp128 + store fp128 %r, fp128* %out + ret void +} + define void @test_fptrunc_float(float %f, half* %p) nounwind { ; V8-OPT-LABEL: test_fptrunc_float: ; V8-OPT: ! %bb.0: @@ -181,6 +265,66 @@ ret void } +define void @test_fptrunc_fp128(fp128* %dp, half* %p) nounwind { +; V8-OPT-LABEL: test_fptrunc_fp128: +; V8-OPT: ! %bb.0: +; V8-OPT-NEXT: save %sp, -104, %sp +; V8-OPT-NEXT: ldd [%i0], %f0 +; V8-OPT-NEXT: ldd [%i0+8], %f2 +; V8-OPT-NEXT: std %f2, [%sp+100] +; V8-OPT-NEXT: call __trunctfhf2 +; V8-OPT-NEXT: std %f0, [%sp+92] +; V8-OPT-NEXT: sth %o0, [%i1] +; V8-OPT-NEXT: ret +; V8-OPT-NEXT: restore +; +; V8-UNOPT-LABEL: test_fptrunc_fp128: +; V8-UNOPT: ! %bb.0: +; V8-UNOPT-NEXT: save %sp, -104, %sp +; V8-UNOPT-NEXT: ldd [%i0], %f4 +; V8-UNOPT-NEXT: ! implicit-def: $q0 +; V8-UNOPT-NEXT: fmovs %f4, %f0 +; V8-UNOPT-NEXT: fmovs %f5, %f1 +; V8-UNOPT-NEXT: ldd [%i0+8], %f4 +; V8-UNOPT-NEXT: fmovs %f4, %f2 +; V8-UNOPT-NEXT: fmovs %f5, %f3 +; V8-UNOPT-NEXT: fmovs %f2, %f4 +; V8-UNOPT-NEXT: fmovs %f3, %f5 +; V8-UNOPT-NEXT: std %f4, [%sp+100] +; V8-UNOPT-NEXT: ! kill: def $d0 killed $d0 killed $q0 +; V8-UNOPT-NEXT: call __trunctfhf2 +; V8-UNOPT-NEXT: std %f0, [%sp+92] +; V8-UNOPT-NEXT: sth %o0, [%i1] +; V8-UNOPT-NEXT: ret +; V8-UNOPT-NEXT: restore +; +; V9-LABEL: test_fptrunc_fp128: +; V9: ! %bb.0: +; V9-NEXT: save %sp, -104, %sp +; V9-NEXT: ldd [%i0], %f0 +; V9-NEXT: ldd [%i0+8], %f2 +; V9-NEXT: std %f2, [%sp+100] +; V9-NEXT: call __trunctfhf2 +; V9-NEXT: std %f0, [%sp+92] +; V9-NEXT: sth %o0, [%i1] +; V9-NEXT: ret +; V9-NEXT: restore +; +; SPARC64-LABEL: test_fptrunc_fp128: +; SPARC64: ! %bb.0: +; SPARC64-NEXT: save %sp, -176, %sp +; SPARC64-NEXT: ldd [%i0], %f0 +; SPARC64-NEXT: call __trunctfhf2 +; SPARC64-NEXT: ldd [%i0+8], %f2 +; SPARC64-NEXT: sth %o0, [%i1] +; SPARC64-NEXT: ret +; SPARC64-NEXT: restore + %d = load fp128, fp128* %dp + %a = fptrunc fp128 %d to half + store half %a, half* %p + ret void +} + define void @test_fadd(half* %p, half* %q) nounwind { ; V8-OPT-LABEL: test_fadd: ; V8-OPT: ! %bb.0: