| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 1 | //===-- Mips16ISelLowering.h - Mips16 DAG Lowering Interface ----*- C++ -*-===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // Subclass of MipsTargetLowering specialized for mips16. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 13 | #include "Mips16ISelLowering.h" | 
| Chandler Carruth | 8a8cd2b | 2014-01-07 11:48:04 +0000 | [diff] [blame] | 14 | #include "MCTargetDesc/MipsBaseInfo.h" | 
| Eric Christopher | 79cc1e3 | 2014-09-02 22:28:02 +0000 | [diff] [blame] | 15 | #include "Mips16HardFloatInfo.h" | 
|  | 16 | #include "MipsMachineFunction.h" | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 17 | #include "MipsRegisterInfo.h" | 
| Reed Kotler | 783c794 | 2013-05-10 22:25:39 +0000 | [diff] [blame] | 18 | #include "MipsTargetMachine.h" | 
| Reed Kotler | 4cdaa7d | 2014-02-14 19:16:39 +0000 | [diff] [blame] | 19 | #include "llvm/ADT/StringRef.h" | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 20 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
|  | 21 | #include "llvm/Support/CommandLine.h" | 
|  | 22 | #include "llvm/Target/TargetInstrInfo.h" | 
| Chandler Carruth | 442f784 | 2014-03-04 10:07:28 +0000 | [diff] [blame] | 23 | #include <string> | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 24 |  | 
|  | 25 | using namespace llvm; | 
|  | 26 |  | 
| Chandler Carruth | 84e68b2 | 2014-04-22 02:41:26 +0000 | [diff] [blame] | 27 | #define DEBUG_TYPE "mips-lower" | 
|  | 28 |  | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 29 | static cl::opt<bool> DontExpandCondPseudos16( | 
|  | 30 | "mips16-dont-expand-cond-pseudo", | 
|  | 31 | cl::init(false), | 
| Sylvestre Ledru | 469de19 | 2014-08-11 18:04:46 +0000 | [diff] [blame] | 32 | cl::desc("Don't expand conditional move related " | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 33 | "pseudos for Mips 16"), | 
|  | 34 | cl::Hidden); | 
|  | 35 |  | 
|  | 36 | namespace { | 
| Benjamin Kramer | c4d547d | 2013-06-13 19:06:52 +0000 | [diff] [blame] | 37 | struct Mips16Libcall { | 
|  | 38 | RTLIB::Libcall Libcall; | 
|  | 39 | const char *Name; | 
|  | 40 |  | 
|  | 41 | bool operator<(const Mips16Libcall &RHS) const { | 
|  | 42 | return std::strcmp(Name, RHS.Name) < 0; | 
|  | 43 | } | 
|  | 44 | }; | 
| Reed Kotler | 83f879d | 2013-08-01 21:17:53 +0000 | [diff] [blame] | 45 |  | 
|  | 46 | struct Mips16IntrinsicHelperType{ | 
|  | 47 | const char* Name; | 
|  | 48 | const char* Helper; | 
|  | 49 |  | 
|  | 50 | bool operator<(const Mips16IntrinsicHelperType &RHS) const { | 
|  | 51 | return std::strcmp(Name, RHS.Name) < 0; | 
|  | 52 | } | 
|  | 53 | bool operator==(const Mips16IntrinsicHelperType &RHS) const { | 
|  | 54 | return std::strcmp(Name, RHS.Name) == 0; | 
|  | 55 | } | 
|  | 56 | }; | 
| Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 57 | } | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 58 |  | 
| Benjamin Kramer | c4d547d | 2013-06-13 19:06:52 +0000 | [diff] [blame] | 59 | // Libcalls for which no helper is generated. Sorted by name for binary search. | 
|  | 60 | static const Mips16Libcall HardFloatLibCalls[] = { | 
|  | 61 | { RTLIB::ADD_F64, "__mips16_adddf3" }, | 
|  | 62 | { RTLIB::ADD_F32, "__mips16_addsf3" }, | 
|  | 63 | { RTLIB::DIV_F64, "__mips16_divdf3" }, | 
|  | 64 | { RTLIB::DIV_F32, "__mips16_divsf3" }, | 
|  | 65 | { RTLIB::OEQ_F64, "__mips16_eqdf2" }, | 
|  | 66 | { RTLIB::OEQ_F32, "__mips16_eqsf2" }, | 
|  | 67 | { RTLIB::FPEXT_F32_F64, "__mips16_extendsfdf2" }, | 
|  | 68 | { RTLIB::FPTOSINT_F64_I32, "__mips16_fix_truncdfsi" }, | 
|  | 69 | { RTLIB::FPTOSINT_F32_I32, "__mips16_fix_truncsfsi" }, | 
|  | 70 | { RTLIB::SINTTOFP_I32_F64, "__mips16_floatsidf" }, | 
|  | 71 | { RTLIB::SINTTOFP_I32_F32, "__mips16_floatsisf" }, | 
|  | 72 | { RTLIB::UINTTOFP_I32_F64, "__mips16_floatunsidf" }, | 
|  | 73 | { RTLIB::UINTTOFP_I32_F32, "__mips16_floatunsisf" }, | 
|  | 74 | { RTLIB::OGE_F64, "__mips16_gedf2" }, | 
|  | 75 | { RTLIB::OGE_F32, "__mips16_gesf2" }, | 
|  | 76 | { RTLIB::OGT_F64, "__mips16_gtdf2" }, | 
|  | 77 | { RTLIB::OGT_F32, "__mips16_gtsf2" }, | 
|  | 78 | { RTLIB::OLE_F64, "__mips16_ledf2" }, | 
|  | 79 | { RTLIB::OLE_F32, "__mips16_lesf2" }, | 
|  | 80 | { RTLIB::OLT_F64, "__mips16_ltdf2" }, | 
|  | 81 | { RTLIB::OLT_F32, "__mips16_ltsf2" }, | 
|  | 82 | { RTLIB::MUL_F64, "__mips16_muldf3" }, | 
|  | 83 | { RTLIB::MUL_F32, "__mips16_mulsf3" }, | 
|  | 84 | { RTLIB::UNE_F64, "__mips16_nedf2" }, | 
|  | 85 | { RTLIB::UNE_F32, "__mips16_nesf2" }, | 
|  | 86 | { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_dc" }, // No associated libcall. | 
|  | 87 | { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_df" }, // No associated libcall. | 
|  | 88 | { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sc" }, // No associated libcall. | 
|  | 89 | { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sf" }, // No associated libcall. | 
|  | 90 | { RTLIB::SUB_F64, "__mips16_subdf3" }, | 
|  | 91 | { RTLIB::SUB_F32, "__mips16_subsf3" }, | 
|  | 92 | { RTLIB::FPROUND_F64_F32, "__mips16_truncdfsf2" }, | 
|  | 93 | { RTLIB::UO_F64, "__mips16_unorddf2" }, | 
|  | 94 | { RTLIB::UO_F32, "__mips16_unordsf2" } | 
|  | 95 | }; | 
|  | 96 |  | 
| Reed Kotler | 83f879d | 2013-08-01 21:17:53 +0000 | [diff] [blame] | 97 | static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = { | 
| Reed Kotler | be316cf | 2013-08-09 21:33:41 +0000 | [diff] [blame] | 98 | {"__fixunsdfsi", "__mips16_call_stub_2" }, | 
| Reed Kotler | 83f879d | 2013-08-01 21:17:53 +0000 | [diff] [blame] | 99 | {"ceil",  "__mips16_call_stub_df_2"}, | 
|  | 100 | {"ceilf", "__mips16_call_stub_sf_1"}, | 
|  | 101 | {"copysign",  "__mips16_call_stub_df_10"}, | 
|  | 102 | {"copysignf", "__mips16_call_stub_sf_5"}, | 
|  | 103 | {"cos",  "__mips16_call_stub_df_2"}, | 
|  | 104 | {"cosf", "__mips16_call_stub_sf_1"}, | 
|  | 105 | {"exp2",  "__mips16_call_stub_df_2"}, | 
|  | 106 | {"exp2f", "__mips16_call_stub_sf_1"}, | 
|  | 107 | {"floor",  "__mips16_call_stub_df_2"}, | 
|  | 108 | {"floorf", "__mips16_call_stub_sf_1"}, | 
|  | 109 | {"log2",  "__mips16_call_stub_df_2"}, | 
|  | 110 | {"log2f", "__mips16_call_stub_sf_1"}, | 
|  | 111 | {"nearbyint",  "__mips16_call_stub_df_2"}, | 
|  | 112 | {"nearbyintf", "__mips16_call_stub_sf_1"}, | 
|  | 113 | {"rint",  "__mips16_call_stub_df_2"}, | 
|  | 114 | {"rintf", "__mips16_call_stub_sf_1"}, | 
|  | 115 | {"sin",  "__mips16_call_stub_df_2"}, | 
|  | 116 | {"sinf", "__mips16_call_stub_sf_1"}, | 
|  | 117 | {"sqrt",  "__mips16_call_stub_df_2"}, | 
|  | 118 | {"sqrtf", "__mips16_call_stub_sf_1"}, | 
|  | 119 | {"trunc",  "__mips16_call_stub_df_2"}, | 
|  | 120 | {"truncf", "__mips16_call_stub_sf_1"}, | 
|  | 121 | }; | 
|  | 122 |  | 
| Eric Christopher | b152660 | 2014-09-19 23:30:42 +0000 | [diff] [blame] | 123 | Mips16TargetLowering::Mips16TargetLowering(const MipsTargetMachine &TM, | 
| Eric Christopher | 8924d27 | 2014-07-18 23:25:04 +0000 | [diff] [blame] | 124 | const MipsSubtarget &STI) | 
|  | 125 | : MipsTargetLowering(TM, STI) { | 
| Reed Kotler | fafaa9d | 2013-03-14 22:02:09 +0000 | [diff] [blame] | 126 |  | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 127 | // Set up the register classes | 
|  | 128 | addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass); | 
|  | 129 |  | 
| Eric Christopher | e8ae3e3 | 2015-05-07 23:10:21 +0000 | [diff] [blame] | 130 | if (!Subtarget.useSoftFloat()) | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 131 | setMips16HardFloatLibCalls(); | 
| Benjamin Kramer | c4d547d | 2013-06-13 19:06:52 +0000 | [diff] [blame] | 132 |  | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 133 | setOperationAction(ISD::ATOMIC_FENCE,       MVT::Other, Expand); | 
|  | 134 | setOperationAction(ISD::ATOMIC_CMP_SWAP,    MVT::i32,   Expand); | 
|  | 135 | setOperationAction(ISD::ATOMIC_SWAP,        MVT::i32,   Expand); | 
|  | 136 | setOperationAction(ISD::ATOMIC_LOAD_ADD,    MVT::i32,   Expand); | 
|  | 137 | setOperationAction(ISD::ATOMIC_LOAD_SUB,    MVT::i32,   Expand); | 
|  | 138 | setOperationAction(ISD::ATOMIC_LOAD_AND,    MVT::i32,   Expand); | 
|  | 139 | setOperationAction(ISD::ATOMIC_LOAD_OR,     MVT::i32,   Expand); | 
|  | 140 | setOperationAction(ISD::ATOMIC_LOAD_XOR,    MVT::i32,   Expand); | 
|  | 141 | setOperationAction(ISD::ATOMIC_LOAD_NAND,   MVT::i32,   Expand); | 
|  | 142 | setOperationAction(ISD::ATOMIC_LOAD_MIN,    MVT::i32,   Expand); | 
|  | 143 | setOperationAction(ISD::ATOMIC_LOAD_MAX,    MVT::i32,   Expand); | 
|  | 144 | setOperationAction(ISD::ATOMIC_LOAD_UMIN,   MVT::i32,   Expand); | 
|  | 145 | setOperationAction(ISD::ATOMIC_LOAD_UMAX,   MVT::i32,   Expand); | 
|  | 146 |  | 
| Reed Kotler | 97309af | 2013-10-08 17:32:33 +0000 | [diff] [blame] | 147 | setOperationAction(ISD::ROTR, MVT::i32,  Expand); | 
|  | 148 | setOperationAction(ISD::ROTR, MVT::i64,  Expand); | 
|  | 149 | setOperationAction(ISD::BSWAP, MVT::i32, Expand); | 
|  | 150 | setOperationAction(ISD::BSWAP, MVT::i64, Expand); | 
|  | 151 |  | 
| Eric Christopher | 23a3a7c | 2015-02-26 00:00:24 +0000 | [diff] [blame] | 152 | computeRegisterProperties(STI.getRegisterInfo()); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 153 | } | 
|  | 154 |  | 
|  | 155 | const MipsTargetLowering * | 
| Eric Christopher | b152660 | 2014-09-19 23:30:42 +0000 | [diff] [blame] | 156 | llvm::createMips16TargetLowering(const MipsTargetMachine &TM, | 
| Eric Christopher | 8924d27 | 2014-07-18 23:25:04 +0000 | [diff] [blame] | 157 | const MipsSubtarget &STI) { | 
|  | 158 | return new Mips16TargetLowering(TM, STI); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 159 | } | 
|  | 160 |  | 
|  | 161 | bool | 
| Matt Arsenault | 6f2a526 | 2014-07-27 17:46:40 +0000 | [diff] [blame] | 162 | Mips16TargetLowering::allowsMisalignedMemoryAccesses(EVT VT, | 
|  | 163 | unsigned, | 
|  | 164 | unsigned, | 
|  | 165 | bool *Fast) const { | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 166 | return false; | 
|  | 167 | } | 
|  | 168 |  | 
|  | 169 | MachineBasicBlock * | 
|  | 170 | Mips16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, | 
|  | 171 | MachineBasicBlock *BB) const { | 
|  | 172 | switch (MI->getOpcode()) { | 
|  | 173 | default: | 
|  | 174 | return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB); | 
|  | 175 | case Mips::SelBeqZ: | 
|  | 176 | return emitSel16(Mips::BeqzRxImm16, MI, BB); | 
|  | 177 | case Mips::SelBneZ: | 
|  | 178 | return emitSel16(Mips::BnezRxImm16, MI, BB); | 
|  | 179 | case Mips::SelTBteqZCmpi: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 180 | return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 181 | case Mips::SelTBteqZSlti: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 182 | return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 183 | case Mips::SelTBteqZSltiu: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 184 | return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 185 | case Mips::SelTBtneZCmpi: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 186 | return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 187 | case Mips::SelTBtneZSlti: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 188 | return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 189 | case Mips::SelTBtneZSltiu: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 190 | return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 191 | case Mips::SelTBteqZCmp: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 192 | return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 193 | case Mips::SelTBteqZSlt: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 194 | return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 195 | case Mips::SelTBteqZSltu: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 196 | return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 197 | case Mips::SelTBtneZCmp: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 198 | return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 199 | case Mips::SelTBtneZSlt: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 200 | return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 201 | case Mips::SelTBtneZSltu: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 202 | return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 203 | case Mips::BteqzT8CmpX16: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 204 | return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 205 | case Mips::BteqzT8SltX16: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 206 | return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 207 | case Mips::BteqzT8SltuX16: | 
|  | 208 | // TBD: figure out a way to get this or remove the instruction | 
|  | 209 | // altogether. | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 210 | return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 211 | case Mips::BtnezT8CmpX16: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 212 | return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 213 | case Mips::BtnezT8SltX16: | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 214 | return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 215 | case Mips::BtnezT8SltuX16: | 
|  | 216 | // TBD: figure out a way to get this or remove the instruction | 
|  | 217 | // altogether. | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 218 | return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 219 | case Mips::BteqzT8CmpiX16: return emitFEXT_T8I8I16_ins( | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 220 | Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 221 | case Mips::BteqzT8SltiX16: return emitFEXT_T8I8I16_ins( | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 222 | Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 223 | case Mips::BteqzT8SltiuX16: return emitFEXT_T8I8I16_ins( | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 224 | Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 225 | case Mips::BtnezT8CmpiX16: return emitFEXT_T8I8I16_ins( | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 226 | Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 227 | case Mips::BtnezT8SltiX16: return emitFEXT_T8I8I16_ins( | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 228 | Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 229 | case Mips::BtnezT8SltiuX16: return emitFEXT_T8I8I16_ins( | 
| Reed Kotler | 09e5915 | 2013-11-15 02:21:52 +0000 | [diff] [blame] | 230 | Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 231 | break; | 
|  | 232 | case Mips::SltCCRxRy16: | 
|  | 233 | return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB); | 
|  | 234 | break; | 
|  | 235 | case Mips::SltiCCRxImmX16: | 
|  | 236 | return emitFEXT_CCRXI16_ins | 
|  | 237 | (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB); | 
|  | 238 | case Mips::SltiuCCRxImmX16: | 
|  | 239 | return emitFEXT_CCRXI16_ins | 
|  | 240 | (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB); | 
|  | 241 | case Mips::SltuCCRxRy16: | 
|  | 242 | return emitFEXT_CCRX16_ins | 
|  | 243 | (Mips::SltuRxRy16, MI, BB); | 
|  | 244 | } | 
|  | 245 | } | 
|  | 246 |  | 
| Daniel Sanders | 23e9877 | 2014-11-02 16:09:29 +0000 | [diff] [blame] | 247 | bool Mips16TargetLowering::isEligibleForTailCallOptimization( | 
|  | 248 | const CCState &CCInfo, unsigned NextStackOffset, | 
|  | 249 | const MipsFunctionInfo &FI) const { | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 250 | // No tail call optimization for mips16. | 
|  | 251 | return false; | 
|  | 252 | } | 
|  | 253 |  | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 254 | void Mips16TargetLowering::setMips16HardFloatLibCalls() { | 
| Benjamin Kramer | c4d547d | 2013-06-13 19:06:52 +0000 | [diff] [blame] | 255 | for (unsigned I = 0; I != array_lengthof(HardFloatLibCalls); ++I) { | 
|  | 256 | assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) && | 
|  | 257 | "Array not sorted!"); | 
|  | 258 | if (HardFloatLibCalls[I].Libcall != RTLIB::UNKNOWN_LIBCALL) | 
|  | 259 | setLibcallName(HardFloatLibCalls[I].Libcall, HardFloatLibCalls[I].Name); | 
|  | 260 | } | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 261 |  | 
| Benjamin Kramer | c4d547d | 2013-06-13 19:06:52 +0000 | [diff] [blame] | 262 | setLibcallName(RTLIB::O_F64, "__mips16_unorddf2"); | 
|  | 263 | setLibcallName(RTLIB::O_F32, "__mips16_unordsf2"); | 
|  | 264 | } | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 265 |  | 
|  | 266 | // | 
|  | 267 | // The Mips16 hard float is a crazy quilt inherited from gcc. I have a much | 
|  | 268 | // cleaner way to do all of this but it will have to wait until the traditional | 
|  | 269 | // gcc mechanism is completed. | 
|  | 270 | // | 
|  | 271 | // For Pic, in order for Mips16 code to call Mips32 code which according the abi | 
|  | 272 | // have either arguments or returned values placed in floating point registers, | 
|  | 273 | // we use a set of helper functions. (This includes functions which return type | 
|  | 274 | //  complex which on Mips are returned in a pair of floating point registers). | 
|  | 275 | // | 
|  | 276 | // This is an encoding that we inherited from gcc. | 
|  | 277 | // In Mips traditional O32, N32 ABI, floating point numbers are passed in | 
|  | 278 | // floating point argument registers 1,2 only when the first and optionally | 
|  | 279 | // the second arguments are float (sf) or double (df). | 
|  | 280 | // For Mips16 we are only concerned with the situations where floating point | 
|  | 281 | // arguments are being passed in floating point registers by the ABI, because | 
|  | 282 | // Mips16 mode code cannot execute floating point instructions to load those | 
|  | 283 | // values and hence helper functions are needed. | 
|  | 284 | // The possibilities are (), (sf), (sf, sf), (sf, df), (df), (df, sf), (df, df) | 
|  | 285 | // the helper function suffixs for these are: | 
|  | 286 | //                        0,  1,    5,        9,         2,   6,        10 | 
|  | 287 | // this suffix can then be calculated as follows: | 
|  | 288 | // for a given argument Arg: | 
|  | 289 | //     Arg1x, Arg2x = 1 :  Arg is sf | 
|  | 290 | //                    2 :  Arg is df | 
|  | 291 | //                    0:   Arg is neither sf or df | 
|  | 292 | // So this stub is the string for number Arg1x + Arg2x*4. | 
|  | 293 | // However not all numbers between 0 and 10 are possible, we check anyway and | 
|  | 294 | // assert if the impossible exists. | 
|  | 295 | // | 
|  | 296 |  | 
|  | 297 | unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber | 
|  | 298 | (ArgListTy &Args) const { | 
|  | 299 | unsigned int resultNum = 0; | 
|  | 300 | if (Args.size() >= 1) { | 
|  | 301 | Type *t = Args[0].Ty; | 
|  | 302 | if (t->isFloatTy()) { | 
|  | 303 | resultNum = 1; | 
|  | 304 | } | 
|  | 305 | else if (t->isDoubleTy()) { | 
|  | 306 | resultNum = 2; | 
|  | 307 | } | 
|  | 308 | } | 
|  | 309 | if (resultNum) { | 
|  | 310 | if (Args.size() >=2) { | 
|  | 311 | Type *t = Args[1].Ty; | 
|  | 312 | if (t->isFloatTy()) { | 
|  | 313 | resultNum += 4; | 
|  | 314 | } | 
|  | 315 | else if (t->isDoubleTy()) { | 
|  | 316 | resultNum += 8; | 
|  | 317 | } | 
|  | 318 | } | 
|  | 319 | } | 
|  | 320 | return resultNum; | 
|  | 321 | } | 
|  | 322 |  | 
|  | 323 | // | 
| Eric Christopher | 9b270d4 | 2014-09-29 21:57:52 +0000 | [diff] [blame] | 324 | // Prefixes are attached to stub numbers depending on the return type. | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 325 | // return type: float  sf_ | 
|  | 326 | //              double df_ | 
|  | 327 | //              single complex sc_ | 
|  | 328 | //              double complext dc_ | 
|  | 329 | //              others  NO PREFIX | 
|  | 330 | // | 
|  | 331 | // | 
|  | 332 | // The full name of a helper function is__mips16_call_stub + | 
|  | 333 | //    return type dependent prefix + stub number | 
|  | 334 | // | 
| Eric Christopher | 9b270d4 | 2014-09-29 21:57:52 +0000 | [diff] [blame] | 335 | // FIXME: This is something that probably should be in a different source file | 
|  | 336 | // and perhaps done differently but my main purpose is to not waste runtime | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 337 | // on something that we can enumerate in the source. Another possibility is | 
|  | 338 | // to have a python script to generate these mapping tables. This will do | 
|  | 339 | // for now. There are a whole series of helper function mapping arrays, one | 
|  | 340 | // for each return type class as outlined above. There there are 11 possible | 
| Eric Christopher | 9b270d4 | 2014-09-29 21:57:52 +0000 | [diff] [blame] | 341 | // entries. Ones with 0 are ones which should never be selected. | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 342 | // | 
|  | 343 | // All the arrays are similar except for ones which return neither | 
| Eric Christopher | 9b270d4 | 2014-09-29 21:57:52 +0000 | [diff] [blame] | 344 | // sf, df, sc, dc, in which we only care about ones which have sf or df as a | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 345 | // first parameter. | 
|  | 346 | // | 
|  | 347 | #define P_ "__mips16_call_stub_" | 
|  | 348 | #define MAX_STUB_NUMBER 10 | 
|  | 349 | #define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10" | 
|  | 350 | #define T P "0" , T1 | 
|  | 351 | #define P P_ | 
|  | 352 | static char const * vMips16Helper[MAX_STUB_NUMBER+1] = | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 353 | {nullptr, T1 }; | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 354 | #undef P | 
|  | 355 | #define P P_ "sf_" | 
|  | 356 | static char const * sfMips16Helper[MAX_STUB_NUMBER+1] = | 
|  | 357 | { T }; | 
|  | 358 | #undef P | 
|  | 359 | #define P P_ "df_" | 
|  | 360 | static char const * dfMips16Helper[MAX_STUB_NUMBER+1] = | 
|  | 361 | { T }; | 
|  | 362 | #undef P | 
|  | 363 | #define P P_ "sc_" | 
|  | 364 | static char const * scMips16Helper[MAX_STUB_NUMBER+1] = | 
|  | 365 | { T }; | 
|  | 366 | #undef P | 
|  | 367 | #define P P_ "dc_" | 
|  | 368 | static char const * dcMips16Helper[MAX_STUB_NUMBER+1] = | 
|  | 369 | { T }; | 
|  | 370 | #undef P | 
|  | 371 | #undef P_ | 
|  | 372 |  | 
|  | 373 |  | 
|  | 374 | const char* Mips16TargetLowering:: | 
|  | 375 | getMips16HelperFunction | 
|  | 376 | (Type* RetTy, ArgListTy &Args, bool &needHelper) const { | 
|  | 377 | const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args); | 
|  | 378 | #ifndef NDEBUG | 
|  | 379 | const unsigned int maxStubNum = 10; | 
|  | 380 | assert(stubNum <= maxStubNum); | 
|  | 381 | const bool validStubNum[maxStubNum+1] = | 
|  | 382 | {true, true, true, false, false, true, true, false, false, true, true}; | 
|  | 383 | assert(validStubNum[stubNum]); | 
|  | 384 | #endif | 
|  | 385 | const char *result; | 
|  | 386 | if (RetTy->isFloatTy()) { | 
|  | 387 | result = sfMips16Helper[stubNum]; | 
|  | 388 | } | 
|  | 389 | else if (RetTy ->isDoubleTy()) { | 
|  | 390 | result = dfMips16Helper[stubNum]; | 
|  | 391 | } | 
|  | 392 | else if (RetTy->isStructTy()) { | 
|  | 393 | // check if it's complex | 
|  | 394 | if (RetTy->getNumContainedTypes() == 2) { | 
|  | 395 | if ((RetTy->getContainedType(0)->isFloatTy()) && | 
|  | 396 | (RetTy->getContainedType(1)->isFloatTy())) { | 
|  | 397 | result = scMips16Helper[stubNum]; | 
|  | 398 | } | 
|  | 399 | else if ((RetTy->getContainedType(0)->isDoubleTy()) && | 
|  | 400 | (RetTy->getContainedType(1)->isDoubleTy())) { | 
|  | 401 | result = dcMips16Helper[stubNum]; | 
|  | 402 | } | 
|  | 403 | else { | 
|  | 404 | llvm_unreachable("Uncovered condition"); | 
|  | 405 | } | 
|  | 406 | } | 
|  | 407 | else { | 
|  | 408 | llvm_unreachable("Uncovered condition"); | 
|  | 409 | } | 
|  | 410 | } | 
|  | 411 | else { | 
|  | 412 | if (stubNum == 0) { | 
|  | 413 | needHelper = false; | 
|  | 414 | return ""; | 
|  | 415 | } | 
|  | 416 | result = vMips16Helper[stubNum]; | 
|  | 417 | } | 
|  | 418 | needHelper = true; | 
|  | 419 | return result; | 
|  | 420 | } | 
|  | 421 |  | 
|  | 422 | void Mips16TargetLowering:: | 
|  | 423 | getOpndList(SmallVectorImpl<SDValue> &Ops, | 
|  | 424 | std::deque< std::pair<unsigned, SDValue> > &RegsToPass, | 
|  | 425 | bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, | 
| Sasa Stankovic | 7072a79 | 2014-10-01 08:22:21 +0000 | [diff] [blame] | 426 | bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, | 
|  | 427 | SDValue Chain) const { | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 428 | SelectionDAG &DAG = CLI.DAG; | 
| Akira Hatanaka | af4211a | 2013-09-28 00:12:32 +0000 | [diff] [blame] | 429 | MachineFunction &MF = DAG.getMachineFunction(); | 
|  | 430 | MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>(); | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 431 | const char* Mips16HelperFunction = nullptr; | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 432 | bool NeedMips16Helper = false; | 
|  | 433 |  | 
| Eric Christopher | 1c29a65 | 2014-07-18 22:55:25 +0000 | [diff] [blame] | 434 | if (Subtarget.inMips16HardFloat()) { | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 435 | // | 
|  | 436 | // currently we don't have symbols tagged with the mips16 or mips32 | 
|  | 437 | // qualifier so we will assume that we don't know what kind it is. | 
|  | 438 | // and generate the helper | 
|  | 439 | // | 
|  | 440 | bool LookupHelper = true; | 
|  | 441 | if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) { | 
| Benjamin Kramer | c4d547d | 2013-06-13 19:06:52 +0000 | [diff] [blame] | 442 | Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() }; | 
|  | 443 |  | 
| Benjamin Kramer | 502b9e1 | 2014-04-12 16:15:53 +0000 | [diff] [blame] | 444 | if (std::binary_search(std::begin(HardFloatLibCalls), | 
|  | 445 | std::end(HardFloatLibCalls), Find)) | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 446 | LookupHelper = false; | 
| Reed Kotler | 83f879d | 2013-08-01 21:17:53 +0000 | [diff] [blame] | 447 | else { | 
| Reed Kotler | 4cdaa7d | 2014-02-14 19:16:39 +0000 | [diff] [blame] | 448 | const char *Symbol = S->getSymbol(); | 
|  | 449 | Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" }; | 
|  | 450 | const Mips16HardFloatInfo::FuncSignature *Signature = | 
|  | 451 | Mips16HardFloatInfo::findFuncSignature(Symbol); | 
|  | 452 | if (!IsPICCall && (Signature && (FuncInfo->StubsNeeded.find(Symbol) == | 
|  | 453 | FuncInfo->StubsNeeded.end()))) { | 
|  | 454 | FuncInfo->StubsNeeded[Symbol] = Signature; | 
|  | 455 | // | 
|  | 456 | // S2 is normally saved if the stub is for a function which | 
|  | 457 | // returns a float or double value and is not otherwise. This is | 
|  | 458 | // because more work is required after the function the stub | 
|  | 459 | // is calling completes, and so the stub cannot directly return | 
|  | 460 | // and the stub has no stack space to store the return address so | 
|  | 461 | // S2 is used for that purpose. | 
|  | 462 | // In order to take advantage of not saving S2, we need to also | 
|  | 463 | // optimize the call in the stub and this requires some further | 
|  | 464 | // functionality in MipsAsmPrinter which we don't have yet. | 
|  | 465 | // So for now we always save S2. The optimization will be done | 
|  | 466 | // in a follow-on patch. | 
|  | 467 | // | 
| Reed Kotler | d2da810 | 2014-02-19 22:11:45 +0000 | [diff] [blame] | 468 | if (1 || (Signature->RetSig != Mips16HardFloatInfo::NoFPRet)) | 
| Reed Kotler | 4cdaa7d | 2014-02-14 19:16:39 +0000 | [diff] [blame] | 469 | FuncInfo->setSaveS2(); | 
|  | 470 | } | 
| Reed Kotler | 83f879d | 2013-08-01 21:17:53 +0000 | [diff] [blame] | 471 | // one more look at list of intrinsics | 
| Benjamin Kramer | 502b9e1 | 2014-04-12 16:15:53 +0000 | [diff] [blame] | 472 | const Mips16IntrinsicHelperType *Helper = | 
|  | 473 | std::lower_bound(std::begin(Mips16IntrinsicHelper), | 
|  | 474 | std::end(Mips16IntrinsicHelper), IntrinsicFind); | 
|  | 475 | if (Helper != std::end(Mips16IntrinsicHelper) && | 
|  | 476 | *Helper == IntrinsicFind) { | 
|  | 477 | Mips16HelperFunction = Helper->Helper; | 
| Reed Kotler | 83f879d | 2013-08-01 21:17:53 +0000 | [diff] [blame] | 478 | NeedMips16Helper = true; | 
|  | 479 | LookupHelper = false; | 
|  | 480 | } | 
|  | 481 |  | 
|  | 482 | } | 
| Benjamin Kramer | c4d547d | 2013-06-13 19:06:52 +0000 | [diff] [blame] | 483 | } else if (GlobalAddressSDNode *G = | 
|  | 484 | dyn_cast<GlobalAddressSDNode>(CLI.Callee)) { | 
|  | 485 | Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, | 
|  | 486 | G->getGlobal()->getName().data() }; | 
|  | 487 |  | 
| Benjamin Kramer | 502b9e1 | 2014-04-12 16:15:53 +0000 | [diff] [blame] | 488 | if (std::binary_search(std::begin(HardFloatLibCalls), | 
|  | 489 | std::end(HardFloatLibCalls), Find)) | 
| Reed Kotler | 0fed8d4 | 2013-05-21 00:50:30 +0000 | [diff] [blame] | 490 | LookupHelper = false; | 
| Reed Kotler | 0fed8d4 | 2013-05-21 00:50:30 +0000 | [diff] [blame] | 491 | } | 
| Saleem Abdulrasool | 9f664c1 | 2014-05-17 21:50:01 +0000 | [diff] [blame] | 492 | if (LookupHelper) | 
|  | 493 | Mips16HelperFunction = | 
|  | 494 | getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 495 | } | 
|  | 496 |  | 
|  | 497 | SDValue JumpTarget = Callee; | 
|  | 498 |  | 
|  | 499 | // T9 should contain the address of the callee function if | 
| Daniel Sanders | 9a4f2c5 | 2015-01-24 14:35:11 +0000 | [diff] [blame] | 500 | // -relocation-model=pic or it is an indirect call. | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 501 | if (IsPICCall || !GlobalOrExternal) { | 
|  | 502 | unsigned V0Reg = Mips::V0; | 
|  | 503 | if (NeedMips16Helper) { | 
|  | 504 | RegsToPass.push_front(std::make_pair(V0Reg, Callee)); | 
| Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 505 | JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction, | 
|  | 506 | getPointerTy(DAG.getDataLayout())); | 
| Akira Hatanaka | af4211a | 2013-09-28 00:12:32 +0000 | [diff] [blame] | 507 | ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget); | 
| Daniel Sanders | 9a4f2c5 | 2015-01-24 14:35:11 +0000 | [diff] [blame] | 508 | JumpTarget = getAddrGlobal(S, CLI.DL, JumpTarget.getValueType(), DAG, | 
| Akira Hatanaka | af4211a | 2013-09-28 00:12:32 +0000 | [diff] [blame] | 509 | MipsII::MO_GOT, Chain, | 
|  | 510 | FuncInfo->callPtrInfo(S->getSymbol())); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 511 | } else | 
|  | 512 | RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee)); | 
|  | 513 | } | 
|  | 514 |  | 
|  | 515 | Ops.push_back(JumpTarget); | 
|  | 516 |  | 
|  | 517 | MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, | 
| Sasa Stankovic | 7072a79 | 2014-10-01 08:22:21 +0000 | [diff] [blame] | 518 | InternalLinkage, IsCallReloc, CLI, Callee, | 
|  | 519 | Chain); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 520 | } | 
|  | 521 |  | 
|  | 522 | MachineBasicBlock *Mips16TargetLowering:: | 
|  | 523 | emitSel16(unsigned Opc, MachineInstr *MI, MachineBasicBlock *BB) const { | 
|  | 524 | if (DontExpandCondPseudos16) | 
|  | 525 | return BB; | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 526 | const TargetInstrInfo *TII = Subtarget.getInstrInfo(); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 527 | DebugLoc DL = MI->getDebugLoc(); | 
|  | 528 | // To "insert" a SELECT_CC instruction, we actually have to insert the | 
|  | 529 | // diamond control-flow pattern.  The incoming instruction knows the | 
|  | 530 | // destination vreg to set, the condition code register to branch on, the | 
|  | 531 | // true/false values to select between, and a branch opcode to use. | 
|  | 532 | const BasicBlock *LLVM_BB = BB->getBasicBlock(); | 
|  | 533 | MachineFunction::iterator It = BB; | 
|  | 534 | ++It; | 
|  | 535 |  | 
|  | 536 | //  thisMBB: | 
|  | 537 | //  ... | 
|  | 538 | //   TrueVal = ... | 
|  | 539 | //   setcc r1, r2, r3 | 
|  | 540 | //   bNE   r1, r0, copy1MBB | 
|  | 541 | //   fallthrough --> copy0MBB | 
|  | 542 | MachineBasicBlock *thisMBB  = BB; | 
|  | 543 | MachineFunction *F = BB->getParent(); | 
|  | 544 | MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); | 
|  | 545 | MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB); | 
|  | 546 | F->insert(It, copy0MBB); | 
|  | 547 | F->insert(It, sinkMBB); | 
|  | 548 |  | 
|  | 549 | // Transfer the remainder of BB and its successor edges to sinkMBB. | 
|  | 550 | sinkMBB->splice(sinkMBB->begin(), BB, | 
| Benjamin Kramer | b6d0bd4 | 2014-03-02 12:27:27 +0000 | [diff] [blame] | 551 | std::next(MachineBasicBlock::iterator(MI)), BB->end()); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 552 | sinkMBB->transferSuccessorsAndUpdatePHIs(BB); | 
|  | 553 |  | 
|  | 554 | // Next, add the true and fallthrough blocks as its successors. | 
|  | 555 | BB->addSuccessor(copy0MBB); | 
|  | 556 | BB->addSuccessor(sinkMBB); | 
|  | 557 |  | 
|  | 558 | BuildMI(BB, DL, TII->get(Opc)).addReg(MI->getOperand(3).getReg()) | 
|  | 559 | .addMBB(sinkMBB); | 
|  | 560 |  | 
|  | 561 | //  copy0MBB: | 
|  | 562 | //   %FalseValue = ... | 
|  | 563 | //   # fallthrough to sinkMBB | 
|  | 564 | BB = copy0MBB; | 
|  | 565 |  | 
|  | 566 | // Update machine-CFG edges | 
|  | 567 | BB->addSuccessor(sinkMBB); | 
|  | 568 |  | 
|  | 569 | //  sinkMBB: | 
|  | 570 | //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ] | 
|  | 571 | //  ... | 
|  | 572 | BB = sinkMBB; | 
|  | 573 |  | 
|  | 574 | BuildMI(*BB, BB->begin(), DL, | 
|  | 575 | TII->get(Mips::PHI), MI->getOperand(0).getReg()) | 
|  | 576 | .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB) | 
|  | 577 | .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB); | 
|  | 578 |  | 
|  | 579 | MI->eraseFromParent();   // The pseudo instruction is gone now. | 
|  | 580 | return BB; | 
|  | 581 | } | 
|  | 582 |  | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 583 | MachineBasicBlock * | 
|  | 584 | Mips16TargetLowering::emitSelT16(unsigned Opc1, unsigned Opc2, MachineInstr *MI, | 
|  | 585 | MachineBasicBlock *BB) const { | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 586 | if (DontExpandCondPseudos16) | 
|  | 587 | return BB; | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 588 | const TargetInstrInfo *TII = Subtarget.getInstrInfo(); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 589 | DebugLoc DL = MI->getDebugLoc(); | 
|  | 590 | // To "insert" a SELECT_CC instruction, we actually have to insert the | 
|  | 591 | // diamond control-flow pattern.  The incoming instruction knows the | 
|  | 592 | // destination vreg to set, the condition code register to branch on, the | 
|  | 593 | // true/false values to select between, and a branch opcode to use. | 
|  | 594 | const BasicBlock *LLVM_BB = BB->getBasicBlock(); | 
|  | 595 | MachineFunction::iterator It = BB; | 
|  | 596 | ++It; | 
|  | 597 |  | 
|  | 598 | //  thisMBB: | 
|  | 599 | //  ... | 
|  | 600 | //   TrueVal = ... | 
|  | 601 | //   setcc r1, r2, r3 | 
|  | 602 | //   bNE   r1, r0, copy1MBB | 
|  | 603 | //   fallthrough --> copy0MBB | 
|  | 604 | MachineBasicBlock *thisMBB  = BB; | 
|  | 605 | MachineFunction *F = BB->getParent(); | 
|  | 606 | MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); | 
|  | 607 | MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB); | 
|  | 608 | F->insert(It, copy0MBB); | 
|  | 609 | F->insert(It, sinkMBB); | 
|  | 610 |  | 
|  | 611 | // Transfer the remainder of BB and its successor edges to sinkMBB. | 
|  | 612 | sinkMBB->splice(sinkMBB->begin(), BB, | 
| Benjamin Kramer | b6d0bd4 | 2014-03-02 12:27:27 +0000 | [diff] [blame] | 613 | std::next(MachineBasicBlock::iterator(MI)), BB->end()); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 614 | sinkMBB->transferSuccessorsAndUpdatePHIs(BB); | 
|  | 615 |  | 
|  | 616 | // Next, add the true and fallthrough blocks as its successors. | 
|  | 617 | BB->addSuccessor(copy0MBB); | 
|  | 618 | BB->addSuccessor(sinkMBB); | 
|  | 619 |  | 
|  | 620 | BuildMI(BB, DL, TII->get(Opc2)).addReg(MI->getOperand(3).getReg()) | 
|  | 621 | .addReg(MI->getOperand(4).getReg()); | 
|  | 622 | BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB); | 
|  | 623 |  | 
|  | 624 | //  copy0MBB: | 
|  | 625 | //   %FalseValue = ... | 
|  | 626 | //   # fallthrough to sinkMBB | 
|  | 627 | BB = copy0MBB; | 
|  | 628 |  | 
|  | 629 | // Update machine-CFG edges | 
|  | 630 | BB->addSuccessor(sinkMBB); | 
|  | 631 |  | 
|  | 632 | //  sinkMBB: | 
|  | 633 | //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ] | 
|  | 634 | //  ... | 
|  | 635 | BB = sinkMBB; | 
|  | 636 |  | 
|  | 637 | BuildMI(*BB, BB->begin(), DL, | 
|  | 638 | TII->get(Mips::PHI), MI->getOperand(0).getReg()) | 
|  | 639 | .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB) | 
|  | 640 | .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB); | 
|  | 641 |  | 
|  | 642 | MI->eraseFromParent();   // The pseudo instruction is gone now. | 
|  | 643 | return BB; | 
|  | 644 |  | 
|  | 645 | } | 
|  | 646 |  | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 647 | MachineBasicBlock * | 
|  | 648 | Mips16TargetLowering::emitSeliT16(unsigned Opc1, unsigned Opc2, | 
|  | 649 | MachineInstr *MI, | 
|  | 650 | MachineBasicBlock *BB) const { | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 651 | if (DontExpandCondPseudos16) | 
|  | 652 | return BB; | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 653 | const TargetInstrInfo *TII = Subtarget.getInstrInfo(); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 654 | DebugLoc DL = MI->getDebugLoc(); | 
|  | 655 | // To "insert" a SELECT_CC instruction, we actually have to insert the | 
|  | 656 | // diamond control-flow pattern.  The incoming instruction knows the | 
|  | 657 | // destination vreg to set, the condition code register to branch on, the | 
|  | 658 | // true/false values to select between, and a branch opcode to use. | 
|  | 659 | const BasicBlock *LLVM_BB = BB->getBasicBlock(); | 
|  | 660 | MachineFunction::iterator It = BB; | 
|  | 661 | ++It; | 
|  | 662 |  | 
|  | 663 | //  thisMBB: | 
|  | 664 | //  ... | 
|  | 665 | //   TrueVal = ... | 
|  | 666 | //   setcc r1, r2, r3 | 
|  | 667 | //   bNE   r1, r0, copy1MBB | 
|  | 668 | //   fallthrough --> copy0MBB | 
|  | 669 | MachineBasicBlock *thisMBB  = BB; | 
|  | 670 | MachineFunction *F = BB->getParent(); | 
|  | 671 | MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); | 
|  | 672 | MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB); | 
|  | 673 | F->insert(It, copy0MBB); | 
|  | 674 | F->insert(It, sinkMBB); | 
|  | 675 |  | 
|  | 676 | // Transfer the remainder of BB and its successor edges to sinkMBB. | 
|  | 677 | sinkMBB->splice(sinkMBB->begin(), BB, | 
| Benjamin Kramer | b6d0bd4 | 2014-03-02 12:27:27 +0000 | [diff] [blame] | 678 | std::next(MachineBasicBlock::iterator(MI)), BB->end()); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 679 | sinkMBB->transferSuccessorsAndUpdatePHIs(BB); | 
|  | 680 |  | 
|  | 681 | // Next, add the true and fallthrough blocks as its successors. | 
|  | 682 | BB->addSuccessor(copy0MBB); | 
|  | 683 | BB->addSuccessor(sinkMBB); | 
|  | 684 |  | 
|  | 685 | BuildMI(BB, DL, TII->get(Opc2)).addReg(MI->getOperand(3).getReg()) | 
|  | 686 | .addImm(MI->getOperand(4).getImm()); | 
|  | 687 | BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB); | 
|  | 688 |  | 
|  | 689 | //  copy0MBB: | 
|  | 690 | //   %FalseValue = ... | 
|  | 691 | //   # fallthrough to sinkMBB | 
|  | 692 | BB = copy0MBB; | 
|  | 693 |  | 
|  | 694 | // Update machine-CFG edges | 
|  | 695 | BB->addSuccessor(sinkMBB); | 
|  | 696 |  | 
|  | 697 | //  sinkMBB: | 
|  | 698 | //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ] | 
|  | 699 | //  ... | 
|  | 700 | BB = sinkMBB; | 
|  | 701 |  | 
|  | 702 | BuildMI(*BB, BB->begin(), DL, | 
|  | 703 | TII->get(Mips::PHI), MI->getOperand(0).getReg()) | 
|  | 704 | .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB) | 
|  | 705 | .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB); | 
|  | 706 |  | 
|  | 707 | MI->eraseFromParent();   // The pseudo instruction is gone now. | 
|  | 708 | return BB; | 
|  | 709 |  | 
|  | 710 | } | 
|  | 711 |  | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 712 | MachineBasicBlock * | 
|  | 713 | Mips16TargetLowering::emitFEXT_T8I816_ins(unsigned BtOpc, unsigned CmpOpc, | 
|  | 714 | MachineInstr *MI, | 
|  | 715 | MachineBasicBlock *BB) const { | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 716 | if (DontExpandCondPseudos16) | 
|  | 717 | return BB; | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 718 | const TargetInstrInfo *TII = Subtarget.getInstrInfo(); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 719 | unsigned regX = MI->getOperand(0).getReg(); | 
|  | 720 | unsigned regY = MI->getOperand(1).getReg(); | 
|  | 721 | MachineBasicBlock *target = MI->getOperand(2).getMBB(); | 
| Akira Hatanaka | d8fb032 | 2013-04-22 20:13:37 +0000 | [diff] [blame] | 722 | BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(CmpOpc)).addReg(regX) | 
|  | 723 | .addReg(regY); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 724 | BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(BtOpc)).addMBB(target); | 
|  | 725 | MI->eraseFromParent();   // The pseudo instruction is gone now. | 
|  | 726 | return BB; | 
|  | 727 | } | 
|  | 728 |  | 
|  | 729 | MachineBasicBlock *Mips16TargetLowering::emitFEXT_T8I8I16_ins( | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 730 | unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, bool ImmSigned, | 
|  | 731 | MachineInstr *MI, MachineBasicBlock *BB) const { | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 732 | if (DontExpandCondPseudos16) | 
|  | 733 | return BB; | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 734 | const TargetInstrInfo *TII = Subtarget.getInstrInfo(); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 735 | unsigned regX = MI->getOperand(0).getReg(); | 
|  | 736 | int64_t imm = MI->getOperand(1).getImm(); | 
|  | 737 | MachineBasicBlock *target = MI->getOperand(2).getMBB(); | 
|  | 738 | unsigned CmpOpc; | 
|  | 739 | if (isUInt<8>(imm)) | 
|  | 740 | CmpOpc = CmpiOpc; | 
| Reed Kotler | ce51083 | 2013-06-09 23:23:46 +0000 | [diff] [blame] | 741 | else if ((!ImmSigned && isUInt<16>(imm)) || | 
|  | 742 | (ImmSigned && isInt<16>(imm))) | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 743 | CmpOpc = CmpiXOpc; | 
|  | 744 | else | 
|  | 745 | llvm_unreachable("immediate field not usable"); | 
| Akira Hatanaka | d8fb032 | 2013-04-22 20:13:37 +0000 | [diff] [blame] | 746 | BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(CmpOpc)).addReg(regX) | 
|  | 747 | .addImm(imm); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 748 | BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(BtOpc)).addMBB(target); | 
|  | 749 | MI->eraseFromParent();   // The pseudo instruction is gone now. | 
|  | 750 | return BB; | 
|  | 751 | } | 
|  | 752 |  | 
|  | 753 | static unsigned Mips16WhichOp8uOr16simm | 
|  | 754 | (unsigned shortOp, unsigned longOp, int64_t Imm) { | 
|  | 755 | if (isUInt<8>(Imm)) | 
|  | 756 | return shortOp; | 
|  | 757 | else if (isInt<16>(Imm)) | 
|  | 758 | return longOp; | 
|  | 759 | else | 
|  | 760 | llvm_unreachable("immediate field not usable"); | 
|  | 761 | } | 
|  | 762 |  | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 763 | MachineBasicBlock * | 
|  | 764 | Mips16TargetLowering::emitFEXT_CCRX16_ins(unsigned SltOpc, MachineInstr *MI, | 
|  | 765 | MachineBasicBlock *BB) const { | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 766 | if (DontExpandCondPseudos16) | 
|  | 767 | return BB; | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 768 | const TargetInstrInfo *TII = Subtarget.getInstrInfo(); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 769 | unsigned CC = MI->getOperand(0).getReg(); | 
|  | 770 | unsigned regX = MI->getOperand(1).getReg(); | 
|  | 771 | unsigned regY = MI->getOperand(2).getReg(); | 
| Reed Kotler | 4cdaa7d | 2014-02-14 19:16:39 +0000 | [diff] [blame] | 772 | BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(SltOpc)).addReg(regX).addReg( | 
|  | 773 | regY); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 774 | BuildMI(*BB, MI, MI->getDebugLoc(), | 
|  | 775 | TII->get(Mips::MoveR3216), CC).addReg(Mips::T8); | 
|  | 776 | MI->eraseFromParent();   // The pseudo instruction is gone now. | 
|  | 777 | return BB; | 
|  | 778 | } | 
|  | 779 |  | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 780 | MachineBasicBlock * | 
|  | 781 | Mips16TargetLowering::emitFEXT_CCRXI16_ins(unsigned SltiOpc, unsigned SltiXOpc, | 
|  | 782 | MachineInstr *MI, | 
|  | 783 | MachineBasicBlock *BB) const { | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 784 | if (DontExpandCondPseudos16) | 
|  | 785 | return BB; | 
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 786 | const TargetInstrInfo *TII = Subtarget.getInstrInfo(); | 
| Akira Hatanaka | 96ca182 | 2013-03-13 00:54:29 +0000 | [diff] [blame] | 787 | unsigned CC = MI->getOperand(0).getReg(); | 
|  | 788 | unsigned regX = MI->getOperand(1).getReg(); | 
|  | 789 | int64_t Imm = MI->getOperand(2).getImm(); | 
|  | 790 | unsigned SltOpc = Mips16WhichOp8uOr16simm(SltiOpc, SltiXOpc, Imm); | 
|  | 791 | BuildMI(*BB, MI, MI->getDebugLoc(), | 
|  | 792 | TII->get(SltOpc)).addReg(regX).addImm(Imm); | 
|  | 793 | BuildMI(*BB, MI, MI->getDebugLoc(), | 
|  | 794 | TII->get(Mips::MoveR3216), CC).addReg(Mips::T8); | 
|  | 795 | MI->eraseFromParent();   // The pseudo instruction is gone now. | 
|  | 796 | return BB; | 
|  | 797 |  | 
|  | 798 | } |