MoveEmitter-mips64.cpp (4985B)
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/MoveEmitter-mips64.h" 8 9 #include "jit/MacroAssembler-inl.h" 10 11 using namespace js; 12 using namespace js::jit; 13 14 void MoveEmitterMIPS64::breakCycle(const MoveOperand& from, 15 const MoveOperand& to, MoveOp::Type type, 16 uint32_t slotId) { 17 // There is some pattern: 18 // (A -> B) 19 // (B -> A) 20 // 21 // This case handles (A -> B), which we reach first. We save B, then allow 22 // the original move to continue. 23 switch (type) { 24 case MoveOp::FLOAT32: 25 if (to.isMemory()) { 26 FloatRegister temp = ScratchFloat32Reg; 27 masm.loadFloat32(getAdjustedAddress(to), temp); 28 masm.storeFloat32(temp, cycleSlot(slotId)); 29 } else { 30 masm.storeFloat32(to.floatReg(), cycleSlot(slotId)); 31 } 32 break; 33 case MoveOp::DOUBLE: 34 if (to.isMemory()) { 35 FloatRegister temp = ScratchDoubleReg; 36 masm.loadDouble(getAdjustedAddress(to), temp); 37 masm.storeDouble(temp, cycleSlot(slotId)); 38 } else { 39 masm.storeDouble(to.floatReg(), cycleSlot(slotId)); 40 } 41 break; 42 case MoveOp::INT32: 43 if (to.isMemory()) { 44 Register temp = tempReg(); 45 masm.load32(getAdjustedAddress(to), temp); 46 masm.store32(temp, cycleSlot(0)); 47 } else { 48 // Second scratch register should not be moved by MoveEmitter. 49 MOZ_ASSERT(to.reg() != spilledReg_); 50 masm.store32(to.reg(), cycleSlot(0)); 51 } 52 break; 53 case MoveOp::GENERAL: 54 if (to.isMemory()) { 55 Register temp = tempReg(); 56 masm.loadPtr(getAdjustedAddress(to), temp); 57 masm.storePtr(temp, cycleSlot(0)); 58 } else { 59 // Second scratch register should not be moved by MoveEmitter. 60 MOZ_ASSERT(to.reg() != spilledReg_); 61 masm.storePtr(to.reg(), cycleSlot(0)); 62 } 63 break; 64 default: 65 MOZ_CRASH("Unexpected move type"); 66 } 67 } 68 69 void MoveEmitterMIPS64::completeCycle(const MoveOperand& from, 70 const MoveOperand& to, MoveOp::Type type, 71 uint32_t slotId) { 72 // There is some pattern: 73 // (A -> B) 74 // (B -> A) 75 // 76 // This case handles (B -> A), which we reach last. We emit a move from the 77 // saved value of B, to A. 78 switch (type) { 79 case MoveOp::FLOAT32: 80 if (to.isMemory()) { 81 FloatRegister temp = ScratchFloat32Reg; 82 masm.loadFloat32(cycleSlot(slotId), temp); 83 masm.storeFloat32(temp, getAdjustedAddress(to)); 84 } else { 85 masm.loadFloat32(cycleSlot(slotId), to.floatReg()); 86 } 87 break; 88 case MoveOp::DOUBLE: 89 if (to.isMemory()) { 90 FloatRegister temp = ScratchDoubleReg; 91 masm.loadDouble(cycleSlot(slotId), temp); 92 masm.storeDouble(temp, getAdjustedAddress(to)); 93 } else { 94 masm.loadDouble(cycleSlot(slotId), to.floatReg()); 95 } 96 break; 97 case MoveOp::INT32: 98 MOZ_ASSERT(slotId == 0); 99 if (to.isMemory()) { 100 Register temp = tempReg(); 101 masm.load32(cycleSlot(0), temp); 102 masm.store32(temp, getAdjustedAddress(to)); 103 } else { 104 // Second scratch register should not be moved by MoveEmitter. 105 MOZ_ASSERT(to.reg() != spilledReg_); 106 masm.load32(cycleSlot(0), to.reg()); 107 } 108 break; 109 case MoveOp::GENERAL: 110 MOZ_ASSERT(slotId == 0); 111 if (to.isMemory()) { 112 Register temp = tempReg(); 113 masm.loadPtr(cycleSlot(0), temp); 114 masm.storePtr(temp, getAdjustedAddress(to)); 115 } else { 116 // Second scratch register should not be moved by MoveEmitter. 117 MOZ_ASSERT(to.reg() != spilledReg_); 118 masm.loadPtr(cycleSlot(0), to.reg()); 119 } 120 break; 121 default: 122 MOZ_CRASH("Unexpected move type"); 123 } 124 } 125 126 void MoveEmitterMIPS64::emitDoubleMove(const MoveOperand& from, 127 const MoveOperand& to) { 128 if (from.isFloatReg()) { 129 if (to.isFloatReg()) { 130 masm.moveDouble(from.floatReg(), to.floatReg()); 131 } else if (to.isGeneralReg()) { 132 masm.moveFromDouble(from.floatReg(), to.reg()); 133 } else { 134 MOZ_ASSERT(to.isMemory()); 135 masm.storeDouble(from.floatReg(), getAdjustedAddress(to)); 136 } 137 } else if (to.isFloatReg()) { 138 if (from.isMemory()) { 139 masm.loadDouble(getAdjustedAddress(from), to.floatReg()); 140 } else { 141 masm.moveToDouble(from.reg(), to.floatReg()); 142 } 143 } else { 144 MOZ_ASSERT(from.isMemory()); 145 MOZ_ASSERT(to.isMemory()); 146 masm.loadDouble(getAdjustedAddress(from), ScratchDoubleReg); 147 masm.storeDouble(ScratchDoubleReg, getAdjustedAddress(to)); 148 } 149 }