1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jit/x64/Lowering-x64.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,182 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "jit/x64/Lowering-x64.h" 1.11 + 1.12 +#include "jit/MIR.h" 1.13 +#include "jit/x64/Assembler-x64.h" 1.14 + 1.15 +#include "jit/shared/Lowering-shared-inl.h" 1.16 + 1.17 +using namespace js; 1.18 +using namespace js::jit; 1.19 + 1.20 +bool 1.21 +LIRGeneratorX64::useBox(LInstruction *lir, size_t n, MDefinition *mir, 1.22 + LUse::Policy policy, bool useAtStart) 1.23 +{ 1.24 + JS_ASSERT(mir->type() == MIRType_Value); 1.25 + 1.26 + if (!ensureDefined(mir)) 1.27 + return false; 1.28 + lir->setOperand(n, LUse(mir->virtualRegister(), policy, useAtStart)); 1.29 + return true; 1.30 +} 1.31 + 1.32 +bool 1.33 +LIRGeneratorX64::useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, Register) 1.34 +{ 1.35 + JS_ASSERT(mir->type() == MIRType_Value); 1.36 + 1.37 + if (!ensureDefined(mir)) 1.38 + return false; 1.39 + lir->setOperand(n, LUse(reg1, mir->virtualRegister())); 1.40 + return true; 1.41 +} 1.42 + 1.43 +LAllocation 1.44 +LIRGeneratorX64::useByteOpRegister(MDefinition *mir) 1.45 +{ 1.46 + return useRegister(mir); 1.47 +} 1.48 + 1.49 +LAllocation 1.50 +LIRGeneratorX64::useByteOpRegisterOrNonDoubleConstant(MDefinition *mir) 1.51 +{ 1.52 + return useRegisterOrNonDoubleConstant(mir); 1.53 +} 1.54 + 1.55 +LDefinition 1.56 +LIRGeneratorX64::tempToUnbox() 1.57 +{ 1.58 + return temp(); 1.59 +} 1.60 + 1.61 +bool 1.62 +LIRGeneratorX64::visitBox(MBox *box) 1.63 +{ 1.64 + MDefinition *opd = box->getOperand(0); 1.65 + 1.66 + // If the operand is a constant, emit near its uses. 1.67 + if (opd->isConstant() && box->canEmitAtUses()) 1.68 + return emitAtUses(box); 1.69 + 1.70 + if (opd->isConstant()) 1.71 + return define(new(alloc()) LValue(opd->toConstant()->value()), box, LDefinition(LDefinition::BOX)); 1.72 + 1.73 + LBox *ins = new(alloc()) LBox(opd->type(), useRegister(opd)); 1.74 + return define(ins, box, LDefinition(LDefinition::BOX)); 1.75 +} 1.76 + 1.77 +bool 1.78 +LIRGeneratorX64::visitUnbox(MUnbox *unbox) 1.79 +{ 1.80 + MDefinition *box = unbox->getOperand(0); 1.81 + LUnboxBase *lir; 1.82 + if (IsFloatingPointType(unbox->type())) 1.83 + lir = new(alloc()) LUnboxFloatingPoint(useRegisterAtStart(box), unbox->type()); 1.84 + else 1.85 + lir = new(alloc()) LUnbox(useRegisterAtStart(box)); 1.86 + 1.87 + if (unbox->fallible() && !assignSnapshot(lir, unbox->bailoutKind())) 1.88 + return false; 1.89 + 1.90 + return define(lir, unbox); 1.91 +} 1.92 + 1.93 +bool 1.94 +LIRGeneratorX64::visitReturn(MReturn *ret) 1.95 +{ 1.96 + MDefinition *opd = ret->getOperand(0); 1.97 + JS_ASSERT(opd->type() == MIRType_Value); 1.98 + 1.99 + LReturn *ins = new(alloc()) LReturn; 1.100 + ins->setOperand(0, useFixed(opd, JSReturnReg)); 1.101 + return add(ins); 1.102 +} 1.103 + 1.104 +bool 1.105 +LIRGeneratorX64::defineUntypedPhi(MPhi *phi, size_t lirIndex) 1.106 +{ 1.107 + return defineTypedPhi(phi, lirIndex); 1.108 +} 1.109 + 1.110 +void 1.111 +LIRGeneratorX64::lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex) 1.112 +{ 1.113 + lowerTypedPhiInput(phi, inputPosition, block, lirIndex); 1.114 +} 1.115 + 1.116 +bool 1.117 +LIRGeneratorX64::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins) 1.118 +{ 1.119 + JS_ASSERT(ins->input()->type() == MIRType_Int32); 1.120 + LAsmJSUInt32ToDouble *lir = new(alloc()) LAsmJSUInt32ToDouble(useRegisterAtStart(ins->input())); 1.121 + return define(lir, ins); 1.122 +} 1.123 + 1.124 +bool 1.125 +LIRGeneratorX64::visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32 *ins) 1.126 +{ 1.127 + JS_ASSERT(ins->input()->type() == MIRType_Int32); 1.128 + LAsmJSUInt32ToFloat32 *lir = new(alloc()) LAsmJSUInt32ToFloat32(useRegisterAtStart(ins->input())); 1.129 + return define(lir, ins); 1.130 +} 1.131 + 1.132 +bool 1.133 +LIRGeneratorX64::visitAsmJSLoadHeap(MAsmJSLoadHeap *ins) 1.134 +{ 1.135 + MDefinition *ptr = ins->ptr(); 1.136 + JS_ASSERT(ptr->type() == MIRType_Int32); 1.137 + 1.138 + // The X64 does not inline an explicit bounds check so has no need to keep the 1.139 + // index in a register, however only a positive index is accepted because a 1.140 + // negative offset encoded as an offset in the addressing mode would not wrap 1.141 + // back into the protected area reserved for the heap. 1.142 + if (ptr->isConstant() && ptr->toConstant()->value().toInt32() >= 0) { 1.143 + LAsmJSLoadHeap *lir = new(alloc()) LAsmJSLoadHeap(LAllocation(ptr->toConstant()->vp())); 1.144 + return define(lir, ins); 1.145 + } 1.146 + return define(new(alloc()) LAsmJSLoadHeap(useRegisterAtStart(ptr)), ins); 1.147 +} 1.148 + 1.149 +bool 1.150 +LIRGeneratorX64::visitAsmJSStoreHeap(MAsmJSStoreHeap *ins) 1.151 +{ 1.152 + MDefinition *ptr = ins->ptr(); 1.153 + JS_ASSERT(ptr->type() == MIRType_Int32); 1.154 + LAsmJSStoreHeap *lir; 1.155 + 1.156 + // Note only a positive constant index is accepted because a negative offset 1.157 + // encoded as an offset in the addressing mode would not wrap back into the 1.158 + // protected area reserved for the heap. 1.159 + LAllocation ptrAlloc = useRegisterOrNonNegativeConstantAtStart(ptr); 1.160 + switch (ins->viewType()) { 1.161 + case ArrayBufferView::TYPE_INT8: case ArrayBufferView::TYPE_UINT8: 1.162 + case ArrayBufferView::TYPE_INT16: case ArrayBufferView::TYPE_UINT16: 1.163 + case ArrayBufferView::TYPE_INT32: case ArrayBufferView::TYPE_UINT32: 1.164 + lir = new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterOrConstantAtStart(ins->value())); 1.165 + break; 1.166 + case ArrayBufferView::TYPE_FLOAT32: case ArrayBufferView::TYPE_FLOAT64: 1.167 + lir = new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterAtStart(ins->value())); 1.168 + break; 1.169 + default: MOZ_ASSUME_UNREACHABLE("unexpected array type"); 1.170 + } 1.171 + 1.172 + return add(lir, ins); 1.173 +} 1.174 + 1.175 +bool 1.176 +LIRGeneratorX64::visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins) 1.177 +{ 1.178 + return define(new(alloc()) LAsmJSLoadFuncPtr(useRegister(ins->index()), temp()), ins); 1.179 +} 1.180 + 1.181 +bool 1.182 +LIRGeneratorX64::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins) 1.183 +{ 1.184 + MOZ_ASSUME_UNREACHABLE("NYI"); 1.185 +}