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_MoveEmitter_x86_shared_h
8 #define jit_MoveEmitter_x86_shared_h
9 
10 #include "mozilla/Maybe.h"
11 
12 #include <stddef.h>
13 #include <stdint.h>
14 
15 #include "jit/MoveResolver.h"
16 #include "jit/Registers.h"
17 
18 namespace js {
19 namespace jit {
20 
21 struct Address;
22 class MacroAssembler;
23 class Operand;
24 
25 class MoveEmitterX86 {
26   bool inCycle_;
27   MacroAssembler& masm;
28 
29   // Original stack push value.
30   uint32_t pushedAtStart_;
31 
32   // This is a store stack offset for the cycle-break spill slot, snapshotting
33   // codegen->framePushed_ at the time it is allocated. -1 if not allocated.
34   int32_t pushedAtCycle_;
35 
36 #ifdef JS_CODEGEN_X86
37   // Optional scratch register for performing moves.
38   mozilla::Maybe<Register> scratchRegister_;
39 #endif
40 
41   void assertDone();
42   Address cycleSlot();
43   Address toAddress(const MoveOperand& operand) const;
44   Operand toOperand(const MoveOperand& operand) const;
45   Operand toPopOperand(const MoveOperand& operand) const;
46 
47   size_t characterizeCycle(const MoveResolver& moves, size_t i,
48                            bool* allGeneralRegs, bool* allFloatRegs);
49   bool maybeEmitOptimizedCycle(const MoveResolver& moves, size_t i,
50                                bool allGeneralRegs, bool allFloatRegs,
51                                size_t swapCount);
52   void emitInt32Move(const MoveOperand& from, const MoveOperand& to,
53                      const MoveResolver& moves, size_t i);
54   void emitGeneralMove(const MoveOperand& from, const MoveOperand& to,
55                        const MoveResolver& moves, size_t i);
56   void emitFloat32Move(const MoveOperand& from, const MoveOperand& to);
57   void emitDoubleMove(const MoveOperand& from, const MoveOperand& to);
58   void emitSimd128Move(const MoveOperand& from, const MoveOperand& to);
59   void breakCycle(const MoveOperand& to, MoveOp::Type type);
60   void completeCycle(const MoveOperand& to, MoveOp::Type type);
61 
62  public:
63   explicit MoveEmitterX86(MacroAssembler& masm);
64   ~MoveEmitterX86();
65   void emit(const MoveResolver& moves);
66   void finish();
67 
setScratchRegister(Register reg)68   void setScratchRegister(Register reg) {
69 #ifdef JS_CODEGEN_X86
70     scratchRegister_.emplace(reg);
71 #endif
72   }
73 
74   mozilla::Maybe<Register> findScratchRegister(const MoveResolver& moves,
75                                                size_t i);
76 };
77 
78 using MoveEmitter = MoveEmitterX86;
79 
80 }  // namespace jit
81 }  // namespace js
82 
83 #endif /* jit_MoveEmitter_x86_shared_h */
84