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/. */
7 #include "jsapi-tests/testsJit.h"
9 #include "jit/JitCommon.h"
10 #include "jit/Linker.h"
12 #include "jit/MacroAssembler-inl.h"
14 // On entry to the JIT code, save every register.
15 void PrepareJit(js::jit::MacroAssembler
& masm
) {
16 using namespace js::jit
;
17 #if defined(JS_CODEGEN_ARM64)
18 masm
.Mov(PseudoStackPointer64
, sp
);
19 masm
.SetStackPointer64(PseudoStackPointer64
);
21 AllocatableRegisterSet
regs(RegisterSet::All());
22 LiveRegisterSet
save(regs
.asLiveSet());
23 #if defined(JS_CODEGEN_ARM)
24 save
.add(js::jit::d15
);
26 #if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) || \
27 defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
28 save
.add(js::jit::ra
);
29 #elif defined(JS_USE_LINK_REGISTER)
30 save
.add(js::jit::lr
);
32 masm
.PushRegsInMask(save
);
35 // Generate the exit path of the JIT code, which restores every register. Then,
36 // make it executable and run it.
37 bool ExecuteJit(JSContext
* cx
, js::jit::MacroAssembler
& masm
) {
38 using namespace js::jit
;
39 AllocatableRegisterSet
regs(RegisterSet::All());
40 LiveRegisterSet
save(regs
.asLiveSet());
41 #if defined(JS_CODEGEN_ARM)
42 save
.add(js::jit::d15
);
44 #if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) || \
45 defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
46 save
.add(js::jit::ra
);
47 #elif defined(JS_USE_LINK_REGISTER)
48 save
.add(js::jit::lr
);
50 masm
.PopRegsInMask(save
);
51 #if defined(JS_CODEGEN_ARM64)
52 // Return using the value popped into x30.
55 // Reset stack pointer.
56 masm
.SetStackPointer64(PseudoStackPointer64
);
58 // Exit the JIT-ed code using the ABI return style.
67 JitCode
* code
= linker
.newCode(cx
, CodeKind::Other
);
71 if (!ExecutableAllocator::makeExecutableAndFlushICache(code
->raw(),
72 code
->bufferSize())) {
76 JS::AutoSuppressGCAnalysis suppress
;
77 EnterTest test
= code
->as
<EnterTest
>();
78 CALL_GENERATED_0(test
);