js/src/jit/mips/CodeGenerator-mips.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: set ts=8 sts=4 et sw=4 tw=99:
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef jit_mips_CodeGenerator_mips_h
michael@0 8 #define jit_mips_CodeGenerator_mips_h
michael@0 9
michael@0 10 #include "jit/mips/Assembler-mips.h"
michael@0 11 #include "jit/shared/CodeGenerator-shared.h"
michael@0 12
michael@0 13 namespace js {
michael@0 14 namespace jit {
michael@0 15
michael@0 16 class OutOfLineBailout;
michael@0 17 class OutOfLineTableSwitch;
michael@0 18
michael@0 19 class CodeGeneratorMIPS : public CodeGeneratorShared
michael@0 20 {
michael@0 21 friend class MoveResolverMIPS;
michael@0 22
michael@0 23 CodeGeneratorMIPS *thisFromCtor() {
michael@0 24 return this;
michael@0 25 }
michael@0 26
michael@0 27 protected:
michael@0 28 // Label for the common return path.
michael@0 29 NonAssertingLabel returnLabel_;
michael@0 30 NonAssertingLabel deoptLabel_;
michael@0 31
michael@0 32 inline Address ToAddress(const LAllocation &a) {
michael@0 33 MOZ_ASSERT(a.isMemory());
michael@0 34 int32_t offset = ToStackOffset(&a);
michael@0 35
michael@0 36 // The way the stack slots work, we assume that everything from
michael@0 37 // depth == 0 downwards is writable however, since our frame is
michael@0 38 // included in this, ensure that the frame gets skipped.
michael@0 39 if (gen->compilingAsmJS())
michael@0 40 offset -= AlignmentMidPrologue;
michael@0 41
michael@0 42 return Address(StackPointer, offset);
michael@0 43 }
michael@0 44
michael@0 45 inline Address ToAddress(const LAllocation *a) {
michael@0 46 return ToAddress(*a);
michael@0 47 }
michael@0 48
michael@0 49 inline Operand ToOperand(const LAllocation &a) {
michael@0 50 if (a.isGeneralReg())
michael@0 51 return Operand(a.toGeneralReg()->reg());
michael@0 52 if (a.isFloatReg())
michael@0 53 return Operand(a.toFloatReg()->reg());
michael@0 54
michael@0 55 MOZ_ASSERT(a.isMemory());
michael@0 56 int32_t offset = ToStackOffset(&a);
michael@0 57
michael@0 58 // The way the stack slots work, we assume that everything from
michael@0 59 // depth == 0 downwards is writable however, since our frame is
michael@0 60 // included in this, ensure that the frame gets skipped.
michael@0 61 if (gen->compilingAsmJS())
michael@0 62 offset -= AlignmentMidPrologue;
michael@0 63
michael@0 64 return Operand(StackPointer, offset);
michael@0 65 }
michael@0 66 inline Operand ToOperand(const LAllocation *a) {
michael@0 67 return ToOperand(*a);
michael@0 68 }
michael@0 69 inline Operand ToOperand(const LDefinition *def) {
michael@0 70 return ToOperand(def->output());
michael@0 71 }
michael@0 72
michael@0 73 MoveOperand toMoveOperand(const LAllocation *a) const;
michael@0 74
michael@0 75 template <typename T1, typename T2>
michael@0 76 bool bailoutCmp32(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) {
michael@0 77 bool goodBailout;
michael@0 78 Label skip;
michael@0 79 masm.ma_b(lhs, rhs, &skip, Assembler::InvertCondition(c), ShortJump);
michael@0 80 goodBailout = bailout(snapshot);
michael@0 81 masm.bind(&skip);
michael@0 82 return goodBailout;
michael@0 83 }
michael@0 84 template<typename T>
michael@0 85 bool bailoutCmp32(Assembler::Condition c, Operand lhs, T rhs, LSnapshot *snapshot) {
michael@0 86 if (lhs.getTag() == Operand::REG)
michael@0 87 return bailoutCmp32(c, lhs.toReg(), rhs, snapshot);
michael@0 88 if (lhs.getTag() == Operand::MEM)
michael@0 89 return bailoutCmp32(c, lhs.toAddress(), rhs, snapshot);
michael@0 90 MOZ_ASSUME_UNREACHABLE("Invalid operand tag.");
michael@0 91 return false;
michael@0 92 }
michael@0 93 template<typename T>
michael@0 94 bool bailoutTest32(Assembler::Condition c, Register lhs, T rhs, LSnapshot *snapshot) {
michael@0 95 Label bail;
michael@0 96 masm.branchTest32(c, lhs, rhs, &bail);
michael@0 97 return bailoutFrom(&bail, snapshot);
michael@0 98 }
michael@0 99 template <typename T1, typename T2>
michael@0 100 bool bailoutCmpPtr(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) {
michael@0 101 return bailoutCmp32(c, lhs, rhs, snapshot);
michael@0 102 }
michael@0 103 bool bailoutTestPtr(Assembler::Condition c, Register lhs, Register rhs, LSnapshot *snapshot) {
michael@0 104 Label bail;
michael@0 105 masm.branchTestPtr(c, lhs, rhs, &bail);
michael@0 106 return bailoutFrom(&bail, snapshot);
michael@0 107 }
michael@0 108
michael@0 109 bool bailoutFrom(Label *label, LSnapshot *snapshot);
michael@0 110 bool bailout(LSnapshot *snapshot);
michael@0 111
michael@0 112 protected:
michael@0 113 bool generatePrologue();
michael@0 114 bool generateEpilogue();
michael@0 115 bool generateOutOfLineCode();
michael@0 116
michael@0 117 template <typename T>
michael@0 118 void branchToBlock(Register lhs, T rhs, MBasicBlock *mir, Assembler::Condition cond)
michael@0 119 {
michael@0 120 Label *label = mir->lir()->label();
michael@0 121 if (Label *oolEntry = labelForBackedgeWithImplicitCheck(mir)) {
michael@0 122 // Note: the backedge is initially a jump to the next instruction.
michael@0 123 // It will be patched to the target block's label during link().
michael@0 124 RepatchLabel rejoin;
michael@0 125 CodeOffsetJump backedge;
michael@0 126 Label skip;
michael@0 127
michael@0 128 masm.ma_b(lhs, rhs, &skip, Assembler::InvertCondition(cond), ShortJump);
michael@0 129 backedge = masm.jumpWithPatch(&rejoin);
michael@0 130 masm.bind(&rejoin);
michael@0 131 masm.bind(&skip);
michael@0 132
michael@0 133 if (!patchableBackedges_.append(PatchableBackedgeInfo(backedge, label, oolEntry)))
michael@0 134 MOZ_CRASH();
michael@0 135 } else {
michael@0 136 masm.ma_b(lhs, rhs, label, cond);
michael@0 137 }
michael@0 138 }
michael@0 139 void branchToBlock(Assembler::FloatFormat fmt, FloatRegister lhs, FloatRegister rhs,
michael@0 140 MBasicBlock *mir, Assembler::DoubleCondition cond);
michael@0 141
michael@0 142 // Emits a branch that directs control flow to the true block if |cond| is
michael@0 143 // true, and the false block if |cond| is false.
michael@0 144 template <typename T>
michael@0 145 void emitBranch(Register lhs, T rhs, Assembler::Condition cond,
michael@0 146 MBasicBlock *mirTrue, MBasicBlock *mirFalse)
michael@0 147 {
michael@0 148 if (isNextBlock(mirFalse->lir())) {
michael@0 149 branchToBlock(lhs, rhs, mirTrue, cond);
michael@0 150 } else {
michael@0 151 branchToBlock(lhs, rhs, mirFalse, Assembler::InvertCondition(cond));
michael@0 152 jumpToBlock(mirTrue);
michael@0 153 }
michael@0 154 }
michael@0 155 void testNullEmitBranch(Assembler::Condition cond, const ValueOperand &value,
michael@0 156 MBasicBlock *ifTrue, MBasicBlock *ifFalse)
michael@0 157 {
michael@0 158 emitBranch(value.typeReg(), (Imm32)ImmType(JSVAL_TYPE_NULL), cond, ifTrue, ifFalse);
michael@0 159 }
michael@0 160 void testUndefinedEmitBranch(Assembler::Condition cond, const ValueOperand &value,
michael@0 161 MBasicBlock *ifTrue, MBasicBlock *ifFalse)
michael@0 162 {
michael@0 163 emitBranch(value.typeReg(), (Imm32)ImmType(JSVAL_TYPE_UNDEFINED), cond, ifTrue, ifFalse);
michael@0 164 }
michael@0 165
michael@0 166 bool emitTableSwitchDispatch(MTableSwitch *mir, const Register &index, const Register &base);
michael@0 167
michael@0 168 public:
michael@0 169 // Instruction visitors.
michael@0 170 virtual bool visitMinMaxD(LMinMaxD *ins);
michael@0 171 virtual bool visitAbsD(LAbsD *ins);
michael@0 172 virtual bool visitAbsF(LAbsF *ins);
michael@0 173 virtual bool visitSqrtD(LSqrtD *ins);
michael@0 174 virtual bool visitSqrtF(LSqrtF *ins);
michael@0 175 virtual bool visitAddI(LAddI *ins);
michael@0 176 virtual bool visitSubI(LSubI *ins);
michael@0 177 virtual bool visitBitNotI(LBitNotI *ins);
michael@0 178 virtual bool visitBitOpI(LBitOpI *ins);
michael@0 179
michael@0 180 virtual bool visitMulI(LMulI *ins);
michael@0 181
michael@0 182 virtual bool visitDivI(LDivI *ins);
michael@0 183 virtual bool visitDivPowTwoI(LDivPowTwoI *ins);
michael@0 184 virtual bool visitModI(LModI *ins);
michael@0 185 virtual bool visitModPowTwoI(LModPowTwoI *ins);
michael@0 186 virtual bool visitModMaskI(LModMaskI *ins);
michael@0 187 virtual bool visitPowHalfD(LPowHalfD *ins);
michael@0 188 virtual bool visitShiftI(LShiftI *ins);
michael@0 189 virtual bool visitUrshD(LUrshD *ins);
michael@0 190
michael@0 191 virtual bool visitTestIAndBranch(LTestIAndBranch *test);
michael@0 192 virtual bool visitCompare(LCompare *comp);
michael@0 193 virtual bool visitCompareAndBranch(LCompareAndBranch *comp);
michael@0 194 virtual bool visitTestDAndBranch(LTestDAndBranch *test);
michael@0 195 virtual bool visitTestFAndBranch(LTestFAndBranch *test);
michael@0 196 virtual bool visitCompareD(LCompareD *comp);
michael@0 197 virtual bool visitCompareF(LCompareF *comp);
michael@0 198 virtual bool visitCompareDAndBranch(LCompareDAndBranch *comp);
michael@0 199 virtual bool visitCompareFAndBranch(LCompareFAndBranch *comp);
michael@0 200 virtual bool visitCompareB(LCompareB *lir);
michael@0 201 virtual bool visitCompareBAndBranch(LCompareBAndBranch *lir);
michael@0 202 virtual bool visitCompareV(LCompareV *lir);
michael@0 203 virtual bool visitCompareVAndBranch(LCompareVAndBranch *lir);
michael@0 204 virtual bool visitBitAndAndBranch(LBitAndAndBranch *lir);
michael@0 205 virtual bool visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir);
michael@0 206 virtual bool visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir);
michael@0 207 virtual bool visitNotI(LNotI *ins);
michael@0 208 virtual bool visitNotD(LNotD *ins);
michael@0 209 virtual bool visitNotF(LNotF *ins);
michael@0 210
michael@0 211 virtual bool visitMathD(LMathD *math);
michael@0 212 virtual bool visitMathF(LMathF *math);
michael@0 213 virtual bool visitFloor(LFloor *lir);
michael@0 214 virtual bool visitFloorF(LFloorF *lir);
michael@0 215 virtual bool visitRound(LRound *lir);
michael@0 216 virtual bool visitRoundF(LRoundF *lir);
michael@0 217 virtual bool visitTruncateDToInt32(LTruncateDToInt32 *ins);
michael@0 218 virtual bool visitTruncateFToInt32(LTruncateFToInt32 *ins);
michael@0 219
michael@0 220 // Out of line visitors.
michael@0 221 bool visitOutOfLineBailout(OutOfLineBailout *ool);
michael@0 222 bool visitOutOfLineTableSwitch(OutOfLineTableSwitch *ool);
michael@0 223
michael@0 224 protected:
michael@0 225 ValueOperand ToValue(LInstruction *ins, size_t pos);
michael@0 226 ValueOperand ToOutValue(LInstruction *ins);
michael@0 227 ValueOperand ToTempValue(LInstruction *ins, size_t pos);
michael@0 228
michael@0 229 // Functions for LTestVAndBranch.
michael@0 230 Register splitTagForTest(const ValueOperand &value);
michael@0 231
michael@0 232 void storeElementTyped(const LAllocation *value, MIRType valueType, MIRType elementType,
michael@0 233 const Register &elements, const LAllocation *index);
michael@0 234
michael@0 235 public:
michael@0 236 CodeGeneratorMIPS(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm);
michael@0 237
michael@0 238 public:
michael@0 239 bool visitBox(LBox *box);
michael@0 240 bool visitBoxFloatingPoint(LBoxFloatingPoint *box);
michael@0 241 bool visitUnbox(LUnbox *unbox);
michael@0 242 bool visitValue(LValue *value);
michael@0 243 bool visitDouble(LDouble *ins);
michael@0 244 bool visitFloat32(LFloat32 *ins);
michael@0 245
michael@0 246 bool visitLoadSlotV(LLoadSlotV *load);
michael@0 247 bool visitLoadSlotT(LLoadSlotT *load);
michael@0 248 bool visitStoreSlotT(LStoreSlotT *load);
michael@0 249
michael@0 250 bool visitLoadElementT(LLoadElementT *load);
michael@0 251
michael@0 252 bool visitGuardShape(LGuardShape *guard);
michael@0 253 bool visitGuardObjectType(LGuardObjectType *guard);
michael@0 254 bool visitGuardClass(LGuardClass *guard);
michael@0 255 bool visitImplicitThis(LImplicitThis *lir);
michael@0 256
michael@0 257 bool visitInterruptCheck(LInterruptCheck *lir);
michael@0 258
michael@0 259 bool visitNegI(LNegI *lir);
michael@0 260 bool visitNegD(LNegD *lir);
michael@0 261 bool visitNegF(LNegF *lir);
michael@0 262 bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins);
michael@0 263 bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins);
michael@0 264 bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins);
michael@0 265 bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins);
michael@0 266 bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins);
michael@0 267 bool visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar *ins);
michael@0 268 bool visitAsmJSLoadFuncPtr(LAsmJSLoadFuncPtr *ins);
michael@0 269 bool visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins);
michael@0 270
michael@0 271 bool visitAsmJSPassStackArg(LAsmJSPassStackArg *ins);
michael@0 272
michael@0 273 bool visitForkJoinGetSlice(LForkJoinGetSlice *ins);
michael@0 274
michael@0 275 bool generateInvalidateEpilogue();
michael@0 276 protected:
michael@0 277 void postAsmJSCall(LAsmJSCall *lir) {}
michael@0 278
michael@0 279 bool visitEffectiveAddress(LEffectiveAddress *ins);
michael@0 280 bool visitUDiv(LUDiv *ins);
michael@0 281 bool visitUMod(LUMod *ins);
michael@0 282 };
michael@0 283
michael@0 284 typedef CodeGeneratorMIPS CodeGeneratorSpecific;
michael@0 285
michael@0 286 // An out-of-line bailout thunk.
michael@0 287 class OutOfLineBailout : public OutOfLineCodeBase<CodeGeneratorMIPS>
michael@0 288 {
michael@0 289 LSnapshot *snapshot_;
michael@0 290 uint32_t frameSize_;
michael@0 291
michael@0 292 public:
michael@0 293 OutOfLineBailout(LSnapshot *snapshot, uint32_t frameSize)
michael@0 294 : snapshot_(snapshot),
michael@0 295 frameSize_(frameSize)
michael@0 296 { }
michael@0 297
michael@0 298 bool accept(CodeGeneratorMIPS *codegen);
michael@0 299
michael@0 300 LSnapshot *snapshot() const {
michael@0 301 return snapshot_;
michael@0 302 }
michael@0 303 };
michael@0 304
michael@0 305 } // namespace jit
michael@0 306 } // namespace js
michael@0 307
michael@0 308 #endif /* jit_mips_CodeGenerator_mips_h */

mercurial