1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim: set ts=8 sts=4 et sw=4 tw=99:
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 "jit/arm64/Assembler-arm64.h"
11 #include "jit/MacroAssembler.h"
12 #include "jit/MoveResolver.h"
13 
14 namespace js {
15 namespace jit {
16 
17 class CodeGenerator;
18 
19 class MoveEmitterARM64
20 {
21     bool inCycle_;
22     MacroAssembler& masm;
23 
24     // Original stack push value.
25     uint32_t pushedAtStart_;
26 
27     // These store stack offsets to spill locations, snapshotting
28     // codegen->framePushed_ at the time they were allocated. They are -1 if no
29     // stack space has been allocated for that particular spill.
30     int32_t pushedAtCycle_;
31     int32_t pushedAtSpill_;
32 
33     void assertDone() {
34         MOZ_ASSERT(!inCycle_);
35     }
36 
37     MemOperand cycleSlot();
38     MemOperand toMemOperand(const MoveOperand& operand) const;
39     ARMRegister toARMReg32(const MoveOperand& operand) const {
40         MOZ_ASSERT(operand.isGeneralReg());
41         return ARMRegister(operand.reg(), 32);
42     }
43     ARMRegister toARMReg64(const MoveOperand& operand) const {
44         if (operand.isGeneralReg())
45             return ARMRegister(operand.reg(), 64);
46         else
47             return ARMRegister(operand.base(), 64);
48     }
49     ARMFPRegister toFPReg(const MoveOperand& operand, MoveOp::Type t) const {
50         MOZ_ASSERT(operand.isFloatReg());
51         return ARMFPRegister(operand.floatReg().encoding(), t == MoveOp::FLOAT32 ? 32 : 64);
52     }
53 
54     void emitFloat32Move(const MoveOperand& from, const MoveOperand& to);
55     void emitDoubleMove(const MoveOperand& from, const MoveOperand& to);
56     void emitInt32Move(const MoveOperand& from, const MoveOperand& to);
57     void emitGeneralMove(const MoveOperand& from, const MoveOperand& to);
58 
59     void emitMove(const MoveOp& move);
60     void breakCycle(const MoveOperand& from, const MoveOperand& to, MoveOp::Type type);
61     void completeCycle(const MoveOperand& from, const MoveOperand& to, MoveOp::Type type);
62 
63   public:
64     MoveEmitterARM64(MacroAssembler& masm)
65       : inCycle_(false),
66         masm(masm),
67         pushedAtStart_(masm.framePushed()),
68         pushedAtCycle_(-1),
69         pushedAtSpill_(-1)
70     { }
71 
72     ~MoveEmitterARM64() {
73         assertDone();
74     }
75 
76     void emit(const MoveResolver& moves);
77     void finish();
78     void setScratchRegister(Register reg) {}
79 };
80 
81 typedef MoveEmitterARM64 MoveEmitter;
82 
83 } // namespace jit
84 } // namespace js
85 
86 #endif /* jit_arm64_MoveEmitter_arm64_h */
87