Lowering-mips64.cpp (5908B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 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/mips64/Lowering-mips64.h" 8 9 #include "jit/Lowering.h" 10 #include "jit/mips64/Assembler-mips64.h" 11 #include "jit/MIR-wasm.h" 12 #include "jit/MIR.h" 13 14 #include "jit/shared/Lowering-shared-inl.h" 15 16 using namespace js; 17 using namespace js::jit; 18 19 void LIRGeneratorMIPS64::defineInt64Phi(MPhi* phi, size_t lirIndex) { 20 defineTypedPhi(phi, lirIndex); 21 } 22 23 void LIRGeneratorMIPS64::lowerInt64PhiInput(MPhi* phi, uint32_t inputPosition, 24 LBlock* block, size_t lirIndex) { 25 lowerTypedPhiInput(phi, inputPosition, block, lirIndex); 26 } 27 28 LBoxAllocation LIRGeneratorMIPS64::useBoxFixed(MDefinition* mir, Register reg1, 29 Register reg2, bool useAtStart) { 30 MOZ_ASSERT(mir->type() == MIRType::Value); 31 32 ensureDefined(mir); 33 return LBoxAllocation(LUse(reg1, mir->virtualRegister(), useAtStart)); 34 } 35 36 LDefinition LIRGeneratorMIPS64::tempToUnbox() { return temp(); } 37 38 void LIRGeneratorMIPS64::lowerDivI64(MDiv* div) { 39 auto* lir = new (alloc()) 40 LDivOrModI64(useRegister(div->lhs()), useRegister(div->rhs())); 41 defineInt64(lir, div); 42 } 43 44 void LIRGeneratorMIPS64::lowerWasmBuiltinDivI64(MWasmBuiltinDivI64* div) { 45 MOZ_CRASH("We don't use runtime div for this architecture"); 46 } 47 48 void LIRGeneratorMIPS64::lowerModI64(MMod* mod) { 49 auto* lir = new (alloc()) 50 LDivOrModI64(useRegister(mod->lhs()), useRegister(mod->rhs())); 51 defineInt64(lir, mod); 52 } 53 54 void LIRGeneratorMIPS64::lowerWasmBuiltinModI64(MWasmBuiltinModI64* mod) { 55 MOZ_CRASH("We don't use runtime mod for this architecture"); 56 } 57 58 void LIRGeneratorMIPS64::lowerUDivI64(MDiv* div) { 59 auto* lir = new (alloc()) 60 LUDivOrModI64(useRegister(div->lhs()), useRegister(div->rhs())); 61 defineInt64(lir, div); 62 } 63 64 void LIRGeneratorMIPS64::lowerUModI64(MMod* mod) { 65 auto* lir = new (alloc()) 66 LUDivOrModI64(useRegister(mod->lhs()), useRegister(mod->rhs())); 67 defineInt64(lir, mod); 68 } 69 70 void LIRGeneratorMIPS64::lowerAtomicLoad64(MLoadUnboxedScalar* ins) { 71 const LUse elements = useRegister(ins->elements()); 72 const LAllocation index = 73 useRegisterOrIndexConstant(ins->index(), ins->storageType()); 74 75 auto* lir = new (alloc()) LAtomicLoad64(elements, index); 76 defineInt64(lir, ins); 77 } 78 79 void LIRGeneratorMIPS64::lowerAtomicStore64(MStoreUnboxedScalar* ins) { 80 LUse elements = useRegister(ins->elements()); 81 LAllocation index = 82 useRegisterOrIndexConstant(ins->index(), ins->writeType()); 83 LInt64Allocation value = useInt64Register(ins->value()); 84 85 add(new (alloc()) LAtomicStore64(elements, index, value), ins); 86 } 87 88 void LIRGenerator::visitBox(MBox* box) { 89 MDefinition* opd = box->getOperand(0); 90 91 // If the operand is a constant, emit near its uses. 92 if (opd->isConstant() && box->canEmitAtUses()) { 93 emitAtUses(box); 94 return; 95 } 96 97 if (opd->isConstant()) { 98 define(new (alloc()) LValue(opd->toConstant()->toJSValue()), box, 99 LDefinition(LDefinition::BOX)); 100 } else { 101 LBox* ins = new (alloc()) LBox(useRegisterAtStart(opd), opd->type()); 102 define(ins, box, LDefinition(LDefinition::BOX)); 103 } 104 } 105 106 void LIRGenerator::visitUnbox(MUnbox* unbox) { 107 MDefinition* box = unbox->getOperand(0); 108 MOZ_ASSERT(box->type() == MIRType::Value); 109 110 LInstructionHelper<1, BOX_PIECES, 0>* lir; 111 if (IsFloatingPointType(unbox->type())) { 112 MOZ_ASSERT(unbox->type() == MIRType::Double); 113 lir = new (alloc()) LUnboxFloatingPoint(useBoxAtStart(box)); 114 } else if (unbox->fallible()) { 115 // If the unbox is fallible, load the Value in a register first to 116 // avoid multiple loads. 117 lir = new (alloc()) LUnbox(useRegisterAtStart(box)); 118 } else { 119 lir = new (alloc()) LUnbox(useAtStart(box)); 120 } 121 122 if (unbox->fallible()) { 123 assignSnapshot(lir, unbox->bailoutKind()); 124 } 125 126 define(lir, unbox); 127 } 128 129 void LIRGenerator::visitReturnImpl(MDefinition* opd, bool isGenerator) { 130 MOZ_ASSERT(opd->type() == MIRType::Value); 131 132 LReturn* ins = new (alloc()) LReturn(isGenerator); 133 ins->setOperand(0, useFixed(opd, JSReturnReg)); 134 add(ins); 135 } 136 137 void LIRGeneratorMIPS64::lowerUntypedPhiInput(MPhi* phi, uint32_t inputPosition, 138 LBlock* block, size_t lirIndex) { 139 lowerTypedPhiInput(phi, inputPosition, block, lirIndex); 140 } 141 142 void LIRGeneratorMIPS64::lowerTruncateDToInt32(MTruncateToInt32* ins) { 143 MDefinition* opd = ins->input(); 144 MOZ_ASSERT(opd->type() == MIRType::Double); 145 146 define(new (alloc()) LTruncateDToInt32(useRegister(opd), tempDouble()), ins); 147 } 148 149 void LIRGeneratorMIPS64::lowerTruncateFToInt32(MTruncateToInt32* ins) { 150 MDefinition* opd = ins->input(); 151 MOZ_ASSERT(opd->type() == MIRType::Float32); 152 153 define(new (alloc()) LTruncateFToInt32(useRegister(opd), tempFloat32()), ins); 154 } 155 156 void LIRGenerator::visitWasmTruncateToInt64(MWasmTruncateToInt64* ins) { 157 MDefinition* opd = ins->input(); 158 MOZ_ASSERT(opd->type() == MIRType::Double || opd->type() == MIRType::Float32); 159 160 defineInt64(new (alloc()) LWasmTruncateToInt64(useRegister(opd)), ins); 161 } 162 163 void LIRGeneratorMIPS64::lowerWasmBuiltinTruncateToInt64( 164 MWasmBuiltinTruncateToInt64* ins) { 165 MOZ_CRASH("We don't use it for this architecture"); 166 } 167 168 void LIRGenerator::visitInt64ToFloatingPoint(MInt64ToFloatingPoint* ins) { 169 MDefinition* opd = ins->input(); 170 MOZ_ASSERT(opd->type() == MIRType::Int64); 171 MOZ_ASSERT(IsFloatingPointType(ins->type())); 172 173 define(new (alloc()) LInt64ToFloatingPoint(useInt64Register(opd)), ins); 174 } 175 176 void LIRGeneratorMIPS64::lowerBuiltinInt64ToFloatingPoint( 177 MBuiltinInt64ToFloatingPoint* ins) { 178 MOZ_CRASH("We don't use it for this architecture"); 179 }