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.

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

mercurial