/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "jit/mips64/Lowering-mips64.h" #include "jit/Lowering.h" #include "jit/mips64/Assembler-mips64.h" #include "jit/MIR.h" #include "jit/shared/Lowering-shared-inl.h" using namespace js; using namespace js::jit; void LIRGeneratorMIPS64::defineInt64Phi(MPhi* phi, size_t lirIndex) { defineTypedPhi(phi, lirIndex); } void LIRGeneratorMIPS64::lowerInt64PhiInput(MPhi* phi, uint32_t inputPosition, LBlock* block, size_t lirIndex) { lowerTypedPhiInput(phi, inputPosition, block, lirIndex); } LBoxAllocation LIRGeneratorMIPS64::useBoxFixed(MDefinition* mir, Register reg1, Register reg2, bool useAtStart) { MOZ_ASSERT(mir->type() == MIRType::Value); ensureDefined(mir); return LBoxAllocation(LUse(reg1, mir->virtualRegister(), useAtStart)); } void LIRGeneratorMIPS64::lowerDivI64(MDiv* div) { if (div->isUnsigned()) { lowerUDivI64(div); return; } LDivOrModI64* lir = new (alloc()) LDivOrModI64(useRegister(div->lhs()), useRegister(div->rhs()), temp()); defineInt64(lir, div); } void LIRGeneratorMIPS64::lowerWasmBuiltinDivI64(MWasmBuiltinDivI64* div) { MOZ_CRASH("We don't use runtime div for this architecture"); } void LIRGeneratorMIPS64::lowerModI64(MMod* mod) { if (mod->isUnsigned()) { lowerUModI64(mod); return; } LDivOrModI64* lir = new (alloc()) LDivOrModI64(useRegister(mod->lhs()), useRegister(mod->rhs()), temp()); defineInt64(lir, mod); } void LIRGeneratorMIPS64::lowerWasmBuiltinModI64(MWasmBuiltinModI64* mod) { MOZ_CRASH("We don't use runtime mod for this architecture"); } void LIRGeneratorMIPS64::lowerUDivI64(MDiv* div) { LUDivOrModI64* lir = new (alloc()) LUDivOrModI64(useRegister(div->lhs()), useRegister(div->rhs()), temp()); defineInt64(lir, div); } void LIRGeneratorMIPS64::lowerUModI64(MMod* mod) { LUDivOrModI64* lir = new (alloc()) LUDivOrModI64(useRegister(mod->lhs()), useRegister(mod->rhs()), temp()); defineInt64(lir, mod); } void LIRGeneratorMIPS64::lowerBigIntDiv(MBigIntDiv* ins) { auto* lir = new (alloc()) LBigIntDiv(useRegister(ins->lhs()), useRegister(ins->rhs()), temp(), temp()); define(lir, ins); assignSafepoint(lir, ins); } void LIRGeneratorMIPS64::lowerBigIntMod(MBigIntMod* ins) { auto* lir = new (alloc()) LBigIntMod(useRegister(ins->lhs()), useRegister(ins->rhs()), temp(), temp()); define(lir, ins); assignSafepoint(lir, ins); } void LIRGeneratorMIPS64::lowerAtomicLoad64(MLoadUnboxedScalar* ins) { const LUse elements = useRegister(ins->elements()); const LAllocation index = useRegisterOrIndexConstant(ins->index(), ins->storageType()); auto* lir = new (alloc()) LAtomicLoad64(elements, index, temp(), tempInt64()); define(lir, ins); assignSafepoint(lir, ins); } void LIRGeneratorMIPS64::lowerAtomicStore64(MStoreUnboxedScalar* ins) { LUse elements = useRegister(ins->elements()); LAllocation index = useRegisterOrIndexConstant(ins->index(), ins->writeType()); LAllocation value = useRegister(ins->value()); add(new (alloc()) LAtomicStore64(elements, index, value, tempInt64()), ins); } void LIRGenerator::visitBox(MBox* box) { MDefinition* opd = box->getOperand(0); // If the operand is a constant, emit near its uses. if (opd->isConstant() && box->canEmitAtUses()) { emitAtUses(box); return; } if (opd->isConstant()) { define(new (alloc()) LValue(opd->toConstant()->toJSValue()), box, LDefinition(LDefinition::BOX)); } else { LBox* ins = new (alloc()) LBox(useRegister(opd), opd->type()); define(ins, box, LDefinition(LDefinition::BOX)); } } void LIRGenerator::visitUnbox(MUnbox* unbox) { MDefinition* box = unbox->getOperand(0); MOZ_ASSERT(box->type() == MIRType::Value); LUnbox* lir; if (IsFloatingPointType(unbox->type())) { lir = new (alloc()) LUnboxFloatingPoint(useRegisterAtStart(box), unbox->type()); } else if (unbox->fallible()) { // If the unbox is fallible, load the Value in a register first to // avoid multiple loads. lir = new (alloc()) LUnbox(useRegisterAtStart(box)); } else { lir = new (alloc()) LUnbox(useAtStart(box)); } if (unbox->fallible()) { assignSnapshot(lir, unbox->bailoutKind()); } define(lir, unbox); } void LIRGenerator::visitReturnImpl(MDefinition* opd, bool isGenerator) { MOZ_ASSERT(opd->type() == MIRType::Value); LReturn* ins = new (alloc()) LReturn(isGenerator); ins->setOperand(0, useFixed(opd, JSReturnReg)); add(ins); } void LIRGeneratorMIPS64::lowerUntypedPhiInput(MPhi* phi, uint32_t inputPosition, LBlock* block, size_t lirIndex) { lowerTypedPhiInput(phi, inputPosition, block, lirIndex); } void LIRGeneratorMIPS64::lowerTruncateDToInt32(MTruncateToInt32* ins) { MDefinition* opd = ins->input(); MOZ_ASSERT(opd->type() == MIRType::Double); define(new (alloc()) LTruncateDToInt32(useRegister(opd), tempDouble()), ins); } void LIRGeneratorMIPS64::lowerTruncateFToInt32(MTruncateToInt32* ins) { MDefinition* opd = ins->input(); MOZ_ASSERT(opd->type() == MIRType::Float32); define(new (alloc()) LTruncateFToInt32(useRegister(opd), tempFloat32()), ins); } void LIRGenerator::visitWasmTruncateToInt64(MWasmTruncateToInt64* ins) { MDefinition* opd = ins->input(); MOZ_ASSERT(opd->type() == MIRType::Double || opd->type() == MIRType::Float32); defineInt64(new (alloc()) LWasmTruncateToInt64(useRegister(opd)), ins); } void LIRGeneratorMIPS64::lowerWasmBuiltinTruncateToInt64( MWasmBuiltinTruncateToInt64* ins) { MOZ_CRASH("We don't use it for this architecture"); } void LIRGenerator::visitInt64ToFloatingPoint(MInt64ToFloatingPoint* ins) { MDefinition* opd = ins->input(); MOZ_ASSERT(opd->type() == MIRType::Int64); MOZ_ASSERT(IsFloatingPointType(ins->type())); define(new (alloc()) LInt64ToFloatingPoint(useInt64Register(opd)), ins); } void LIRGeneratorMIPS64::lowerBuiltinInt64ToFloatingPoint( MBuiltinInt64ToFloatingPoint* ins) { MOZ_CRASH("We don't use it for this architecture"); }