xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceTargetLoweringMIPS32.h (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceTargetLoweringMIPS32.h - MIPS32 lowering ---*- C++-*-===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker //                        The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker ///
10*03ce13f7SAndroid Build Coastguard Worker /// \file
11*03ce13f7SAndroid Build Coastguard Worker /// \brief Declares the TargetLoweringMIPS32 class, which implements the
12*03ce13f7SAndroid Build Coastguard Worker /// TargetLowering interface for the MIPS 32-bit architecture.
13*03ce13f7SAndroid Build Coastguard Worker ///
14*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*03ce13f7SAndroid Build Coastguard Worker 
16*03ce13f7SAndroid Build Coastguard Worker #ifndef SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H
17*03ce13f7SAndroid Build Coastguard Worker #define SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H
18*03ce13f7SAndroid Build Coastguard Worker 
19*03ce13f7SAndroid Build Coastguard Worker #include "IceAssemblerMIPS32.h"
20*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h"
21*03ce13f7SAndroid Build Coastguard Worker #include "IceInstMIPS32.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "IceRegistersMIPS32.h"
23*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLowering.h"
24*03ce13f7SAndroid Build Coastguard Worker 
25*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
26*03ce13f7SAndroid Build Coastguard Worker namespace MIPS32 {
27*03ce13f7SAndroid Build Coastguard Worker 
28*03ce13f7SAndroid Build Coastguard Worker class TargetMIPS32 : public TargetLowering {
29*03ce13f7SAndroid Build Coastguard Worker   TargetMIPS32() = delete;
30*03ce13f7SAndroid Build Coastguard Worker   TargetMIPS32(const TargetMIPS32 &) = delete;
31*03ce13f7SAndroid Build Coastguard Worker   TargetMIPS32 &operator=(const TargetMIPS32 &) = delete;
32*03ce13f7SAndroid Build Coastguard Worker 
33*03ce13f7SAndroid Build Coastguard Worker public:
34*03ce13f7SAndroid Build Coastguard Worker   ~TargetMIPS32() override = default;
35*03ce13f7SAndroid Build Coastguard Worker 
36*03ce13f7SAndroid Build Coastguard Worker   static void staticInit(GlobalContext *Ctx);
shouldBePooled(const Constant * C)37*03ce13f7SAndroid Build Coastguard Worker   static bool shouldBePooled(const Constant *C) {
38*03ce13f7SAndroid Build Coastguard Worker     if (auto *ConstDouble = llvm::dyn_cast<ConstantDouble>(C)) {
39*03ce13f7SAndroid Build Coastguard Worker       return !Utils::isPositiveZero(ConstDouble->getValue());
40*03ce13f7SAndroid Build Coastguard Worker     }
41*03ce13f7SAndroid Build Coastguard Worker     if (auto *ConstFloat = llvm::dyn_cast<ConstantFloat>(C)) {
42*03ce13f7SAndroid Build Coastguard Worker       return !Utils::isPositiveZero(ConstFloat->getValue());
43*03ce13f7SAndroid Build Coastguard Worker     }
44*03ce13f7SAndroid Build Coastguard Worker     return false;
45*03ce13f7SAndroid Build Coastguard Worker   }
getPointerType()46*03ce13f7SAndroid Build Coastguard Worker   static ::Ice::Type getPointerType() { return ::Ice::IceType_i32; }
create(Cfg * Func)47*03ce13f7SAndroid Build Coastguard Worker   static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) {
48*03ce13f7SAndroid Build Coastguard Worker     return makeUnique<TargetMIPS32>(Func);
49*03ce13f7SAndroid Build Coastguard Worker   }
50*03ce13f7SAndroid Build Coastguard Worker 
createAssembler()51*03ce13f7SAndroid Build Coastguard Worker   std::unique_ptr<::Ice::Assembler> createAssembler() const override {
52*03ce13f7SAndroid Build Coastguard Worker     return makeUnique<MIPS32::AssemblerMIPS32>();
53*03ce13f7SAndroid Build Coastguard Worker   }
54*03ce13f7SAndroid Build Coastguard Worker 
initNodeForLowering(CfgNode * Node)55*03ce13f7SAndroid Build Coastguard Worker   void initNodeForLowering(CfgNode *Node) override {
56*03ce13f7SAndroid Build Coastguard Worker     Computations.forgetProducers();
57*03ce13f7SAndroid Build Coastguard Worker     Computations.recordProducers(Node);
58*03ce13f7SAndroid Build Coastguard Worker     Computations.dump(Func);
59*03ce13f7SAndroid Build Coastguard Worker   }
60*03ce13f7SAndroid Build Coastguard Worker 
61*03ce13f7SAndroid Build Coastguard Worker   void translateOm1() override;
62*03ce13f7SAndroid Build Coastguard Worker   void translateO2() override;
63*03ce13f7SAndroid Build Coastguard Worker   bool doBranchOpt(Inst *Instr, const CfgNode *NextNode) override;
setImplicitRet(Variable * Ret)64*03ce13f7SAndroid Build Coastguard Worker   void setImplicitRet(Variable *Ret) { ImplicitRet = Ret; }
getImplicitRet()65*03ce13f7SAndroid Build Coastguard Worker   Variable *getImplicitRet() const { return ImplicitRet; }
getNumRegisters()66*03ce13f7SAndroid Build Coastguard Worker   SizeT getNumRegisters() const override { return RegMIPS32::Reg_NUM; }
67*03ce13f7SAndroid Build Coastguard Worker   Variable *getPhysicalRegister(RegNumT RegNum,
68*03ce13f7SAndroid Build Coastguard Worker                                 Type Ty = IceType_void) override;
69*03ce13f7SAndroid Build Coastguard Worker   const char *getRegName(RegNumT RegNum, Type Ty) const override;
70*03ce13f7SAndroid Build Coastguard Worker   SmallBitVector getRegisterSet(RegSetMask Include,
71*03ce13f7SAndroid Build Coastguard Worker                                 RegSetMask Exclude) const override;
72*03ce13f7SAndroid Build Coastguard Worker   const SmallBitVector &
getRegistersForVariable(const Variable * Var)73*03ce13f7SAndroid Build Coastguard Worker   getRegistersForVariable(const Variable *Var) const override {
74*03ce13f7SAndroid Build Coastguard Worker     RegClass RC = Var->getRegClass();
75*03ce13f7SAndroid Build Coastguard Worker     assert(RC < RC_Target);
76*03ce13f7SAndroid Build Coastguard Worker     return TypeToRegisterSet[RC];
77*03ce13f7SAndroid Build Coastguard Worker   }
78*03ce13f7SAndroid Build Coastguard Worker   const SmallBitVector &
getAllRegistersForVariable(const Variable * Var)79*03ce13f7SAndroid Build Coastguard Worker   getAllRegistersForVariable(const Variable *Var) const override {
80*03ce13f7SAndroid Build Coastguard Worker     RegClass RC = Var->getRegClass();
81*03ce13f7SAndroid Build Coastguard Worker     assert(RC < RC_Target);
82*03ce13f7SAndroid Build Coastguard Worker     return TypeToRegisterSetUnfiltered[RC];
83*03ce13f7SAndroid Build Coastguard Worker   }
getAliasesForRegister(RegNumT Reg)84*03ce13f7SAndroid Build Coastguard Worker   const SmallBitVector &getAliasesForRegister(RegNumT Reg) const override {
85*03ce13f7SAndroid Build Coastguard Worker     return RegisterAliases[Reg];
86*03ce13f7SAndroid Build Coastguard Worker   }
hasFramePointer()87*03ce13f7SAndroid Build Coastguard Worker   bool hasFramePointer() const override { return UsesFramePointer; }
setHasFramePointer()88*03ce13f7SAndroid Build Coastguard Worker   void setHasFramePointer() override { UsesFramePointer = true; }
getStackReg()89*03ce13f7SAndroid Build Coastguard Worker   RegNumT getStackReg() const override { return RegMIPS32::Reg_SP; }
getFrameReg()90*03ce13f7SAndroid Build Coastguard Worker   RegNumT getFrameReg() const override { return RegMIPS32::Reg_FP; }
getFrameOrStackReg()91*03ce13f7SAndroid Build Coastguard Worker   RegNumT getFrameOrStackReg() const override {
92*03ce13f7SAndroid Build Coastguard Worker     return UsesFramePointer ? getFrameReg() : getStackReg();
93*03ce13f7SAndroid Build Coastguard Worker   }
getReservedTmpReg()94*03ce13f7SAndroid Build Coastguard Worker   RegNumT getReservedTmpReg() const { return RegMIPS32::Reg_AT; }
typeWidthInBytesOnStack(Type Ty)95*03ce13f7SAndroid Build Coastguard Worker   size_t typeWidthInBytesOnStack(Type Ty) const override {
96*03ce13f7SAndroid Build Coastguard Worker     // Round up to the next multiple of 4 bytes. In particular, i1, i8, and i16
97*03ce13f7SAndroid Build Coastguard Worker     // are rounded up to 4 bytes.
98*03ce13f7SAndroid Build Coastguard Worker     return (typeWidthInBytes(Ty) + 3) & ~3;
99*03ce13f7SAndroid Build Coastguard Worker   }
100*03ce13f7SAndroid Build Coastguard Worker   uint32_t getStackAlignment() const override;
reserveFixedAllocaArea(size_t Size,size_t Align)101*03ce13f7SAndroid Build Coastguard Worker   void reserveFixedAllocaArea(size_t Size, size_t Align) override {
102*03ce13f7SAndroid Build Coastguard Worker     FixedAllocaSizeBytes = Size;
103*03ce13f7SAndroid Build Coastguard Worker     assert(llvm::isPowerOf2_32(Align));
104*03ce13f7SAndroid Build Coastguard Worker     FixedAllocaAlignBytes = Align;
105*03ce13f7SAndroid Build Coastguard Worker     PrologEmitsFixedAllocas = true;
106*03ce13f7SAndroid Build Coastguard Worker   }
getFrameFixedAllocaOffset()107*03ce13f7SAndroid Build Coastguard Worker   int32_t getFrameFixedAllocaOffset() const override {
108*03ce13f7SAndroid Build Coastguard Worker     int32_t FixedAllocaOffset =
109*03ce13f7SAndroid Build Coastguard Worker         Utils::applyAlignment(CurrentAllocaOffset, FixedAllocaAlignBytes);
110*03ce13f7SAndroid Build Coastguard Worker     return FixedAllocaOffset - MaxOutArgsSizeBytes;
111*03ce13f7SAndroid Build Coastguard Worker   }
112*03ce13f7SAndroid Build Coastguard Worker 
maxOutArgsSizeBytes()113*03ce13f7SAndroid Build Coastguard Worker   uint32_t maxOutArgsSizeBytes() const override { return MaxOutArgsSizeBytes; }
114*03ce13f7SAndroid Build Coastguard Worker 
getFramePointerOffset(uint32_t CurrentOffset,uint32_t Size)115*03ce13f7SAndroid Build Coastguard Worker   uint32_t getFramePointerOffset(uint32_t CurrentOffset,
116*03ce13f7SAndroid Build Coastguard Worker                                  uint32_t Size) const override {
117*03ce13f7SAndroid Build Coastguard Worker     (void)Size;
118*03ce13f7SAndroid Build Coastguard Worker     return CurrentOffset + MaxOutArgsSizeBytes;
119*03ce13f7SAndroid Build Coastguard Worker   }
120*03ce13f7SAndroid Build Coastguard Worker 
shouldSplitToVariable64On32(Type Ty)121*03ce13f7SAndroid Build Coastguard Worker   bool shouldSplitToVariable64On32(Type Ty) const override {
122*03ce13f7SAndroid Build Coastguard Worker     return Ty == IceType_i64;
123*03ce13f7SAndroid Build Coastguard Worker   }
124*03ce13f7SAndroid Build Coastguard Worker 
shouldSplitToVariableVecOn32(Type Ty)125*03ce13f7SAndroid Build Coastguard Worker   bool shouldSplitToVariableVecOn32(Type Ty) const override {
126*03ce13f7SAndroid Build Coastguard Worker     return isVectorType(Ty);
127*03ce13f7SAndroid Build Coastguard Worker   }
128*03ce13f7SAndroid Build Coastguard Worker 
129*03ce13f7SAndroid Build Coastguard Worker   // TODO(ascull): what is the best size of MIPS?
getMinJumpTableSize()130*03ce13f7SAndroid Build Coastguard Worker   SizeT getMinJumpTableSize() const override { return 3; }
131*03ce13f7SAndroid Build Coastguard Worker   void emitJumpTable(const Cfg *Func,
132*03ce13f7SAndroid Build Coastguard Worker                      const InstJumpTable *JumpTable) const override;
133*03ce13f7SAndroid Build Coastguard Worker 
134*03ce13f7SAndroid Build Coastguard Worker   void emitVariable(const Variable *Var) const override;
135*03ce13f7SAndroid Build Coastguard Worker 
emit(const ConstantInteger32 * C)136*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantInteger32 *C) const final {
137*03ce13f7SAndroid Build Coastguard Worker     if (!BuildDefs::dump())
138*03ce13f7SAndroid Build Coastguard Worker       return;
139*03ce13f7SAndroid Build Coastguard Worker     Ostream &Str = Ctx->getStrEmit();
140*03ce13f7SAndroid Build Coastguard Worker     Str << C->getValue();
141*03ce13f7SAndroid Build Coastguard Worker   }
emit(const ConstantInteger64 * C)142*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantInteger64 *C) const final {
143*03ce13f7SAndroid Build Coastguard Worker     (void)C;
144*03ce13f7SAndroid Build Coastguard Worker     llvm::report_fatal_error("Not yet implemented");
145*03ce13f7SAndroid Build Coastguard Worker   }
emit(const ConstantFloat * C)146*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantFloat *C) const final {
147*03ce13f7SAndroid Build Coastguard Worker     (void)C;
148*03ce13f7SAndroid Build Coastguard Worker     llvm::report_fatal_error("Not yet implemented");
149*03ce13f7SAndroid Build Coastguard Worker   }
emit(const ConstantDouble * C)150*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantDouble *C) const final {
151*03ce13f7SAndroid Build Coastguard Worker     (void)C;
152*03ce13f7SAndroid Build Coastguard Worker     llvm::report_fatal_error("Not yet implemented");
153*03ce13f7SAndroid Build Coastguard Worker   }
emit(const ConstantUndef * C)154*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantUndef *C) const final {
155*03ce13f7SAndroid Build Coastguard Worker     (void)C;
156*03ce13f7SAndroid Build Coastguard Worker     llvm::report_fatal_error("Not yet implemented");
157*03ce13f7SAndroid Build Coastguard Worker   }
emit(const ConstantRelocatable * C)158*03ce13f7SAndroid Build Coastguard Worker   void emit(const ConstantRelocatable *C) const final {
159*03ce13f7SAndroid Build Coastguard Worker     (void)C;
160*03ce13f7SAndroid Build Coastguard Worker     llvm::report_fatal_error("Not yet implemented");
161*03ce13f7SAndroid Build Coastguard Worker   }
162*03ce13f7SAndroid Build Coastguard Worker 
163*03ce13f7SAndroid Build Coastguard Worker   // The following are helpers that insert lowered MIPS32 instructions with
164*03ce13f7SAndroid Build Coastguard Worker   // minimal syntactic overhead, so that the lowering code can look as close to
165*03ce13f7SAndroid Build Coastguard Worker   // assembly as practical.
_add(Variable * Dest,Variable * Src0,Variable * Src1)166*03ce13f7SAndroid Build Coastguard Worker   void _add(Variable *Dest, Variable *Src0, Variable *Src1) {
167*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Add>(Dest, Src0, Src1);
168*03ce13f7SAndroid Build Coastguard Worker   }
169*03ce13f7SAndroid Build Coastguard Worker 
_addu(Variable * Dest,Variable * Src0,Variable * Src1)170*03ce13f7SAndroid Build Coastguard Worker   void _addu(Variable *Dest, Variable *Src0, Variable *Src1) {
171*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Addu>(Dest, Src0, Src1);
172*03ce13f7SAndroid Build Coastguard Worker   }
173*03ce13f7SAndroid Build Coastguard Worker 
_and(Variable * Dest,Variable * Src0,Variable * Src1)174*03ce13f7SAndroid Build Coastguard Worker   void _and(Variable *Dest, Variable *Src0, Variable *Src1) {
175*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32And>(Dest, Src0, Src1);
176*03ce13f7SAndroid Build Coastguard Worker   }
177*03ce13f7SAndroid Build Coastguard Worker 
_andi(Variable * Dest,Variable * Src,uint32_t Imm)178*03ce13f7SAndroid Build Coastguard Worker   void _andi(Variable *Dest, Variable *Src, uint32_t Imm) {
179*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Andi>(Dest, Src, Imm);
180*03ce13f7SAndroid Build Coastguard Worker   }
181*03ce13f7SAndroid Build Coastguard Worker 
_br(CfgNode * Target)182*03ce13f7SAndroid Build Coastguard Worker   void _br(CfgNode *Target) { Context.insert<InstMIPS32Br>(Target); }
183*03ce13f7SAndroid Build Coastguard Worker 
_br(CfgNode * Target,const InstMIPS32Label * Label)184*03ce13f7SAndroid Build Coastguard Worker   void _br(CfgNode *Target, const InstMIPS32Label *Label) {
185*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Br>(Target, Label);
186*03ce13f7SAndroid Build Coastguard Worker   }
187*03ce13f7SAndroid Build Coastguard Worker 
_br(CfgNode * TargetTrue,CfgNode * TargetFalse,Operand * Src0,Operand * Src1,CondMIPS32::Cond Condition)188*03ce13f7SAndroid Build Coastguard Worker   void _br(CfgNode *TargetTrue, CfgNode *TargetFalse, Operand *Src0,
189*03ce13f7SAndroid Build Coastguard Worker            Operand *Src1, CondMIPS32::Cond Condition) {
190*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Br>(TargetTrue, TargetFalse, Src0, Src1,
191*03ce13f7SAndroid Build Coastguard Worker                                  Condition);
192*03ce13f7SAndroid Build Coastguard Worker   }
193*03ce13f7SAndroid Build Coastguard Worker 
_br(CfgNode * TargetTrue,CfgNode * TargetFalse,Operand * Src0,CondMIPS32::Cond Condition)194*03ce13f7SAndroid Build Coastguard Worker   void _br(CfgNode *TargetTrue, CfgNode *TargetFalse, Operand *Src0,
195*03ce13f7SAndroid Build Coastguard Worker            CondMIPS32::Cond Condition) {
196*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Br>(TargetTrue, TargetFalse, Src0, Condition);
197*03ce13f7SAndroid Build Coastguard Worker   }
198*03ce13f7SAndroid Build Coastguard Worker 
_br(CfgNode * TargetTrue,CfgNode * TargetFalse,Operand * Src0,Operand * Src1,const InstMIPS32Label * Label,CondMIPS32::Cond Condition)199*03ce13f7SAndroid Build Coastguard Worker   void _br(CfgNode *TargetTrue, CfgNode *TargetFalse, Operand *Src0,
200*03ce13f7SAndroid Build Coastguard Worker            Operand *Src1, const InstMIPS32Label *Label,
201*03ce13f7SAndroid Build Coastguard Worker            CondMIPS32::Cond Condition) {
202*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Br>(TargetTrue, TargetFalse, Src0, Src1, Label,
203*03ce13f7SAndroid Build Coastguard Worker                                  Condition);
204*03ce13f7SAndroid Build Coastguard Worker   }
205*03ce13f7SAndroid Build Coastguard Worker 
206*03ce13f7SAndroid Build Coastguard Worker   void _ret(Variable *RA, Variable *Src0 = nullptr) {
207*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Ret>(RA, Src0);
208*03ce13f7SAndroid Build Coastguard Worker   }
209*03ce13f7SAndroid Build Coastguard Worker 
_abs_d(Variable * Dest,Variable * Src)210*03ce13f7SAndroid Build Coastguard Worker   void _abs_d(Variable *Dest, Variable *Src) {
211*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Abs_d>(Dest, Src);
212*03ce13f7SAndroid Build Coastguard Worker   }
213*03ce13f7SAndroid Build Coastguard Worker 
_abs_s(Variable * Dest,Variable * Src)214*03ce13f7SAndroid Build Coastguard Worker   void _abs_s(Variable *Dest, Variable *Src) {
215*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Abs_s>(Dest, Src);
216*03ce13f7SAndroid Build Coastguard Worker   }
217*03ce13f7SAndroid Build Coastguard Worker 
_addi(Variable * Dest,Variable * Src,uint32_t Imm)218*03ce13f7SAndroid Build Coastguard Worker   void _addi(Variable *Dest, Variable *Src, uint32_t Imm) {
219*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Addi>(Dest, Src, Imm);
220*03ce13f7SAndroid Build Coastguard Worker   }
221*03ce13f7SAndroid Build Coastguard Worker 
_add_d(Variable * Dest,Variable * Src0,Variable * Src1)222*03ce13f7SAndroid Build Coastguard Worker   void _add_d(Variable *Dest, Variable *Src0, Variable *Src1) {
223*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Add_d>(Dest, Src0, Src1);
224*03ce13f7SAndroid Build Coastguard Worker   }
225*03ce13f7SAndroid Build Coastguard Worker 
_add_s(Variable * Dest,Variable * Src0,Variable * Src1)226*03ce13f7SAndroid Build Coastguard Worker   void _add_s(Variable *Dest, Variable *Src0, Variable *Src1) {
227*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Add_s>(Dest, Src0, Src1);
228*03ce13f7SAndroid Build Coastguard Worker   }
229*03ce13f7SAndroid Build Coastguard Worker 
_addiu(Variable * Dest,Variable * Src,uint32_t Imm)230*03ce13f7SAndroid Build Coastguard Worker   void _addiu(Variable *Dest, Variable *Src, uint32_t Imm) {
231*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Addiu>(Dest, Src, Imm);
232*03ce13f7SAndroid Build Coastguard Worker   }
233*03ce13f7SAndroid Build Coastguard Worker 
_addiu(Variable * Dest,Variable * Src0,Operand * Src1,RelocOp Reloc)234*03ce13f7SAndroid Build Coastguard Worker   void _addiu(Variable *Dest, Variable *Src0, Operand *Src1, RelocOp Reloc) {
235*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Addiu>(Dest, Src0, Src1, Reloc);
236*03ce13f7SAndroid Build Coastguard Worker   }
237*03ce13f7SAndroid Build Coastguard Worker 
_c_eq_d(Variable * Src0,Variable * Src1)238*03ce13f7SAndroid Build Coastguard Worker   void _c_eq_d(Variable *Src0, Variable *Src1) {
239*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_eq_d>(Src0, Src1);
240*03ce13f7SAndroid Build Coastguard Worker   }
241*03ce13f7SAndroid Build Coastguard Worker 
_c_eq_s(Variable * Src0,Variable * Src1)242*03ce13f7SAndroid Build Coastguard Worker   void _c_eq_s(Variable *Src0, Variable *Src1) {
243*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_eq_s>(Src0, Src1);
244*03ce13f7SAndroid Build Coastguard Worker   }
245*03ce13f7SAndroid Build Coastguard Worker 
_c_ole_d(Variable * Src0,Variable * Src1)246*03ce13f7SAndroid Build Coastguard Worker   void _c_ole_d(Variable *Src0, Variable *Src1) {
247*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_ole_d>(Src0, Src1);
248*03ce13f7SAndroid Build Coastguard Worker   }
249*03ce13f7SAndroid Build Coastguard Worker 
_c_ole_s(Variable * Src0,Variable * Src1)250*03ce13f7SAndroid Build Coastguard Worker   void _c_ole_s(Variable *Src0, Variable *Src1) {
251*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_ole_s>(Src0, Src1);
252*03ce13f7SAndroid Build Coastguard Worker   }
253*03ce13f7SAndroid Build Coastguard Worker 
_c_olt_d(Variable * Src0,Variable * Src1)254*03ce13f7SAndroid Build Coastguard Worker   void _c_olt_d(Variable *Src0, Variable *Src1) {
255*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_olt_d>(Src0, Src1);
256*03ce13f7SAndroid Build Coastguard Worker   }
257*03ce13f7SAndroid Build Coastguard Worker 
_c_olt_s(Variable * Src0,Variable * Src1)258*03ce13f7SAndroid Build Coastguard Worker   void _c_olt_s(Variable *Src0, Variable *Src1) {
259*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_olt_s>(Src0, Src1);
260*03ce13f7SAndroid Build Coastguard Worker   }
261*03ce13f7SAndroid Build Coastguard Worker 
_c_ueq_d(Variable * Src0,Variable * Src1)262*03ce13f7SAndroid Build Coastguard Worker   void _c_ueq_d(Variable *Src0, Variable *Src1) {
263*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_ueq_d>(Src0, Src1);
264*03ce13f7SAndroid Build Coastguard Worker   }
265*03ce13f7SAndroid Build Coastguard Worker 
_c_ueq_s(Variable * Src0,Variable * Src1)266*03ce13f7SAndroid Build Coastguard Worker   void _c_ueq_s(Variable *Src0, Variable *Src1) {
267*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_ueq_s>(Src0, Src1);
268*03ce13f7SAndroid Build Coastguard Worker   }
269*03ce13f7SAndroid Build Coastguard Worker 
_c_ule_d(Variable * Src0,Variable * Src1)270*03ce13f7SAndroid Build Coastguard Worker   void _c_ule_d(Variable *Src0, Variable *Src1) {
271*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_ule_d>(Src0, Src1);
272*03ce13f7SAndroid Build Coastguard Worker   }
273*03ce13f7SAndroid Build Coastguard Worker 
_c_ule_s(Variable * Src0,Variable * Src1)274*03ce13f7SAndroid Build Coastguard Worker   void _c_ule_s(Variable *Src0, Variable *Src1) {
275*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_ule_s>(Src0, Src1);
276*03ce13f7SAndroid Build Coastguard Worker   }
277*03ce13f7SAndroid Build Coastguard Worker 
_c_ult_d(Variable * Src0,Variable * Src1)278*03ce13f7SAndroid Build Coastguard Worker   void _c_ult_d(Variable *Src0, Variable *Src1) {
279*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_ult_d>(Src0, Src1);
280*03ce13f7SAndroid Build Coastguard Worker   }
281*03ce13f7SAndroid Build Coastguard Worker 
_c_ult_s(Variable * Src0,Variable * Src1)282*03ce13f7SAndroid Build Coastguard Worker   void _c_ult_s(Variable *Src0, Variable *Src1) {
283*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_ult_s>(Src0, Src1);
284*03ce13f7SAndroid Build Coastguard Worker   }
285*03ce13f7SAndroid Build Coastguard Worker 
_c_un_d(Variable * Src0,Variable * Src1)286*03ce13f7SAndroid Build Coastguard Worker   void _c_un_d(Variable *Src0, Variable *Src1) {
287*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_un_d>(Src0, Src1);
288*03ce13f7SAndroid Build Coastguard Worker   }
289*03ce13f7SAndroid Build Coastguard Worker 
_c_un_s(Variable * Src0,Variable * Src1)290*03ce13f7SAndroid Build Coastguard Worker   void _c_un_s(Variable *Src0, Variable *Src1) {
291*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32C_un_s>(Src0, Src1);
292*03ce13f7SAndroid Build Coastguard Worker   }
293*03ce13f7SAndroid Build Coastguard Worker 
_clz(Variable * Dest,Variable * Src)294*03ce13f7SAndroid Build Coastguard Worker   void _clz(Variable *Dest, Variable *Src) {
295*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Clz>(Dest, Src);
296*03ce13f7SAndroid Build Coastguard Worker   }
297*03ce13f7SAndroid Build Coastguard Worker 
_cvt_d_l(Variable * Dest,Variable * Src)298*03ce13f7SAndroid Build Coastguard Worker   void _cvt_d_l(Variable *Dest, Variable *Src) {
299*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Cvt_d_l>(Dest, Src);
300*03ce13f7SAndroid Build Coastguard Worker   }
301*03ce13f7SAndroid Build Coastguard Worker 
_cvt_d_s(Variable * Dest,Variable * Src)302*03ce13f7SAndroid Build Coastguard Worker   void _cvt_d_s(Variable *Dest, Variable *Src) {
303*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Cvt_d_s>(Dest, Src);
304*03ce13f7SAndroid Build Coastguard Worker   }
305*03ce13f7SAndroid Build Coastguard Worker 
_cvt_d_w(Variable * Dest,Variable * Src)306*03ce13f7SAndroid Build Coastguard Worker   void _cvt_d_w(Variable *Dest, Variable *Src) {
307*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Cvt_d_w>(Dest, Src);
308*03ce13f7SAndroid Build Coastguard Worker   }
309*03ce13f7SAndroid Build Coastguard Worker 
_cvt_s_d(Variable * Dest,Variable * Src)310*03ce13f7SAndroid Build Coastguard Worker   void _cvt_s_d(Variable *Dest, Variable *Src) {
311*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Cvt_s_d>(Dest, Src);
312*03ce13f7SAndroid Build Coastguard Worker   }
313*03ce13f7SAndroid Build Coastguard Worker 
_cvt_s_l(Variable * Dest,Variable * Src)314*03ce13f7SAndroid Build Coastguard Worker   void _cvt_s_l(Variable *Dest, Variable *Src) {
315*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Cvt_s_l>(Dest, Src);
316*03ce13f7SAndroid Build Coastguard Worker   }
317*03ce13f7SAndroid Build Coastguard Worker 
_cvt_s_w(Variable * Dest,Variable * Src)318*03ce13f7SAndroid Build Coastguard Worker   void _cvt_s_w(Variable *Dest, Variable *Src) {
319*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Cvt_s_w>(Dest, Src);
320*03ce13f7SAndroid Build Coastguard Worker   }
321*03ce13f7SAndroid Build Coastguard Worker 
_div(Variable * Dest,Variable * Src0,Variable * Src1)322*03ce13f7SAndroid Build Coastguard Worker   void _div(Variable *Dest, Variable *Src0, Variable *Src1) {
323*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Div>(Dest, Src0, Src1);
324*03ce13f7SAndroid Build Coastguard Worker   }
325*03ce13f7SAndroid Build Coastguard Worker 
_div_d(Variable * Dest,Variable * Src0,Variable * Src1)326*03ce13f7SAndroid Build Coastguard Worker   void _div_d(Variable *Dest, Variable *Src0, Variable *Src1) {
327*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Div_d>(Dest, Src0, Src1);
328*03ce13f7SAndroid Build Coastguard Worker   }
329*03ce13f7SAndroid Build Coastguard Worker 
_div_s(Variable * Dest,Variable * Src0,Variable * Src1)330*03ce13f7SAndroid Build Coastguard Worker   void _div_s(Variable *Dest, Variable *Src0, Variable *Src1) {
331*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Div_s>(Dest, Src0, Src1);
332*03ce13f7SAndroid Build Coastguard Worker   }
333*03ce13f7SAndroid Build Coastguard Worker 
_divu(Variable * Dest,Variable * Src0,Variable * Src1)334*03ce13f7SAndroid Build Coastguard Worker   void _divu(Variable *Dest, Variable *Src0, Variable *Src1) {
335*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Divu>(Dest, Src0, Src1);
336*03ce13f7SAndroid Build Coastguard Worker   }
337*03ce13f7SAndroid Build Coastguard Worker 
338*03ce13f7SAndroid Build Coastguard Worker   void _ldc1(Variable *Value, OperandMIPS32Mem *Mem, RelocOp Reloc = RO_No) {
339*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Ldc1>(Value, Mem, Reloc);
340*03ce13f7SAndroid Build Coastguard Worker   }
341*03ce13f7SAndroid Build Coastguard Worker 
_ll(Variable * Value,OperandMIPS32Mem * Mem)342*03ce13f7SAndroid Build Coastguard Worker   void _ll(Variable *Value, OperandMIPS32Mem *Mem) {
343*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Ll>(Value, Mem);
344*03ce13f7SAndroid Build Coastguard Worker   }
345*03ce13f7SAndroid Build Coastguard Worker 
_lw(Variable * Value,OperandMIPS32Mem * Mem)346*03ce13f7SAndroid Build Coastguard Worker   void _lw(Variable *Value, OperandMIPS32Mem *Mem) {
347*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Lw>(Value, Mem);
348*03ce13f7SAndroid Build Coastguard Worker   }
349*03ce13f7SAndroid Build Coastguard Worker 
350*03ce13f7SAndroid Build Coastguard Worker   void _lwc1(Variable *Value, OperandMIPS32Mem *Mem, RelocOp Reloc = RO_No) {
351*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Lwc1>(Value, Mem, Reloc);
352*03ce13f7SAndroid Build Coastguard Worker   }
353*03ce13f7SAndroid Build Coastguard Worker 
354*03ce13f7SAndroid Build Coastguard Worker   void _lui(Variable *Dest, Operand *Src, RelocOp Reloc = RO_No) {
355*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Lui>(Dest, Src, Reloc);
356*03ce13f7SAndroid Build Coastguard Worker   }
357*03ce13f7SAndroid Build Coastguard Worker 
_mfc1(Variable * Dest,Variable * Src)358*03ce13f7SAndroid Build Coastguard Worker   void _mfc1(Variable *Dest, Variable *Src) {
359*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mfc1>(Dest, Src);
360*03ce13f7SAndroid Build Coastguard Worker   }
361*03ce13f7SAndroid Build Coastguard Worker 
_mfhi(Variable * Dest,Operand * Src)362*03ce13f7SAndroid Build Coastguard Worker   void _mfhi(Variable *Dest, Operand *Src) {
363*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mfhi>(Dest, Src);
364*03ce13f7SAndroid Build Coastguard Worker   }
365*03ce13f7SAndroid Build Coastguard Worker 
_mflo(Variable * Dest,Operand * Src)366*03ce13f7SAndroid Build Coastguard Worker   void _mflo(Variable *Dest, Operand *Src) {
367*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mflo>(Dest, Src);
368*03ce13f7SAndroid Build Coastguard Worker   }
369*03ce13f7SAndroid Build Coastguard Worker 
370*03ce13f7SAndroid Build Coastguard Worker   void _mov(Variable *Dest, Operand *Src0, Operand *Src1 = nullptr) {
371*03ce13f7SAndroid Build Coastguard Worker     assert(Dest != nullptr);
372*03ce13f7SAndroid Build Coastguard Worker     // Variable* Src0_ = llvm::dyn_cast<Variable>(Src0);
373*03ce13f7SAndroid Build Coastguard Worker     if (llvm::isa<ConstantRelocatable>(Src0)) {
374*03ce13f7SAndroid Build Coastguard Worker       Context.insert<InstMIPS32La>(Dest, Src0);
375*03ce13f7SAndroid Build Coastguard Worker     } else {
376*03ce13f7SAndroid Build Coastguard Worker       auto *Instr = Context.insert<InstMIPS32Mov>(Dest, Src0, Src1);
377*03ce13f7SAndroid Build Coastguard Worker       if (Instr->getDestHi() != nullptr) {
378*03ce13f7SAndroid Build Coastguard Worker         // If DestHi is available, then Dest must be a Variable64On32. We add a
379*03ce13f7SAndroid Build Coastguard Worker         // fake-def for Instr.DestHi here.
380*03ce13f7SAndroid Build Coastguard Worker         assert(llvm::isa<Variable64On32>(Dest));
381*03ce13f7SAndroid Build Coastguard Worker         Context.insert<InstFakeDef>(Instr->getDestHi());
382*03ce13f7SAndroid Build Coastguard Worker       }
383*03ce13f7SAndroid Build Coastguard Worker     }
384*03ce13f7SAndroid Build Coastguard Worker   }
385*03ce13f7SAndroid Build Coastguard Worker 
386*03ce13f7SAndroid Build Coastguard Worker   void _mov_redefined(Variable *Dest, Operand *Src0, Operand *Src1 = nullptr) {
387*03ce13f7SAndroid Build Coastguard Worker     if (llvm::isa<ConstantRelocatable>(Src0)) {
388*03ce13f7SAndroid Build Coastguard Worker       Context.insert<InstMIPS32La>(Dest, Src0);
389*03ce13f7SAndroid Build Coastguard Worker     } else {
390*03ce13f7SAndroid Build Coastguard Worker       auto *Instr = Context.insert<InstMIPS32Mov>(Dest, Src0, Src1);
391*03ce13f7SAndroid Build Coastguard Worker       Instr->setDestRedefined();
392*03ce13f7SAndroid Build Coastguard Worker       if (Instr->getDestHi() != nullptr) {
393*03ce13f7SAndroid Build Coastguard Worker         // If Instr is multi-dest, then Dest must be a Variable64On32. We add a
394*03ce13f7SAndroid Build Coastguard Worker         // fake-def for Instr.DestHi here.
395*03ce13f7SAndroid Build Coastguard Worker         assert(llvm::isa<Variable64On32>(Dest));
396*03ce13f7SAndroid Build Coastguard Worker         Context.insert<InstFakeDef>(Instr->getDestHi());
397*03ce13f7SAndroid Build Coastguard Worker       }
398*03ce13f7SAndroid Build Coastguard Worker     }
399*03ce13f7SAndroid Build Coastguard Worker   }
400*03ce13f7SAndroid Build Coastguard Worker 
_mov_fp64_to_i64(Variable * Dest,Operand * Src,Int64Part Int64HiLo)401*03ce13f7SAndroid Build Coastguard Worker   void _mov_fp64_to_i64(Variable *Dest, Operand *Src, Int64Part Int64HiLo) {
402*03ce13f7SAndroid Build Coastguard Worker     assert(Dest != nullptr);
403*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32MovFP64ToI64>(Dest, Src, Int64HiLo);
404*03ce13f7SAndroid Build Coastguard Worker   }
405*03ce13f7SAndroid Build Coastguard Worker 
_mov_d(Variable * Dest,Variable * Src)406*03ce13f7SAndroid Build Coastguard Worker   void _mov_d(Variable *Dest, Variable *Src) {
407*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mov_d>(Dest, Src);
408*03ce13f7SAndroid Build Coastguard Worker   }
409*03ce13f7SAndroid Build Coastguard Worker 
_mov_s(Variable * Dest,Variable * Src)410*03ce13f7SAndroid Build Coastguard Worker   void _mov_s(Variable *Dest, Variable *Src) {
411*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mov_s>(Dest, Src);
412*03ce13f7SAndroid Build Coastguard Worker   }
413*03ce13f7SAndroid Build Coastguard Worker 
_movf(Variable * Dest,Variable * Src0,Operand * FCC)414*03ce13f7SAndroid Build Coastguard Worker   void _movf(Variable *Dest, Variable *Src0, Operand *FCC) {
415*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Movf>(Dest, Src0, FCC)->setDestRedefined();
416*03ce13f7SAndroid Build Coastguard Worker   }
417*03ce13f7SAndroid Build Coastguard Worker 
_movn(Variable * Dest,Variable * Src0,Variable * Src1)418*03ce13f7SAndroid Build Coastguard Worker   void _movn(Variable *Dest, Variable *Src0, Variable *Src1) {
419*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Movn>(Dest, Src0, Src1)->setDestRedefined();
420*03ce13f7SAndroid Build Coastguard Worker   }
421*03ce13f7SAndroid Build Coastguard Worker 
_movn_d(Variable * Dest,Variable * Src0,Variable * Src1)422*03ce13f7SAndroid Build Coastguard Worker   void _movn_d(Variable *Dest, Variable *Src0, Variable *Src1) {
423*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Movn_d>(Dest, Src0, Src1)->setDestRedefined();
424*03ce13f7SAndroid Build Coastguard Worker   }
425*03ce13f7SAndroid Build Coastguard Worker 
_movn_s(Variable * Dest,Variable * Src0,Variable * Src1)426*03ce13f7SAndroid Build Coastguard Worker   void _movn_s(Variable *Dest, Variable *Src0, Variable *Src1) {
427*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Movn_s>(Dest, Src0, Src1)->setDestRedefined();
428*03ce13f7SAndroid Build Coastguard Worker   }
429*03ce13f7SAndroid Build Coastguard Worker 
_movt(Variable * Dest,Variable * Src0,Operand * FCC)430*03ce13f7SAndroid Build Coastguard Worker   void _movt(Variable *Dest, Variable *Src0, Operand *FCC) {
431*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Movt>(Dest, Src0, FCC)->setDestRedefined();
432*03ce13f7SAndroid Build Coastguard Worker   }
433*03ce13f7SAndroid Build Coastguard Worker 
_movz(Variable * Dest,Variable * Src0,Variable * Src1)434*03ce13f7SAndroid Build Coastguard Worker   void _movz(Variable *Dest, Variable *Src0, Variable *Src1) {
435*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Movz>(Dest, Src0, Src1)->setDestRedefined();
436*03ce13f7SAndroid Build Coastguard Worker   }
437*03ce13f7SAndroid Build Coastguard Worker 
_movz_d(Variable * Dest,Variable * Src0,Variable * Src1)438*03ce13f7SAndroid Build Coastguard Worker   void _movz_d(Variable *Dest, Variable *Src0, Variable *Src1) {
439*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Movz_d>(Dest, Src0, Src1)->setDestRedefined();
440*03ce13f7SAndroid Build Coastguard Worker   }
441*03ce13f7SAndroid Build Coastguard Worker 
_movz_s(Variable * Dest,Variable * Src0,Variable * Src1)442*03ce13f7SAndroid Build Coastguard Worker   void _movz_s(Variable *Dest, Variable *Src0, Variable *Src1) {
443*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Movz_s>(Dest, Src0, Src1)->setDestRedefined();
444*03ce13f7SAndroid Build Coastguard Worker   }
445*03ce13f7SAndroid Build Coastguard Worker 
_mtc1(Variable * Dest,Variable * Src)446*03ce13f7SAndroid Build Coastguard Worker   void _mtc1(Variable *Dest, Variable *Src) {
447*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mtc1>(Dest, Src);
448*03ce13f7SAndroid Build Coastguard Worker   }
449*03ce13f7SAndroid Build Coastguard Worker 
_mthi(Variable * Dest,Operand * Src)450*03ce13f7SAndroid Build Coastguard Worker   void _mthi(Variable *Dest, Operand *Src) {
451*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mthi>(Dest, Src);
452*03ce13f7SAndroid Build Coastguard Worker   }
453*03ce13f7SAndroid Build Coastguard Worker 
_mtlo(Variable * Dest,Operand * Src)454*03ce13f7SAndroid Build Coastguard Worker   void _mtlo(Variable *Dest, Operand *Src) {
455*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mtlo>(Dest, Src);
456*03ce13f7SAndroid Build Coastguard Worker   }
457*03ce13f7SAndroid Build Coastguard Worker 
_mul(Variable * Dest,Variable * Src0,Variable * Src1)458*03ce13f7SAndroid Build Coastguard Worker   void _mul(Variable *Dest, Variable *Src0, Variable *Src1) {
459*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mul>(Dest, Src0, Src1);
460*03ce13f7SAndroid Build Coastguard Worker   }
461*03ce13f7SAndroid Build Coastguard Worker 
_mul_d(Variable * Dest,Variable * Src0,Variable * Src1)462*03ce13f7SAndroid Build Coastguard Worker   void _mul_d(Variable *Dest, Variable *Src0, Variable *Src1) {
463*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mul_d>(Dest, Src0, Src1);
464*03ce13f7SAndroid Build Coastguard Worker   }
465*03ce13f7SAndroid Build Coastguard Worker 
_mul_s(Variable * Dest,Variable * Src0,Variable * Src1)466*03ce13f7SAndroid Build Coastguard Worker   void _mul_s(Variable *Dest, Variable *Src0, Variable *Src1) {
467*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mul_s>(Dest, Src0, Src1);
468*03ce13f7SAndroid Build Coastguard Worker   }
469*03ce13f7SAndroid Build Coastguard Worker 
_mult(Variable * Dest,Variable * Src0,Variable * Src1)470*03ce13f7SAndroid Build Coastguard Worker   void _mult(Variable *Dest, Variable *Src0, Variable *Src1) {
471*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Mult>(Dest, Src0, Src1);
472*03ce13f7SAndroid Build Coastguard Worker   }
473*03ce13f7SAndroid Build Coastguard Worker 
_multu(Variable * Dest,Variable * Src0,Variable * Src1)474*03ce13f7SAndroid Build Coastguard Worker   void _multu(Variable *Dest, Variable *Src0, Variable *Src1) {
475*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Multu>(Dest, Src0, Src1);
476*03ce13f7SAndroid Build Coastguard Worker   }
477*03ce13f7SAndroid Build Coastguard Worker 
_nop()478*03ce13f7SAndroid Build Coastguard Worker   void _nop() { Context.insert<InstMIPS32Sll>(getZero(), getZero(), 0); }
479*03ce13f7SAndroid Build Coastguard Worker 
_nor(Variable * Dest,Variable * Src0,Variable * Src1)480*03ce13f7SAndroid Build Coastguard Worker   void _nor(Variable *Dest, Variable *Src0, Variable *Src1) {
481*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Nor>(Dest, Src0, Src1);
482*03ce13f7SAndroid Build Coastguard Worker   }
483*03ce13f7SAndroid Build Coastguard Worker 
_not(Variable * Dest,Variable * Src0)484*03ce13f7SAndroid Build Coastguard Worker   void _not(Variable *Dest, Variable *Src0) {
485*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Nor>(Dest, Src0, getZero());
486*03ce13f7SAndroid Build Coastguard Worker   }
487*03ce13f7SAndroid Build Coastguard Worker 
_or(Variable * Dest,Variable * Src0,Variable * Src1)488*03ce13f7SAndroid Build Coastguard Worker   void _or(Variable *Dest, Variable *Src0, Variable *Src1) {
489*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Or>(Dest, Src0, Src1);
490*03ce13f7SAndroid Build Coastguard Worker   }
491*03ce13f7SAndroid Build Coastguard Worker 
_ori(Variable * Dest,Variable * Src,uint32_t Imm)492*03ce13f7SAndroid Build Coastguard Worker   void _ori(Variable *Dest, Variable *Src, uint32_t Imm) {
493*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Ori>(Dest, Src, Imm);
494*03ce13f7SAndroid Build Coastguard Worker   }
495*03ce13f7SAndroid Build Coastguard Worker 
_sc(Variable * Value,OperandMIPS32Mem * Mem)496*03ce13f7SAndroid Build Coastguard Worker   InstMIPS32Sc *_sc(Variable *Value, OperandMIPS32Mem *Mem) {
497*03ce13f7SAndroid Build Coastguard Worker     return Context.insert<InstMIPS32Sc>(Value, Mem);
498*03ce13f7SAndroid Build Coastguard Worker   }
499*03ce13f7SAndroid Build Coastguard Worker 
_sdc1(Variable * Value,OperandMIPS32Mem * Mem)500*03ce13f7SAndroid Build Coastguard Worker   void _sdc1(Variable *Value, OperandMIPS32Mem *Mem) {
501*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sdc1>(Value, Mem);
502*03ce13f7SAndroid Build Coastguard Worker   }
503*03ce13f7SAndroid Build Coastguard Worker 
_sll(Variable * Dest,Variable * Src,uint32_t Imm)504*03ce13f7SAndroid Build Coastguard Worker   void _sll(Variable *Dest, Variable *Src, uint32_t Imm) {
505*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sll>(Dest, Src, Imm);
506*03ce13f7SAndroid Build Coastguard Worker   }
507*03ce13f7SAndroid Build Coastguard Worker 
_sllv(Variable * Dest,Variable * Src0,Variable * Src1)508*03ce13f7SAndroid Build Coastguard Worker   void _sllv(Variable *Dest, Variable *Src0, Variable *Src1) {
509*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sllv>(Dest, Src0, Src1);
510*03ce13f7SAndroid Build Coastguard Worker   }
511*03ce13f7SAndroid Build Coastguard Worker 
_slt(Variable * Dest,Variable * Src0,Variable * Src1)512*03ce13f7SAndroid Build Coastguard Worker   void _slt(Variable *Dest, Variable *Src0, Variable *Src1) {
513*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Slt>(Dest, Src0, Src1);
514*03ce13f7SAndroid Build Coastguard Worker   }
515*03ce13f7SAndroid Build Coastguard Worker 
_slti(Variable * Dest,Variable * Src,uint32_t Imm)516*03ce13f7SAndroid Build Coastguard Worker   void _slti(Variable *Dest, Variable *Src, uint32_t Imm) {
517*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Slti>(Dest, Src, Imm);
518*03ce13f7SAndroid Build Coastguard Worker   }
519*03ce13f7SAndroid Build Coastguard Worker 
_sltiu(Variable * Dest,Variable * Src,uint32_t Imm)520*03ce13f7SAndroid Build Coastguard Worker   void _sltiu(Variable *Dest, Variable *Src, uint32_t Imm) {
521*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sltiu>(Dest, Src, Imm);
522*03ce13f7SAndroid Build Coastguard Worker   }
523*03ce13f7SAndroid Build Coastguard Worker 
_sltu(Variable * Dest,Variable * Src0,Variable * Src1)524*03ce13f7SAndroid Build Coastguard Worker   void _sltu(Variable *Dest, Variable *Src0, Variable *Src1) {
525*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sltu>(Dest, Src0, Src1);
526*03ce13f7SAndroid Build Coastguard Worker   }
527*03ce13f7SAndroid Build Coastguard Worker 
_sqrt_d(Variable * Dest,Variable * Src)528*03ce13f7SAndroid Build Coastguard Worker   void _sqrt_d(Variable *Dest, Variable *Src) {
529*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sqrt_d>(Dest, Src);
530*03ce13f7SAndroid Build Coastguard Worker   }
531*03ce13f7SAndroid Build Coastguard Worker 
_sqrt_s(Variable * Dest,Variable * Src)532*03ce13f7SAndroid Build Coastguard Worker   void _sqrt_s(Variable *Dest, Variable *Src) {
533*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sqrt_s>(Dest, Src);
534*03ce13f7SAndroid Build Coastguard Worker   }
535*03ce13f7SAndroid Build Coastguard Worker 
_sra(Variable * Dest,Variable * Src,uint32_t Imm)536*03ce13f7SAndroid Build Coastguard Worker   void _sra(Variable *Dest, Variable *Src, uint32_t Imm) {
537*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sra>(Dest, Src, Imm);
538*03ce13f7SAndroid Build Coastguard Worker   }
539*03ce13f7SAndroid Build Coastguard Worker 
_srav(Variable * Dest,Variable * Src0,Variable * Src1)540*03ce13f7SAndroid Build Coastguard Worker   void _srav(Variable *Dest, Variable *Src0, Variable *Src1) {
541*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Srav>(Dest, Src0, Src1);
542*03ce13f7SAndroid Build Coastguard Worker   }
543*03ce13f7SAndroid Build Coastguard Worker 
_srl(Variable * Dest,Variable * Src,uint32_t Imm)544*03ce13f7SAndroid Build Coastguard Worker   void _srl(Variable *Dest, Variable *Src, uint32_t Imm) {
545*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Srl>(Dest, Src, Imm);
546*03ce13f7SAndroid Build Coastguard Worker   }
547*03ce13f7SAndroid Build Coastguard Worker 
_srlv(Variable * Dest,Variable * Src0,Variable * Src1)548*03ce13f7SAndroid Build Coastguard Worker   void _srlv(Variable *Dest, Variable *Src0, Variable *Src1) {
549*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Srlv>(Dest, Src0, Src1);
550*03ce13f7SAndroid Build Coastguard Worker   }
551*03ce13f7SAndroid Build Coastguard Worker 
_sub(Variable * Dest,Variable * Src0,Variable * Src1)552*03ce13f7SAndroid Build Coastguard Worker   void _sub(Variable *Dest, Variable *Src0, Variable *Src1) {
553*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sub>(Dest, Src0, Src1);
554*03ce13f7SAndroid Build Coastguard Worker   }
555*03ce13f7SAndroid Build Coastguard Worker 
_sub_d(Variable * Dest,Variable * Src0,Variable * Src1)556*03ce13f7SAndroid Build Coastguard Worker   void _sub_d(Variable *Dest, Variable *Src0, Variable *Src1) {
557*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sub_d>(Dest, Src0, Src1);
558*03ce13f7SAndroid Build Coastguard Worker   }
559*03ce13f7SAndroid Build Coastguard Worker 
_sub_s(Variable * Dest,Variable * Src0,Variable * Src1)560*03ce13f7SAndroid Build Coastguard Worker   void _sub_s(Variable *Dest, Variable *Src0, Variable *Src1) {
561*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sub_s>(Dest, Src0, Src1);
562*03ce13f7SAndroid Build Coastguard Worker   }
563*03ce13f7SAndroid Build Coastguard Worker 
_subu(Variable * Dest,Variable * Src0,Variable * Src1)564*03ce13f7SAndroid Build Coastguard Worker   void _subu(Variable *Dest, Variable *Src0, Variable *Src1) {
565*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Subu>(Dest, Src0, Src1);
566*03ce13f7SAndroid Build Coastguard Worker   }
567*03ce13f7SAndroid Build Coastguard Worker 
_sw(Variable * Value,OperandMIPS32Mem * Mem)568*03ce13f7SAndroid Build Coastguard Worker   void _sw(Variable *Value, OperandMIPS32Mem *Mem) {
569*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Sw>(Value, Mem);
570*03ce13f7SAndroid Build Coastguard Worker   }
571*03ce13f7SAndroid Build Coastguard Worker 
_swc1(Variable * Value,OperandMIPS32Mem * Mem)572*03ce13f7SAndroid Build Coastguard Worker   void _swc1(Variable *Value, OperandMIPS32Mem *Mem) {
573*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Swc1>(Value, Mem);
574*03ce13f7SAndroid Build Coastguard Worker   }
575*03ce13f7SAndroid Build Coastguard Worker 
_sync()576*03ce13f7SAndroid Build Coastguard Worker   void _sync() { Context.insert<InstMIPS32Sync>(); }
577*03ce13f7SAndroid Build Coastguard Worker 
_teq(Variable * Src0,Variable * Src1,uint32_t TrapCode)578*03ce13f7SAndroid Build Coastguard Worker   void _teq(Variable *Src0, Variable *Src1, uint32_t TrapCode) {
579*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Teq>(Src0, Src1, TrapCode);
580*03ce13f7SAndroid Build Coastguard Worker   }
581*03ce13f7SAndroid Build Coastguard Worker 
_trunc_l_d(Variable * Dest,Variable * Src)582*03ce13f7SAndroid Build Coastguard Worker   void _trunc_l_d(Variable *Dest, Variable *Src) {
583*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Trunc_l_d>(Dest, Src);
584*03ce13f7SAndroid Build Coastguard Worker   }
585*03ce13f7SAndroid Build Coastguard Worker 
_trunc_l_s(Variable * Dest,Variable * Src)586*03ce13f7SAndroid Build Coastguard Worker   void _trunc_l_s(Variable *Dest, Variable *Src) {
587*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Trunc_l_s>(Dest, Src);
588*03ce13f7SAndroid Build Coastguard Worker   }
589*03ce13f7SAndroid Build Coastguard Worker 
_trunc_w_d(Variable * Dest,Variable * Src)590*03ce13f7SAndroid Build Coastguard Worker   void _trunc_w_d(Variable *Dest, Variable *Src) {
591*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Trunc_w_d>(Dest, Src);
592*03ce13f7SAndroid Build Coastguard Worker   }
593*03ce13f7SAndroid Build Coastguard Worker 
_trunc_w_s(Variable * Dest,Variable * Src)594*03ce13f7SAndroid Build Coastguard Worker   void _trunc_w_s(Variable *Dest, Variable *Src) {
595*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Trunc_w_s>(Dest, Src);
596*03ce13f7SAndroid Build Coastguard Worker   }
597*03ce13f7SAndroid Build Coastguard Worker 
_xor(Variable * Dest,Variable * Src0,Variable * Src1)598*03ce13f7SAndroid Build Coastguard Worker   void _xor(Variable *Dest, Variable *Src0, Variable *Src1) {
599*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Xor>(Dest, Src0, Src1);
600*03ce13f7SAndroid Build Coastguard Worker   }
601*03ce13f7SAndroid Build Coastguard Worker 
_xori(Variable * Dest,Variable * Src,uint32_t Imm)602*03ce13f7SAndroid Build Coastguard Worker   void _xori(Variable *Dest, Variable *Src, uint32_t Imm) {
603*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstMIPS32Xori>(Dest, Src, Imm);
604*03ce13f7SAndroid Build Coastguard Worker   }
605*03ce13f7SAndroid Build Coastguard Worker 
606*03ce13f7SAndroid Build Coastguard Worker   void lowerArguments() override;
607*03ce13f7SAndroid Build Coastguard Worker 
608*03ce13f7SAndroid Build Coastguard Worker   /// Make a pass through the SortedSpilledVariables and actually assign stack
609*03ce13f7SAndroid Build Coastguard Worker   /// slots. SpillAreaPaddingBytes takes into account stack alignment padding.
610*03ce13f7SAndroid Build Coastguard Worker   /// The SpillArea starts after that amount of padding. This matches the scheme
611*03ce13f7SAndroid Build Coastguard Worker   /// in getVarStackSlotParams, where there may be a separate multi-block global
612*03ce13f7SAndroid Build Coastguard Worker   /// var spill area and a local var spill area.
613*03ce13f7SAndroid Build Coastguard Worker   void assignVarStackSlots(VarList &SortedSpilledVariables,
614*03ce13f7SAndroid Build Coastguard Worker                            size_t SpillAreaPaddingBytes,
615*03ce13f7SAndroid Build Coastguard Worker                            size_t SpillAreaSizeBytes,
616*03ce13f7SAndroid Build Coastguard Worker                            size_t GlobalsAndSubsequentPaddingSize);
617*03ce13f7SAndroid Build Coastguard Worker 
618*03ce13f7SAndroid Build Coastguard Worker   /// Operand legalization helpers.  To deal with address mode constraints,
619*03ce13f7SAndroid Build Coastguard Worker   /// the helpers will create a new Operand and emit instructions that
620*03ce13f7SAndroid Build Coastguard Worker   /// guarantee that the Operand kind is one of those indicated by the
621*03ce13f7SAndroid Build Coastguard Worker   /// LegalMask (a bitmask of allowed kinds).  If the input Operand is known
622*03ce13f7SAndroid Build Coastguard Worker   /// to already meet the constraints, it may be simply returned as the result,
623*03ce13f7SAndroid Build Coastguard Worker   /// without creating any new instructions or operands.
624*03ce13f7SAndroid Build Coastguard Worker   enum OperandLegalization {
625*03ce13f7SAndroid Build Coastguard Worker     Legal_None = 0,
626*03ce13f7SAndroid Build Coastguard Worker     Legal_Reg = 1 << 0, // physical register, not stack location
627*03ce13f7SAndroid Build Coastguard Worker     Legal_Imm = 1 << 1,
628*03ce13f7SAndroid Build Coastguard Worker     Legal_Mem = 1 << 2,
629*03ce13f7SAndroid Build Coastguard Worker     Legal_Rematerializable = 1 << 3,
630*03ce13f7SAndroid Build Coastguard Worker     Legal_Default = ~Legal_None
631*03ce13f7SAndroid Build Coastguard Worker   };
632*03ce13f7SAndroid Build Coastguard Worker   typedef uint32_t LegalMask;
633*03ce13f7SAndroid Build Coastguard Worker   Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default,
634*03ce13f7SAndroid Build Coastguard Worker                     RegNumT RegNum = RegNumT());
635*03ce13f7SAndroid Build Coastguard Worker 
636*03ce13f7SAndroid Build Coastguard Worker   Variable *legalizeToVar(Operand *From, RegNumT RegNum = RegNumT());
637*03ce13f7SAndroid Build Coastguard Worker 
638*03ce13f7SAndroid Build Coastguard Worker   Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT());
639*03ce13f7SAndroid Build Coastguard Worker 
640*03ce13f7SAndroid Build Coastguard Worker   Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT());
641*03ce13f7SAndroid Build Coastguard Worker 
getZero()642*03ce13f7SAndroid Build Coastguard Worker   Variable *getZero() {
643*03ce13f7SAndroid Build Coastguard Worker     auto *Zero = makeReg(IceType_i32, RegMIPS32::Reg_ZERO);
644*03ce13f7SAndroid Build Coastguard Worker     Context.insert<InstFakeDef>(Zero);
645*03ce13f7SAndroid Build Coastguard Worker     return Zero;
646*03ce13f7SAndroid Build Coastguard Worker   }
647*03ce13f7SAndroid Build Coastguard Worker 
648*03ce13f7SAndroid Build Coastguard Worker   Variable *I32Reg(RegNumT RegNum = RegNumT()) {
649*03ce13f7SAndroid Build Coastguard Worker     return makeReg(IceType_i32, RegNum);
650*03ce13f7SAndroid Build Coastguard Worker   }
651*03ce13f7SAndroid Build Coastguard Worker 
652*03ce13f7SAndroid Build Coastguard Worker   Variable *F32Reg(RegNumT RegNum = RegNumT()) {
653*03ce13f7SAndroid Build Coastguard Worker     return makeReg(IceType_f32, RegNum);
654*03ce13f7SAndroid Build Coastguard Worker   }
655*03ce13f7SAndroid Build Coastguard Worker 
656*03ce13f7SAndroid Build Coastguard Worker   Variable *F64Reg(RegNumT RegNum = RegNumT()) {
657*03ce13f7SAndroid Build Coastguard Worker     return makeReg(IceType_f64, RegNum);
658*03ce13f7SAndroid Build Coastguard Worker   }
659*03ce13f7SAndroid Build Coastguard Worker 
660*03ce13f7SAndroid Build Coastguard Worker   static Type stackSlotType();
661*03ce13f7SAndroid Build Coastguard Worker   Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT());
662*03ce13f7SAndroid Build Coastguard Worker 
663*03ce13f7SAndroid Build Coastguard Worker   void unsetIfNonLeafFunc();
664*03ce13f7SAndroid Build Coastguard Worker 
665*03ce13f7SAndroid Build Coastguard Worker   // Iterates over the CFG and determines the maximum outgoing stack arguments
666*03ce13f7SAndroid Build Coastguard Worker   // bytes. This information is later used during addProlog() to pre-allocate
667*03ce13f7SAndroid Build Coastguard Worker   // the outargs area
668*03ce13f7SAndroid Build Coastguard Worker   void findMaxStackOutArgsSize();
669*03ce13f7SAndroid Build Coastguard Worker 
670*03ce13f7SAndroid Build Coastguard Worker   void postLowerLegalization();
671*03ce13f7SAndroid Build Coastguard Worker 
672*03ce13f7SAndroid Build Coastguard Worker   void addProlog(CfgNode *Node) override;
673*03ce13f7SAndroid Build Coastguard Worker   void addEpilog(CfgNode *Node) override;
674*03ce13f7SAndroid Build Coastguard Worker 
675*03ce13f7SAndroid Build Coastguard Worker   // Ensure that a 64-bit Variable has been split into 2 32-bit
676*03ce13f7SAndroid Build Coastguard Worker   // Variables, creating them if necessary.  This is needed for all
677*03ce13f7SAndroid Build Coastguard Worker   // I64 operations.
678*03ce13f7SAndroid Build Coastguard Worker   void split64(Variable *Var);
679*03ce13f7SAndroid Build Coastguard Worker   Operand *loOperand(Operand *Operand);
680*03ce13f7SAndroid Build Coastguard Worker   Operand *hiOperand(Operand *Operand);
681*03ce13f7SAndroid Build Coastguard Worker   Operand *getOperandAtIndex(Operand *Operand, Type BaseType, uint32_t Index);
682*03ce13f7SAndroid Build Coastguard Worker 
683*03ce13f7SAndroid Build Coastguard Worker   void finishArgumentLowering(Variable *Arg, bool PartialOnStack,
684*03ce13f7SAndroid Build Coastguard Worker                               Variable *FramePtr, size_t BasicFrameOffset,
685*03ce13f7SAndroid Build Coastguard Worker                               size_t *InArgsSizeBytes);
686*03ce13f7SAndroid Build Coastguard Worker 
687*03ce13f7SAndroid Build Coastguard Worker   Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT());
688*03ce13f7SAndroid Build Coastguard Worker 
689*03ce13f7SAndroid Build Coastguard Worker   /// Helper class that understands the Calling Convention and register
690*03ce13f7SAndroid Build Coastguard Worker   /// assignments as per MIPS O32 abi.
691*03ce13f7SAndroid Build Coastguard Worker   class CallingConv {
692*03ce13f7SAndroid Build Coastguard Worker     CallingConv(const CallingConv &) = delete;
693*03ce13f7SAndroid Build Coastguard Worker     CallingConv &operator=(const CallingConv &) = delete;
694*03ce13f7SAndroid Build Coastguard Worker 
695*03ce13f7SAndroid Build Coastguard Worker   public:
696*03ce13f7SAndroid Build Coastguard Worker     CallingConv();
697*03ce13f7SAndroid Build Coastguard Worker     ~CallingConv() = default;
698*03ce13f7SAndroid Build Coastguard Worker 
699*03ce13f7SAndroid Build Coastguard Worker     /// argInReg returns true if there is a Register available for the requested
700*03ce13f7SAndroid Build Coastguard Worker     /// type, and false otherwise. If it returns true, Reg is set to the
701*03ce13f7SAndroid Build Coastguard Worker     /// appropriate register number. Note that, when Ty == IceType_i64, Reg will
702*03ce13f7SAndroid Build Coastguard Worker     /// be an I64 register pair.
703*03ce13f7SAndroid Build Coastguard Worker     bool argInReg(Type Ty, uint32_t ArgNo, RegNumT *Reg);
discardReg(RegNumT Reg)704*03ce13f7SAndroid Build Coastguard Worker     void discardReg(RegNumT Reg) { GPRegsUsed |= RegisterAliases[Reg]; }
705*03ce13f7SAndroid Build Coastguard Worker 
706*03ce13f7SAndroid Build Coastguard Worker   private:
707*03ce13f7SAndroid Build Coastguard Worker     // argInGPR is used to find if any GPR register is available for argument of
708*03ce13f7SAndroid Build Coastguard Worker     // type Ty
709*03ce13f7SAndroid Build Coastguard Worker     bool argInGPR(Type Ty, RegNumT *Reg);
710*03ce13f7SAndroid Build Coastguard Worker     /// argInVFP is to floating-point/vector types what argInGPR is for integer
711*03ce13f7SAndroid Build Coastguard Worker     /// types.
712*03ce13f7SAndroid Build Coastguard Worker     bool argInVFP(Type Ty, RegNumT *Reg);
713*03ce13f7SAndroid Build Coastguard Worker     inline void discardNextGPRAndItsAliases(CfgVector<RegNumT> *Regs);
714*03ce13f7SAndroid Build Coastguard Worker     inline void alignGPR(CfgVector<RegNumT> *Regs);
715*03ce13f7SAndroid Build Coastguard Worker     void discardUnavailableGPRsAndTheirAliases(CfgVector<RegNumT> *Regs);
716*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector GPRegsUsed;
717*03ce13f7SAndroid Build Coastguard Worker     CfgVector<RegNumT> GPRArgs;
718*03ce13f7SAndroid Build Coastguard Worker     CfgVector<RegNumT> I64Args;
719*03ce13f7SAndroid Build Coastguard Worker 
720*03ce13f7SAndroid Build Coastguard Worker     void discardUnavailableVFPRegsAndTheirAliases(CfgVector<RegNumT> *Regs);
721*03ce13f7SAndroid Build Coastguard Worker     SmallBitVector VFPRegsUsed;
722*03ce13f7SAndroid Build Coastguard Worker     CfgVector<RegNumT> FP32Args;
723*03ce13f7SAndroid Build Coastguard Worker     CfgVector<RegNumT> FP64Args;
724*03ce13f7SAndroid Build Coastguard Worker     // UseFPRegs is a flag indicating if FP registers can be used
725*03ce13f7SAndroid Build Coastguard Worker     bool UseFPRegs = false;
726*03ce13f7SAndroid Build Coastguard Worker   };
727*03ce13f7SAndroid Build Coastguard Worker 
728*03ce13f7SAndroid Build Coastguard Worker protected:
729*03ce13f7SAndroid Build Coastguard Worker   explicit TargetMIPS32(Cfg *Func);
730*03ce13f7SAndroid Build Coastguard Worker 
731*03ce13f7SAndroid Build Coastguard Worker   void postLower() override;
732*03ce13f7SAndroid Build Coastguard Worker 
733*03ce13f7SAndroid Build Coastguard Worker   void lowerAlloca(const InstAlloca *Instr) override;
734*03ce13f7SAndroid Build Coastguard Worker   void lowerArithmetic(const InstArithmetic *Instr) override;
735*03ce13f7SAndroid Build Coastguard Worker   void lowerInt64Arithmetic(const InstArithmetic *Instr, Variable *Dest,
736*03ce13f7SAndroid Build Coastguard Worker                             Operand *Src0, Operand *Src1);
737*03ce13f7SAndroid Build Coastguard Worker   void lowerAssign(const InstAssign *Instr) override;
738*03ce13f7SAndroid Build Coastguard Worker   void lowerBr(const InstBr *Instr) override;
739*03ce13f7SAndroid Build Coastguard Worker   void lowerBreakpoint(const InstBreakpoint *Instr) override;
740*03ce13f7SAndroid Build Coastguard Worker   void lowerCall(const InstCall *Instr) override;
741*03ce13f7SAndroid Build Coastguard Worker   void lowerCast(const InstCast *Instr) override;
742*03ce13f7SAndroid Build Coastguard Worker   void lowerExtractElement(const InstExtractElement *Instr) override;
743*03ce13f7SAndroid Build Coastguard Worker   void lowerFcmp(const InstFcmp *Instr) override;
744*03ce13f7SAndroid Build Coastguard Worker   void lowerIcmp(const InstIcmp *Instr) override;
745*03ce13f7SAndroid Build Coastguard Worker   void lower64Icmp(const InstIcmp *Instr);
746*03ce13f7SAndroid Build Coastguard Worker   void createArithInst(Intrinsics::AtomicRMWOperation Operation, Variable *Dest,
747*03ce13f7SAndroid Build Coastguard Worker                        Variable *Src0, Variable *Src1);
748*03ce13f7SAndroid Build Coastguard Worker   void lowerIntrinsic(const InstIntrinsic *Instr) override;
749*03ce13f7SAndroid Build Coastguard Worker   void lowerInsertElement(const InstInsertElement *Instr) override;
750*03ce13f7SAndroid Build Coastguard Worker   void lowerLoad(const InstLoad *Instr) override;
751*03ce13f7SAndroid Build Coastguard Worker   void lowerPhi(const InstPhi *Instr) override;
752*03ce13f7SAndroid Build Coastguard Worker   void lowerRet(const InstRet *Instr) override;
753*03ce13f7SAndroid Build Coastguard Worker   void lowerSelect(const InstSelect *Instr) override;
754*03ce13f7SAndroid Build Coastguard Worker   void lowerShuffleVector(const InstShuffleVector *Instr) override;
755*03ce13f7SAndroid Build Coastguard Worker   void lowerStore(const InstStore *Instr) override;
756*03ce13f7SAndroid Build Coastguard Worker   void lowerSwitch(const InstSwitch *Instr) override;
757*03ce13f7SAndroid Build Coastguard Worker   void lowerUnreachable(const InstUnreachable *Instr) override;
758*03ce13f7SAndroid Build Coastguard Worker   void lowerOther(const Inst *Instr) override;
759*03ce13f7SAndroid Build Coastguard Worker   void prelowerPhis() override;
760*03ce13f7SAndroid Build Coastguard Worker   uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override;
761*03ce13f7SAndroid Build Coastguard Worker   void genTargetHelperCallFor(Inst *Instr) override;
762*03ce13f7SAndroid Build Coastguard Worker   void doAddressOptLoad() override;
763*03ce13f7SAndroid Build Coastguard Worker   void doAddressOptStore() override;
764*03ce13f7SAndroid Build Coastguard Worker 
765*03ce13f7SAndroid Build Coastguard Worker   OperandMIPS32Mem *formMemoryOperand(Operand *Ptr, Type Ty);
766*03ce13f7SAndroid Build Coastguard Worker 
767*03ce13f7SAndroid Build Coastguard Worker   class PostLoweringLegalizer {
768*03ce13f7SAndroid Build Coastguard Worker     PostLoweringLegalizer() = delete;
769*03ce13f7SAndroid Build Coastguard Worker     PostLoweringLegalizer(const PostLoweringLegalizer &) = delete;
770*03ce13f7SAndroid Build Coastguard Worker     PostLoweringLegalizer &operator=(const PostLoweringLegalizer &) = delete;
771*03ce13f7SAndroid Build Coastguard Worker 
772*03ce13f7SAndroid Build Coastguard Worker   public:
PostLoweringLegalizer(TargetMIPS32 * Target)773*03ce13f7SAndroid Build Coastguard Worker     explicit PostLoweringLegalizer(TargetMIPS32 *Target)
774*03ce13f7SAndroid Build Coastguard Worker         : Target(Target), StackOrFrameReg(Target->getPhysicalRegister(
775*03ce13f7SAndroid Build Coastguard Worker                               Target->getFrameOrStackReg())) {}
776*03ce13f7SAndroid Build Coastguard Worker 
777*03ce13f7SAndroid Build Coastguard Worker     /// Legalizes Mem. if Mem.Base is a rematerializable variable,
778*03ce13f7SAndroid Build Coastguard Worker     /// Mem.Offset is fixed up.
779*03ce13f7SAndroid Build Coastguard Worker     OperandMIPS32Mem *legalizeMemOperand(OperandMIPS32Mem *Mem);
780*03ce13f7SAndroid Build Coastguard Worker 
781*03ce13f7SAndroid Build Coastguard Worker     /// Legalizes Immediate if larger value overflows range of 16 bits
782*03ce13f7SAndroid Build Coastguard Worker     Variable *legalizeImmediate(int32_t Imm);
783*03ce13f7SAndroid Build Coastguard Worker 
784*03ce13f7SAndroid Build Coastguard Worker     /// Legalizes Mov if its Source (or Destination) is a spilled Variable, or
785*03ce13f7SAndroid Build Coastguard Worker     /// if its Source is a Rematerializable variable (this form is used in lieu
786*03ce13f7SAndroid Build Coastguard Worker     /// of lea, which is not available in MIPS.)
787*03ce13f7SAndroid Build Coastguard Worker     ///
788*03ce13f7SAndroid Build Coastguard Worker     /// Moves to memory become store instructions, and moves from memory, loads.
789*03ce13f7SAndroid Build Coastguard Worker     void legalizeMov(InstMIPS32Mov *Mov);
790*03ce13f7SAndroid Build Coastguard Worker     void legalizeMovFp(InstMIPS32MovFP64ToI64 *MovInstr);
791*03ce13f7SAndroid Build Coastguard Worker 
792*03ce13f7SAndroid Build Coastguard Worker   private:
793*03ce13f7SAndroid Build Coastguard Worker     /// Creates a new Base register centered around [Base, +/- Offset].
794*03ce13f7SAndroid Build Coastguard Worker     Variable *newBaseRegister(Variable *Base, int32_t Offset,
795*03ce13f7SAndroid Build Coastguard Worker                               RegNumT ScratchRegNum);
796*03ce13f7SAndroid Build Coastguard Worker 
797*03ce13f7SAndroid Build Coastguard Worker     TargetMIPS32 *const Target;
798*03ce13f7SAndroid Build Coastguard Worker     Variable *const StackOrFrameReg;
799*03ce13f7SAndroid Build Coastguard Worker   };
800*03ce13f7SAndroid Build Coastguard Worker 
801*03ce13f7SAndroid Build Coastguard Worker   bool UsesFramePointer = false;
802*03ce13f7SAndroid Build Coastguard Worker   bool NeedsStackAlignment = false;
803*03ce13f7SAndroid Build Coastguard Worker   bool MaybeLeafFunc = true;
804*03ce13f7SAndroid Build Coastguard Worker   bool PrologEmitsFixedAllocas = false;
805*03ce13f7SAndroid Build Coastguard Worker   bool VariableAllocaUsed = false;
806*03ce13f7SAndroid Build Coastguard Worker   uint32_t MaxOutArgsSizeBytes = 0;
807*03ce13f7SAndroid Build Coastguard Worker   uint32_t TotalStackSizeBytes = 0;
808*03ce13f7SAndroid Build Coastguard Worker   uint32_t CurrentAllocaOffset = 0;
809*03ce13f7SAndroid Build Coastguard Worker   uint32_t VariableAllocaAlignBytes = 0;
810*03ce13f7SAndroid Build Coastguard Worker   static SmallBitVector TypeToRegisterSet[RCMIPS32_NUM];
811*03ce13f7SAndroid Build Coastguard Worker   static SmallBitVector TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
812*03ce13f7SAndroid Build Coastguard Worker   static SmallBitVector RegisterAliases[RegMIPS32::Reg_NUM];
813*03ce13f7SAndroid Build Coastguard Worker   SmallBitVector RegsUsed;
814*03ce13f7SAndroid Build Coastguard Worker   VarList PhysicalRegisters[IceType_NUM];
815*03ce13f7SAndroid Build Coastguard Worker   VarList PreservedGPRs;
816*03ce13f7SAndroid Build Coastguard Worker   static constexpr uint32_t CHAR_BITS = 8;
817*03ce13f7SAndroid Build Coastguard Worker   static constexpr uint32_t INT32_BITS = 32;
818*03ce13f7SAndroid Build Coastguard Worker   size_t SpillAreaSizeBytes = 0;
819*03ce13f7SAndroid Build Coastguard Worker   size_t FixedAllocaSizeBytes = 0;
820*03ce13f7SAndroid Build Coastguard Worker   size_t FixedAllocaAlignBytes = 0;
821*03ce13f7SAndroid Build Coastguard Worker   size_t PreservedRegsSizeBytes = 0;
822*03ce13f7SAndroid Build Coastguard Worker   Variable *ImplicitRet = nullptr; /// Implicit return
823*03ce13f7SAndroid Build Coastguard Worker 
824*03ce13f7SAndroid Build Coastguard Worker private:
825*03ce13f7SAndroid Build Coastguard Worker   ENABLE_MAKE_UNIQUE;
826*03ce13f7SAndroid Build Coastguard Worker 
827*03ce13f7SAndroid Build Coastguard Worker   OperandMIPS32Mem *formAddressingMode(Type Ty, Cfg *Func, const Inst *LdSt,
828*03ce13f7SAndroid Build Coastguard Worker                                        Operand *Base);
829*03ce13f7SAndroid Build Coastguard Worker 
830*03ce13f7SAndroid Build Coastguard Worker   class ComputationTracker {
831*03ce13f7SAndroid Build Coastguard Worker   public:
832*03ce13f7SAndroid Build Coastguard Worker     ComputationTracker() = default;
833*03ce13f7SAndroid Build Coastguard Worker     ~ComputationTracker() = default;
834*03ce13f7SAndroid Build Coastguard Worker 
forgetProducers()835*03ce13f7SAndroid Build Coastguard Worker     void forgetProducers() { KnownComputations.clear(); }
836*03ce13f7SAndroid Build Coastguard Worker     void recordProducers(CfgNode *Node);
837*03ce13f7SAndroid Build Coastguard Worker 
getProducerOf(const Operand * Opnd)838*03ce13f7SAndroid Build Coastguard Worker     const Inst *getProducerOf(const Operand *Opnd) const {
839*03ce13f7SAndroid Build Coastguard Worker       auto *Var = llvm::dyn_cast<Variable>(Opnd);
840*03ce13f7SAndroid Build Coastguard Worker       if (Var == nullptr) {
841*03ce13f7SAndroid Build Coastguard Worker         return nullptr;
842*03ce13f7SAndroid Build Coastguard Worker       }
843*03ce13f7SAndroid Build Coastguard Worker 
844*03ce13f7SAndroid Build Coastguard Worker       auto Iter = KnownComputations.find(Var->getIndex());
845*03ce13f7SAndroid Build Coastguard Worker       if (Iter == KnownComputations.end()) {
846*03ce13f7SAndroid Build Coastguard Worker         return nullptr;
847*03ce13f7SAndroid Build Coastguard Worker       }
848*03ce13f7SAndroid Build Coastguard Worker 
849*03ce13f7SAndroid Build Coastguard Worker       return Iter->second.Instr;
850*03ce13f7SAndroid Build Coastguard Worker     }
851*03ce13f7SAndroid Build Coastguard Worker 
dump(const Cfg * Func)852*03ce13f7SAndroid Build Coastguard Worker     void dump(const Cfg *Func) const {
853*03ce13f7SAndroid Build Coastguard Worker       if (!BuildDefs::dump() || !Func->isVerbose(IceV_Folding))
854*03ce13f7SAndroid Build Coastguard Worker         return;
855*03ce13f7SAndroid Build Coastguard Worker       OstreamLocker L(Func->getContext());
856*03ce13f7SAndroid Build Coastguard Worker       Ostream &Str = Func->getContext()->getStrDump();
857*03ce13f7SAndroid Build Coastguard Worker       Str << "foldable producer:\n";
858*03ce13f7SAndroid Build Coastguard Worker       for (const auto &Computation : KnownComputations) {
859*03ce13f7SAndroid Build Coastguard Worker         Str << "    ";
860*03ce13f7SAndroid Build Coastguard Worker         Computation.second.Instr->dump(Func);
861*03ce13f7SAndroid Build Coastguard Worker         Str << "\n";
862*03ce13f7SAndroid Build Coastguard Worker       }
863*03ce13f7SAndroid Build Coastguard Worker       Str << "\n";
864*03ce13f7SAndroid Build Coastguard Worker     }
865*03ce13f7SAndroid Build Coastguard Worker 
866*03ce13f7SAndroid Build Coastguard Worker   private:
867*03ce13f7SAndroid Build Coastguard Worker     class ComputationEntry {
868*03ce13f7SAndroid Build Coastguard Worker     public:
ComputationEntry(Inst * I,Type Ty)869*03ce13f7SAndroid Build Coastguard Worker       ComputationEntry(Inst *I, Type Ty) : Instr(I), ComputationType(Ty) {}
870*03ce13f7SAndroid Build Coastguard Worker       Inst *const Instr;
871*03ce13f7SAndroid Build Coastguard Worker       // Boolean folding is disabled for variables whose live range is multi
872*03ce13f7SAndroid Build Coastguard Worker       // block. We conservatively initialize IsLiveOut to true, and set it to
873*03ce13f7SAndroid Build Coastguard Worker       // false once we find the end of the live range for the variable defined
874*03ce13f7SAndroid Build Coastguard Worker       // by this instruction. If liveness analysis is not performed (e.g., in
875*03ce13f7SAndroid Build Coastguard Worker       // Om1 mode) IsLiveOut will never be set to false, and folding will be
876*03ce13f7SAndroid Build Coastguard Worker       // disabled.
877*03ce13f7SAndroid Build Coastguard Worker       bool IsLiveOut = true;
878*03ce13f7SAndroid Build Coastguard Worker       int32_t NumUses = 0;
879*03ce13f7SAndroid Build Coastguard Worker       Type ComputationType;
880*03ce13f7SAndroid Build Coastguard Worker     };
881*03ce13f7SAndroid Build Coastguard Worker 
882*03ce13f7SAndroid Build Coastguard Worker     // ComputationMap maps a Variable number to a payload identifying which
883*03ce13f7SAndroid Build Coastguard Worker     // instruction defined it.
884*03ce13f7SAndroid Build Coastguard Worker     using ComputationMap = CfgUnorderedMap<SizeT, ComputationEntry>;
885*03ce13f7SAndroid Build Coastguard Worker     ComputationMap KnownComputations;
886*03ce13f7SAndroid Build Coastguard Worker   };
887*03ce13f7SAndroid Build Coastguard Worker 
888*03ce13f7SAndroid Build Coastguard Worker   ComputationTracker Computations;
889*03ce13f7SAndroid Build Coastguard Worker };
890*03ce13f7SAndroid Build Coastguard Worker 
891*03ce13f7SAndroid Build Coastguard Worker class TargetDataMIPS32 final : public TargetDataLowering {
892*03ce13f7SAndroid Build Coastguard Worker   TargetDataMIPS32() = delete;
893*03ce13f7SAndroid Build Coastguard Worker   TargetDataMIPS32(const TargetDataMIPS32 &) = delete;
894*03ce13f7SAndroid Build Coastguard Worker   TargetDataMIPS32 &operator=(const TargetDataMIPS32 &) = delete;
895*03ce13f7SAndroid Build Coastguard Worker 
896*03ce13f7SAndroid Build Coastguard Worker public:
create(GlobalContext * Ctx)897*03ce13f7SAndroid Build Coastguard Worker   static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) {
898*03ce13f7SAndroid Build Coastguard Worker     return std::unique_ptr<TargetDataLowering>(new TargetDataMIPS32(Ctx));
899*03ce13f7SAndroid Build Coastguard Worker   }
900*03ce13f7SAndroid Build Coastguard Worker 
901*03ce13f7SAndroid Build Coastguard Worker   void lowerGlobals(const VariableDeclarationList &Vars,
902*03ce13f7SAndroid Build Coastguard Worker                     const std::string &SectionSuffix) override;
903*03ce13f7SAndroid Build Coastguard Worker   void lowerConstants() override;
904*03ce13f7SAndroid Build Coastguard Worker   void lowerJumpTables() override;
905*03ce13f7SAndroid Build Coastguard Worker   void emitTargetRODataSections() override;
906*03ce13f7SAndroid Build Coastguard Worker 
907*03ce13f7SAndroid Build Coastguard Worker protected:
908*03ce13f7SAndroid Build Coastguard Worker   explicit TargetDataMIPS32(GlobalContext *Ctx);
909*03ce13f7SAndroid Build Coastguard Worker 
910*03ce13f7SAndroid Build Coastguard Worker private:
911*03ce13f7SAndroid Build Coastguard Worker   ~TargetDataMIPS32() override = default;
912*03ce13f7SAndroid Build Coastguard Worker };
913*03ce13f7SAndroid Build Coastguard Worker 
914*03ce13f7SAndroid Build Coastguard Worker class TargetHeaderMIPS32 final : public TargetHeaderLowering {
915*03ce13f7SAndroid Build Coastguard Worker   TargetHeaderMIPS32() = delete;
916*03ce13f7SAndroid Build Coastguard Worker   TargetHeaderMIPS32(const TargetHeaderMIPS32 &) = delete;
917*03ce13f7SAndroid Build Coastguard Worker   TargetHeaderMIPS32 &operator=(const TargetHeaderMIPS32 &) = delete;
918*03ce13f7SAndroid Build Coastguard Worker 
919*03ce13f7SAndroid Build Coastguard Worker public:
create(GlobalContext * Ctx)920*03ce13f7SAndroid Build Coastguard Worker   static std::unique_ptr<TargetHeaderLowering> create(GlobalContext *Ctx) {
921*03ce13f7SAndroid Build Coastguard Worker     return std::unique_ptr<TargetHeaderLowering>(new TargetHeaderMIPS32(Ctx));
922*03ce13f7SAndroid Build Coastguard Worker   }
923*03ce13f7SAndroid Build Coastguard Worker 
924*03ce13f7SAndroid Build Coastguard Worker   void lower() override;
925*03ce13f7SAndroid Build Coastguard Worker 
926*03ce13f7SAndroid Build Coastguard Worker protected:
927*03ce13f7SAndroid Build Coastguard Worker   explicit TargetHeaderMIPS32(GlobalContext *Ctx);
928*03ce13f7SAndroid Build Coastguard Worker 
929*03ce13f7SAndroid Build Coastguard Worker private:
930*03ce13f7SAndroid Build Coastguard Worker   ~TargetHeaderMIPS32() = default;
931*03ce13f7SAndroid Build Coastguard Worker };
932*03ce13f7SAndroid Build Coastguard Worker 
933*03ce13f7SAndroid Build Coastguard Worker // This structure (with some minor modifications) is copied from
934*03ce13f7SAndroid Build Coastguard Worker // llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h file.
935*03ce13f7SAndroid Build Coastguard Worker struct MipsABIFlagsSection {
936*03ce13f7SAndroid Build Coastguard Worker 
937*03ce13f7SAndroid Build Coastguard Worker   // Version of the MIPS.abiflags section
938*03ce13f7SAndroid Build Coastguard Worker   enum AFL_VERSION {
939*03ce13f7SAndroid Build Coastguard Worker     AFL_VERSION_V0 = 0 // Version 0
940*03ce13f7SAndroid Build Coastguard Worker   };
941*03ce13f7SAndroid Build Coastguard Worker 
942*03ce13f7SAndroid Build Coastguard Worker   // The level of the ISA: 1-5, 32, 64.
943*03ce13f7SAndroid Build Coastguard Worker   enum AFL_ISA_LEVEL {
944*03ce13f7SAndroid Build Coastguard Worker     AFL_ISA_LEVEL_NONE = 0,
945*03ce13f7SAndroid Build Coastguard Worker     AFL_ISA_LEVEL_MIPS32 = 32, // MIPS32
946*03ce13f7SAndroid Build Coastguard Worker   };
947*03ce13f7SAndroid Build Coastguard Worker 
948*03ce13f7SAndroid Build Coastguard Worker   // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
949*03ce13f7SAndroid Build Coastguard Worker   enum AFL_ISA_REV {
950*03ce13f7SAndroid Build Coastguard Worker     AFL_ISA_REV_NONE = 0,
951*03ce13f7SAndroid Build Coastguard Worker     AFL_ISA_REV_R1 = 1, // R1
952*03ce13f7SAndroid Build Coastguard Worker   };
953*03ce13f7SAndroid Build Coastguard Worker 
954*03ce13f7SAndroid Build Coastguard Worker   // Values for the xxx_size bytes of an ABI flags structure.
955*03ce13f7SAndroid Build Coastguard Worker   enum AFL_REG {
956*03ce13f7SAndroid Build Coastguard Worker     AFL_REG_NONE = 0x00, // No registers.
957*03ce13f7SAndroid Build Coastguard Worker     AFL_REG_32 = 0x01,   // 32-bit registers.
958*03ce13f7SAndroid Build Coastguard Worker     AFL_REG_64 = 0x02,   // 64-bit registers.
959*03ce13f7SAndroid Build Coastguard Worker     AFL_REG_128 = 0x03   // 128-bit registers.
960*03ce13f7SAndroid Build Coastguard Worker   };
961*03ce13f7SAndroid Build Coastguard Worker 
962*03ce13f7SAndroid Build Coastguard Worker   // Values for the fp_abi word of an ABI flags structure.
963*03ce13f7SAndroid Build Coastguard Worker   enum AFL_FP_ABI {
964*03ce13f7SAndroid Build Coastguard Worker     AFL_FP_ANY = 0,
965*03ce13f7SAndroid Build Coastguard Worker     AFL_FP_DOUBLE = 1,
966*03ce13f7SAndroid Build Coastguard Worker     AFL_FP_XX = 5,
967*03ce13f7SAndroid Build Coastguard Worker     AFL_FP_64 = 6,
968*03ce13f7SAndroid Build Coastguard Worker     AFL_FP_64A = 7
969*03ce13f7SAndroid Build Coastguard Worker   };
970*03ce13f7SAndroid Build Coastguard Worker 
971*03ce13f7SAndroid Build Coastguard Worker   // Values for the isa_ext word of an ABI flags structure.
972*03ce13f7SAndroid Build Coastguard Worker   enum AFL_EXT {
973*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_NONE = 0,
974*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_XLR = 1,          // RMI Xlr instruction.
975*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_OCTEON2 = 2,      // Cavium Networks Octeon2.
976*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_OCTEONP = 3,      // Cavium Networks OcteonP.
977*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_LOONGSON_3A = 4,  // Loongson 3A.
978*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_OCTEON = 5,       // Cavium Networks Octeon.
979*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_5900 = 6,         // MIPS R5900 instruction.
980*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_4650 = 7,         // MIPS R4650 instruction.
981*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_4010 = 8,         // LSI R4010 instruction.
982*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_4100 = 9,         // NEC VR4100 instruction.
983*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_3900 = 10,        // Toshiba R3900 instruction.
984*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_10000 = 11,       // MIPS R10000 instruction.
985*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_SB1 = 12,         // Broadcom SB-1 instruction.
986*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_4111 = 13,        // NEC VR4111/VR4181 instruction.
987*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_4120 = 14,        // NEC VR4120 instruction.
988*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_5400 = 15,        // NEC VR5400 instruction.
989*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_5500 = 16,        // NEC VR5500 instruction.
990*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_LOONGSON_2E = 17, // ST Microelectronics Loongson 2E.
991*03ce13f7SAndroid Build Coastguard Worker     AFL_EXT_LOONGSON_2F = 18  // ST Microelectronics Loongson 2F.
992*03ce13f7SAndroid Build Coastguard Worker   };
993*03ce13f7SAndroid Build Coastguard Worker 
994*03ce13f7SAndroid Build Coastguard Worker   // Masks for the ases word of an ABI flags structure.
995*03ce13f7SAndroid Build Coastguard Worker   enum AFL_ASE {
996*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_NONE = 0x00000000,
997*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_DSP = 0x00000001,       // DSP ASE.
998*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_DSPR2 = 0x00000002,     // DSP R2 ASE.
999*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_EVA = 0x00000004,       // Enhanced VA Scheme.
1000*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_MCU = 0x00000008,       // MCU (MicroController) ASE.
1001*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_MDMX = 0x00000010,      // MDMX ASE.
1002*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_MIPS3D = 0x00000020,    // MIPS-3D ASE.
1003*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_MT = 0x00000040,        // MT ASE.
1004*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_SMARTMIPS = 0x00000080, // SmartMIPS ASE.
1005*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_VIRT = 0x00000100,      // VZ ASE.
1006*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_MSA = 0x00000200,       // MSA ASE.
1007*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_MIPS16 = 0x00000400,    // MIPS16 ASE.
1008*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_MICROMIPS = 0x00000800, // MICROMIPS ASE.
1009*03ce13f7SAndroid Build Coastguard Worker     AFL_ASE_XPA = 0x00001000        // XPA ASE.
1010*03ce13f7SAndroid Build Coastguard Worker   };
1011*03ce13f7SAndroid Build Coastguard Worker 
1012*03ce13f7SAndroid Build Coastguard Worker   enum AFL_FLAGS1 { AFL_FLAGS1_NONE = 0, AFL_FLAGS1_ODDSPREG = 1 };
1013*03ce13f7SAndroid Build Coastguard Worker 
1014*03ce13f7SAndroid Build Coastguard Worker   enum AFL_FLAGS2 { AFL_FLAGS2_NONE = 0 };
1015*03ce13f7SAndroid Build Coastguard Worker 
1016*03ce13f7SAndroid Build Coastguard Worker   uint16_t Version = AFL_VERSION_V0;
1017*03ce13f7SAndroid Build Coastguard Worker   uint8_t ISALevel = AFL_ISA_LEVEL_MIPS32;
1018*03ce13f7SAndroid Build Coastguard Worker   uint8_t ISARevision = AFL_ISA_REV_R1;
1019*03ce13f7SAndroid Build Coastguard Worker   uint8_t GPRSize = AFL_REG_32;
1020*03ce13f7SAndroid Build Coastguard Worker   uint8_t CPR1Size = AFL_REG_32;
1021*03ce13f7SAndroid Build Coastguard Worker   uint8_t CPR2Size = AFL_REG_NONE;
1022*03ce13f7SAndroid Build Coastguard Worker   uint8_t FPABI = AFL_FP_DOUBLE;
1023*03ce13f7SAndroid Build Coastguard Worker   uint32_t Extension = AFL_EXT_NONE;
1024*03ce13f7SAndroid Build Coastguard Worker   uint32_t ASE = AFL_ASE_NONE;
1025*03ce13f7SAndroid Build Coastguard Worker   uint32_t Flags1 = AFL_FLAGS1_ODDSPREG;
1026*03ce13f7SAndroid Build Coastguard Worker   uint32_t Flags2 = AFL_FLAGS2_NONE;
1027*03ce13f7SAndroid Build Coastguard Worker 
1028*03ce13f7SAndroid Build Coastguard Worker   MipsABIFlagsSection() = default;
1029*03ce13f7SAndroid Build Coastguard Worker };
1030*03ce13f7SAndroid Build Coastguard Worker 
1031*03ce13f7SAndroid Build Coastguard Worker } // end of namespace MIPS32
1032*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
1033*03ce13f7SAndroid Build Coastguard Worker 
1034*03ce13f7SAndroid Build Coastguard Worker #endif // SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H
1035