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 .clampScalar(0, s32, s32); 45 46 getActionDefinitionsBuilder(G_GEP) 47 .legalFor({{p0, s32}}); 48 49 getActionDefinitionsBuilder(G_FRAME_INDEX) 50 .legalFor({p0}); 51 52 getActionDefinitionsBuilder(G_GLOBAL_VALUE) 53 .legalFor({p0}); 54 55 computeTables(); 56 verify(*ST.getInstrInfo()); 57 } 58 59 bool MipsLegalizerInfo::legalizeCustom(MachineInstr &MI, 60 MachineRegisterInfo &MRI, 61 MachineIRBuilder &MIRBuilder) const { 62 63 using namespace TargetOpcode; 64 65 MIRBuilder.setInstr(MI); 66 67 switch (MI.getOpcode()) { 68 case G_ADD: { 69 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 70 71 const LLT sHalf = LLT::scalar(Size / 2); 72 73 unsigned RHSLow = MRI.createGenericVirtualRegister(sHalf); 74 unsigned RHSHigh = MRI.createGenericVirtualRegister(sHalf); 75 unsigned LHSLow = MRI.createGenericVirtualRegister(sHalf); 76 unsigned LHSHigh = MRI.createGenericVirtualRegister(sHalf); 77 unsigned ResLow = MRI.createGenericVirtualRegister(sHalf); 78 unsigned ResHigh = MRI.createGenericVirtualRegister(sHalf); 79 unsigned Carry = MRI.createGenericVirtualRegister(sHalf); 80 unsigned TmpResHigh = MRI.createGenericVirtualRegister(sHalf); 81 82 MIRBuilder.buildUnmerge({RHSLow, RHSHigh}, MI.getOperand(2).getReg()); 83 MIRBuilder.buildUnmerge({LHSLow, LHSHigh}, MI.getOperand(1).getReg()); 84 85 MIRBuilder.buildAdd(TmpResHigh, LHSHigh, RHSHigh); 86 MIRBuilder.buildAdd(ResLow, LHSLow, RHSLow); 87 MIRBuilder.buildICmp(CmpInst::ICMP_ULT, Carry, ResLow, LHSLow); 88 MIRBuilder.buildAdd(ResHigh, TmpResHigh, Carry); 89 90 MIRBuilder.buildMerge(MI.getOperand(0).getReg(), {ResLow, ResHigh}); 91 92 MI.eraseFromParent(); 93 break; 94 } 95 default: 96 return false; 97 } 98 99 return true; 100 } 101