]>
git.saurik.com Git - apple/javascriptcore.git/blob - ftl/FTLSaveRestore.cpp
2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "FTLSaveRestore.h"
33 #include "MacroAssembler.h"
34 #include "RegisterSet.h"
36 namespace JSC
{ namespace FTL
{
38 static size_t bytesForGPRs()
40 return MacroAssembler::numberOfRegisters() * sizeof(int64_t);
43 static size_t bytesForFPRs()
45 // FIXME: It might be worthwhile saving the full state of the FP registers, at some point.
46 // Right now we don't need this since we only do the save/restore just prior to OSR exit, and
47 // OSR exit will be guaranteed to only need the double portion of the FP registers.
48 return MacroAssembler::numberOfFPRegisters() * sizeof(double);
51 size_t requiredScratchMemorySizeInBytes()
53 return bytesForGPRs() + bytesForFPRs();
56 size_t offsetOfGPR(GPRReg reg
)
58 return MacroAssembler::registerIndex(reg
) * sizeof(int64_t);
61 size_t offsetOfFPR(FPRReg reg
)
63 return bytesForGPRs() + MacroAssembler::fpRegisterIndex(reg
) * sizeof(double);
66 size_t offsetOfReg(Reg reg
)
69 return offsetOfGPR(reg
.gpr());
70 return offsetOfFPR(reg
.fpr());
78 special
= RegisterSet::stackRegisters();
79 special
.merge(RegisterSet::reservedHardwareRegisters());
81 first
= MacroAssembler::firstRegister();
82 while (special
.get(first
))
83 first
= MacroAssembler::nextRegister(first
);
84 second
= MacroAssembler::nextRegister(first
);
85 while (special
.get(second
))
86 second
= MacroAssembler::nextRegister(second
);
94 } // anonymous namespace
96 void saveAllRegisters(MacroAssembler
& jit
, char* scratchMemory
)
100 // Get the first register out of the way, so that we can use it as a pointer.
101 jit
.poke64(regs
.first
, 0);
102 jit
.move(MacroAssembler::TrustedImmPtr(scratchMemory
), regs
.first
);
104 // Get all of the other GPRs out of the way.
105 for (MacroAssembler::RegisterID reg
= regs
.second
; reg
<= MacroAssembler::lastRegister(); reg
= MacroAssembler::nextRegister(reg
)) {
106 if (regs
.special
.get(reg
))
108 jit
.store64(reg
, MacroAssembler::Address(regs
.first
, offsetOfGPR(reg
)));
111 // Restore the first register into the second one and save it.
112 jit
.peek64(regs
.second
, 0);
113 jit
.store64(regs
.second
, MacroAssembler::Address(regs
.first
, offsetOfGPR(regs
.first
)));
115 // Finally save all FPR's.
116 for (MacroAssembler::FPRegisterID reg
= MacroAssembler::firstFPRegister(); reg
<= MacroAssembler::lastFPRegister(); reg
= MacroAssembler::nextFPRegister(reg
)) {
117 if (regs
.special
.get(reg
))
119 jit
.storeDouble(reg
, MacroAssembler::Address(regs
.first
, offsetOfFPR(reg
)));
123 void restoreAllRegisters(MacroAssembler
& jit
, char* scratchMemory
)
127 // Give ourselves a pointer to the scratch memory.
128 jit
.move(MacroAssembler::TrustedImmPtr(scratchMemory
), regs
.first
);
130 // Restore all FPR's.
131 for (MacroAssembler::FPRegisterID reg
= MacroAssembler::firstFPRegister(); reg
<= MacroAssembler::lastFPRegister(); reg
= MacroAssembler::nextFPRegister(reg
)) {
132 if (regs
.special
.get(reg
))
134 jit
.loadDouble(MacroAssembler::Address(regs
.first
, offsetOfFPR(reg
)), reg
);
137 for (MacroAssembler::RegisterID reg
= regs
.second
; reg
<= MacroAssembler::lastRegister(); reg
= MacroAssembler::nextRegister(reg
)) {
138 if (regs
.special
.get(reg
))
140 jit
.load64(MacroAssembler::Address(regs
.first
, offsetOfGPR(reg
)), reg
);
143 jit
.load64(MacroAssembler::Address(regs
.first
, offsetOfGPR(regs
.first
)), regs
.first
);
146 } } // namespace JSC::FTL
148 #endif // ENABLE(FTL_JIT)