|
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/. */ |
|
6 |
|
7 #include "jit/x64/Lowering-x64.h" |
|
8 |
|
9 #include "jit/MIR.h" |
|
10 #include "jit/x64/Assembler-x64.h" |
|
11 |
|
12 #include "jit/shared/Lowering-shared-inl.h" |
|
13 |
|
14 using namespace js; |
|
15 using namespace js::jit; |
|
16 |
|
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); |
|
22 |
|
23 if (!ensureDefined(mir)) |
|
24 return false; |
|
25 lir->setOperand(n, LUse(mir->virtualRegister(), policy, useAtStart)); |
|
26 return true; |
|
27 } |
|
28 |
|
29 bool |
|
30 LIRGeneratorX64::useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, Register) |
|
31 { |
|
32 JS_ASSERT(mir->type() == MIRType_Value); |
|
33 |
|
34 if (!ensureDefined(mir)) |
|
35 return false; |
|
36 lir->setOperand(n, LUse(reg1, mir->virtualRegister())); |
|
37 return true; |
|
38 } |
|
39 |
|
40 LAllocation |
|
41 LIRGeneratorX64::useByteOpRegister(MDefinition *mir) |
|
42 { |
|
43 return useRegister(mir); |
|
44 } |
|
45 |
|
46 LAllocation |
|
47 LIRGeneratorX64::useByteOpRegisterOrNonDoubleConstant(MDefinition *mir) |
|
48 { |
|
49 return useRegisterOrNonDoubleConstant(mir); |
|
50 } |
|
51 |
|
52 LDefinition |
|
53 LIRGeneratorX64::tempToUnbox() |
|
54 { |
|
55 return temp(); |
|
56 } |
|
57 |
|
58 bool |
|
59 LIRGeneratorX64::visitBox(MBox *box) |
|
60 { |
|
61 MDefinition *opd = box->getOperand(0); |
|
62 |
|
63 // If the operand is a constant, emit near its uses. |
|
64 if (opd->isConstant() && box->canEmitAtUses()) |
|
65 return emitAtUses(box); |
|
66 |
|
67 if (opd->isConstant()) |
|
68 return define(new(alloc()) LValue(opd->toConstant()->value()), box, LDefinition(LDefinition::BOX)); |
|
69 |
|
70 LBox *ins = new(alloc()) LBox(opd->type(), useRegister(opd)); |
|
71 return define(ins, box, LDefinition(LDefinition::BOX)); |
|
72 } |
|
73 |
|
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)); |
|
83 |
|
84 if (unbox->fallible() && !assignSnapshot(lir, unbox->bailoutKind())) |
|
85 return false; |
|
86 |
|
87 return define(lir, unbox); |
|
88 } |
|
89 |
|
90 bool |
|
91 LIRGeneratorX64::visitReturn(MReturn *ret) |
|
92 { |
|
93 MDefinition *opd = ret->getOperand(0); |
|
94 JS_ASSERT(opd->type() == MIRType_Value); |
|
95 |
|
96 LReturn *ins = new(alloc()) LReturn; |
|
97 ins->setOperand(0, useFixed(opd, JSReturnReg)); |
|
98 return add(ins); |
|
99 } |
|
100 |
|
101 bool |
|
102 LIRGeneratorX64::defineUntypedPhi(MPhi *phi, size_t lirIndex) |
|
103 { |
|
104 return defineTypedPhi(phi, lirIndex); |
|
105 } |
|
106 |
|
107 void |
|
108 LIRGeneratorX64::lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex) |
|
109 { |
|
110 lowerTypedPhiInput(phi, inputPosition, block, lirIndex); |
|
111 } |
|
112 |
|
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 } |
|
120 |
|
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 } |
|
128 |
|
129 bool |
|
130 LIRGeneratorX64::visitAsmJSLoadHeap(MAsmJSLoadHeap *ins) |
|
131 { |
|
132 MDefinition *ptr = ins->ptr(); |
|
133 JS_ASSERT(ptr->type() == MIRType_Int32); |
|
134 |
|
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 } |
|
145 |
|
146 bool |
|
147 LIRGeneratorX64::visitAsmJSStoreHeap(MAsmJSStoreHeap *ins) |
|
148 { |
|
149 MDefinition *ptr = ins->ptr(); |
|
150 JS_ASSERT(ptr->type() == MIRType_Int32); |
|
151 LAsmJSStoreHeap *lir; |
|
152 |
|
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 } |
|
168 |
|
169 return add(lir, ins); |
|
170 } |
|
171 |
|
172 bool |
|
173 LIRGeneratorX64::visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins) |
|
174 { |
|
175 return define(new(alloc()) LAsmJSLoadFuncPtr(useRegister(ins->index()), temp()), ins); |
|
176 } |
|
177 |
|
178 bool |
|
179 LIRGeneratorX64::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins) |
|
180 { |
|
181 MOZ_ASSUME_UNREACHABLE("NYI"); |
|
182 } |