MoveEmitter-arm64.h (3131B)
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 #ifndef jit_arm64_MoveEmitter_arm64_h 8 #define jit_arm64_MoveEmitter_arm64_h 9 10 #include "mozilla/Assertions.h" 11 12 #include <stdint.h> 13 14 #include "jit/arm64/Assembler-arm64.h" 15 #include "jit/MacroAssembler.h" 16 #include "jit/MoveResolver.h" 17 #include "jit/Registers.h" 18 19 namespace js { 20 namespace jit { 21 22 class CodeGenerator; 23 24 class MoveEmitterARM64 { 25 bool inCycle_; 26 MacroAssembler& masm; 27 28 // A scratch general register used to break cycles. 29 ARMRegister cycleGeneralReg_; 30 31 // Original stack push value. 32 uint32_t pushedAtStart_; 33 34 // This stores a stack offset to a spill location, snapshotting 35 // codegen->framePushed_ at the time it was allocated. It is -1 if no 36 // stack space has been allocated for that particular spill. 37 int32_t pushedAtCycle_; 38 39 void assertDone() { MOZ_ASSERT(!inCycle_); } 40 41 MemOperand cycleSlot(); 42 MemOperand toMemOperand(const MoveOperand& operand) const; 43 ARMRegister toARMReg32(const MoveOperand& operand) const { 44 MOZ_ASSERT(operand.isGeneralReg()); 45 return ARMRegister(operand.reg(), 32); 46 } 47 ARMRegister toARMReg64(const MoveOperand& operand) const { 48 if (operand.isGeneralReg()) { 49 return ARMRegister(operand.reg(), 64); 50 } else { 51 return ARMRegister(operand.base(), 64); 52 } 53 } 54 ARMFPRegister toFPReg(const MoveOperand& operand, MoveOp::Type t) const { 55 MOZ_ASSERT(operand.isFloatReg()); 56 switch (t) { 57 case MoveOp::FLOAT32: 58 return ARMFPRegister(operand.floatReg().encoding(), 32); 59 case MoveOp::DOUBLE: 60 return ARMFPRegister(operand.floatReg().encoding(), 64); 61 case MoveOp::SIMD128: 62 return ARMFPRegister(operand.floatReg().encoding(), 128); 63 default: 64 MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Bad register type"); 65 } 66 } 67 68 void emitFloat32Move(const MoveOperand& from, const MoveOperand& to); 69 void emitDoubleMove(const MoveOperand& from, const MoveOperand& to); 70 void emitSimd128Move(const MoveOperand& from, const MoveOperand& to); 71 void emitInt32Move(const MoveOperand& from, const MoveOperand& to); 72 void emitGeneralMove(const MoveOperand& from, const MoveOperand& to); 73 74 void emitMove(const MoveOp& move); 75 void breakCycle(const MoveOperand& from, const MoveOperand& to, 76 MoveOp::Type type); 77 void completeCycle(const MoveOperand& from, const MoveOperand& to, 78 MoveOp::Type type); 79 80 public: 81 explicit MoveEmitterARM64(MacroAssembler& masm) 82 : inCycle_(false), 83 masm(masm), 84 pushedAtStart_(masm.framePushed()), 85 pushedAtCycle_(-1) {} 86 87 ~MoveEmitterARM64() { assertDone(); } 88 89 void emit(const MoveResolver& moves); 90 void finish(); 91 void setScratchRegister(Register reg) {} 92 }; 93 94 using MoveEmitter = MoveEmitterARM64; 95 96 } // namespace jit 97 } // namespace js 98 99 #endif /* jit_arm64_MoveEmitter_arm64_h */