mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-16 14:31:59 +00:00
Add sqrt and powi intrinsics for long double.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42423 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ef0ab932ef
commit
317096ab37
@ -18,7 +18,9 @@
|
||||
namespace llvm {
|
||||
namespace RTLIB {
|
||||
/// RTLIB::Libcall enum - This enum defines all of the runtime library calls
|
||||
/// the backend can emit.
|
||||
/// the backend can emit. "LD" is used for all long double types, since
|
||||
/// these functions will have the same interface on different targets even
|
||||
/// though the data is not in the same format.
|
||||
///
|
||||
enum Libcall {
|
||||
// Integer
|
||||
@ -56,8 +58,10 @@ namespace RTLIB {
|
||||
NEG_F64,
|
||||
POWI_F32,
|
||||
POWI_F64,
|
||||
POWI_LD,
|
||||
SQRT_F32,
|
||||
SQRT_F64,
|
||||
SQRT_LD,
|
||||
SIN_F32,
|
||||
SIN_F64,
|
||||
COS_F32,
|
||||
|
@ -76,6 +76,9 @@ def llvm_i32_ty : LLVMType<i32>;
|
||||
def llvm_i64_ty : LLVMType<i64>;
|
||||
def llvm_float_ty : LLVMType<f32>;
|
||||
def llvm_double_ty : LLVMType<f64>;
|
||||
def llvm_f80_ty : LLVMType<f80>;
|
||||
def llvm_f128_ty : LLVMType<f128>;
|
||||
def llvm_ppcf128_ty : LLVMType<ppcf128>;
|
||||
def llvm_ptr_ty : LLVMPointerType<llvm_i8_ty>; // i8*
|
||||
def llvm_ptrptr_ty : LLVMPointerType<llvm_ptr_ty>; // i8**
|
||||
def llvm_empty_ty : LLVMType<OtherVT>; // { }
|
||||
@ -177,9 +180,16 @@ let Properties = [IntrWriteArgMem] in {
|
||||
let Properties = [IntrNoMem] in {
|
||||
def int_sqrt_f32 : Intrinsic<[llvm_float_ty, llvm_float_ty]>;
|
||||
def int_sqrt_f64 : Intrinsic<[llvm_double_ty, llvm_double_ty]>;
|
||||
def int_sqrt_f80 : Intrinsic<[llvm_f80_ty, llvm_f80_ty]>;
|
||||
def int_sqrt_f128 : Intrinsic<[llvm_f128_ty, llvm_f128_ty]>;
|
||||
def int_sqrt_ppcf128 : Intrinsic<[llvm_ppcf128_ty, llvm_ppcf128_ty]>;
|
||||
|
||||
def int_powi_f32 : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_i32_ty]>;
|
||||
def int_powi_f64 : Intrinsic<[llvm_double_ty, llvm_double_ty, llvm_i32_ty]>;
|
||||
def int_powi_f80 : Intrinsic<[llvm_f80_ty, llvm_f80_ty, llvm_i32_ty]>;
|
||||
def int_powi_f128 : Intrinsic<[llvm_f128_ty, llvm_f128_ty, llvm_i32_ty]>;
|
||||
def int_powi_ppcf128 : Intrinsic<[llvm_ppcf128_ty, llvm_ppcf128_ty,
|
||||
llvm_i32_ty]>;
|
||||
}
|
||||
|
||||
// NOTE: these are internal interfaces.
|
||||
|
@ -331,8 +331,14 @@ llvm::canConstantFoldCallTo(Function *F) {
|
||||
switch (F->getIntrinsicID()) {
|
||||
case Intrinsic::sqrt_f32:
|
||||
case Intrinsic::sqrt_f64:
|
||||
case Intrinsic::sqrt_f80:
|
||||
case Intrinsic::sqrt_f128:
|
||||
case Intrinsic::sqrt_ppcf128:
|
||||
case Intrinsic::powi_f32:
|
||||
case Intrinsic::powi_f64:
|
||||
case Intrinsic::powi_f80:
|
||||
case Intrinsic::powi_f128:
|
||||
case Intrinsic::powi_ppcf128:
|
||||
case Intrinsic::bswap:
|
||||
case Intrinsic::ctpop:
|
||||
case Intrinsic::ctlz:
|
||||
|
@ -3044,7 +3044,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
|
||||
switch(Node->getOpcode()) {
|
||||
case ISD::FSQRT:
|
||||
LC = VT == MVT::f32 ? RTLIB::SQRT_F32 : RTLIB::SQRT_F64;
|
||||
LC = VT == MVT::f32 ? RTLIB::SQRT_F32 :
|
||||
VT == MVT::f64 ? RTLIB::SQRT_F64 : RTLIB::SQRT_LD;
|
||||
break;
|
||||
case ISD::FSIN:
|
||||
LC = VT == MVT::f32 ? RTLIB::SIN_F32 : RTLIB::SIN_F64;
|
||||
@ -3065,8 +3066,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
break;
|
||||
case ISD::FPOWI: {
|
||||
// We always lower FPOWI into a libcall. No target support it yet.
|
||||
RTLIB::Libcall LC = Node->getValueType(0) == MVT::f32
|
||||
? RTLIB::POWI_F32 : RTLIB::POWI_F64;
|
||||
RTLIB::Libcall LC =
|
||||
Node->getValueType(0) == MVT::f32 ? RTLIB::POWI_F32 :
|
||||
Node->getValueType(0) == MVT::f64 ? RTLIB::POWI_F64 :
|
||||
RTLIB::POWI_LD;
|
||||
SDOperand Dummy;
|
||||
Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
|
||||
false/*sign irrelevant*/, Dummy);
|
||||
@ -5688,8 +5691,9 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||
Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::FPROUND_F64_F32),Node,true,Hi);
|
||||
break;
|
||||
case ISD::FPOWI:
|
||||
Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32)
|
||||
? RTLIB::POWI_F32 : RTLIB::POWI_F64),
|
||||
Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32) ? RTLIB::POWI_F32 :
|
||||
(VT == MVT::f64) ? RTLIB::POWI_F64 :
|
||||
RTLIB::POWI_LD),
|
||||
Node, false, Hi);
|
||||
break;
|
||||
case ISD::FSQRT:
|
||||
@ -5698,7 +5702,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
|
||||
switch(Node->getOpcode()) {
|
||||
case ISD::FSQRT:
|
||||
LC = (VT == MVT::f32) ? RTLIB::SQRT_F32 : RTLIB::SQRT_F64;
|
||||
LC = (VT == MVT::f32) ? RTLIB::SQRT_F32 :
|
||||
(VT == MVT::f64) ? RTLIB::SQRT_F64 : RTLIB::SQRT_LD;
|
||||
break;
|
||||
case ISD::FSIN:
|
||||
LC = (VT == MVT::f32) ? RTLIB::SIN_F32 : RTLIB::SIN_F64;
|
||||
|
@ -2798,12 +2798,18 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
|
||||
case Intrinsic::sqrt_f32:
|
||||
case Intrinsic::sqrt_f64:
|
||||
case Intrinsic::sqrt_f80:
|
||||
case Intrinsic::sqrt_f128:
|
||||
case Intrinsic::sqrt_ppcf128:
|
||||
setValue(&I, DAG.getNode(ISD::FSQRT,
|
||||
getValue(I.getOperand(1)).getValueType(),
|
||||
getValue(I.getOperand(1))));
|
||||
return 0;
|
||||
case Intrinsic::powi_f32:
|
||||
case Intrinsic::powi_f64:
|
||||
case Intrinsic::powi_f80:
|
||||
case Intrinsic::powi_f128:
|
||||
case Intrinsic::powi_ppcf128:
|
||||
setValue(&I, DAG.getNode(ISD::FPOWI,
|
||||
getValue(I.getOperand(1)).getValueType(),
|
||||
getValue(I.getOperand(1)),
|
||||
|
@ -58,8 +58,10 @@ static void InitLibcallNames(const char **Names) {
|
||||
Names[RTLIB::NEG_F64] = "__negdf2";
|
||||
Names[RTLIB::POWI_F32] = "__powisf2";
|
||||
Names[RTLIB::POWI_F64] = "__powidf2";
|
||||
Names[RTLIB::POWI_LD] = "__powixf2";
|
||||
Names[RTLIB::SQRT_F32] = "sqrtf";
|
||||
Names[RTLIB::SQRT_F64] = "sqrt";
|
||||
Names[RTLIB::SQRT_LD] = "sqrtl";
|
||||
Names[RTLIB::SIN_F32] = "sinf";
|
||||
Names[RTLIB::SIN_F64] = "sin";
|
||||
Names[RTLIB::COS_F32] = "cosf";
|
||||
|
47
test/CodeGen/X86/2007-09-27-LDIntrinsics.ll
Normal file
47
test/CodeGen/X86/2007-09-27-LDIntrinsics.ll
Normal file
@ -0,0 +1,47 @@
|
||||
; RUN: llvm-as < %s | llc | grep powixf2
|
||||
; RUN: llvm-as < %s | llc | grep fsqrt
|
||||
; ModuleID = 'yyy.c'
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i686-apple-darwin8"
|
||||
|
||||
define x86_fp80 @foo(x86_fp80 %x) {
|
||||
entry:
|
||||
%x_addr = alloca x86_fp80 ; <x86_fp80*> [#uses=2]
|
||||
%retval = alloca x86_fp80 ; <x86_fp80*> [#uses=2]
|
||||
%tmp = alloca x86_fp80 ; <x86_fp80*> [#uses=2]
|
||||
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
|
||||
store x86_fp80 %x, x86_fp80* %x_addr
|
||||
%tmp1 = load x86_fp80* %x_addr, align 16 ; <x86_fp80> [#uses=1]
|
||||
%tmp2 = call x86_fp80 @llvm.sqrt.f80( x86_fp80 %tmp1 ) ; <x86_fp80> [#uses=1]
|
||||
store x86_fp80 %tmp2, x86_fp80* %tmp, align 16
|
||||
%tmp3 = load x86_fp80* %tmp, align 16 ; <x86_fp80> [#uses=1]
|
||||
store x86_fp80 %tmp3, x86_fp80* %retval, align 16
|
||||
br label %return
|
||||
|
||||
return: ; preds = %entry
|
||||
%retval4 = load x86_fp80* %retval ; <x86_fp80> [#uses=1]
|
||||
ret x86_fp80 %retval4
|
||||
}
|
||||
|
||||
declare x86_fp80 @llvm.sqrt.f80(x86_fp80)
|
||||
|
||||
define x86_fp80 @bar(x86_fp80 %x) {
|
||||
entry:
|
||||
%x_addr = alloca x86_fp80 ; <x86_fp80*> [#uses=2]
|
||||
%retval = alloca x86_fp80 ; <x86_fp80*> [#uses=2]
|
||||
%tmp = alloca x86_fp80 ; <x86_fp80*> [#uses=2]
|
||||
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
|
||||
store x86_fp80 %x, x86_fp80* %x_addr
|
||||
%tmp1 = load x86_fp80* %x_addr, align 16 ; <x86_fp80> [#uses=1]
|
||||
%tmp2 = call x86_fp80 @llvm.powi.f80( x86_fp80 %tmp1, i32 3 ) ; <x86_fp80> [#uses=1]
|
||||
store x86_fp80 %tmp2, x86_fp80* %tmp, align 16
|
||||
%tmp3 = load x86_fp80* %tmp, align 16 ; <x86_fp80> [#uses=1]
|
||||
store x86_fp80 %tmp3, x86_fp80* %retval, align 16
|
||||
br label %return
|
||||
|
||||
return: ; preds = %entry
|
||||
%retval4 = load x86_fp80* %retval ; <x86_fp80> [#uses=1]
|
||||
ret x86_fp80 %retval4
|
||||
}
|
||||
|
||||
declare x86_fp80 @llvm.powi.f80(x86_fp80, i32)
|
@ -49,6 +49,7 @@ std::string llvm::getName(MVT::ValueType T) {
|
||||
case MVT::f64: return "MVT::f64";
|
||||
case MVT::f80: return "MVT::f80";
|
||||
case MVT::f128: return "MVT::f128";
|
||||
case MVT::ppcf128: return "MVT::ppcf128";
|
||||
case MVT::Flag: return "MVT::Flag";
|
||||
case MVT::isVoid:return "MVT::void";
|
||||
case MVT::v8i8: return "MVT::v8i8";
|
||||
@ -84,6 +85,7 @@ std::string llvm::getEnumName(MVT::ValueType T) {
|
||||
case MVT::f64: return "MVT::f64";
|
||||
case MVT::f80: return "MVT::f80";
|
||||
case MVT::f128: return "MVT::f128";
|
||||
case MVT::ppcf128: return "MVT::ppcf128";
|
||||
case MVT::Flag: return "MVT::Flag";
|
||||
case MVT::isVoid:return "MVT::isVoid";
|
||||
case MVT::v8i8: return "MVT::v8i8";
|
||||
|
@ -131,6 +131,12 @@ static void EmitTypeForValueType(std::ostream &OS, MVT::ValueType VT) {
|
||||
OS << "Type::FloatTy";
|
||||
} else if (VT == MVT::f64) {
|
||||
OS << "Type::DoubleTy";
|
||||
} else if (VT == MVT::f80) {
|
||||
OS << "Type::X86_FP80Ty";
|
||||
} else if (VT == MVT::f128) {
|
||||
OS << "Type::FP128Ty";
|
||||
} else if (VT == MVT::ppcf128) {
|
||||
OS << "Type::PPC_FP128Ty";
|
||||
} else if (VT == MVT::isVoid) {
|
||||
OS << "Type::VoidTy";
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user