Wed, 31 Dec 2014 06:09:35 +0100
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 #include "jit/x64/Lowering-x64.h"
9 #include "jit/MIR.h"
10 #include "jit/x64/Assembler-x64.h"
12 #include "jit/shared/Lowering-shared-inl.h"
14 using namespace js;
15 using namespace js::jit;
17 bool
18 LIRGeneratorX64::useBox(LInstruction *lir, size_t n, MDefinition *mir,
19 LUse::Policy policy, bool useAtStart)
20 {
21 JS_ASSERT(mir->type() == MIRType_Value);
23 if (!ensureDefined(mir))
24 return false;
25 lir->setOperand(n, LUse(mir->virtualRegister(), policy, useAtStart));
26 return true;
27 }
29 bool
30 LIRGeneratorX64::useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, Register)
31 {
32 JS_ASSERT(mir->type() == MIRType_Value);
34 if (!ensureDefined(mir))
35 return false;
36 lir->setOperand(n, LUse(reg1, mir->virtualRegister()));
37 return true;
38 }
40 LAllocation
41 LIRGeneratorX64::useByteOpRegister(MDefinition *mir)
42 {
43 return useRegister(mir);
44 }
46 LAllocation
47 LIRGeneratorX64::useByteOpRegisterOrNonDoubleConstant(MDefinition *mir)
48 {
49 return useRegisterOrNonDoubleConstant(mir);
50 }
52 LDefinition
53 LIRGeneratorX64::tempToUnbox()
54 {
55 return temp();
56 }
58 bool
59 LIRGeneratorX64::visitBox(MBox *box)
60 {
61 MDefinition *opd = box->getOperand(0);
63 // If the operand is a constant, emit near its uses.
64 if (opd->isConstant() && box->canEmitAtUses())
65 return emitAtUses(box);
67 if (opd->isConstant())
68 return define(new(alloc()) LValue(opd->toConstant()->value()), box, LDefinition(LDefinition::BOX));
70 LBox *ins = new(alloc()) LBox(opd->type(), useRegister(opd));
71 return define(ins, box, LDefinition(LDefinition::BOX));
72 }
74 bool
75 LIRGeneratorX64::visitUnbox(MUnbox *unbox)
76 {
77 MDefinition *box = unbox->getOperand(0);
78 LUnboxBase *lir;
79 if (IsFloatingPointType(unbox->type()))
80 lir = new(alloc()) LUnboxFloatingPoint(useRegisterAtStart(box), unbox->type());
81 else
82 lir = new(alloc()) LUnbox(useRegisterAtStart(box));
84 if (unbox->fallible() && !assignSnapshot(lir, unbox->bailoutKind()))
85 return false;
87 return define(lir, unbox);
88 }
90 bool
91 LIRGeneratorX64::visitReturn(MReturn *ret)
92 {
93 MDefinition *opd = ret->getOperand(0);
94 JS_ASSERT(opd->type() == MIRType_Value);
96 LReturn *ins = new(alloc()) LReturn;
97 ins->setOperand(0, useFixed(opd, JSReturnReg));
98 return add(ins);
99 }
101 bool
102 LIRGeneratorX64::defineUntypedPhi(MPhi *phi, size_t lirIndex)
103 {
104 return defineTypedPhi(phi, lirIndex);
105 }
107 void
108 LIRGeneratorX64::lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex)
109 {
110 lowerTypedPhiInput(phi, inputPosition, block, lirIndex);
111 }
113 bool
114 LIRGeneratorX64::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins)
115 {
116 JS_ASSERT(ins->input()->type() == MIRType_Int32);
117 LAsmJSUInt32ToDouble *lir = new(alloc()) LAsmJSUInt32ToDouble(useRegisterAtStart(ins->input()));
118 return define(lir, ins);
119 }
121 bool
122 LIRGeneratorX64::visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32 *ins)
123 {
124 JS_ASSERT(ins->input()->type() == MIRType_Int32);
125 LAsmJSUInt32ToFloat32 *lir = new(alloc()) LAsmJSUInt32ToFloat32(useRegisterAtStart(ins->input()));
126 return define(lir, ins);
127 }
129 bool
130 LIRGeneratorX64::visitAsmJSLoadHeap(MAsmJSLoadHeap *ins)
131 {
132 MDefinition *ptr = ins->ptr();
133 JS_ASSERT(ptr->type() == MIRType_Int32);
135 // The X64 does not inline an explicit bounds check so has no need to keep the
136 // index in a register, however only a positive index is accepted because a
137 // negative offset encoded as an offset in the addressing mode would not wrap
138 // back into the protected area reserved for the heap.
139 if (ptr->isConstant() && ptr->toConstant()->value().toInt32() >= 0) {
140 LAsmJSLoadHeap *lir = new(alloc()) LAsmJSLoadHeap(LAllocation(ptr->toConstant()->vp()));
141 return define(lir, ins);
142 }
143 return define(new(alloc()) LAsmJSLoadHeap(useRegisterAtStart(ptr)), ins);
144 }
146 bool
147 LIRGeneratorX64::visitAsmJSStoreHeap(MAsmJSStoreHeap *ins)
148 {
149 MDefinition *ptr = ins->ptr();
150 JS_ASSERT(ptr->type() == MIRType_Int32);
151 LAsmJSStoreHeap *lir;
153 // Note only a positive constant index is accepted because a negative offset
154 // encoded as an offset in the addressing mode would not wrap back into the
155 // protected area reserved for the heap.
156 LAllocation ptrAlloc = useRegisterOrNonNegativeConstantAtStart(ptr);
157 switch (ins->viewType()) {
158 case ArrayBufferView::TYPE_INT8: case ArrayBufferView::TYPE_UINT8:
159 case ArrayBufferView::TYPE_INT16: case ArrayBufferView::TYPE_UINT16:
160 case ArrayBufferView::TYPE_INT32: case ArrayBufferView::TYPE_UINT32:
161 lir = new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterOrConstantAtStart(ins->value()));
162 break;
163 case ArrayBufferView::TYPE_FLOAT32: case ArrayBufferView::TYPE_FLOAT64:
164 lir = new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterAtStart(ins->value()));
165 break;
166 default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
167 }
169 return add(lir, ins);
170 }
172 bool
173 LIRGeneratorX64::visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins)
174 {
175 return define(new(alloc()) LAsmJSLoadFuncPtr(useRegister(ins->index()), temp()), ins);
176 }
178 bool
179 LIRGeneratorX64::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins)
180 {
181 MOZ_ASSUME_UNREACHABLE("NYI");
182 }