From 24373e35a496896590b653be16f6c2e3778f5761 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Wed, 28 Jan 2015 22:08:16 +0000 Subject: [PATCH] [Hexagon] Updating several V5 intrinsics and adding FP tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227379 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/IntrinsicsHexagon.td | 85 +-- lib/Target/Hexagon/HexagonISelLowering.cpp | 2 +- lib/Target/Hexagon/HexagonInstrInfoV5.td | 32 ++ lib/Target/Hexagon/HexagonIntrinsics.td | 30 + lib/Target/Hexagon/HexagonIntrinsicsV3.td | 22 +- lib/Target/Hexagon/HexagonIntrinsicsV5.td | 383 ++----------- test/CodeGen/Hexagon/intrinsics/xtype_alu.ll | 545 +++++++++++++++++++ test/CodeGen/Hexagon/intrinsics/xtype_fp.ll | 331 +++++++++++ 8 files changed, 1008 insertions(+), 422 deletions(-) create mode 100644 test/CodeGen/Hexagon/intrinsics/xtype_alu.ll create mode 100644 test/CodeGen/Hexagon/intrinsics/xtype_fp.ll diff --git a/include/llvm/IR/IntrinsicsHexagon.td b/include/llvm/IR/IntrinsicsHexagon.td index 8a8872931f3..ef666b4149e 100644 --- a/include/llvm/IR/IntrinsicsHexagon.td +++ b/include/llvm/IR/IntrinsicsHexagon.td @@ -499,12 +499,12 @@ class Hexagon_qi_sfsf_Intrinsic [llvm_i1_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]>; // -// Hexagon_qi_sfsi_Intrinsic +// Hexagon_si_sfsi_Intrinsic // -class Hexagon_qi_sfsi_Intrinsic +class Hexagon_si_sfsi_Intrinsic : Hexagon_Intrinsic; + [llvm_i32_ty], [llvm_float_ty, llvm_i32_ty], + [IntrNoMem, Throws]>; // // Hexagon_qi_sfqi_Intrinsic // @@ -580,12 +580,12 @@ class Hexagon_qi_dfdf_Intrinsic [llvm_i1_ty], [llvm_double_ty, llvm_double_ty], [IntrNoMem]>; // -// Hexagon_qi_dfsi_Intrinsic +// Hexagon_si_dfsi_Intrinsic // -class Hexagon_qi_dfsi_Intrinsic +class Hexagon_si_dfsi_Intrinsic : Hexagon_Intrinsic; + [llvm_i32_ty], [llvm_double_ty, llvm_i32_ty], + [IntrNoMem, Throws]>; // // // Hexagon_df_dfdfdf_Intrinsic @@ -3639,7 +3639,7 @@ Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfmin">; // BUILTIN_INFO(HEXAGON.F2_sfclass,QI_ftype_SFSI,2) // def int_hexagon_F2_sfclass : -Hexagon_qi_sfsi_Intrinsic<"HEXAGON_F2_sfclass">; +Hexagon_si_sfsi_Intrinsic<"HEXAGON_F2_sfclass">; // // BUILTIN_INFO(HEXAGON.F2_sfimm_p,SF_ftype_SI,1) // @@ -3666,56 +3666,6 @@ Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sffixupd">; def int_hexagon_F2_sffixupr : Hexagon_sf_sf_Intrinsic<"HEXAGON_F2_sffixupr">; // -// BUILTIN_INFO(HEXAGON.F2_dfadd,DF_ftype_DFDF,2) -// -def int_hexagon_F2_dfadd : -Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfadd">; -// -// BUILTIN_INFO(HEXAGON.F2_dfsub,DF_ftype_DFDF,2) -// -def int_hexagon_F2_dfsub : -Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfsub">; -// -// BUILTIN_INFO(HEXAGON.F2_dfmpy,DF_ftype_DFDF,2) -// -def int_hexagon_F2_dfmpy : -Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmpy">; -// -// BUILTIN_INFO(HEXAGON.F2_dffma,DF_ftype_DFDFDF,3) -// -def int_hexagon_F2_dffma : -Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffma">; -// -// BUILTIN_INFO(HEXAGON.F2_dffms,DF_ftype_DFDFDF,3) -// -def int_hexagon_F2_dffms : -Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffms">; -// -// BUILTIN_INFO(HEXAGON.F2_dffma_lib,DF_ftype_DFDFDF,3) -// -def int_hexagon_F2_dffma_lib : -Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffma_lib">; -// -// BUILTIN_INFO(HEXAGON.F2_dffms_lib,DF_ftype_DFDFDF,3) -// -def int_hexagon_F2_dffms_lib : -Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffms_lib">; -// -// BUILTIN_INFO(HEXAGON.F2_dffma_sc,DF_ftype_DFDFDFQI,4) -// -def int_hexagon_F2_dffma_sc : -Hexagon_df_dfdfdfqi_Intrinsic<"HEXAGON_F2_dffma_sc">; -// -// BUILTIN_INFO(HEXAGON.F2_dfmax,DF_ftype_DFDF,2) -// -def int_hexagon_F2_dfmax : -Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmax">; -// -// BUILTIN_INFO(HEXAGON.F2_dfmin,DF_ftype_DFDF,2) -// -def int_hexagon_F2_dfmin : -Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmin">; -// // BUILTIN_INFO(HEXAGON.F2_dfcmpeq,QI_ftype_DFDF,2) // def int_hexagon_F2_dfcmpeq : @@ -3739,7 +3689,7 @@ Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpuo">; // BUILTIN_INFO(HEXAGON.F2_dfclass,QI_ftype_DFSI,2) // def int_hexagon_F2_dfclass : -Hexagon_qi_dfsi_Intrinsic<"HEXAGON_F2_dfclass">; +Hexagon_si_dfsi_Intrinsic<"HEXAGON_F2_dfclass">; // // BUILTIN_INFO(HEXAGON.F2_dfimm_p,DF_ftype_SI,1) // @@ -3751,21 +3701,6 @@ Hexagon_df_si_Intrinsic<"HEXAGON_F2_dfimm_p">; def int_hexagon_F2_dfimm_n : Hexagon_df_si_Intrinsic<"HEXAGON_F2_dfimm_n">; // -// BUILTIN_INFO(HEXAGON.F2_dffixupn,DF_ftype_DFDF,2) -// -def int_hexagon_F2_dffixupn : -Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dffixupn">; -// -// BUILTIN_INFO(HEXAGON.F2_dffixupd,DF_ftype_DFDF,2) -// -def int_hexagon_F2_dffixupd : -Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dffixupd">; -// -// BUILTIN_INFO(HEXAGON.F2_dffixupr,DF_ftype_DF,1) -// -def int_hexagon_F2_dffixupr : -Hexagon_df_df_Intrinsic<"HEXAGON_F2_dffixupr">; -// // BUILTIN_INFO(HEXAGON.F2_conv_sf2df,DF_ftype_SF,1) // def int_hexagon_F2_conv_sf2df : diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp index 61e0f72d8a7..daf56604709 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -877,7 +877,7 @@ const { RegInfo.createVirtualRegister(&Hexagon::IntRegsRegClass); RegInfo.addLiveIn(VA.getLocReg(), VReg); InVals.push_back(DAG.getCopyFromReg(Chain, dl, VReg, RegVT)); - } else if (RegVT == MVT::i64) { + } else if (RegVT == MVT::i64 || RegVT == MVT::f64) { unsigned VReg = RegInfo.createVirtualRegister(&Hexagon::DoubleRegsRegClass); RegInfo.addLiveIn(VA.getLocReg(), VReg); diff --git a/lib/Target/Hexagon/HexagonInstrInfoV5.td b/lib/Target/Hexagon/HexagonInstrInfoV5.td index 54c4d379710..68ac167807b 100644 --- a/lib/Target/Hexagon/HexagonInstrInfoV5.td +++ b/lib/Target/Hexagon/HexagonInstrInfoV5.td @@ -725,6 +725,38 @@ def MUX_ri_f : ALU32_rr<(outs IntRegs:$dst), [(set F32:$dst, (f32 (select I1:$src1, fpimm:$src2, F32:$src3)))]>, Requires<[HasV5T]>; +//===----------------------------------------------------------------------===// +// :natural forms of vasrh and vasrhub insns +//===----------------------------------------------------------------------===// +// S5_asrhub_rnd_sat: Vector arithmetic shift right by immediate with round, +// saturate, and pack. +let Defs = [USR_OVF], hasSideEffects = 0, hasNewValue = 1, opNewValue = 0 in +class T_ASRHUB + : SInst <(outs IntRegs:$Rd), + (ins DoubleRegs:$Rss, u4Imm:$u4), + "$Rd = vasrhub($Rss, #$u4):"#!if(isSat, "sat", "raw"), + [], "", S_2op_tc_2_SLOT23>, + Requires<[HasV5T]> { + bits<5> Rd; + bits<5> Rss; + bits<4> u4; + + let IClass = 0b1000; + + let Inst{27-21} = 0b1000011; + let Inst{20-16} = Rss; + let Inst{13-12} = 0b00; + let Inst{11-8} = u4; + let Inst{7-6} = 0b10; + let Inst{5} = isSat; + let Inst{4-0} = Rd; + } +def S5_asrhub_sat : T_ASRHUB <1>; + +def S5_asrhub_rnd_sat_goodsyntax + : SInst <(outs IntRegs:$Rd), (ins DoubleRegs:$Rss, u4Imm:$u4), + "$Rd = vasrhub($Rss, #$u4):rnd:sat">, Requires<[HasV5T]>; + // Classify floating-point value let isFP = 1, isCodeGenOnly = 0 in def F2_sfclass : T_TEST_BIT_IMM<"sfclass", 0b111>; diff --git a/lib/Target/Hexagon/HexagonIntrinsics.td b/lib/Target/Hexagon/HexagonIntrinsics.td index b1dcf80f142..0ba96bc60b5 100644 --- a/lib/Target/Hexagon/HexagonIntrinsics.td +++ b/lib/Target/Hexagon/HexagonIntrinsics.td @@ -113,6 +113,36 @@ class T_PR_pat : Pat <(IntID I64:$Rs, I32:$Rt), (MI DoubleRegs:$Rs, I32:$Rt)>; +class T_D_pat + : Pat<(IntID (F64:$Rs)), + (MI (F64:$Rs))>; + +class T_DI_pat > + : Pat<(IntID F64:$Rs, ImmPred:$It), + (MI F64:$Rs, ImmPred:$It)>; + +class T_F_pat + : Pat<(IntID F32:$Rs), + (MI F32:$Rs)>; + +class T_FI_pat > + : Pat<(IntID F32:$Rs, ImmPred:$It), + (MI F32:$Rs, ImmPred:$It)>; + +class T_FF_pat + : Pat<(IntID F32:$Rs, F32:$Rt), + (MI F32:$Rs, F32:$Rt)>; + +class T_FFF_pat + : Pat<(IntID F32:$Rs, F32:$Rt, F32:$Ru), + (MI F32:$Rs, F32:$Rt, F32:$Ru)>; + +class T_FFFQ_pat + : Pat <(IntID F32:$Rs, F32:$Rt, F32:$Ru, (i32 PredRegs:$Rx)), + (MI F32:$Rs, F32:$Rt, F32:$Ru, PredRegs:$Rx)>; + //===----------------------------------------------------------------------===// // MPYS / Multipy signed/unsigned halfwords //Rd=mpy[u](Rs.[H|L],Rt.[H|L])[:<<1][:rnd][:sat] diff --git a/lib/Target/Hexagon/HexagonIntrinsicsV3.td b/lib/Target/Hexagon/HexagonIntrinsicsV3.td index 2a54e62d20a..f24aa96097b 100644 --- a/lib/Target/Hexagon/HexagonIntrinsicsV3.td +++ b/lib/Target/Hexagon/HexagonIntrinsicsV3.td @@ -23,8 +23,6 @@ def Hexagon_M2_vrcmpys_s1rp: si_MInst_disi_s1_rnd_sat <"vrcmpys", int_hexagon_M2_vrcmpys_s1rp>; - - /******************************************************************** * MTYPE/VB * *********************************************************************/ @@ -34,17 +32,9 @@ def Hexagon_M2_vradduh: si_MInst_didi <"vradduh", int_hexagon_M2_vradduh>; -/******************************************************************** -* ALU64/ALU * -*********************************************************************/ - -// ALU64 / ALU / Add. -def Hexagon_A2_addsp: - di_ALU64_sidi <"add", int_hexagon_A2_addsp>; -def Hexagon_A2_addpsat: - di_ALU64_didi <"add", int_hexagon_A2_addpsat>; - -def Hexagon_A2_maxp: - di_ALU64_didi <"max", int_hexagon_A2_maxp>; -def Hexagon_A2_maxup: - di_ALU64_didi <"maxu", int_hexagon_A2_maxup>; +def: T_RP_pat; +def: T_PP_pat; +def: T_PP_pat; +def: T_PP_pat; +def: T_PP_pat; +def: T_PP_pat; diff --git a/lib/Target/Hexagon/HexagonIntrinsicsV5.td b/lib/Target/Hexagon/HexagonIntrinsicsV5.td index 3724a585719..b9beb301b51 100644 --- a/lib/Target/Hexagon/HexagonIntrinsicsV5.td +++ b/lib/Target/Hexagon/HexagonIntrinsicsV5.td @@ -7,80 +7,66 @@ // //===----------------------------------------------------------------------===// +def : T_FF_pat; +def : T_FF_pat; +def : T_FF_pat; +def : T_FF_pat; +def : T_FF_pat; + +def : T_FF_pat; +def : T_FF_pat; +def : T_F_pat ; + +def : T_P_pat ; +def : T_PI_pat ; + def : T_PI_pat ; def : T_PI_pat ; -class sf_SInst_sf - : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set IntRegs:$dst, (IntID IntRegs:$src1))]>; +def : T_PI_pat ; -class si_SInst_sf - : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set IntRegs:$dst, (IntID IntRegs:$src1))]>; +def : T_FFF_pat ; +def : T_FFF_pat ; +def : T_FFF_pat ; +def : T_FFF_pat ; +def : T_FFFQ_pat ; -class sf_SInst_si - : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set IntRegs:$dst, (IntID IntRegs:$src1))]>; +// Create floating-point value +def : T_I_pat ; +def : T_I_pat ; +def : T_I_pat ; +def : T_I_pat ; -class sf_SInst_di - : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set IntRegs:$dst, (IntID DoubleRegs:$src1))]>; - -class sf_SInst_df - : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set IntRegs:$dst, (IntID DoubleRegs:$src1))]>; - -class si_SInst_df - : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set IntRegs:$dst, (IntID DoubleRegs:$src1))]>; - -class df_SInst_sf - : SInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set DoubleRegs:$dst, (IntID IntRegs:$src1))]>; - -class di_SInst_sf - : SInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set DoubleRegs:$dst, (IntID IntRegs:$src1))]>; - -class df_SInst_si - : SInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set DoubleRegs:$dst, (IntID IntRegs:$src1))]>; - -class df_SInst_df - : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1))]>; - -class di_SInst_df - : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1))]>; - - -class df_SInst_di - : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1), - !strconcat("$dst = ", !strconcat(opc , "($src1)")), - [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1))]>; - -class sf_MInst_sfsf - : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), - !strconcat("$dst = ", !strconcat(opc , "($src1, $src2)")), - [(set IntRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2))]>; - -class df_MInst_dfdf - : MInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), - !strconcat("$dst = ", !strconcat(opc , "($src1, $src2)")), - [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1, DoubleRegs:$src2))]>; +def : T_DI_pat ; +def : T_FI_pat ; +def : T_F_pat ; +def : T_D_pat ; +def : T_R_pat ; +def : T_R_pat ; +def : T_R_pat ; +def : T_R_pat ; +def : T_P_pat ; +def : T_P_pat ; +def : T_P_pat ; +def : T_P_pat ; +def : T_F_pat ; +def : T_F_pat ; +def : T_F_pat ; +def : T_F_pat ; +def : T_D_pat ; +def : T_D_pat ; +def : T_D_pat ; +def : T_D_pat ; +def : T_F_pat ; +def : T_F_pat ; +def : T_F_pat ; +def : T_F_pat ; +def : T_D_pat ; +def : T_D_pat ; +def : T_D_pat ; +def : T_D_pat ; class qi_ALU64_dfdf : ALU64_rr<(outs PredRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), @@ -92,99 +78,6 @@ class qi_ALU64_dfu5 !strconcat("$dst = ", !strconcat(opc , "($src1, #$src2)")), [(set PredRegs:$dst, (IntID DoubleRegs:$src1, imm:$src2))]>; - -class sf_MInst_sfsfsf_acc - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, - IntRegs:$dst2), - !strconcat("$dst += ", !strconcat(opc , - "($src1, $src2)")), - [(set IntRegs:$dst, (IntID IntRegs:$src1, - IntRegs:$src2, IntRegs:$dst2))], - "$dst2 = $dst">; - -class sf_MInst_sfsfsf_nac - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, - IntRegs:$dst2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1, $src2)")), - [(set IntRegs:$dst, (IntID IntRegs:$src1, - IntRegs:$src2, IntRegs:$dst2))], - "$dst2 = $dst">; - - -class sf_MInst_sfsfsfsi_sc - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2, IntRegs:$src3), - !strconcat("$dst += ", !strconcat(opc , - "($src1, $src2, $src3):scale")), - [(set IntRegs:$dst, (IntID IntRegs:$dst2, IntRegs:$src1, - IntRegs:$src2, IntRegs:$src3))], - "$dst2 = $dst">; - -class sf_MInst_sfsfsf_acc_lib - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, - IntRegs:$dst2), - !strconcat("$dst += ", !strconcat(opc , - "($src1, $src2):lib")), - [(set IntRegs:$dst, (IntID IntRegs:$src1, - IntRegs:$src2, IntRegs:$dst2))], - "$dst2 = $dst">; - -class sf_MInst_sfsfsf_nac_lib - : MInst_acc<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, - IntRegs:$dst2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1, $src2):lib")), - [(set IntRegs:$dst, (IntID IntRegs:$src1, - IntRegs:$src2, IntRegs:$dst2))], - "$dst2 = $dst">; - -class df_MInst_dfdfdf_acc - : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2, - DoubleRegs:$dst2), - !strconcat("$dst += ", !strconcat(opc , - "($src1, $src2)")), - [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1, - DoubleRegs:$src2, DoubleRegs:$dst2))], - "$dst2 = $dst">; - -class df_MInst_dfdfdf_nac - : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2, - DoubleRegs:$dst2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1, $src2)")), - [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1, - DoubleRegs:$src2, DoubleRegs:$dst2))], - "$dst2 = $dst">; - - -class df_MInst_dfdfdfsi_sc - : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$dst2, DoubleRegs:$src1, - DoubleRegs:$src2, IntRegs:$src3), - !strconcat("$dst += ", !strconcat(opc , - "($src1, $src2, $src3):scale")), - [(set DoubleRegs:$dst, (IntID DoubleRegs:$dst2, DoubleRegs:$src1, - DoubleRegs:$src2, IntRegs:$src3))], - "$dst2 = $dst">; - -class df_MInst_dfdfdf_acc_lib - : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2, - DoubleRegs:$dst2), - !strconcat("$dst += ", !strconcat(opc , - "($src1, $src2):lib")), - [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1, - DoubleRegs:$src2, DoubleRegs:$dst2))], - "$dst2 = $dst">; - -class df_MInst_dfdfdf_nac_lib - : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2, - DoubleRegs:$dst2), - !strconcat("$dst -= ", !strconcat(opc , - "($src1, $src2):lib")), - [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1, - DoubleRegs:$src2, DoubleRegs:$dst2))], - "$dst2 = $dst">; - class qi_SInst_sfsf : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), !strconcat("$dst = ", !strconcat(opc , "($src1, $src2)")), @@ -195,47 +88,11 @@ class qi_SInst_sfu5 !strconcat("$dst = ", !strconcat(opc , "($src1, #$src2)")), [(set PredRegs:$dst, (IntID IntRegs:$src1, imm:$src2))]>; -class sf_ALU64_u10_pos - : ALU64_ri<(outs IntRegs:$dst), (ins u10Imm:$src1), - !strconcat("$dst = ", !strconcat(opc , "#$src1):pos")), - [(set IntRegs:$dst, (IntID imm:$src1))]>; - -class sf_ALU64_u10_neg - : ALU64_ri<(outs IntRegs:$dst), (ins u10Imm:$src1), - !strconcat("$dst = ", !strconcat(opc , "#$src1):neg")), - [(set IntRegs:$dst, (IntID imm:$src1))]>; - -class df_ALU64_u10_pos - : ALU64_ri<(outs DoubleRegs:$dst), (ins u10Imm:$src1), - !strconcat("$dst = ", !strconcat(opc , "#$src1):pos")), - [(set DoubleRegs:$dst, (IntID imm:$src1))]>; - -class df_ALU64_u10_neg - : ALU64_ri<(outs DoubleRegs:$dst), (ins u10Imm:$src1), - !strconcat("$dst = ", !strconcat(opc , "#$src1):neg")), - [(set DoubleRegs:$dst, (IntID imm:$src1))]>; - -class di_MInst_diu6 - : MInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2), - !strconcat("$dst = ", !strconcat(opc , "($src1, #$src2)")), - [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1, imm:$src2))]>; - class di_MInst_diu4_rnd : MInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u4Imm:$src2), !strconcat("$dst = ", !strconcat(opc , "($src1, #$src2):rnd")), [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1, imm:$src2))]>; -class si_MInst_diu4_rnd_sat - : MInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1, u4Imm:$src2), - !strconcat("$dst = ", !strconcat(opc , "($src1, #$src2):rnd:sat")), - [(set IntRegs:$dst, (IntID DoubleRegs:$src1, imm:$src2))]>; - -class si_SInst_diu4_sat - : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1, u4Imm:$src2), - !strconcat("$dst = ", !strconcat(opc , "($src1, #$src2):sat")), - [(set IntRegs:$dst, (IntID DoubleRegs:$src1, imm:$src2))]>; - - def HEXAGON_C4_fastcorner9: qi_SInst_qiqi <"fastcorner9", int_hexagon_C4_fastcorner9>; def HEXAGON_C4_fastcorner9_not: @@ -262,34 +119,8 @@ def HEXAGON_M5_vdmacbsu: di_MInst_dididi_acc_sat <"vdmpybsu", int_hexagon_M5_vdmacbsu>; def HEXAGON_A5_vaddhubs: si_SInst_didi_sat <"vaddhub", int_hexagon_A5_vaddhubs>; -def HEXAGON_S5_popcountp: - si_SInst_di <"popcount", int_hexagon_S5_popcountp>; -def HEXAGON_S5_asrhub_rnd_sat_goodsyntax: - si_MInst_diu4_rnd_sat <"vasrhub", int_hexagon_S5_asrhub_rnd_sat_goodsyntax>; -def HEXAGON_S5_asrhub_sat: - si_SInst_diu4_sat <"vasrhub", int_hexagon_S5_asrhub_sat>; def HEXAGON_S5_vasrhrnd_goodsyntax: di_MInst_diu4_rnd <"vasrh", int_hexagon_S5_vasrhrnd_goodsyntax>; -def HEXAGON_S2_asr_i_p_rnd: - di_SInst_diu6 <"asr", int_hexagon_S2_asr_i_p_rnd>; -def HEXAGON_S2_asr_i_p_rnd_goodsyntax: - di_MInst_diu6 <"asrrnd", int_hexagon_S2_asr_i_p_rnd_goodsyntax>; -def HEXAGON_F2_sfadd: - sf_MInst_sfsf <"sfadd", int_hexagon_F2_sfadd>; -def HEXAGON_F2_sfsub: - sf_MInst_sfsf <"sfsub", int_hexagon_F2_sfsub>; -def HEXAGON_F2_sfmpy: - sf_MInst_sfsf <"sfmpy", int_hexagon_F2_sfmpy>; -def HEXAGON_F2_sffma: - sf_MInst_sfsfsf_acc <"sfmpy", int_hexagon_F2_sffma>; -def HEXAGON_F2_sffma_sc: - sf_MInst_sfsfsfsi_sc <"sfmpy", int_hexagon_F2_sffma_sc>; -def HEXAGON_F2_sffms: - sf_MInst_sfsfsf_nac <"sfmpy", int_hexagon_F2_sffms>; -def HEXAGON_F2_sffma_lib: - sf_MInst_sfsfsf_acc_lib <"sfmpy", int_hexagon_F2_sffma_lib>; -def HEXAGON_F2_sffms_lib: - sf_MInst_sfsfsf_nac_lib <"sfmpy", int_hexagon_F2_sffms_lib>; def HEXAGON_F2_sfcmpeq: qi_SInst_sfsf <"sfcmp.eq", int_hexagon_F2_sfcmpeq>; def HEXAGON_F2_sfcmpgt: @@ -298,111 +129,3 @@ def HEXAGON_F2_sfcmpge: qi_SInst_sfsf <"sfcmp.ge", int_hexagon_F2_sfcmpge>; def HEXAGON_F2_sfcmpuo: qi_SInst_sfsf <"sfcmp.uo", int_hexagon_F2_sfcmpuo>; -def HEXAGON_F2_sfmax: - sf_MInst_sfsf <"sfmax", int_hexagon_F2_sfmax>; -def HEXAGON_F2_sfmin: - sf_MInst_sfsf <"sfmin", int_hexagon_F2_sfmin>; -def HEXAGON_F2_sfclass: - qi_SInst_sfu5 <"sfclass", int_hexagon_F2_sfclass>; -def HEXAGON_F2_sfimm_p: - sf_ALU64_u10_pos <"sfmake", int_hexagon_F2_sfimm_p>; -def HEXAGON_F2_sfimm_n: - sf_ALU64_u10_neg <"sfmake", int_hexagon_F2_sfimm_n>; -def HEXAGON_F2_sffixupn: - sf_MInst_sfsf <"sffixupn", int_hexagon_F2_sffixupn>; -def HEXAGON_F2_sffixupd: - sf_MInst_sfsf <"sffixupd", int_hexagon_F2_sffixupd>; -def HEXAGON_F2_sffixupr: - sf_SInst_sf <"sffixupr", int_hexagon_F2_sffixupr>; -def HEXAGON_F2_dfadd: - df_MInst_dfdf <"dfadd", int_hexagon_F2_dfadd>; -def HEXAGON_F2_dfsub: - df_MInst_dfdf <"dfsub", int_hexagon_F2_dfsub>; -def HEXAGON_F2_dfmpy: - df_MInst_dfdf <"dfmpy", int_hexagon_F2_dfmpy>; -def HEXAGON_F2_dffma: - df_MInst_dfdfdf_acc <"dfmpy", int_hexagon_F2_dffma>; -def HEXAGON_F2_dffms: - df_MInst_dfdfdf_nac <"dfmpy", int_hexagon_F2_dffms>; -def HEXAGON_F2_dffma_lib: - df_MInst_dfdfdf_acc_lib <"dfmpy", int_hexagon_F2_dffma_lib>; -def HEXAGON_F2_dffms_lib: - df_MInst_dfdfdf_nac_lib <"dfmpy", int_hexagon_F2_dffms_lib>; -def HEXAGON_F2_dffma_sc: - df_MInst_dfdfdfsi_sc <"dfmpy", int_hexagon_F2_dffma_sc>; -def HEXAGON_F2_dfmax: - df_MInst_dfdf <"dfmax", int_hexagon_F2_dfmax>; -def HEXAGON_F2_dfmin: - df_MInst_dfdf <"dfmin", int_hexagon_F2_dfmin>; -def HEXAGON_F2_dfcmpeq: - qi_ALU64_dfdf <"dfcmp.eq", int_hexagon_F2_dfcmpeq>; -def HEXAGON_F2_dfcmpgt: - qi_ALU64_dfdf <"dfcmp.gt", int_hexagon_F2_dfcmpgt>; -def HEXAGON_F2_dfcmpge: - qi_ALU64_dfdf <"dfcmp.ge", int_hexagon_F2_dfcmpge>; -def HEXAGON_F2_dfcmpuo: - qi_ALU64_dfdf <"dfcmp.uo", int_hexagon_F2_dfcmpuo>; -def HEXAGON_F2_dfclass: - qi_ALU64_dfu5 <"dfclass", int_hexagon_F2_dfclass>; -def HEXAGON_F2_dfimm_p: - df_ALU64_u10_pos <"dfmake", int_hexagon_F2_dfimm_p>; -def HEXAGON_F2_dfimm_n: - df_ALU64_u10_neg <"dfmake", int_hexagon_F2_dfimm_n>; -def HEXAGON_F2_dffixupn: - df_MInst_dfdf <"dffixupn", int_hexagon_F2_dffixupn>; -def HEXAGON_F2_dffixupd: - df_MInst_dfdf <"dffixupd", int_hexagon_F2_dffixupd>; -def HEXAGON_F2_dffixupr: - df_SInst_df <"dffixupr", int_hexagon_F2_dffixupr>; -def HEXAGON_F2_conv_sf2df: - df_SInst_sf <"convert_sf2df", int_hexagon_F2_conv_sf2df>; -def HEXAGON_F2_conv_df2sf: - sf_SInst_df <"convert_df2sf", int_hexagon_F2_conv_df2sf>; -def HEXAGON_F2_conv_uw2sf: - sf_SInst_si <"convert_uw2sf", int_hexagon_F2_conv_uw2sf>; -def HEXAGON_F2_conv_uw2df: - df_SInst_si <"convert_uw2df", int_hexagon_F2_conv_uw2df>; -def HEXAGON_F2_conv_w2sf: - sf_SInst_si <"convert_w2sf", int_hexagon_F2_conv_w2sf>; -def HEXAGON_F2_conv_w2df: - df_SInst_si <"convert_w2df", int_hexagon_F2_conv_w2df>; -def HEXAGON_F2_conv_ud2sf: - sf_SInst_di <"convert_ud2sf", int_hexagon_F2_conv_ud2sf>; -def HEXAGON_F2_conv_ud2df: - df_SInst_di <"convert_ud2df", int_hexagon_F2_conv_ud2df>; -def HEXAGON_F2_conv_d2sf: - sf_SInst_di <"convert_d2sf", int_hexagon_F2_conv_d2sf>; -def HEXAGON_F2_conv_d2df: - df_SInst_di <"convert_d2df", int_hexagon_F2_conv_d2df>; -def HEXAGON_F2_conv_sf2uw: - si_SInst_sf <"convert_sf2uw", int_hexagon_F2_conv_sf2uw>; -def HEXAGON_F2_conv_sf2w: - si_SInst_sf <"convert_sf2w", int_hexagon_F2_conv_sf2w>; -def HEXAGON_F2_conv_sf2ud: - di_SInst_sf <"convert_sf2ud", int_hexagon_F2_conv_sf2ud>; -def HEXAGON_F2_conv_sf2d: - di_SInst_sf <"convert_sf2d", int_hexagon_F2_conv_sf2d>; -def HEXAGON_F2_conv_df2uw: - si_SInst_df <"convert_df2uw", int_hexagon_F2_conv_df2uw>; -def HEXAGON_F2_conv_df2w: - si_SInst_df <"convert_df2w", int_hexagon_F2_conv_df2w>; -def HEXAGON_F2_conv_df2ud: - di_SInst_df <"convert_df2ud", int_hexagon_F2_conv_df2ud>; -def HEXAGON_F2_conv_df2d: - di_SInst_df <"convert_df2d", int_hexagon_F2_conv_df2d>; -def HEXAGON_F2_conv_sf2uw_chop: - si_SInst_sf <"convert_sf2uw", int_hexagon_F2_conv_sf2uw_chop>; -def HEXAGON_F2_conv_sf2w_chop: - si_SInst_sf <"convert_sf2w", int_hexagon_F2_conv_sf2w_chop>; -def HEXAGON_F2_conv_sf2ud_chop: - di_SInst_sf <"convert_sf2ud", int_hexagon_F2_conv_sf2ud_chop>; -def HEXAGON_F2_conv_sf2d_chop: - di_SInst_sf <"convert_sf2d", int_hexagon_F2_conv_sf2d_chop>; -def HEXAGON_F2_conv_df2uw_chop: - si_SInst_df <"convert_df2uw", int_hexagon_F2_conv_df2uw_chop>; -def HEXAGON_F2_conv_df2w_chop: - si_SInst_df <"convert_df2w", int_hexagon_F2_conv_df2w_chop>; -def HEXAGON_F2_conv_df2ud_chop: - di_SInst_df <"convert_df2ud", int_hexagon_F2_conv_df2ud_chop>; -def HEXAGON_F2_conv_df2d_chop: - di_SInst_df <"convert_df2d", int_hexagon_F2_conv_df2d_chop>; diff --git a/test/CodeGen/Hexagon/intrinsics/xtype_alu.ll b/test/CodeGen/Hexagon/intrinsics/xtype_alu.ll new file mode 100644 index 00000000000..5485440161a --- /dev/null +++ b/test/CodeGen/Hexagon/intrinsics/xtype_alu.ll @@ -0,0 +1,545 @@ +; RUN: llc -march=hexagon -O0 < %s | FileCheck %s +; Hexagon Programmer's Reference Manual 11.10.1 XTYPE/ALU + +; Absolute value doubleword +declare i64 @llvm.hexagon.A2.absp(i64) +define i64 @A2_absp(i64 %a) { + %z = call i64 @llvm.hexagon.A2.absp(i64 %a) + ret i64 %z +} +; CHECK: r1:0 = abs(r1:0) + +; Absolute value word +declare i32 @llvm.hexagon.A2.abs(i32) +define i32 @A2_abs(i32 %a) { + %z = call i32 @llvm.hexagon.A2.abs(i32 %a) + ret i32 %z +} +; CHECK: r0 = abs(r0) + +declare i32 @llvm.hexagon.A2.abssat(i32) +define i32 @A2_abssat(i32 %a) { + %z = call i32 @llvm.hexagon.A2.abssat(i32 %a) + ret i32 %z +} +; CHECK: r0 = abs(r0):sat + +; Add and accumulate +declare i32 @llvm.hexagon.S4.addaddi(i32, i32, i32) +define i32 @S4_addaddi(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.S4.addaddi(i32 %a, i32 %b, i32 0) + ret i32 %z +} +; CHECK: r0 = add(r0, add(r1, #0)) + +declare i32 @llvm.hexagon.S4.subaddi(i32, i32, i32) +define i32 @S4_subaddi(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.S4.subaddi(i32 %a, i32 0, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0, sub(#0, r1)) + +declare i32 @llvm.hexagon.M2.accii(i32, i32, i32) +define i32 @M2_accii(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.M2.accii(i32 %a, i32 %b, i32 0) + ret i32 %z +} +; CHECK: r0 += add(r1, #0) + +declare i32 @llvm.hexagon.M2.naccii(i32, i32, i32) +define i32 @M2_naccii(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.M2.naccii(i32 %a, i32 %b, i32 0) + ret i32 %z +} +; CHECK: r0 -= add(r1, #0) + +declare i32 @llvm.hexagon.M2.acci(i32, i32, i32) +define i32 @M2_acci(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M2.acci(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 += add(r1, r2) + +declare i32 @llvm.hexagon.M2.nacci(i32, i32, i32) +define i32 @M2_nacci(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M2.nacci(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 -= add(r1, r2) + +; Add doublewords +declare i64 @llvm.hexagon.A2.addp(i64, i64) +define i64 @A2_addp(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A2.addp(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = add(r1:0, r3:2) + +declare i64 @llvm.hexagon.A2.addpsat(i64, i64) +define i64 @A2_addpsat(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A2.addpsat(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = add(r1:0, r3:2):sat + +; Add halfword +declare i32 @llvm.hexagon.A2.addh.l16.ll(i32, i32) +define i32 @A2_addh_l16_ll(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.l16.ll(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.l, r1.l) + +declare i32 @llvm.hexagon.A2.addh.l16.hl(i32, i32) +define i32 @A2_addh_l16_hl(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.l16.hl(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.l, r1.h) + +declare i32 @llvm.hexagon.A2.addh.l16.sat.ll(i32, i32) +define i32 @A2_addh_l16_sat.ll(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.l16.sat.ll(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.l, r1.l):sat + +declare i32 @llvm.hexagon.A2.addh.l16.sat.hl(i32, i32) +define i32 @A2_addh_l16_sat.hl(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.l16.sat.hl(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.l, r1.h):sat + +declare i32 @llvm.hexagon.A2.addh.h16.ll(i32, i32) +define i32 @A2_addh_h16_ll(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.h16.ll(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.l, r1.l):<<16 + +declare i32 @llvm.hexagon.A2.addh.h16.lh(i32, i32) +define i32 @A2_addh_h16_lh(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.h16.lh(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.l, r1.h):<<16 + +declare i32 @llvm.hexagon.A2.addh.h16.hl(i32, i32) +define i32 @A2_addh_h16_hl(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.h16.hl(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.h, r1.l):<<16 + +declare i32 @llvm.hexagon.A2.addh.h16.hh(i32, i32) +define i32 @A2_addh_h16_hh(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.h16.hh(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.h, r1.h):<<16 + +declare i32 @llvm.hexagon.A2.addh.h16.sat.ll(i32, i32) +define i32 @A2_addh_h16_sat_ll(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.h16.sat.ll(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.l, r1.l):sat:<<16 + +declare i32 @llvm.hexagon.A2.addh.h16.sat.lh(i32, i32) +define i32 @A2_addh_h16_sat_lh(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.h16.sat.lh(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.l, r1.h):sat:<<16 + +declare i32 @llvm.hexagon.A2.addh.h16.sat.hl(i32, i32) +define i32 @A2_addh_h16_sat_hl(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.h16.sat.hl(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.h, r1.l):sat:<<16 + +declare i32 @llvm.hexagon.A2.addh.h16.sat.hh(i32, i32) +define i32 @A2_addh_h16_sat_hh(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.addh.h16.sat.hh(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = add(r0.h, r1.h):sat:<<16 + +; Logical doublewords +declare i64 @llvm.hexagon.A2.notp(i64) +define i64 @A2_notp(i64 %a) { + %z = call i64 @llvm.hexagon.A2.notp(i64 %a) + ret i64 %z +} +; CHECK: r1:0 = not(r1:0) + +declare i64 @llvm.hexagon.A2.andp(i64, i64) +define i64 @A2_andp(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A2.andp(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = and(r1:0, r3:2) + +declare i64 @llvm.hexagon.A4.andnp(i64, i64) +define i64 @A2_andnp(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A4.andnp(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = and(r1:0, ~r3:2) + +declare i64 @llvm.hexagon.A2.orp(i64, i64) +define i64 @A2_orp(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A2.orp(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = or(r1:0, r3:2) + +declare i64 @llvm.hexagon.A4.ornp(i64, i64) +define i64 @A2_ornp(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A4.ornp(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = or(r1:0, ~r3:2) + +declare i64 @llvm.hexagon.A2.xorp(i64, i64) +define i64 @A2_xorp(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A2.xorp(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = xor(r1:0, r3:2) + +; Logical-logical doublewords +declare i64 @llvm.hexagon.M4.xor.xacc(i64, i64, i64) +define i64 @M4_xor_xacc(i64 %a, i64 %b, i64 %c) { + %z = call i64 @llvm.hexagon.M4.xor.xacc(i64 %a, i64 %b, i64 %c) + ret i64 %z +} +; CHECK: r1:0 ^= xor(r3:2, r5:4) + +; Logical-logical words +declare i32 @llvm.hexagon.S4.or.andi(i32, i32, i32) +define i32 @S4_or_andi(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.S4.or.andi(i32 %a, i32 %b, i32 0) + ret i32 %z +} +; CHECK: r0 |= and(r1, #0) + +declare i32 @llvm.hexagon.S4.or.andix(i32, i32, i32) +define i32 @S4_or_andix(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.S4.or.andix(i32 %a, i32 %b, i32 0) + ret i32 %z +} +; CHECK: r1 = or(r0, and(r1, #0)) + +declare i32 @llvm.hexagon.M4.or.andn(i32, i32, i32) +define i32 @M4_or_andn(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.or.andn(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 |= and(r1, ~r2) + +declare i32 @llvm.hexagon.M4.and.andn(i32, i32, i32) +define i32 @M4_and_andn(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.and.andn(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 &= and(r1, ~r2) + +declare i32 @llvm.hexagon.M4.xor.andn(i32, i32, i32) +define i32 @M4_xor_andn(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.xor.andn(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 ^= and(r1, ~r2) + +declare i32 @llvm.hexagon.M4.and.and(i32, i32, i32) +define i32 @M4_and_and(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.and.and(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 &= and(r1, r2) + +declare i32 @llvm.hexagon.M4.and.or(i32, i32, i32) +define i32 @M4_and_or(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.and.or(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 &= or(r1, r2) + +declare i32 @llvm.hexagon.M4.and.xor(i32, i32, i32) +define i32 @M4_and_xor(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.and.xor(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 &= xor(r1, r2) + +declare i32 @llvm.hexagon.M4.or.and(i32, i32, i32) +define i32 @M4_or_and(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.or.and(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 |= and(r1, r2) + +declare i32 @llvm.hexagon.M4.or.or(i32, i32, i32) +define i32 @M4_or_or(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.or.or(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 |= or(r1, r2) + +declare i32 @llvm.hexagon.M4.or.xor(i32, i32, i32) +define i32 @M4_or_xor(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.or.xor(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 |= xor(r1, r2) + +declare i32 @llvm.hexagon.M4.xor.and(i32, i32, i32) +define i32 @M4_xor_and(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.xor.and(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 ^= and(r1, r2) + +declare i32 @llvm.hexagon.M4.xor.or(i32, i32, i32) +define i32 @M4_xor_or(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M4.xor.or(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 ^= or(r1, r2) + +; Maximum words +declare i32 @llvm.hexagon.A2.max(i32, i32) +define i32 @A2_max(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.max(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = max(r0, r1) + +declare i32 @llvm.hexagon.A2.maxu(i32, i32) +define i32 @A2_maxu(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.maxu(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = maxu(r0, r1) + +; Maximum doublewords +declare i64 @llvm.hexagon.A2.maxp(i64, i64) +define i64 @A2_maxp(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A2.maxp(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = max(r1:0, r3:2) + +declare i64 @llvm.hexagon.A2.maxup(i64, i64) +define i64 @A2_maxup(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A2.maxup(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = maxu(r1:0, r3:2) + +; Minimum words +declare i32 @llvm.hexagon.A2.min(i32, i32) +define i32 @A2_min(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.min(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = min(r0, r1) + +declare i32 @llvm.hexagon.A2.minu(i32, i32) +define i32 @A2_minu(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.minu(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = minu(r0, r1) + +; Minimum doublewords +declare i64 @llvm.hexagon.A2.minp(i64, i64) +define i64 @A2_minp(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A2.minp(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = min(r1:0, r3:2) + +declare i64 @llvm.hexagon.A2.minup(i64, i64) +define i64 @A2_minup(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A2.minup(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = minu(r1:0, r3:2) + +; Module wrap +declare i32 @llvm.hexagon.A4.modwrapu(i32, i32) +define i32 @A4_modwrapu(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A4.modwrapu(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = modwrap(r0, r1) + +; Negate +declare i64 @llvm.hexagon.A2.negp(i64) +define i64 @A2_negp(i64 %a) { + %z = call i64 @llvm.hexagon.A2.negp(i64 %a) + ret i64 %z +} +; CHECK: r1:0 = neg(r1:0) + +declare i32 @llvm.hexagon.A2.negsat(i32) +define i32 @A2_negsat(i32 %a) { + %z = call i32 @llvm.hexagon.A2.negsat(i32 %a) + ret i32 %z +} +; CHECK: r0 = neg(r0):sat + +; Round +declare i32 @llvm.hexagon.A2.roundsat(i64) +define i32 @A2_roundsat(i64 %a) { + %z = call i32 @llvm.hexagon.A2.roundsat(i64 %a) + ret i32 %z +} +; CHECK: r0 = round(r1:0):sat + +declare i32 @llvm.hexagon.A4.cround.ri(i32, i32) +define i32 @A4_cround_ri(i32 %a) { + %z = call i32 @llvm.hexagon.A4.cround.ri(i32 %a, i32 0) + ret i32 %z +} +; CHECK: r0 = cround(r0, #0) + +declare i32 @llvm.hexagon.A4.round.ri(i32, i32) +define i32 @A4_round_ri(i32 %a) { + %z = call i32 @llvm.hexagon.A4.round.ri(i32 %a, i32 0) + ret i32 %z +} +; CHECK: r0 = round(r0, #0) + +declare i32 @llvm.hexagon.A4.round.ri.sat(i32, i32) +define i32 @A4_round_ri_sat(i32 %a) { + %z = call i32 @llvm.hexagon.A4.round.ri.sat(i32 %a, i32 0) + ret i32 %z +} +; CHECK: r0 = round(r0, #0):sat + +declare i32 @llvm.hexagon.A4.cround.rr(i32, i32) +define i32 @A4_cround_rr(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A4.cround.rr(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = cround(r0, r1) + +declare i32 @llvm.hexagon.A4.round.rr(i32, i32) +define i32 @A4_round_rr(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A4.round.rr(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = round(r0, r1) + +declare i32 @llvm.hexagon.A4.round.rr.sat(i32, i32) +define i32 @A4_round_rr_sat(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A4.round.rr.sat(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = round(r0, r1):sat + +; Subtract doublewords +declare i64 @llvm.hexagon.A2.subp(i64, i64) +define i64 @A2_subp(i64 %a, i64 %b) { + %z = call i64 @llvm.hexagon.A2.subp(i64 %a, i64 %b) + ret i64 %z +} +; CHECK: r1:0 = sub(r1:0, r3:2) + +; Subtract and accumulate +declare i32 @llvm.hexagon.M2.subacc(i32, i32, i32) +define i32 @M2_subacc(i32 %a, i32 %b, i32 %c) { + %z = call i32 @llvm.hexagon.M2.subacc(i32 %a, i32 %b, i32 %c) + ret i32 %z +} +; CHECK: r0 += sub(r1, r2) + +; Subtract halfwords +declare i32 @llvm.hexagon.A2.subh.l16.ll(i32, i32) +define i32 @A2_subh_l16_ll(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.l16.ll(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.l, r1.l) + +declare i32 @llvm.hexagon.A2.subh.l16.hl(i32, i32) +define i32 @A2_subh_l16_hl(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.l16.hl(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.l, r1.h) + +declare i32 @llvm.hexagon.A2.subh.l16.sat.ll(i32, i32) +define i32 @A2_subh_l16_sat.ll(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.l16.sat.ll(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.l, r1.l):sat + +declare i32 @llvm.hexagon.A2.subh.l16.sat.hl(i32, i32) +define i32 @A2_subh_l16_sat.hl(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.l16.sat.hl(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.l, r1.h):sat + +declare i32 @llvm.hexagon.A2.subh.h16.ll(i32, i32) +define i32 @A2_subh_h16_ll(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.h16.ll(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.l, r1.l):<<16 + +declare i32 @llvm.hexagon.A2.subh.h16.lh(i32, i32) +define i32 @A2_subh_h16_lh(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.h16.lh(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.l, r1.h):<<16 + +declare i32 @llvm.hexagon.A2.subh.h16.hl(i32, i32) +define i32 @A2_subh_h16_hl(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.h16.hl(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.h, r1.l):<<16 + +declare i32 @llvm.hexagon.A2.subh.h16.hh(i32, i32) +define i32 @A2_subh_h16_hh(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.h16.hh(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.h, r1.h):<<16 + +declare i32 @llvm.hexagon.A2.subh.h16.sat.ll(i32, i32) +define i32 @A2_subh_h16_sat_ll(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.h16.sat.ll(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.l, r1.l):sat:<<16 + +declare i32 @llvm.hexagon.A2.subh.h16.sat.lh(i32, i32) +define i32 @A2_subh_h16_sat_lh(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.h16.sat.lh(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.l, r1.h):sat:<<16 + +declare i32 @llvm.hexagon.A2.subh.h16.sat.hl(i32, i32) +define i32 @A2_subh_h16_sat_hl(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.h16.sat.hl(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.h, r1.l):sat:<<16 + +declare i32 @llvm.hexagon.A2.subh.h16.sat.hh(i32, i32) +define i32 @A2_subh_h16_sat_hh(i32 %a, i32 %b) { + %z = call i32 @llvm.hexagon.A2.subh.h16.sat.hh(i32 %a, i32 %b) + ret i32 %z +} +; CHECK: r0 = sub(r0.h, r1.h):sat:<<16 diff --git a/test/CodeGen/Hexagon/intrinsics/xtype_fp.ll b/test/CodeGen/Hexagon/intrinsics/xtype_fp.ll new file mode 100644 index 00000000000..f6d0025693b --- /dev/null +++ b/test/CodeGen/Hexagon/intrinsics/xtype_fp.ll @@ -0,0 +1,331 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv5 -O0 < %s | FileCheck %s +; Hexagon Programmer's Reference Manual 11.10.4 XTYPE/FP + +; Floating point addition +declare float @llvm.hexagon.F2.sfadd(float, float) +define float @F2_sfadd(float %a, float %b) { + %z = call float @llvm.hexagon.F2.sfadd(float %a, float %b) + ret float %z +} +; CHECK: r0 = sfadd(r0, r1) + +; Classify floating-point value +declare i32 @llvm.hexagon.F2.sfclass(float, i32) +define i32 @F2_sfclass(float %a) { + %z = call i32 @llvm.hexagon.F2.sfclass(float %a, i32 0) + ret i32 %z +} +; CHECK: p0 = sfclass(r0, #0) + +declare i32 @llvm.hexagon.F2.dfclass(double, i32) +define i32 @F2_dfclass(double %a) { + %z = call i32 @llvm.hexagon.F2.dfclass(double %a, i32 0) + ret i32 %z +} +; CHECK: p0 = dfclass(r1:0, #0) + +; Convert floating-point value to other format +declare double @llvm.hexagon.F2.conv.sf2df(float) +define double @F2_conv_sf2df(float %a) { + %z = call double @llvm.hexagon.F2.conv.sf2df(float %a) + ret double %z +} +; CHECK: = convert_sf2df(r0) + +declare float @llvm.hexagon.F2.conv.df2sf(double) +define float @F2_conv_df2sf(double %a) { + %z = call float @llvm.hexagon.F2.conv.df2sf(double %a) + ret float %z +} +; CHECK: r0 = convert_df2sf(r1:0) + +; Convert integer to floating-point value +declare double @llvm.hexagon.F2.conv.ud2df(i64) +define double @F2_conv_ud2df(i64 %a) { + %z = call double @llvm.hexagon.F2.conv.ud2df(i64 %a) + ret double %z +} +; CHECK: r1:0 = convert_ud2df(r1:0) + +declare double @llvm.hexagon.F2.conv.d2df(i64) +define double @F2_conv_d2df(i64 %a) { + %z = call double @llvm.hexagon.F2.conv.d2df(i64 %a) + ret double %z +} +; CHECK: r1:0 = convert_d2df(r1:0) + +declare double @llvm.hexagon.F2.conv.uw2df(i32) +define double @F2_conv_uw2df(i32 %a) { + %z = call double @llvm.hexagon.F2.conv.uw2df(i32 %a) + ret double %z +} +; CHECK: = convert_uw2df(r0) + +declare double @llvm.hexagon.F2.conv.w2df(i32) +define double @F2_conv_w2df(i32 %a) { + %z = call double @llvm.hexagon.F2.conv.w2df(i32 %a) + ret double %z +} +; CHECK: = convert_w2df(r0) + +declare float @llvm.hexagon.F2.conv.ud2sf(i64) +define float @F2_conv_ud2sf(i64 %a) { + %z = call float @llvm.hexagon.F2.conv.ud2sf(i64 %a) + ret float %z +} +; CHECK: r0 = convert_ud2sf(r1:0) + +declare float @llvm.hexagon.F2.conv.d2sf(i64) +define float @F2_conv_d2sf(i64 %a) { + %z = call float @llvm.hexagon.F2.conv.d2sf(i64 %a) + ret float %z +} +; CHECK: r0 = convert_d2sf(r1:0) + +declare float @llvm.hexagon.F2.conv.uw2sf(i32) +define float @F2_conv_uw2sf(i32 %a) { + %z = call float @llvm.hexagon.F2.conv.uw2sf(i32 %a) + ret float %z +} +; CHECK: r0 = convert_uw2sf(r0) + +declare float @llvm.hexagon.F2.conv.w2sf(i32) +define float @F2_conv_w2sf(i32 %a) { + %z = call float @llvm.hexagon.F2.conv.w2sf(i32 %a) + ret float %z +} +; CHECK: r0 = convert_w2sf(r0) + +; Convert floating-point value to integer +declare i64 @llvm.hexagon.F2.conv.df2d(double) +define i64 @F2_conv_df2d(double %a) { + %z = call i64 @llvm.hexagon.F2.conv.df2d(double %a) + ret i64 %z +} +; CHECK: r1:0 = convert_df2d(r1:0) + +declare i64 @llvm.hexagon.F2.conv.df2ud(double) +define i64 @F2_conv_df2ud(double %a) { + %z = call i64 @llvm.hexagon.F2.conv.df2ud(double %a) + ret i64 %z +} +; CHECK: r1:0 = convert_df2ud(r1:0) + +declare i64 @llvm.hexagon.F2.conv.df2d.chop(double) +define i64 @F2_conv_df2d_chop(double %a) { + %z = call i64 @llvm.hexagon.F2.conv.df2d.chop(double %a) + ret i64 %z +} +; CHECK: r1:0 = convert_df2d(r1:0):chop + +declare i64 @llvm.hexagon.F2.conv.df2ud.chop(double) +define i64 @F2_conv_df2ud_chop(double %a) { + %z = call i64 @llvm.hexagon.F2.conv.df2ud.chop(double %a) + ret i64 %z +} +; CHECK: r1:0 = convert_df2ud(r1:0):chop + +declare i64 @llvm.hexagon.F2.conv.sf2ud(float) +define i64 @F2_conv_sf2ud(float %a) { + %z = call i64 @llvm.hexagon.F2.conv.sf2ud(float %a) + ret i64 %z +} +; CHECK: = convert_sf2ud(r0) + +declare i64 @llvm.hexagon.F2.conv.sf2d(float) +define i64 @F2_conv_sf2d(float %a) { + %z = call i64 @llvm.hexagon.F2.conv.sf2d(float %a) + ret i64 %z +} +; CHECK: = convert_sf2d(r0) + +declare i64 @llvm.hexagon.F2.conv.sf2d.chop(float) +define i64 @F2_conv_sf2d_chop(float %a) { + %z = call i64 @llvm.hexagon.F2.conv.sf2d.chop(float %a) + ret i64 %z +} +; CHECK: = convert_sf2d(r0):chop + +declare i64 @llvm.hexagon.F2.conv.sf2ud.chop(float) +define i64 @F2_conv_sf2ud_chop(float %a) { + %z = call i64 @llvm.hexagon.F2.conv.sf2ud.chop(float %a) + ret i64 %z +} +; CHECK: = convert_sf2ud(r0):chop + +declare i32 @llvm.hexagon.F2.conv.df2uw(double) +define i32 @F2_conv_df2uw(double %a) { + %z = call i32 @llvm.hexagon.F2.conv.df2uw(double %a) + ret i32 %z +} +; CHECK: r0 = convert_df2uw(r1:0) + +declare i32 @llvm.hexagon.F2.conv.df2w(double) +define i32 @F2_conv_df2w(double %a) { + %z = call i32 @llvm.hexagon.F2.conv.df2w(double %a) + ret i32 %z +} +; CHECK: r0 = convert_df2w(r1:0) + +declare i32 @llvm.hexagon.F2.conv.df2w.chop(double) +define i32 @F2_conv_df2w_chop(double %a) { + %z = call i32 @llvm.hexagon.F2.conv.df2w.chop(double %a) + ret i32 %z +} +; CHECK: r0 = convert_df2w(r1:0):chop + +declare i32 @llvm.hexagon.F2.conv.df2uw.chop(double) +define i32 @F2_conv_df2uw_chop(double %a) { + %z = call i32 @llvm.hexagon.F2.conv.df2uw.chop(double %a) + ret i32 %z +} +; CHECK: r0 = convert_df2uw(r1:0):chop + +declare i32 @llvm.hexagon.F2.conv.sf2uw(float) +define i32 @F2_conv_sf2uw(float %a) { + %z = call i32 @llvm.hexagon.F2.conv.sf2uw(float %a) + ret i32 %z +} +; CHECK: r0 = convert_sf2uw(r0) + +declare i32 @llvm.hexagon.F2.conv.sf2uw.chop(float) +define i32 @F2_conv_sf2uw_chop(float %a) { + %z = call i32 @llvm.hexagon.F2.conv.sf2uw.chop(float %a) + ret i32 %z +} +; CHECK: r0 = convert_sf2uw(r0):chop + +declare i32 @llvm.hexagon.F2.conv.sf2w(float) +define i32 @F2_conv_sf2w(float %a) { + %z = call i32 @llvm.hexagon.F2.conv.sf2w(float %a) + ret i32 %z +} +; CHECK: r0 = convert_sf2w(r0) + +declare i32 @llvm.hexagon.F2.conv.sf2w.chop(float) +define i32 @F2_conv_sf2w_chop(float %a) { + %z = call i32 @llvm.hexagon.F2.conv.sf2w.chop(float %a) + ret i32 %z +} +; CHECK: r0 = convert_sf2w(r0):chop + +; Floating point extreme value assistance +declare float @llvm.hexagon.F2.sffixupr(float) +define float @F2_sffixupr(float %a) { + %z = call float @llvm.hexagon.F2.sffixupr(float %a) + ret float %z +} +; CHECK: r0 = sffixupr(r0) + +declare float @llvm.hexagon.F2.sffixupn(float, float) +define float @F2_sffixupn(float %a, float %b) { + %z = call float @llvm.hexagon.F2.sffixupn(float %a, float %b) + ret float %z +} +; CHECK: r0 = sffixupn(r0, r1) + +declare float @llvm.hexagon.F2.sffixupd(float, float) +define float @F2_sffixupd(float %a, float %b) { + %z = call float @llvm.hexagon.F2.sffixupd(float %a, float %b) + ret float %z +} +; CHECK: r0 = sffixupd(r0, r1) + +; Floating point fused multiply-add +declare float @llvm.hexagon.F2.sffma(float, float, float) +define float @F2_sffma(float %a, float %b, float %c) { + %z = call float @llvm.hexagon.F2.sffma(float %a, float %b, float %c) + ret float %z +} +; CHECK: r0 += sfmpy(r1, r2) + +declare float @llvm.hexagon.F2.sffms(float, float, float) +define float @F2_sffms(float %a, float %b, float %c) { + %z = call float @llvm.hexagon.F2.sffms(float %a, float %b, float %c) + ret float %z +} +; CHECK: r0 -= sfmpy(r1, r2) + +; Floating point fused multiply-add with scaling +declare float @llvm.hexagon.F2.sffma.sc(float, float, float, i32) +define float @F2_sffma_sc(float %a, float %b, float %c, i32 %d) { + %z = call float @llvm.hexagon.F2.sffma.sc(float %a, float %b, float %c, i32 %d) + ret float %z +} +; CHECK: r0 += sfmpy(r1, r2, p0):scale + +; Floating point fused multiply-add for library routines +declare float @llvm.hexagon.F2.sffma.lib(float, float, float) +define float @F2_sffma_lib(float %a, float %b, float %c) { + %z = call float @llvm.hexagon.F2.sffma.lib(float %a, float %b, float %c) + ret float %z +} +; CHECK: r0 += sfmpy(r1, r2):lib + +declare float @llvm.hexagon.F2.sffms.lib(float, float, float) +define float @F2_sffms_lib(float %a, float %b, float %c) { + %z = call float @llvm.hexagon.F2.sffms.lib(float %a, float %b, float %c) + ret float %z +} +; CHECK: r0 -= sfmpy(r1, r2):lib + +; Create floating-point constant +declare float @llvm.hexagon.F2.sfimm.p(i32) +define float @F2_sfimm_p() { + %z = call float @llvm.hexagon.F2.sfimm.p(i32 0) + ret float %z +} +; CHECK: r0 = sfmake(#0):pos + +declare float @llvm.hexagon.F2.sfimm.n(i32) +define float @F2_sfimm_n() { + %z = call float @llvm.hexagon.F2.sfimm.n(i32 0) + ret float %z +} +; CHECK: r0 = sfmake(#0):neg + +declare double @llvm.hexagon.F2.dfimm.p(i32) +define double @F2_dfimm_p() { + %z = call double @llvm.hexagon.F2.dfimm.p(i32 0) + ret double %z +} +; CHECK: r1:0 = dfmake(#0):pos + +declare double @llvm.hexagon.F2.dfimm.n(i32) +define double @F2_dfimm_n() { + %z = call double @llvm.hexagon.F2.dfimm.n(i32 0) + ret double %z +} +; CHECK: r1:0 = dfmake(#0):neg + +; Floating point maximum +declare float @llvm.hexagon.F2.sfmax(float, float) +define float @F2_sfmax(float %a, float %b) { + %z = call float @llvm.hexagon.F2.sfmax(float %a, float %b) + ret float %z +} +; CHECK: r0 = sfmax(r0, r1) + +; Floating point minimum +declare float @llvm.hexagon.F2.sfmin(float, float) +define float @F2_sfmin(float %a, float %b) { + %z = call float @llvm.hexagon.F2.sfmin(float %a, float %b) + ret float %z +} +; CHECK: r0 = sfmin(r0, r1) + +; Floating point multiply +declare float @llvm.hexagon.F2.sfmpy(float, float) +define float @F2_sfmpy(float %a, float %b) { + %z = call float @llvm.hexagon.F2.sfmpy(float %a, float %b) + ret float %z +} +; CHECK: r0 = sfmpy(r0, r1) + +; Floating point subtraction +declare float @llvm.hexagon.F2.sfsub(float, float) +define float @F2_sfsub(float %a, float %b) { + %z = call float @llvm.hexagon.F2.sfsub(float %a, float %b) + ret float %z +} +; CHECK: r0 = sfsub(r0, r1)