1 //===- MipsLegalizerInfo.cpp ------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// This file implements the targeting of the Machinelegalizer class for Mips.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
14 #include "MipsLegalizerInfo.h"
15 #include "MipsTargetMachine.h"
16 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
20 MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget
&ST
) {
21 using namespace TargetOpcode
;
23 const LLT s32
= LLT::scalar(32);
24 const LLT s64
= LLT::scalar(64);
25 const LLT p0
= LLT::pointer(0, 32);
27 getActionDefinitionsBuilder(G_ADD
)
32 getActionDefinitionsBuilder({G_LOAD
, G_STORE
})
33 .legalForCartesianProduct({p0
, s32
}, {p0
});
35 getActionDefinitionsBuilder({G_AND
, G_OR
, G_XOR
, G_SHL
, G_ASHR
, G_LSHR
})
38 getActionDefinitionsBuilder(G_ICMP
)
39 .legalFor({{s32
, s32
}})
42 getActionDefinitionsBuilder(G_CONSTANT
)
47 getActionDefinitionsBuilder(G_GEP
)
48 .legalFor({{p0
, s32
}});
50 getActionDefinitionsBuilder(G_FRAME_INDEX
)
53 getActionDefinitionsBuilder(G_GLOBAL_VALUE
)
57 verify(*ST
.getInstrInfo());
60 bool MipsLegalizerInfo::legalizeCustom(MachineInstr
&MI
,
61 MachineRegisterInfo
&MRI
,
62 MachineIRBuilder
&MIRBuilder
) const {
64 using namespace TargetOpcode
;
66 MIRBuilder
.setInstr(MI
);
68 switch (MI
.getOpcode()) {
70 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
72 const LLT sHalf
= LLT::scalar(Size
/ 2);
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
);
83 MIRBuilder
.buildUnmerge({RHSLow
, RHSHigh
}, MI
.getOperand(2).getReg());
84 MIRBuilder
.buildUnmerge({LHSLow
, LHSHigh
}, MI
.getOperand(1).getReg());
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
);
91 MIRBuilder
.buildMerge(MI
.getOperand(0).getReg(), {ResLow
, ResHigh
});
98 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
99 const LLT sHalf
= LLT::scalar(Size
/ 2);
101 const APInt
&CImmValue
= MI
.getOperand(1).getCImm()->getValue();
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)));
112 MIRBuilder
.buildMerge(MI
.getOperand(0).getReg(), {ResLow
, ResHigh
});
114 MI
.eraseFromParent();