100 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
//===- MipsLegalizerInfo.cpp ------------------------------------*- C++ -*-===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
/// \file
 | 
						|
/// This file implements the targeting of the Machinelegalizer class for Mips.
 | 
						|
/// \todo This should be generated by TableGen.
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "MipsLegalizerInfo.h"
 | 
						|
#include "MipsTargetMachine.h"
 | 
						|
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
 | 
						|
 | 
						|
using namespace llvm;
 | 
						|
 | 
						|
MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
 | 
						|
  using namespace TargetOpcode;
 | 
						|
 | 
						|
  const LLT s32 = LLT::scalar(32);
 | 
						|
  const LLT s64 = LLT::scalar(64);
 | 
						|
  const LLT p0 = LLT::pointer(0, 32);
 | 
						|
 | 
						|
  getActionDefinitionsBuilder(G_ADD)
 | 
						|
      .legalFor({s32})
 | 
						|
      .minScalar(0, s32)
 | 
						|
      .customFor({s64});
 | 
						|
 | 
						|
  getActionDefinitionsBuilder({G_LOAD, G_STORE})
 | 
						|
      .legalForCartesianProduct({p0, s32}, {p0});
 | 
						|
 | 
						|
  getActionDefinitionsBuilder({G_AND, G_OR, G_XOR, G_SHL, G_ASHR, G_LSHR})
 | 
						|
      .legalFor({s32});
 | 
						|
 | 
						|
  getActionDefinitionsBuilder(G_ICMP)
 | 
						|
      .legalFor({{s32, s32}})
 | 
						|
      .minScalar(0, s32);
 | 
						|
 | 
						|
  getActionDefinitionsBuilder(G_CONSTANT)
 | 
						|
      .legalFor({s32});
 | 
						|
 | 
						|
  getActionDefinitionsBuilder(G_GEP)
 | 
						|
      .legalFor({{p0, s32}});
 | 
						|
 | 
						|
  getActionDefinitionsBuilder(G_FRAME_INDEX)
 | 
						|
      .legalFor({p0});
 | 
						|
 | 
						|
  getActionDefinitionsBuilder(G_GLOBAL_VALUE)
 | 
						|
      .legalFor({p0});
 | 
						|
 | 
						|
  computeTables();
 | 
						|
  verify(*ST.getInstrInfo());
 | 
						|
}
 | 
						|
 | 
						|
bool MipsLegalizerInfo::legalizeCustom(MachineInstr &MI,
 | 
						|
                                       MachineRegisterInfo &MRI,
 | 
						|
                                       MachineIRBuilder &MIRBuilder) const {
 | 
						|
 | 
						|
  using namespace TargetOpcode;
 | 
						|
 | 
						|
  MIRBuilder.setInstr(MI);
 | 
						|
 | 
						|
  switch (MI.getOpcode()) {
 | 
						|
  case G_ADD: {
 | 
						|
    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
 | 
						|
 | 
						|
    const LLT sHalf = LLT::scalar(Size / 2);
 | 
						|
 | 
						|
    unsigned RHSLow = MRI.createGenericVirtualRegister(sHalf);
 | 
						|
    unsigned RHSHigh = MRI.createGenericVirtualRegister(sHalf);
 | 
						|
    unsigned LHSLow = MRI.createGenericVirtualRegister(sHalf);
 | 
						|
    unsigned LHSHigh = MRI.createGenericVirtualRegister(sHalf);
 | 
						|
    unsigned ResLow = MRI.createGenericVirtualRegister(sHalf);
 | 
						|
    unsigned ResHigh = MRI.createGenericVirtualRegister(sHalf);
 | 
						|
    unsigned Carry = MRI.createGenericVirtualRegister(sHalf);
 | 
						|
    unsigned TmpResHigh = MRI.createGenericVirtualRegister(sHalf);
 | 
						|
 | 
						|
    MIRBuilder.buildUnmerge({RHSHigh, RHSLow}, MI.getOperand(2).getReg());
 | 
						|
    MIRBuilder.buildUnmerge({LHSHigh, LHSLow}, MI.getOperand(1).getReg());
 | 
						|
 | 
						|
    MIRBuilder.buildAdd(TmpResHigh, LHSHigh, RHSHigh);
 | 
						|
    MIRBuilder.buildAdd(ResLow, LHSLow, RHSLow);
 | 
						|
    MIRBuilder.buildICmp(CmpInst::ICMP_ULT, Carry, ResLow, LHSLow);
 | 
						|
    MIRBuilder.buildAdd(ResHigh, TmpResHigh, Carry);
 | 
						|
 | 
						|
    MIRBuilder.buildMerge(MI.getOperand(0).getReg(), {ResHigh, ResLow});
 | 
						|
 | 
						|
    MI.eraseFromParent();
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  default:
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 |