• LLVM学习笔记(62)


    4.4.3.3.2. 指令处理的设置

    4.4.3.3.2.1. 目标机器相关设置

    除了基类以外,X86TargetLowering构造函数本身也是一个庞然大物,我们必须要分段来看。V7.0做了不小的改动,改进了代码的结构,修改了一些指令的设置。

    100     X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,

    101                                          const X86Subtarget &STI)

    102         : TargetLowering(TM), Subtarget(&STI) {

    103       bool UseX87 = !Subtarget.useSoftFloat() && Subtarget.hasX87();

    104       X86ScalarSSEf64 = Subtarget->hasSSE2();

    105       X86ScalarSSEf32 = Subtarget->hasSSE1();

    106       MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));

    107    

    108       // Set up the TargetLowering object.

    109    

    110       // X86 is weird. It always uses i8 for shift amounts and setcc results.

    111       setBooleanContents(ZeroOrOneBooleanContent);

    112       // X86-SSE is even stranger. It uses -1 or 0 for vector masks.

    113       setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);

    114    

    115       // For 64-bit, since we have so many registers, use the ILP scheduler.

    116       // For 32-bit, use the register pressure specific scheduling.

    117       // For Atom, always use ILP scheduling.

    118       if (Subtarget->isAtom())

    119         setSchedulingPreference(Sched::ILP);

    120       else if (Subtarget->is64Bit())

    121         setSchedulingPreference(Sched::ILP);

    122       else

    123         setSchedulingPreference(Sched::RegPressure);

    124       const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();

    125      setStackPointerRegisterToSaveRestore(RegInfo->getStackRegister());

    126    

    127       // Bypass expensive divides on Atom when compiling with O2.

    128       if (TM.getOptLevel() >= CodeGenOpt::Default) {

    129         if (Subtarget->hasSlowDivide32())

    130           addBypassSlowDiv(32, 8);

    131         if (Subtarget->hasSlowDivide64() && Subtarget->is64Bit())

    132           addBypassSlowDiv(64, 32);

    133       }

    134    

    135       if (Subtarget->isTargetKnownWindowsMSVC() ||

    136           Subtarget.isTargetWindowsItanium()) {

    137         // Setup Windows compiler runtime calls.

    138         setLibcallName(RTLIB::SDIV_I64, "_alldiv");

    139         setLibcallName(RTLIB::UDIV_I64, "_aulldiv");

    140         setLibcallName(RTLIB::SREM_I64, "_allrem");

    141         setLibcallName(RTLIB::UREM_I64, "_aullrem");

    142         setLibcallName(RTLIB::MUL_I64, "_allmul");

    143         setLibcallCallingConv(RTLIB::SDIV_I64, CallingConv::X86_StdCall);

    144         setLibcallCallingConv(RTLIB::UDIV_I64, CallingConv::X86_StdCall);

    145         setLibcallCallingConv(RTLIB::SREM_I64, CallingConv::X86_StdCall);

    146         setLibcallCallingConv(RTLIB::UREM_I64, CallingConv::X86_StdCall);

    147         setLibcallCallingConv(RTLIB::MUL_I64, CallingConv::X86_StdCall);

    148       }

    149    

    150       if (Subtarget->isTargetDarwin()) {

    151         // Darwin should use _setjmp/_longjmp instead of setjmp/longjmp.

    152         setUseUnderscoreSetJmp(false);

    153         setUseUnderscoreLongJmp(false);

    154       } else if (Subtarget->isTargetWindowsGNU()) {

    155         // MS runtime is weird: it exports _setjmp, but longjmp!

    156         setUseUnderscoreSetJmp(true);

    157         setUseUnderscoreLongJmp(false);

    158       } else {

    159         setUseUnderscoreSetJmp(true);

    160         setUseUnderscoreLongJmp(true);

    161       }

    162    

    163       // Set up the register classes.

    164       addRegisterClass(MVT::i8, &X86::GR8RegClass);

    165       addRegisterClass(MVT::i16, &X86::GR16RegClass);

    166       addRegisterClass(MVT::i32, &X86::GR32RegClass);

    167       if (Subtarget->is64Bit())

    168         addRegisterClass(MVT::i64, &X86::GR64RegClass);

    111行将布尔值的表示方式更改为ZeroOrOneBooleanContent(原是UndefinedBooleanContent)。118~123行根据CPU类型更改调度模式。125行的getStackRegister()返回X86RegisterInfo的StackPtr成员(它在X86RegisterInfo构造函数里根据目标机器设置)。

    基类TargetLoweringBase类型为DenseMap的BypassSlowDivWidths的容器用于通知代码生成器绕过慢的除法或取余指令。例如,BypassSlowDivWidths[32,8]格式代码生成器在操作数为小于256的正整数时,使用8位div/rem指令绕过32位div/rem指令。上面130行为类似Atom的处理器设置这个容器项。

    164行以下的GRXRegClass都是由TableGen根据.td文件描述生成在X86GenRegisterInfo.inc文件里的对象定义。为了关联这些对象与它们的类型,定义了容器AvailableRegClasses(类型std::vector< std::pair>)与容器const TargetRegisterClass *RegClassForVT[MVT:: LAST_VALUETYPE],并通过addRegisterClass()实现关联。

    4.4.3.3.2.2. 标量操作数类型的处理设置

    下面根据目标X86芯片支持的指令集为各种操作设置处理活动。这是一些比较繁琐的工作。要针对每种IR操作与每种操作数类型来设置。下面Expand的含义是建议将操作数分为较小的两部分。

    X86TargetLowering::X86TargetLowering(续)

    170       for (MVT VT : MVT::integer_valuetypes())

    171         setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);

    172    

    173       // We don't accept any truncstore of integer registers.

    174       setTruncStoreAction(MVT::i64, MVT::i32, Expand);

    175       setTruncStoreAction(MVT::i64, MVT::i16, Expand);

    176       setTruncStoreAction(MVT::i64, MVT::i8 , Expand);

    177       setTruncStoreAction(MVT::i32, MVT::i16, Expand);

    178       setTruncStoreAction(MVT::i32, MVT::i8 , Expand);

    179       setTruncStoreAction(MVT::i16, MVT::i8,  Expand);

    180    

    181       setTruncStoreAction(MVT::f64, MVT::f32, Expand);

    182    

    183       // SETOEQ and SETUNE require checking two conditions.

    184       setCondCodeAction(ISD::SETOEQ, MVT::f32, Expand);

    185       setCondCodeAction(ISD::SETOEQ, MVT::f64, Expand);

    186       setCondCodeAction(ISD::SETOEQ, MVT::f80, Expand);

    187       setCondCodeAction(ISD::SETUNE, MVT::f32, Expand);

    188       setCondCodeAction(ISD::SETUNE, MVT::f64, Expand);

    189       setCondCodeAction(ISD::SETUNE, MVT::f80, Expand);

    190    

    191       // Integer absolute.

    192       if (Subtarget.hasCMov()) {

    193         setOperationAction(ISD::ABS , MVT::i16  , Custom);

    194         setOperationAction(ISD::ABS, MVT::i32  , Custom);

    195         if (Subtarget.is64Bit())

    196           setOperationAction(ISD::ABS, MVT::i64  , Custom);

    197       }

    198    

    199       // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this

    200       // operation.

    201       setOperationAction(ISD::UINT_TO_FP       , MVT::i1   , Promote);

    202       setOperationAction(ISD::UINT_TO_FP       , MVT::i8   , Promote);

    203       setOperationAction(ISD::UINT_TO_FP       , MVT::i16  , Promote);

    204    

    205       if (Subtarget.is64Bit()) {

    206         if (!Subtarget.useSoftFloat() && Subtarget.hasAVX512())

    207           // f32/f64 are legal, f80 is custom.

    208           setOperationAction(ISD::UINT_TO_FP   , MVT::i32  , Custom);

    209         else

    210           setOperationAction(ISD::UINT_TO_FP   , MVT::i32  , Promote);

    211           setOperationAction(ISD::UINT_TO_FP     , MVT::i64  , Custom);

    212       } else if (!Subtarget.useSoftFloat()) {

    213         // We have an algorithm for SSE2->double, and we turn this into a

    214         // 64-bit FILD followed by conditional FADD for other targets.

    215         setOperationAction(ISD::UINT_TO_FP     , MVT::i64  , Custom);

    216         // We have an algorithm for SSE2, and we turn this into a 64-bit

    217         // FILD or VCVTUSI2SS/SD for other targets.

    218         setOperationAction(ISD::UINT_TO_FP     , MVT::i32  , Custom);

    219       } else {

    220         setOperationAction(ISD::UINT_TO_FP     , MVT::i32  , Expand);

    221       }

    222    

    223       // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have

    224       // this operation.

    225       setOperationAction(ISD::SINT_TO_FP       , MVT::i1   , Promote);

    226       setOperationAction(ISD::SINT_TO_FP       , MVT::i8   , Promote);

    227    

    228       if (!Subtarget->useSoftFloat()) {

    229         // SSE has no i16 to fp conversion, only i32

    230         if (X86ScalarSSEf32) {

    231           setOperationAction(ISD::SINT_TO_FP     , MVT::i16  , Promote);

    232           // f32 and f64 cases are Legal, f80 case is not

    233           setOperationAction(ISD::SINT_TO_FP     , MVT::i32  , Custom);

    234         } else {

    235           setOperationAction(ISD::SINT_TO_FP     , MVT::i16  , Custom);

    236           setOperationAction(ISD::SINT_TO_FP     , MVT::i32  , Custom);

    237         }

    238       } else {

    239         setOperationAction(ISD::SINT_TO_FP     , MVT::i16  , Promote);

    240         setOperationAction(ISD::SINT_TO_FP     , MVT::i32  , Promote Expand);

    241       }

    242    

    243       // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have

    244       // this operation.

    245       setOperationAction(ISD::FP_TO_SINT       , MVT::i1   , Promote);

    246       setOperationAction(ISD::FP_TO_SINT       , MVT::i8   , Promote);

    247    

    248       if (!Subtarget.useSoftFloat()) {

    249         // In 32-bit mode these are custom lowered.  In 64-bit mode F32 and F64

    250         // are Legal, f80 is custom lowered.

    251         setOperationAction(ISD::FP_TO_SINT     , MVT::i64  , Custom);

    252         setOperationAction(ISD::SINT_TO_FP     , MVT::i64  , Custom);

    253    

    254         if (X86ScalarSSEf32) {

    255           setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Promote);

    256           // f32 and f64 cases are Legal, f80 case is not

    257           setOperationAction(ISD::FP_TO_SINT     , MVT::i32  , Custom);

    258         } else {

    259           setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Custom);

    260           setOperationAction(ISD::FP_TO_SINT     , MVT::i32  , Custom);

    261         }

    262       } else {

    263         setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Promote);

    264         setOperationAction(ISD::FP_TO_SINT     , MVT::i32  , Expand);

    265         setOperationAction(ISD::FP_TO_SINT     , MVT::i64  , Expand);

    266       }

    267    

    268       // Handle FP_TO_UINT by promoting the destination to a larger signed

    269       // conversion.

    270       setOperationAction(ISD::FP_TO_UINT       , MVT::i1   , Promote);

    271       setOperationAction(ISD::FP_TO_UINT       , MVT::i8   , Promote);

    272       setOperationAction(ISD::FP_TO_UINT       , MVT::i16  , Promote);

    273    

    274       if (Subtarget.is64Bit()) {

    275         if (!Subtarget.useSoftFloat() && Subtarget.hasAVX512()) {

    276           // FP_TO_UINT-i32/i64 is legal for f32/f64, but custom for f80.

    277           setOperationAction(ISD::FP_TO_UINT   , MVT::i32  , Custom);

    278           setOperationAction(ISD::FP_TO_UINT   , MVT::i64  , Custom);

    279         } else {

    280           setOperationAction(ISD::FP_TO_UINT   , MVT::i32  , Promote);

    281           setOperationAction(ISD::FP_TO_UINT   , MVT::i64  , Expand);

    282         }

    283       } else if (!Subtarget.useSoftFloat()) {

    284         // Since AVX is a superset of SSE3, only check for SSE here.

    285         if (Subtarget.hasSSE1() && !Subtarget.hasSSE3())

    286           // Expand FP_TO_UINT into a select.

    287           // FIXME: We would like to use a Custom expander here eventually to do

    288           // the optimal thing for SSE vs. the default expansion in the legalizer.

    289           setOperationAction(ISD::FP_TO_UINT   , MVT::i32  , Expand);

    290         else

    291           // With AVX512 we can use vcvts[ds]2usi for f32/f64->i32, f80 is custom.

    292           // With SSE3 we can use fisttpll to convert to a signed i64; without

    293           // SSE, we're stuck with a fistpll.

    294           setOperationAction(ISD::FP_TO_UINT   , MVT::i32  , Custom);

    295    

    296         setOperationAction(ISD::FP_TO_UINT     , MVT::i64  , Custom);

    297       }

    298    

    299       // TODO: when we have SSE, these could be more efficient, by using movd/movq.

    300       if (!X86ScalarSSEf64) {

    301         setOperationAction(ISD::BITCAST        , MVT::f32  , Expand);

    302         setOperationAction(ISD::BITCAST        , MVT::i32  , Expand);

    303         if (Subtarget->is64Bit()) {

    304           setOperationAction(ISD::BITCAST      , MVT::f64  , Expand);

    305           // Without SSE, i64->f64 goes through memory.

    306           setOperationAction(ISD::BITCAST      , MVT::i64  , Expand);

    307         }

    308       } else if (!Subtarget.is64Bit())

    309         setOperationAction(ISD::BITCAST      , MVT::i64  , Custom);

    310    

    311       // Scalar integer divide and remainder are lowered to use operations that

    312       // produce two results, to match the available instructions. This exposes

    313       // the two-result form to trivial CSE, which is able to combine x/y and x%y

    314       // into a single instruction.

    315       //

    316       // Scalar integer multiply-high is also lowered to use two-result

    317       // operations, to match the available instructions. However, plain multiply

    318       // (low) operations are left as Legal, as there are single-result

    319       // instructions for this in x86. Using the two-result multiply instructions

    320       // when both high and low results are needed must be arranged by dagcombine.

    321       for (auto VT : { MVT::i8, MVT::i16, MVT::i32, MVT::i64 }) {

    322         setOperationAction(ISD::MULHS, VT, Expand);

    323         setOperationAction(ISD::MULHU, VT, Expand);

    324         setOperationAction(ISD::SDIV, VT, Expand);

    325         setOperationAction(ISD::UDIV, VT, Expand);

    326         setOperationAction(ISD::SREM, VT, Expand);

    327         setOperationAction(ISD::UREM, VT, Expand);

    328       }

    329    

    330       setOperationAction(ISD::BR_JT            , MVT::Other, Expand);

    331       setOperationAction(ISD::BRCOND           , MVT::Other, Custom);

    332       for (auto VT : { MVT::f32, MVT::f64, MVT::f80, MVT::f128,

    333                        MVT::i8,  MVT::i16, MVT::i32, MVT::i64 }) {

    334         setOperationAction(ISD::BR_CC,     VT, Expand);

    335         setOperationAction(ISD::SELECT_CC, VT, Expand);

    336       }

    337       if (Subtarget->is64Bit())

    338         setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Legal);

    339       setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Legal);

    340       setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8   , Legal);

    341       setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);

    342       setOperationAction(ISD::FP_ROUND_INREG   , MVT::f32  , Expand);

    343    

    344       setOperationAction(ISD::FREM             , MVT::f32  , Expand);

    345       setOperationAction(ISD::FREM             , MVT::f64  , Expand);

    346       setOperationAction(ISD::FREM             , MVT::f80  , Expand);

    347       setOperationAction(ISD::FLT_ROUNDS_      , MVT::i32  , Custom);

    348    

    349       // Promote the i8 variants and force them on up to i32 which has a shorter

    350      // encoding.

    351       setOperationPromotedToType(ISD::CTTZ           , MVT::i8   , MVT::i32);

    352       setOperationPromotedToType(ISD::CTTZ_ZERO_UNDEF, MVT::i8   , MVT::i32);

    353       if (Subtarget->hasBMI()) {

    354         setOperationAction(ISD::CTTZ           , MVT::i16  , Custom);

    355         setOperationAction(ISD::CTTZ           , MVT::i32  , Custom);

    356         setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i16  , Legal);

    357         setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32  , Legal);

    358         if (Subtarget->is64Bit()) {

    359           setOperationAction(ISD::CTTZ         , MVT::i64  , Custom);

    360           setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Expand);

    361        }

    362      }

    363    

    364       if (Subtarget->hasLZCNT()) {

    365         // When promoting the i8 variants, force them to i32 for a shorter

    366         // encoding.

    367         setOperationPromotedToType(ISD::CTLZ           , MVT::i8   , MVT::i32);

    368         setOperationPromotedToType(ISD::CTLZ_ZERO_UNDEF, MVT::i8   , MVT::i32);

    369       } else {

    370         setOperationAction(ISD::CTLZ           , MVT::i8   , Custom);

    371         setOperationAction(ISD::CTLZ           , MVT::i16  , Custom);

    372         setOperationAction(ISD::CTLZ           , MVT::i32  , Custom);

    373         setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i8   , Custom);

    374         setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i16  , Custom);

    375         setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32  , Custom);

    376         if (Subtarget->is64Bit()) {

    377           setOperationAction(ISD::CTLZ         , MVT::i64  , Custom);

    378           setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Custom);

    379         }

    380       }

    381    

    382       // Special handling for half-precision floating point conversions.

    383       // If we don't have F16C support, then lower half float conversions

    384       // into library calls.

    385       if (Subtarget->useSoftFloat() || !Subtarget->hasF16C()) {

    386         setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);

    387         setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);

    388       }

    389    

    390       // There's never any support for operations beyond MVT::f32.

    391       setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);

    392       setOperationAction(ISD::FP16_TO_FP, MVT::f80, Expand);

    393       setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand);

    394       setOperationAction(ISD::FP_TO_FP16, MVT::f80, Expand);

    395    

    396       setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);

    397       setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);

    398       setLoadExtAction(ISD::EXTLOAD, MVT::f80, MVT::f16, Expand);

    399       setTruncStoreAction(MVT::f32, MVT::f16, Expand);

    400       setTruncStoreAction(MVT::f64, MVT::f16, Expand);

    401       setTruncStoreAction(MVT::f80, MVT::f16, Expand);

    402    

    403       if (Subtarget->hasPOPCNT()) {

    404         setOperationPromotedToType(ISD::CTPOP, MVT::i8, MVT::i32);

    405       } else {

    406         setOperationAction(ISD::CTPOP          , MVT::i8   , Expand);

    407         setOperationAction(ISD::CTPOP          , MVT::i16  , Expand);

    408         setOperationAction(ISD::CTPOP          , MVT::i32  , Expand);

    409         if (Subtarget->is64Bit())

    410           setOperationAction(ISD::CTPOP        , MVT::i64  , Expand);

    411       }

    412    

    413       setOperationAction(ISD::READCYCLECOUNTER , MVT::i64  , Custom);

    414    

    415       if (!Subtarget->hasMOVBE())

    416         setOperationAction(ISD::BSWAP          , MVT::i16  , Expand);

    417    

    418       // These should be promoted to a larger select which is supported.

    419       setOperationAction(ISD::SELECT          , MVT::i1   , Promote);

    420       // X86 wants to expand cmov itself.

    421       for (auto VT : { MVT::f32, MVT::f64, MVT::f80, MVT::f128 }) {

    422         setOperationAction(ISD::SELECT, VT, Custom);

    423         setOperationAction(ISD::SETCC, VT, Custom);

    424       }

    425       for (auto VT : { MVT::i8, MVT::i16, MVT::i32, MVT::i64 }) {

    426         if (VT == MVT::i64 && !Subtarget.is64Bit())

    427           continue;

    428         setOperationAction(ISD::SELECT, VT, Custom);

    429         setOperationAction(ISD::SETCC,  VT, Custom);

    430       }

    431    

    432      // Custom action for SELECT MMX and expand action for SELECT_CC MMX

    433       setOperationAction(ISD::SELECT, MVT::x86mmx, Custom);

    434       setOperationAction(ISD::SELECT_CC, MVT::x86mmx, Expand);

    435    

    436       setOperationAction(ISD::EH_RETURN       , MVT::Other, Custom);

    437       // NOTE: EH_SJLJ_SETJMP/_LONGJMP are not recommended, since

    438       // LLVM/Clang supports zero-cost DWARF and SEH exception handling.

    439       setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);

    440       setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);

    441       setOperationAction(ISD::EH_SJLJ_SETUP_DISPATCH, MVT::Other, Custom);

    442       if (TM.Options.ExceptionModel == ExceptionHandling::SjLj)

    443         setLibcallName(RTLIB::UNWIND_RESUME, "_Unwind_SjLj_Resume");

    444    

    445       // Darwin ABI issue.

    446       for (auto VT : { MVT::i32, MVT::i64 }) {

    447         if (VT == MVT::i64 && !Subtarget.is64Bit())

    448           continue;

    449         setOperationAction(ISD::ConstantPool    , VT, Custom);

    450         setOperationAction(ISD::JumpTable       , VT, Custom);

    451         setOperationAction(ISD::GlobalAddress   , VT, Custom);

    452         setOperationAction(ISD::GlobalTLSAddress, VT, Custom);

    453         setOperationAction(ISD::ExternalSymbol  , VT, Custom);

    454         setOperationAction(ISD::BlockAddress    , VT, Custom);

    455       }

    456    

    457       // 64-bit shl, sar, srl (iff 32-bit x86)

    458       for (auto VT : { MVT::i32, MVT::i64 }) {

    459         if (VT == MVT::i64 && !Subtarget.is64Bit())

    460           continue;

    461         setOperationAction(ISD::SHL_PARTS, VT, Custom);

    462         setOperationAction(ISD::SRA_PARTS, VT, Custom);

    463         setOperationAction(ISD::SRL_PARTS, VT, Custom);

    464       }

    465    

    466       if (Subtarget.hasSSEPrefetch() || Subtarget.has3DNow())

    467         setOperationAction(ISD::PREFETCH      , MVT::Other, Legal);

    468    

    469       setOperationAction(ISD::ATOMIC_FENCE  , MVT::Other, Custom);

    470    

    471       // Expand certain atomics

    472       for (auto VT : { MVT::i8, MVT::i16, MVT::i32, MVT::i64 }) {

    473        setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, VT, Custom);

    474         setOperationAction(ISD::ATOMIC_LOAD_SUB, VT, Custom);

    475         setOperationAction(ISD::ATOMIC_LOAD_ADD, VT, Custom);

    476         setOperationAction(ISD::ATOMIC_LOAD_OR, VT, Custom);

    477         setOperationAction(ISD::ATOMIC_LOAD_XOR, VT, Custom);

    478         setOperationAction(ISD::ATOMIC_LOAD_AND, VT, Custom);

    479         setOperationAction(ISD::ATOMIC_STORE, VT, Custom);

    480       }

    481    

    482       if (Subtarget->hasCmpxchg16b()) {

    483         setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, MVT::i128, Custom);

    484       }

    485    

    486       // FIXME - use subtarget debug flags

    487       if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetELF() &&

    488           !Subtarget->isTargetCygMing() && !Subtarget->isTargetWin64() &&

    489           TM.Options.ExceptionModel != ExceptionHandling::SjLj) {

    490         setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);

    491       }

    492    

    493       setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom);

    494       setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i64, Custom);

    495    

    496       setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom);

    497       setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom);

    498    

    499       setOperationAction(ISD::TRAP, MVT::Other, Legal);

    500       setOperationAction(ISD::DEBUGTRAP, MVT::Other, Legal);

    501    

    502       // VASTART needs to be custom lowered to use the VarArgsFrameIndex

    503       setOperationAction(ISD::VASTART           , MVT::Other, Custom);

    504       setOperationAction(ISD::VAEND             , MVT::Other, Expand);

    505       bool Is64Bit = Subtarget.is64Bit();

    506       setOperationAction(ISD::VAARG,  MVT::Other, Is64Bit ? Custom : Expand);

    507       setOperationAction(ISD::VACOPY, MVT::Other, Is64Bit ? Custom : Expand);

    508    

    509       setOperationAction(ISD::STACKSAVE,          MVT::Other, Expand);

    510       setOperationAction(ISD::STACKRESTORE,       MVT::Other, Expand);

    511    

    512       setOperationAction(ISD::DYNAMIC_STACKALLOC, getPointerTy(*TD) PtrVT, Custom);

    513    

    514       // GC_TRANSITION_START and GC_TRANSITION_END need custom lowering.

    515       setOperationAction(ISD::GC_TRANSITION_START, MVT::Other, Custom);

    516       setOperationAction(ISD::GC_TRANSITION_END, MVT::Other, Custom);

    X86TargetLowering构造函数非常冗长,但不算太复杂。上面所调用的AddPromotedToType()是将指定的操作,指定的操作数类型,与提升类型关联。维持这个关联关系的容器是PromoteToType(类型std::map, MVT::SimpleValueType>,其中std::pair记录操作与操作数原始类型)。

    V7.0进行了一些代码结构上的改良,例如将setOperationAction()AddPromotedToType()组合为setOperationPromotedToType(),并修改了一些指令与指定类型操作数的处理。

    518行的useSoftFloat()如果返回true,表示目标机器使用软件方法实现浮点操作。不过X86处理器族都使用硬件实现浮点操作。那么下面开始处理浮点操作。

    X86TargetLowering::X86TargetLowering(续)

    518       if (!Subtarget->useSoftFloat() && X86ScalarSSEf64) {

    519         // f32 and f64 use SSE.

    520         // Set up the FP register classes.

    521         addRegisterClass(MVT::f32, Subtarget.hasAVX512() ? &X86::FR32XRegClass

    522                                                          : &X86::FR32RegClass);

    523         addRegisterClass(MVT::f64, Subtarget.hasAVX512() ? &X86::FR64XRegClass

    524                                                          : &X86::FR64RegClass);

    525    

    526         for (auto VT : { MVT::f32, MVT::f64 }) {

    527           // Use ANDPD to simulate FABS.

    528           setOperationAction(ISD::FABS, VT, Custom);

    529    

    530           // Use XORP to simulate FNEG.

    531           setOperationAction(ISD::FNEG, VT, Custom);

    532    

    533           // Use ANDPD and ORPD to simulate FCOPYSIGN.

    534           setOperationAction(ISD::FCOPYSIGN, VT, Custom);

    535    

    536           // We don't support sin/cos/fmod

    537           setOperationAction(ISD::FSIN   , VT, Expand);

    538           setOperationAction(ISD::FCOS   , VT, Expand);

    539           setOperationAction(ISD::FSINCOS, VT, Expand);

    540         }

    541    

    542         // Lower this to MOVMSK plus an AND.

    543         setOperationAction(ISD::FGETSIGN, MVT::i64, Custom);

    544         setOperationAction(ISD::FGETSIGN, MVT::i32, Custom);

    545    

    546         // Expand FP immediates into loads from the stack, except for the special

    547         // cases we handle.

    548         addLegalFPImmediate(APFloat(+0.0)); // xorpd

    549         addLegalFPImmediate(APFloat(+0.0f)); // xorps

    550       } else if (UseX87 && X86ScalarSSEf32) {

    551         // Use SSE for f32, x87 for f64.

    552         // Set up the FP register classes.

    553         addRegisterClass(MVT::f32, &X86::FR32RegClass);

    554         addRegisterClass(MVT::f64, &X86::RFP64RegClass);

    555    

    556         // Use ANDPS to simulate FABS.

    557         setOperationAction(ISD::FABS , MVT::f32, Custom);

    558    

    559         // Use XORP to simulate FNEG.

    560         setOperationAction(ISD::FNEG , MVT::f32, Custom);

    561    

    562         setOperationAction(ISD::UNDEF,     MVT::f64, Expand);

    563    

    564         // Use ANDPS and ORPS to simulate FCOPYSIGN.

    565         setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);

    566         setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);

    567    

    568         // We don't support sin/cos/fmod

    569         setOperationAction(ISD::FSIN   , MVT::f32, Expand);

    570         setOperationAction(ISD::FCOS   , MVT::f32, Expand);

    571         setOperationAction(ISD::FSINCOS, MVT::f32, Expand);

    572    

    573         // Special cases we handle for FP constants.

    574         addLegalFPImmediate(APFloat(+0.0f)); // xorps

    575         addLegalFPImmediate(APFloat(+0.0)); // FLD0

    576         addLegalFPImmediate(APFloat(+1.0)); // FLD1

    577         addLegalFPImmediate(APFloat(-0.0)); // FLD0/FCHS

    578         addLegalFPImmediate(APFloat(-1.0)); // FLD1/FCHS

    579    

    580         // Always expand sin/cos functions even though x87 has an instruction.

    581         setOperationAction(ISD::FSIN   , MVT::f64, Expand);

    582         setOperationAction(ISD::FCOS   , MVT::f64, Expand);

    583         setOperationAction(ISD::FSINCOS, MVT::f64, Expand);

    584       } else if (UseX87) {

    585         // f32 and f64 in x87.

    586         // Set up the FP register classes.

    587         addRegisterClass(MVT::f64, &X86::RFP64RegClass);

    588         addRegisterClass(MVT::f32, &X86::RFP32RegClass);

    589    

    590         for (auto VT : { MVT::f32, MVT::f64 }) {

    591           setOperationAction(ISD::UNDEF,     VT, Expand);

    592           setOperationAction(ISD::FCOPYSIGN, VT, Expand);

    593    

    594           // Always expand sin/cos functions even though x87 has an instruction.

    595           setOperationAction(ISD::FSIN   , VT, Expand);

    596           setOperationAction(ISD::FCOS   , VT, Expand);

    597           setOperationAction(ISD::FSINCOS, VT, Expand);

    598        }

    599         addLegalFPImmediate(APFloat(+0.0)); // FLD0

    600         addLegalFPImmediate(APFloat(+1.0)); // FLD1

    601         addLegalFPImmediate(APFloat(-0.0)); // FLD0/FCHS

    602         addLegalFPImmediate(APFloat(-1.0)); // FLD1/FCHS

    603         addLegalFPImmediate(APFloat(+0.0f)); // FLD0

    604         addLegalFPImmediate(APFloat(+1.0f)); // FLD1

    605         addLegalFPImmediate(APFloat(-0.0f)); // FLD0/FCHS

    606         addLegalFPImmediate(APFloat(-1.0f)); // FLD1/FCHS

    607       }

    608    

    609       // We don't support FMA.

    610       setOperationAction(ISD::FMA, MVT::f64, Expand);

    611       setOperationAction(ISD::FMA, MVT::f32, Expand);

    612    

    613       // Long double always uses X87.

    614       if (UseX87) {

    615         if (Subtarget.is64Bit() && Subtarget.hasMMX()) {

    616           addRegisterClass(MVT::f128, &X86::VR128RegClass);

    617           ValueTypeActions.setTypeAction(MVT::f128, TypeSoftenFloat);

    618           setOperationAction(ISD::FABS , MVT::f128, Custom);

    619           setOperationAction(ISD::FNEG , MVT::f128, Custom);

    620           setOperationAction(ISD::FCOPYSIGN, MVT::f128, Custom);

    621         }

    622    

    623         addRegisterClass(MVT::f80, &X86::RFP80RegClass);

    624         setOperationAction(ISD::UNDEF,     MVT::f80, Expand);

    625         setOperationAction(ISD::FCOPYSIGN, MVT::f80, Expand);

    626         {

    627           APFloat TmpFlt = APFloat::getZero(APFloat::x87DoubleExtended);

    628           addLegalFPImmediate(TmpFlt);  // FLD0

    629           TmpFlt.changeSign();

    630           addLegalFPImmediate(TmpFlt);  // FLD0/FCHS

    631    

    632           bool ignored;

    633           APFloat TmpFlt2(+1.0);

    634           TmpFlt2.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven,

    635                           &ignored);

    636           addLegalFPImmediate(TmpFlt2);  // FLD1

    637           TmpFlt2.changeSign();

    638           addLegalFPImmediate(TmpFlt2);  // FLD1/FCHS

    639         }

    640    

    641         // Always expand sin/cos functions even though x87 has an instruction.

    642         setOperationAction(ISD::FSIN   , MVT::f80, Expand);

    643         setOperationAction(ISD::FCOS   , MVT::f80, Expand);

    644         setOperationAction(ISD::FSINCOS, MVT::f80, Expand);

    645    

    646         setOperationAction(ISD::FFLOOR, MVT::f80, Expand);

    647         setOperationAction(ISD::FCEIL,  MVT::f80, Expand);

    648         setOperationAction(ISD::FTRUNC, MVT::f80, Expand);

    649         setOperationAction(ISD::FRINT,  MVT::f80, Expand);

    650         setOperationAction(ISD::FNEARBYINT, MVT::f80, Expand);

    651         setOperationAction(ISD::FMA, MVT::f80, Expand);

    652       }

    653    

    654       // Always use a library call for pow.

    655       setOperationAction(ISD::FPOW             , MVT::f32  , Expand);

    656       setOperationAction(ISD::FPOW             , MVT::f64  , Expand);

    657       setOperationAction(ISD::FPOW             , MVT::f80  , Expand);

    658    

    659       setOperationAction(ISD::FLOG, MVT::f80, Expand);

    660       setOperationAction(ISD::FLOG2, MVT::f80, Expand);

    661       setOperationAction(ISD::FLOG10, MVT::f80, Expand);

    662       setOperationAction(ISD::FEXP, MVT::f80, Expand);

    663       setOperationAction(ISD::FEXP2, MVT::f80, Expand);

    664       setOperationAction(ISD::FMINNUM, MVT::f80, Expand);

    665       setOperationAction(ISD::FMAXNUM, MVT::f80, Expand);

    上面的addLegalFPImmediate()向容器LegalFPImmediates(类型std::vector)记录指令选择能合法用于浮点指令的浮点立即数。

  • 相关阅读:
    sipp3.6多方案压测脚本
    Rust学习记录(linux)——安装、创建、编译、输入输出
    在Android 上开发一个显示系统属性的APK应用
    各类值得收藏的开源项目推荐介绍
    在Debian系统上安装StoneDB数据库
    吴恩达《机器学习》1-4:无监督学习
    ATJ2157内存篇【炬芯音频芯片】---sct语法
    790.多米诺和托米诺平铺(DP)
    centos7.8 开启mysql3306端口
    Base64编码与打印标签(label)实例
  • 原文地址:https://blog.csdn.net/wuhui_gdnt/article/details/134553267