1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef jit_mips_shared_CodeGenerator_mips_shared_h
8 #define jit_mips_shared_CodeGenerator_mips_shared_h
9 
10 #include "jit/shared/CodeGenerator-shared.h"
11 
12 namespace js {
13 namespace jit {
14 
15 class CodeGeneratorMIPSShared;
16 class OutOfLineBailout;
17 class OutOfLineTableSwitch;
18 
19 using OutOfLineWasmTruncateCheck =
20     OutOfLineWasmTruncateCheckBase<CodeGeneratorMIPSShared>;
21 
22 class CodeGeneratorMIPSShared : public CodeGeneratorShared {
23   friend class MoveResolverMIPS;
24 
25  protected:
26   CodeGeneratorMIPSShared(MIRGenerator* gen, LIRGraph* graph,
27                           MacroAssembler* masm);
28 
29   NonAssertingLabel deoptLabel_;
30 
31   Operand ToOperand(const LAllocation& a);
32   Operand ToOperand(const LAllocation* a);
33   Operand ToOperand(const LDefinition* def);
34 
35 #ifdef JS_PUNBOX64
36   Operand ToOperandOrRegister64(const LInt64Allocation input);
37 #else
38   Register64 ToOperandOrRegister64(const LInt64Allocation input);
39 #endif
40 
41   MoveOperand toMoveOperand(LAllocation a) const;
42 
43   template <typename T1, typename T2>
bailoutCmp32(Assembler::Condition c,T1 lhs,T2 rhs,LSnapshot * snapshot)44   void bailoutCmp32(Assembler::Condition c, T1 lhs, T2 rhs,
45                     LSnapshot* snapshot) {
46     Label bail;
47     masm.branch32(c, lhs, rhs, &bail);
48     bailoutFrom(&bail, snapshot);
49   }
50   template <typename T1, typename T2>
bailoutTest32(Assembler::Condition c,T1 lhs,T2 rhs,LSnapshot * snapshot)51   void bailoutTest32(Assembler::Condition c, T1 lhs, T2 rhs,
52                      LSnapshot* snapshot) {
53     Label bail;
54     masm.branchTest32(c, lhs, rhs, &bail);
55     bailoutFrom(&bail, snapshot);
56   }
57   template <typename T1, typename T2>
bailoutCmpPtr(Assembler::Condition c,T1 lhs,T2 rhs,LSnapshot * snapshot)58   void bailoutCmpPtr(Assembler::Condition c, T1 lhs, T2 rhs,
59                      LSnapshot* snapshot) {
60     Label bail;
61     masm.branchPtr(c, lhs, rhs, &bail);
62     bailoutFrom(&bail, snapshot);
63   }
bailoutTestPtr(Assembler::Condition c,Register lhs,Register rhs,LSnapshot * snapshot)64   void bailoutTestPtr(Assembler::Condition c, Register lhs, Register rhs,
65                       LSnapshot* snapshot) {
66     Label bail;
67     masm.branchTestPtr(c, lhs, rhs, &bail);
68     bailoutFrom(&bail, snapshot);
69   }
bailoutIfFalseBool(Register reg,LSnapshot * snapshot)70   void bailoutIfFalseBool(Register reg, LSnapshot* snapshot) {
71     Label bail;
72     masm.branchTest32(Assembler::Zero, reg, Imm32(0xFF), &bail);
73     bailoutFrom(&bail, snapshot);
74   }
75 
76   void bailoutFrom(Label* label, LSnapshot* snapshot);
77   void bailout(LSnapshot* snapshot);
78 
79   bool generateOutOfLineCode();
80 
81   template <typename T>
branchToBlock(Register lhs,T rhs,MBasicBlock * mir,Assembler::Condition cond)82   void branchToBlock(Register lhs, T rhs, MBasicBlock* mir,
83                      Assembler::Condition cond) {
84     masm.ma_b(lhs, rhs, skipTrivialBlocks(mir)->lir()->label(), cond);
85   }
86   void branchToBlock(Assembler::FloatFormat fmt, FloatRegister lhs,
87                      FloatRegister rhs, MBasicBlock* mir,
88                      Assembler::DoubleCondition cond);
89 
90   // Emits a branch that directs control flow to the true block if |cond| is
91   // true, and the false block if |cond| is false.
92   template <typename T>
emitBranch(Register lhs,T rhs,Assembler::Condition cond,MBasicBlock * mirTrue,MBasicBlock * mirFalse)93   void emitBranch(Register lhs, T rhs, Assembler::Condition cond,
94                   MBasicBlock* mirTrue, MBasicBlock* mirFalse) {
95     if (isNextBlock(mirFalse->lir())) {
96       branchToBlock(lhs, rhs, mirTrue, cond);
97     } else {
98       branchToBlock(lhs, rhs, mirFalse, Assembler::InvertCondition(cond));
99       jumpToBlock(mirTrue);
100     }
101   }
testZeroEmitBranch(Assembler::Condition cond,Register reg,MBasicBlock * ifTrue,MBasicBlock * ifFalse)102   void testZeroEmitBranch(Assembler::Condition cond, Register reg,
103                           MBasicBlock* ifTrue, MBasicBlock* ifFalse) {
104     emitBranch(reg, Imm32(0), cond, ifTrue, ifFalse);
105   }
106 
107   void emitTableSwitchDispatch(MTableSwitch* mir, Register index,
108                                Register base);
109 
110   template <typename T>
111   void emitWasmLoad(T* ins);
112   template <typename T>
113   void emitWasmStore(T* ins);
114 
115   void generateInvalidateEpilogue();
116 
117   // Generating a result.
118   template <typename S, typename T>
119   void atomicBinopToTypedIntArray(AtomicOp op, Scalar::Type arrayType,
120                                   const S& value, const T& mem,
121                                   Register flagTemp, Register outTemp,
122                                   Register valueTemp, Register offsetTemp,
123                                   Register maskTemp, AnyRegister output);
124 
125   // Generating no result.
126   template <typename S, typename T>
127   void atomicBinopToTypedIntArray(AtomicOp op, Scalar::Type arrayType,
128                                   const S& value, const T& mem,
129                                   Register flagTemp, Register valueTemp,
130                                   Register offsetTemp, Register maskTemp);
131 
132  public:
133   // Out of line visitors.
134   void visitOutOfLineBailout(OutOfLineBailout* ool);
135   void visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool);
136   void visitOutOfLineWasmTruncateCheck(OutOfLineWasmTruncateCheck* ool);
137 };
138 
139 // An out-of-line bailout thunk.
140 class OutOfLineBailout : public OutOfLineCodeBase<CodeGeneratorMIPSShared> {
141  protected:
142   LSnapshot* snapshot_;
143   uint32_t frameSize_;
144 
145  public:
OutOfLineBailout(LSnapshot * snapshot,uint32_t frameSize)146   OutOfLineBailout(LSnapshot* snapshot, uint32_t frameSize)
147       : snapshot_(snapshot), frameSize_(frameSize) {}
148 
149   void accept(CodeGeneratorMIPSShared* codegen) override;
150 
snapshot()151   LSnapshot* snapshot() const { return snapshot_; }
152 };
153 
154 }  // namespace jit
155 }  // namespace js
156 
157 #endif /* jit_mips_shared_CodeGenerator_mips_shared_h */
158