1 //===- MipsLegalizerInfo.cpp ------------------------------------*- 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 /// \file 10 /// This file implements the targeting of the Machinelegalizer class for Mips. 11 /// \todo This should be generated by TableGen. 12 //===----------------------------------------------------------------------===// 13 14 #include "MipsLegalizerInfo.h" 15 #include "MipsTargetMachine.h" 16 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 17 18 using namespace llvm; 19 20 MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { 21 using namespace TargetOpcode; 22 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) 28 .legalFor({s32}) 29 .minScalar(0, s32) 30 .customFor({s64}); 31 32 getActionDefinitionsBuilder({G_LOAD, G_STORE}) 33 .legalForCartesianProduct({p0, s32}, {p0}); 34 35 getActionDefinitionsBuilder({G_AND, G_OR, G_XOR, G_SHL, G_ASHR, G_LSHR}) 36 .legalFor({s32}); 37 38 getActionDefinitionsBuilder(G_ICMP) 39 .legalFor({{s32, s32}}) 40 .minScalar(0, s32); 41 42 getActionDefinitionsBuilder(G_CONSTANT) 43 .legalFor({s32}) 44 .minScalar(0, s32) 45 .customFor({s64}); 46 47 getActionDefinitionsBuilder(G_GEP) 48 .legalFor({{p0, s32}}); 49 50 getActionDefinitionsBuilder(G_FRAME_INDEX) 51 .legalFor({p0}); 52 53 getActionDefinitionsBuilder(G_GLOBAL_VALUE) 54 .legalFor({p0}); 55 56 computeTables(); 57 verify(*ST.getInstrInfo()); 58 } 59 60 bool MipsLegalizerInfo::legalizeCustom(MachineInstr &MI, 61 MachineRegisterInfo &MRI, 62 MachineIRBuilder &MIRBuilder) const { 63 64 using namespace TargetOpcode; 65 66 MIRBuilder.setInstr(MI); 67 68 switch (MI.getOpcode()) { 69 case G_ADD: { 70 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 71 72 const LLT sHalf = LLT::scalar(Size / 2); 73 74 unsigned RHSLow = MRI.createGenericVirtualRegister(sHalf); 75 unsigned RHSHigh = MRI.createGenericVirtualRegister(sHalf); 76 unsigned LHSLow = MRI.createGenericVirtualRegister(sHalf); 77 unsigned LHSHigh = MRI.createGenericVirtualRegister(sHalf); 78 unsigned ResLow = MRI.createGenericVirtualRegister(sHalf); 79 unsigned ResHigh = MRI.createGenericVirtualRegister(sHalf); 80 unsigned Carry = MRI.createGenericVirtualRegister(sHalf); 81 unsigned TmpResHigh = MRI.createGenericVirtualRegister(sHalf); 82 83 MIRBuilder.buildUnmerge({RHSHigh, RHSLow}, MI.getOperand(2).getReg()); 84 MIRBuilder.buildUnmerge({LHSHigh, LHSLow}, MI.getOperand(1).getReg()); 85 86 MIRBuilder.buildAdd(TmpResHigh, LHSHigh, RHSHigh); 87 MIRBuilder.buildAdd(ResLow, LHSLow, RHSLow); 88 MIRBuilder.buildICmp(CmpInst::ICMP_ULT, Carry, ResLow, LHSLow); 89 MIRBuilder.buildAdd(ResHigh, TmpResHigh, Carry); 90 91 MIRBuilder.buildMerge(MI.getOperand(0).getReg(), {ResHigh, ResLow}); 92 93 MI.eraseFromParent(); 94 break; 95 } 96 case G_CONSTANT: { 97 98 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 99 const LLT sHalf = LLT::scalar(Size / 2); 100 101 const APInt &CImmValue = MI.getOperand(1).getCImm()->getValue(); 102 103 unsigned ResLow = MRI.createGenericVirtualRegister(sHalf); 104 unsigned ResHigh = MRI.createGenericVirtualRegister(sHalf); 105 MIRBuilder.buildConstant( 106 ResLow, *ConstantInt::get(MI.getMF()->getFunction().getContext(), 107 CImmValue.trunc(Size / 2))); 108 MIRBuilder.buildConstant( 109 ResHigh, *ConstantInt::get(MI.getMF()->getFunction().getContext(), 110 CImmValue.lshr(Size / 2).trunc(Size / 2))); 111 112 MIRBuilder.buildMerge(MI.getOperand(0).getReg(), {ResHigh, ResLow}); 113 114 MI.eraseFromParent(); 115 break; 116 } 117 default: 118 return false; 119 } 120 121 return true; 122 } 123