1 //===- MipsLegalizerInfo.cpp ------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements the targeting of the Machinelegalizer class for Mips. 10 /// \todo This should be generated by TableGen. 11 //===----------------------------------------------------------------------===// 12 13 #include "MipsLegalizerInfo.h" 14 #include "MipsTargetMachine.h" 15 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 16 17 using namespace llvm; 18 19 MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { 20 using namespace TargetOpcode; 21 22 const LLT s1 = LLT::scalar(1); 23 const LLT s32 = LLT::scalar(32); 24 const LLT s64 = LLT::scalar(64); 25 const LLT p0 = LLT::pointer(0, 32); 26 27 getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL}) 28 .legalFor({s32}) 29 .clampScalar(0, s32, s32); 30 31 getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_USUBO, G_USUBE, G_UMULO}) 32 .lowerFor({{s32, s1}}); 33 34 getActionDefinitionsBuilder(G_UMULH) 35 .legalFor({s32}) 36 .maxScalar(0, s32); 37 38 getActionDefinitionsBuilder({G_LOAD, G_STORE}) 39 .legalForTypesWithMemDesc({{s32, p0, 8, 8}, 40 {s32, p0, 16, 8}, 41 {s32, p0, 32, 8}, 42 {s64, p0, 64, 8}, 43 {p0, p0, 32, 8}}) 44 .minScalar(0, s32); 45 46 getActionDefinitionsBuilder(G_UNMERGE_VALUES) 47 .legalFor({{s32, s64}}); 48 49 getActionDefinitionsBuilder(G_MERGE_VALUES) 50 .legalFor({{s64, s32}}); 51 52 getActionDefinitionsBuilder({G_ZEXTLOAD, G_SEXTLOAD}) 53 .legalForTypesWithMemDesc({{s32, p0, 8, 8}, 54 {s32, p0, 16, 8}}) 55 .clampScalar(0, s32, s32); 56 57 getActionDefinitionsBuilder({G_ZEXT, G_SEXT}) 58 .legalIf([](const LegalityQuery &Query) { return false; }) 59 .maxScalar(0, s32); 60 61 getActionDefinitionsBuilder(G_TRUNC) 62 .legalIf([](const LegalityQuery &Query) { return false; }) 63 .maxScalar(1, s32); 64 65 getActionDefinitionsBuilder(G_SELECT) 66 .legalForCartesianProduct({p0, s32, s64}, {s32}) 67 .minScalar(0, s32) 68 .minScalar(1, s32); 69 70 getActionDefinitionsBuilder(G_BRCOND) 71 .legalFor({s32}) 72 .minScalar(0, s32); 73 74 getActionDefinitionsBuilder(G_BRJT) 75 .legalFor({{p0, s32}}); 76 77 getActionDefinitionsBuilder(G_PHI) 78 .legalFor({p0, s32, s64}) 79 .minScalar(0, s32); 80 81 getActionDefinitionsBuilder({G_AND, G_OR, G_XOR}) 82 .legalFor({s32}) 83 .clampScalar(0, s32, s32); 84 85 getActionDefinitionsBuilder({G_SDIV, G_SREM, G_UREM, G_UDIV}) 86 .legalFor({s32}) 87 .minScalar(0, s32) 88 .libcallFor({s64}); 89 90 getActionDefinitionsBuilder({G_SHL, G_ASHR, G_LSHR}) 91 .legalFor({{s32, s32}}) 92 .clampScalar(1, s32, s32); 93 94 getActionDefinitionsBuilder(G_ICMP) 95 .legalForCartesianProduct({s32}, {s32, p0}) 96 .clampScalar(1, s32, s32) 97 .minScalar(0, s32); 98 99 getActionDefinitionsBuilder(G_CONSTANT) 100 .legalFor({s32}) 101 .clampScalar(0, s32, s32); 102 103 getActionDefinitionsBuilder({G_GEP, G_INTTOPTR}) 104 .legalFor({{p0, s32}}); 105 106 getActionDefinitionsBuilder(G_PTRTOINT) 107 .legalFor({{s32, p0}}); 108 109 getActionDefinitionsBuilder(G_FRAME_INDEX) 110 .legalFor({p0}); 111 112 getActionDefinitionsBuilder({G_GLOBAL_VALUE, G_JUMP_TABLE}) 113 .legalFor({p0}); 114 115 // FP instructions 116 getActionDefinitionsBuilder(G_FCONSTANT) 117 .legalFor({s32, s64}); 118 119 getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FABS, G_FSQRT}) 120 .legalFor({s32, s64}); 121 122 getActionDefinitionsBuilder(G_FCMP) 123 .legalFor({{s32, s32}, {s32, s64}}) 124 .minScalar(0, s32); 125 126 getActionDefinitionsBuilder({G_FCEIL, G_FFLOOR}) 127 .libcallFor({s32, s64}); 128 129 getActionDefinitionsBuilder(G_FPEXT) 130 .legalFor({{s64, s32}}); 131 132 getActionDefinitionsBuilder(G_FPTRUNC) 133 .legalFor({{s32, s64}}); 134 135 // FP to int conversion instructions 136 getActionDefinitionsBuilder(G_FPTOSI) 137 .legalForCartesianProduct({s32}, {s64, s32}) 138 .libcallForCartesianProduct({s64}, {s64, s32}) 139 .minScalar(0, s32); 140 141 getActionDefinitionsBuilder(G_FPTOUI) 142 .libcallForCartesianProduct({s64}, {s64, s32}) 143 .minScalar(0, s32); 144 145 // Int to FP conversion instructions 146 getActionDefinitionsBuilder(G_SITOFP) 147 .legalForCartesianProduct({s64, s32}, {s32}) 148 .libcallForCartesianProduct({s64, s32}, {s64}) 149 .minScalar(1, s32); 150 151 getActionDefinitionsBuilder(G_UITOFP) 152 .libcallForCartesianProduct({s64, s32}, {s64}) 153 .minScalar(1, s32); 154 155 getActionDefinitionsBuilder(G_SEXT_INREG).lower(); 156 157 computeTables(); 158 verify(*ST.getInstrInfo()); 159 } 160 161 bool MipsLegalizerInfo::legalizeCustom(MachineInstr &MI, 162 MachineRegisterInfo &MRI, 163 MachineIRBuilder &MIRBuilder, 164 GISelChangeObserver &Observer) const { 165 166 using namespace TargetOpcode; 167 168 MIRBuilder.setInstr(MI); 169 170 return false; 171 } 172 173 bool MipsLegalizerInfo::legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI, 174 MachineIRBuilder &MIRBuilder) const { 175 switch (MI.getIntrinsicID()) { 176 case Intrinsic::memcpy: 177 case Intrinsic::memset: 178 case Intrinsic::memmove: 179 if (createMemLibcall(MIRBuilder, MRI, MI) == 180 LegalizerHelper::UnableToLegalize) 181 return false; 182 MI.eraseFromParent(); 183 return true; 184 default: 185 break; 186 } 187 return true; 188 } 189