asmjit 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/asmjit.gemspec +1 -1
- data/ext/asmjit/asmjit/.editorconfig +10 -0
- data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
- data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
- data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
- data/ext/asmjit/asmjit/.gitignore +6 -0
- data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
- data/ext/asmjit/asmjit/LICENSE.md +17 -0
- data/ext/asmjit/asmjit/README.md +69 -0
- data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
- data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
- data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
- data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
- data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
- data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
- data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
- data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
- data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
- data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
- data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
- data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
- data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
- data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
- data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
- data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
- data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
- data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
- data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
- data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
- data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
- data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
- data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
- data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
- data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
- data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
- data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
- data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
- data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
- data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
- data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
- data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
- data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
- data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
- data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
- data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
- data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
- data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
- data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
- data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
- data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
- data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
- data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
- data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
- data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
- data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
- data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
- data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
- data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
- data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
- data/ext/asmjit/asmjit/test/broken.cpp +312 -0
- data/ext/asmjit/asmjit/test/broken.h +148 -0
- data/ext/asmjit/asmjit/test/cmdline.h +61 -0
- data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
- data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
- data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
- data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
- data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
- data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
- data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
- data/ext/asmjit/asmjit.cc +18 -0
- data/lib/asmjit/version.rb +1 -1
- metadata +197 -2
@@ -0,0 +1,619 @@
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
2
|
+
//
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
4
|
+
// SPDX-License-Identifier: Zlib
|
5
|
+
|
6
|
+
#include "../core/api-build_p.h"
|
7
|
+
#if !defined(ASMJIT_NO_X86)
|
8
|
+
|
9
|
+
#include "../core/formatter.h"
|
10
|
+
#include "../core/funcargscontext_p.h"
|
11
|
+
#include "../core/string.h"
|
12
|
+
#include "../core/support.h"
|
13
|
+
#include "../core/type.h"
|
14
|
+
#include "../core/radefs_p.h"
|
15
|
+
#include "../x86/x86emithelper_p.h"
|
16
|
+
#include "../x86/x86emitter.h"
|
17
|
+
#include "../x86/x86formatter_p.h"
|
18
|
+
#include "../x86/x86instapi_p.h"
|
19
|
+
|
20
|
+
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
|
21
|
+
|
22
|
+
// x86::EmitHelper - Utilities
|
23
|
+
// ===========================
|
24
|
+
|
25
|
+
static inline uint32_t getXmmMovInst(const FuncFrame& frame) {
|
26
|
+
bool avx = frame.isAvxEnabled();
|
27
|
+
bool aligned = frame.hasAlignedVecSR();
|
28
|
+
|
29
|
+
return aligned ? (avx ? Inst::kIdVmovaps : Inst::kIdMovaps)
|
30
|
+
: (avx ? Inst::kIdVmovups : Inst::kIdMovups);
|
31
|
+
}
|
32
|
+
|
33
|
+
//! Converts `size` to a 'kmov?' instruction.
|
34
|
+
static inline uint32_t kmovInstFromSize(uint32_t size) noexcept {
|
35
|
+
switch (size) {
|
36
|
+
case 1: return Inst::kIdKmovb;
|
37
|
+
case 2: return Inst::kIdKmovw;
|
38
|
+
case 4: return Inst::kIdKmovd;
|
39
|
+
case 8: return Inst::kIdKmovq;
|
40
|
+
default: return Inst::kIdNone;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
static inline uint32_t makeCastOp(TypeId dst, TypeId src) noexcept {
|
45
|
+
return (uint32_t(dst) << 8) | uint32_t(src);
|
46
|
+
}
|
47
|
+
|
48
|
+
// x86::EmitHelper - Emit Reg Move
|
49
|
+
// ===============================
|
50
|
+
|
51
|
+
ASMJIT_FAVOR_SIZE Error EmitHelper::emitRegMove(
|
52
|
+
const Operand_& dst_,
|
53
|
+
const Operand_& src_, TypeId typeId, const char* comment) {
|
54
|
+
|
55
|
+
// Invalid or abstract TypeIds are not allowed.
|
56
|
+
ASMJIT_ASSERT(TypeUtils::isValid(typeId) && !TypeUtils::isAbstract(typeId));
|
57
|
+
|
58
|
+
Operand dst(dst_);
|
59
|
+
Operand src(src_);
|
60
|
+
|
61
|
+
InstId instId = Inst::kIdNone;
|
62
|
+
uint32_t memFlags = 0;
|
63
|
+
uint32_t overrideMemSize = 0;
|
64
|
+
|
65
|
+
enum MemFlags : uint32_t {
|
66
|
+
kDstMem = 0x1,
|
67
|
+
kSrcMem = 0x2
|
68
|
+
};
|
69
|
+
|
70
|
+
// Detect memory operands and patch them to have the same size as the register. BaseCompiler always sets memory size
|
71
|
+
// of allocs and spills, so it shouldn't be really necessary, however, after this function was separated from Compiler
|
72
|
+
// it's better to make sure that the size is always specified, as we can use 'movzx' and 'movsx' that rely on it.
|
73
|
+
if (dst.isMem()) { memFlags |= kDstMem; dst.as<Mem>().setSize(src.size()); }
|
74
|
+
if (src.isMem()) { memFlags |= kSrcMem; src.as<Mem>().setSize(dst.size()); }
|
75
|
+
|
76
|
+
switch (typeId) {
|
77
|
+
case TypeId::kInt8:
|
78
|
+
case TypeId::kUInt8:
|
79
|
+
case TypeId::kInt16:
|
80
|
+
case TypeId::kUInt16:
|
81
|
+
// Special case - 'movzx' load.
|
82
|
+
if (memFlags & kSrcMem) {
|
83
|
+
instId = Inst::kIdMovzx;
|
84
|
+
dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
|
85
|
+
break;
|
86
|
+
}
|
87
|
+
|
88
|
+
if (!memFlags) {
|
89
|
+
// Change both destination and source registers to GPD (safer, no dependencies).
|
90
|
+
dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
|
91
|
+
src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
|
92
|
+
}
|
93
|
+
ASMJIT_FALLTHROUGH;
|
94
|
+
|
95
|
+
case TypeId::kInt32:
|
96
|
+
case TypeId::kUInt32:
|
97
|
+
case TypeId::kInt64:
|
98
|
+
case TypeId::kUInt64:
|
99
|
+
instId = Inst::kIdMov;
|
100
|
+
break;
|
101
|
+
|
102
|
+
case TypeId::kMmx32:
|
103
|
+
instId = Inst::kIdMovd;
|
104
|
+
if (memFlags) break;
|
105
|
+
ASMJIT_FALLTHROUGH;
|
106
|
+
|
107
|
+
case TypeId::kMmx64 : instId = Inst::kIdMovq ; break;
|
108
|
+
case TypeId::kMask8 : instId = Inst::kIdKmovb; break;
|
109
|
+
case TypeId::kMask16: instId = Inst::kIdKmovw; break;
|
110
|
+
case TypeId::kMask32: instId = Inst::kIdKmovd; break;
|
111
|
+
case TypeId::kMask64: instId = Inst::kIdKmovq; break;
|
112
|
+
|
113
|
+
default: {
|
114
|
+
TypeId scalarTypeId = TypeUtils::scalarOf(typeId);
|
115
|
+
if (TypeUtils::isVec32(typeId) && memFlags) {
|
116
|
+
overrideMemSize = 4;
|
117
|
+
if (scalarTypeId == TypeId::kFloat32)
|
118
|
+
instId = _avxEnabled ? Inst::kIdVmovss : Inst::kIdMovss;
|
119
|
+
else
|
120
|
+
instId = _avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
|
121
|
+
break;
|
122
|
+
}
|
123
|
+
|
124
|
+
if (TypeUtils::isVec64(typeId) && memFlags) {
|
125
|
+
overrideMemSize = 8;
|
126
|
+
if (scalarTypeId == TypeId::kFloat64)
|
127
|
+
instId = _avxEnabled ? Inst::kIdVmovsd : Inst::kIdMovsd;
|
128
|
+
else
|
129
|
+
instId = _avxEnabled ? Inst::kIdVmovq : Inst::kIdMovq;
|
130
|
+
break;
|
131
|
+
}
|
132
|
+
|
133
|
+
if (scalarTypeId == TypeId::kFloat32)
|
134
|
+
instId = _avxEnabled ? Inst::kIdVmovaps : Inst::kIdMovaps;
|
135
|
+
else if (scalarTypeId == TypeId::kFloat64)
|
136
|
+
instId = _avxEnabled ? Inst::kIdVmovapd : Inst::kIdMovapd;
|
137
|
+
else if (!_avx512Enabled)
|
138
|
+
instId = _avxEnabled ? Inst::kIdVmovdqa : Inst::kIdMovdqa;
|
139
|
+
else
|
140
|
+
instId = Inst::kIdVmovdqa32;
|
141
|
+
break;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
if (!instId)
|
146
|
+
return DebugUtils::errored(kErrorInvalidState);
|
147
|
+
|
148
|
+
if (overrideMemSize) {
|
149
|
+
if (dst.isMem()) dst.as<Mem>().setSize(overrideMemSize);
|
150
|
+
if (src.isMem()) src.as<Mem>().setSize(overrideMemSize);
|
151
|
+
}
|
152
|
+
|
153
|
+
_emitter->setInlineComment(comment);
|
154
|
+
return _emitter->emit(instId, dst, src);
|
155
|
+
}
|
156
|
+
|
157
|
+
// x86::EmitHelper - Emit Arg Move
|
158
|
+
// ===============================
|
159
|
+
|
160
|
+
ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
|
161
|
+
const BaseReg& dst_, TypeId dstTypeId,
|
162
|
+
const Operand_& src_, TypeId srcTypeId, const char* comment) {
|
163
|
+
|
164
|
+
// Deduce optional `dstTypeId`, which may be `TypeId::kVoid` in some cases.
|
165
|
+
if (dstTypeId == TypeId::kVoid) {
|
166
|
+
const ArchTraits& archTraits = ArchTraits::byArch(_emitter->arch());
|
167
|
+
dstTypeId = archTraits.regTypeToTypeId(dst_.type());
|
168
|
+
}
|
169
|
+
|
170
|
+
// Invalid or abstract TypeIds are not allowed.
|
171
|
+
ASMJIT_ASSERT(TypeUtils::isValid(dstTypeId) && !TypeUtils::isAbstract(dstTypeId));
|
172
|
+
ASMJIT_ASSERT(TypeUtils::isValid(srcTypeId) && !TypeUtils::isAbstract(srcTypeId));
|
173
|
+
|
174
|
+
Reg dst(dst_.as<Reg>());
|
175
|
+
Operand src(src_);
|
176
|
+
|
177
|
+
uint32_t dstSize = TypeUtils::sizeOf(dstTypeId);
|
178
|
+
uint32_t srcSize = TypeUtils::sizeOf(srcTypeId);
|
179
|
+
|
180
|
+
InstId instId = Inst::kIdNone;
|
181
|
+
|
182
|
+
// Not a real loop, just 'break' is nicer than 'goto'.
|
183
|
+
for (;;) {
|
184
|
+
if (TypeUtils::isInt(dstTypeId)) {
|
185
|
+
if (TypeUtils::isInt(srcTypeId)) {
|
186
|
+
instId = Inst::kIdMovsx;
|
187
|
+
uint32_t castOp = makeCastOp(dstTypeId, srcTypeId);
|
188
|
+
|
189
|
+
// Sign extend by using 'movsx'.
|
190
|
+
if (castOp == makeCastOp(TypeId::kInt16, TypeId::kInt8 ) ||
|
191
|
+
castOp == makeCastOp(TypeId::kInt32, TypeId::kInt8 ) ||
|
192
|
+
castOp == makeCastOp(TypeId::kInt32, TypeId::kInt16) ||
|
193
|
+
castOp == makeCastOp(TypeId::kInt64, TypeId::kInt8 ) ||
|
194
|
+
castOp == makeCastOp(TypeId::kInt64, TypeId::kInt16))
|
195
|
+
break;
|
196
|
+
|
197
|
+
// Sign extend by using 'movsxd'.
|
198
|
+
instId = Inst::kIdMovsxd;
|
199
|
+
if (castOp == makeCastOp(TypeId::kInt64, TypeId::kInt32))
|
200
|
+
break;
|
201
|
+
}
|
202
|
+
|
203
|
+
if (TypeUtils::isInt(srcTypeId) || src_.isMem()) {
|
204
|
+
// Zero extend by using 'movzx' or 'mov'.
|
205
|
+
if (dstSize <= 4 && srcSize < 4) {
|
206
|
+
instId = Inst::kIdMovzx;
|
207
|
+
dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
|
208
|
+
}
|
209
|
+
else {
|
210
|
+
// We should have caught all possibilities where `srcSize` is less than 4, so we don't have to worry
|
211
|
+
// about 'movzx' anymore. Minimum size is enough to determine if we want 32-bit or 64-bit move.
|
212
|
+
instId = Inst::kIdMov;
|
213
|
+
srcSize = Support::min(srcSize, dstSize);
|
214
|
+
|
215
|
+
dst.setSignature(srcSize == 4 ? Reg::signatureOfT<RegType::kX86_Gpd>()
|
216
|
+
: Reg::signatureOfT<RegType::kX86_Gpq>());
|
217
|
+
if (src.isReg())
|
218
|
+
src.setSignature(dst.signature());
|
219
|
+
}
|
220
|
+
break;
|
221
|
+
}
|
222
|
+
|
223
|
+
// NOTE: The previous branch caught all memory sources, from here it's always register to register conversion,
|
224
|
+
// so catch the remaining cases.
|
225
|
+
srcSize = Support::min(srcSize, dstSize);
|
226
|
+
|
227
|
+
if (TypeUtils::isMmx(srcTypeId)) {
|
228
|
+
// 64-bit move.
|
229
|
+
instId = Inst::kIdMovq;
|
230
|
+
if (srcSize == 8)
|
231
|
+
break;
|
232
|
+
|
233
|
+
// 32-bit move.
|
234
|
+
instId = Inst::kIdMovd;
|
235
|
+
dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
|
236
|
+
break;
|
237
|
+
}
|
238
|
+
|
239
|
+
if (TypeUtils::isMask(srcTypeId)) {
|
240
|
+
instId = kmovInstFromSize(srcSize);
|
241
|
+
dst.setSignature(srcSize <= 4 ? Reg::signatureOfT<RegType::kX86_Gpd>()
|
242
|
+
: Reg::signatureOfT<RegType::kX86_Gpq>());
|
243
|
+
break;
|
244
|
+
}
|
245
|
+
|
246
|
+
if (TypeUtils::isVec(srcTypeId)) {
|
247
|
+
// 64-bit move.
|
248
|
+
instId = _avxEnabled ? Inst::kIdVmovq : Inst::kIdMovq;
|
249
|
+
if (srcSize == 8)
|
250
|
+
break;
|
251
|
+
|
252
|
+
// 32-bit move.
|
253
|
+
instId = _avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
|
254
|
+
dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
|
255
|
+
break;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
if (TypeUtils::isMmx(dstTypeId)) {
|
260
|
+
instId = Inst::kIdMovq;
|
261
|
+
srcSize = Support::min(srcSize, dstSize);
|
262
|
+
|
263
|
+
if (TypeUtils::isInt(srcTypeId) || src.isMem()) {
|
264
|
+
// 64-bit move.
|
265
|
+
if (srcSize == 8)
|
266
|
+
break;
|
267
|
+
|
268
|
+
// 32-bit move.
|
269
|
+
instId = Inst::kIdMovd;
|
270
|
+
if (src.isReg())
|
271
|
+
src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
|
272
|
+
break;
|
273
|
+
}
|
274
|
+
|
275
|
+
if (TypeUtils::isMmx(srcTypeId))
|
276
|
+
break;
|
277
|
+
|
278
|
+
// This will hurt if AVX is enabled.
|
279
|
+
instId = Inst::kIdMovdq2q;
|
280
|
+
if (TypeUtils::isVec(srcTypeId))
|
281
|
+
break;
|
282
|
+
}
|
283
|
+
|
284
|
+
if (TypeUtils::isMask(dstTypeId)) {
|
285
|
+
srcSize = Support::min(srcSize, dstSize);
|
286
|
+
|
287
|
+
if (TypeUtils::isInt(srcTypeId) || TypeUtils::isMask(srcTypeId) || src.isMem()) {
|
288
|
+
instId = kmovInstFromSize(srcSize);
|
289
|
+
if (Reg::isGp(src) && srcSize <= 4)
|
290
|
+
src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
|
291
|
+
break;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
if (TypeUtils::isVec(dstTypeId)) {
|
296
|
+
// By default set destination to XMM, will be set to YMM|ZMM if needed.
|
297
|
+
dst.setSignature(Reg::signatureOfT<RegType::kX86_Xmm>());
|
298
|
+
|
299
|
+
// This will hurt if AVX is enabled.
|
300
|
+
if (Reg::isMm(src)) {
|
301
|
+
// 64-bit move.
|
302
|
+
instId = Inst::kIdMovq2dq;
|
303
|
+
break;
|
304
|
+
}
|
305
|
+
|
306
|
+
// Argument conversion.
|
307
|
+
TypeId dstScalarId = TypeUtils::scalarOf(dstTypeId);
|
308
|
+
TypeId srcScalarId = TypeUtils::scalarOf(srcTypeId);
|
309
|
+
|
310
|
+
if (dstScalarId == TypeId::kFloat32 && srcScalarId == TypeId::kFloat64) {
|
311
|
+
srcSize = Support::min(dstSize * 2, srcSize);
|
312
|
+
dstSize = srcSize / 2;
|
313
|
+
|
314
|
+
if (srcSize <= 8)
|
315
|
+
instId = _avxEnabled ? Inst::kIdVcvtss2sd : Inst::kIdCvtss2sd;
|
316
|
+
else
|
317
|
+
instId = _avxEnabled ? Inst::kIdVcvtps2pd : Inst::kIdCvtps2pd;
|
318
|
+
|
319
|
+
if (dstSize == 32)
|
320
|
+
dst.setSignature(Reg::signatureOfT<RegType::kX86_Ymm>());
|
321
|
+
if (src.isReg())
|
322
|
+
src.setSignature(Reg::signatureOfVecBySize(srcSize));
|
323
|
+
break;
|
324
|
+
}
|
325
|
+
|
326
|
+
if (dstScalarId == TypeId::kFloat64 && srcScalarId == TypeId::kFloat32) {
|
327
|
+
srcSize = Support::min(dstSize, srcSize * 2) / 2;
|
328
|
+
dstSize = srcSize * 2;
|
329
|
+
|
330
|
+
if (srcSize <= 4)
|
331
|
+
instId = _avxEnabled ? Inst::kIdVcvtsd2ss : Inst::kIdCvtsd2ss;
|
332
|
+
else
|
333
|
+
instId = _avxEnabled ? Inst::kIdVcvtpd2ps : Inst::kIdCvtpd2ps;
|
334
|
+
|
335
|
+
dst.setSignature(Reg::signatureOfVecBySize(dstSize));
|
336
|
+
if (src.isReg() && srcSize >= 32)
|
337
|
+
src.setSignature(Reg::signatureOfT<RegType::kX86_Ymm>());
|
338
|
+
break;
|
339
|
+
}
|
340
|
+
|
341
|
+
srcSize = Support::min(srcSize, dstSize);
|
342
|
+
if (Reg::isGp(src) || src.isMem()) {
|
343
|
+
// 32-bit move.
|
344
|
+
if (srcSize <= 4) {
|
345
|
+
instId = _avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
|
346
|
+
if (src.isReg())
|
347
|
+
src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
|
348
|
+
break;
|
349
|
+
}
|
350
|
+
|
351
|
+
// 64-bit move.
|
352
|
+
if (srcSize == 8) {
|
353
|
+
instId = _avxEnabled ? Inst::kIdVmovq : Inst::kIdMovq;
|
354
|
+
break;
|
355
|
+
}
|
356
|
+
}
|
357
|
+
|
358
|
+
if (Reg::isVec(src) || src.isMem()) {
|
359
|
+
instId = _avxEnabled ? Inst::kIdVmovaps : Inst::kIdMovaps;
|
360
|
+
|
361
|
+
if (src.isMem() && srcSize < _emitter->environment().stackAlignment())
|
362
|
+
instId = _avxEnabled ? Inst::kIdVmovups : Inst::kIdMovups;
|
363
|
+
|
364
|
+
OperandSignature signature = Reg::signatureOfVecBySize(srcSize);
|
365
|
+
dst.setSignature(signature);
|
366
|
+
if (src.isReg())
|
367
|
+
src.setSignature(signature);
|
368
|
+
break;
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
return DebugUtils::errored(kErrorInvalidState);
|
373
|
+
}
|
374
|
+
|
375
|
+
if (src.isMem())
|
376
|
+
src.as<Mem>().setSize(srcSize);
|
377
|
+
|
378
|
+
_emitter->setInlineComment(comment);
|
379
|
+
return _emitter->emit(instId, dst, src);
|
380
|
+
}
|
381
|
+
|
382
|
+
Error EmitHelper::emitRegSwap(
|
383
|
+
const BaseReg& a,
|
384
|
+
const BaseReg& b, const char* comment) {
|
385
|
+
|
386
|
+
if (a.isGp() && b.isGp()) {
|
387
|
+
_emitter->setInlineComment(comment);
|
388
|
+
return _emitter->emit(Inst::kIdXchg, a, b);
|
389
|
+
}
|
390
|
+
else
|
391
|
+
return DebugUtils::errored(kErrorInvalidState);
|
392
|
+
}
|
393
|
+
|
394
|
+
// x86::EmitHelper - Emit Prolog & Epilog
|
395
|
+
// ======================================
|
396
|
+
|
397
|
+
static inline void X86Internal_setupSaveRestoreInfo(RegGroup group, const FuncFrame& frame, Reg& xReg, uint32_t& xInst, uint32_t& xSize) noexcept {
|
398
|
+
switch (group) {
|
399
|
+
case RegGroup::kVec:
|
400
|
+
xReg = xmm(0);
|
401
|
+
xInst = getXmmMovInst(frame);
|
402
|
+
xSize = xReg.size();
|
403
|
+
break;
|
404
|
+
case RegGroup::kX86_K:
|
405
|
+
xReg = k(0);
|
406
|
+
xInst = Inst::kIdKmovq;
|
407
|
+
xSize = xReg.size();
|
408
|
+
break;
|
409
|
+
case RegGroup::kX86_MM:
|
410
|
+
xReg = mm(0);
|
411
|
+
xInst = Inst::kIdMovq;
|
412
|
+
xSize = xReg.size();
|
413
|
+
break;
|
414
|
+
default:
|
415
|
+
break;
|
416
|
+
}
|
417
|
+
}
|
418
|
+
|
419
|
+
ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
|
420
|
+
Emitter* emitter = _emitter->as<Emitter>();
|
421
|
+
uint32_t gpSaved = frame.savedRegs(RegGroup::kGp);
|
422
|
+
|
423
|
+
Gp zsp = emitter->zsp(); // ESP|RSP register.
|
424
|
+
Gp zbp = emitter->zbp(); // EBP|RBP register.
|
425
|
+
Gp gpReg = zsp; // General purpose register (temporary).
|
426
|
+
Gp saReg = zsp; // Stack-arguments base pointer.
|
427
|
+
|
428
|
+
// Emit: 'push zbp'
|
429
|
+
// 'mov zbp, zsp'.
|
430
|
+
if (frame.hasPreservedFP()) {
|
431
|
+
gpSaved &= ~Support::bitMask(Gp::kIdBp);
|
432
|
+
ASMJIT_PROPAGATE(emitter->push(zbp));
|
433
|
+
ASMJIT_PROPAGATE(emitter->mov(zbp, zsp));
|
434
|
+
}
|
435
|
+
|
436
|
+
// Emit: 'push gp' sequence.
|
437
|
+
{
|
438
|
+
Support::BitWordIterator<RegMask> it(gpSaved);
|
439
|
+
while (it.hasNext()) {
|
440
|
+
gpReg.setId(it.next());
|
441
|
+
ASMJIT_PROPAGATE(emitter->push(gpReg));
|
442
|
+
}
|
443
|
+
}
|
444
|
+
|
445
|
+
// Emit: 'mov saReg, zsp'.
|
446
|
+
uint32_t saRegId = frame.saRegId();
|
447
|
+
if (saRegId != BaseReg::kIdBad && saRegId != Gp::kIdSp) {
|
448
|
+
saReg.setId(saRegId);
|
449
|
+
if (frame.hasPreservedFP()) {
|
450
|
+
if (saRegId != Gp::kIdBp)
|
451
|
+
ASMJIT_PROPAGATE(emitter->mov(saReg, zbp));
|
452
|
+
}
|
453
|
+
else {
|
454
|
+
ASMJIT_PROPAGATE(emitter->mov(saReg, zsp));
|
455
|
+
}
|
456
|
+
}
|
457
|
+
|
458
|
+
// Emit: 'and zsp, StackAlignment'.
|
459
|
+
if (frame.hasDynamicAlignment()) {
|
460
|
+
ASMJIT_PROPAGATE(emitter->and_(zsp, -int32_t(frame.finalStackAlignment())));
|
461
|
+
}
|
462
|
+
|
463
|
+
// Emit: 'sub zsp, StackAdjustment'.
|
464
|
+
if (frame.hasStackAdjustment()) {
|
465
|
+
ASMJIT_PROPAGATE(emitter->sub(zsp, frame.stackAdjustment()));
|
466
|
+
}
|
467
|
+
|
468
|
+
// Emit: 'mov [zsp + DAOffset], saReg'.
|
469
|
+
if (frame.hasDynamicAlignment() && frame.hasDAOffset()) {
|
470
|
+
Mem saMem = ptr(zsp, int32_t(frame.daOffset()));
|
471
|
+
ASMJIT_PROPAGATE(emitter->mov(saMem, saReg));
|
472
|
+
}
|
473
|
+
|
474
|
+
// Emit 'movxxx [zsp + X], {[x|y|z]mm, k}'.
|
475
|
+
{
|
476
|
+
Reg xReg;
|
477
|
+
Mem xBase = ptr(zsp, int32_t(frame.extraRegSaveOffset()));
|
478
|
+
|
479
|
+
uint32_t xInst;
|
480
|
+
uint32_t xSize;
|
481
|
+
|
482
|
+
for (RegGroup group : Support::EnumValues<RegGroup, RegGroup(1), RegGroup::kMaxVirt>{}) {
|
483
|
+
Support::BitWordIterator<RegMask> it(frame.savedRegs(group));
|
484
|
+
if (it.hasNext()) {
|
485
|
+
X86Internal_setupSaveRestoreInfo(group, frame, xReg, xInst, xSize);
|
486
|
+
do {
|
487
|
+
xReg.setId(it.next());
|
488
|
+
ASMJIT_PROPAGATE(emitter->emit(xInst, xBase, xReg));
|
489
|
+
xBase.addOffsetLo32(int32_t(xSize));
|
490
|
+
} while (it.hasNext());
|
491
|
+
}
|
492
|
+
}
|
493
|
+
}
|
494
|
+
|
495
|
+
return kErrorOk;
|
496
|
+
}
|
497
|
+
|
498
|
+
ASMJIT_FAVOR_SIZE Error EmitHelper::emitEpilog(const FuncFrame& frame) {
|
499
|
+
Emitter* emitter = _emitter->as<Emitter>();
|
500
|
+
|
501
|
+
uint32_t i;
|
502
|
+
uint32_t regId;
|
503
|
+
|
504
|
+
uint32_t registerSize = emitter->registerSize();
|
505
|
+
uint32_t gpSaved = frame.savedRegs(RegGroup::kGp);
|
506
|
+
|
507
|
+
Gp zsp = emitter->zsp(); // ESP|RSP register.
|
508
|
+
Gp zbp = emitter->zbp(); // EBP|RBP register.
|
509
|
+
Gp gpReg = emitter->zsp(); // General purpose register (temporary).
|
510
|
+
|
511
|
+
// Don't emit 'pop zbp' in the pop sequence, this case is handled separately.
|
512
|
+
if (frame.hasPreservedFP())
|
513
|
+
gpSaved &= ~Support::bitMask(Gp::kIdBp);
|
514
|
+
|
515
|
+
// Emit 'movxxx {[x|y|z]mm, k}, [zsp + X]'.
|
516
|
+
{
|
517
|
+
Reg xReg;
|
518
|
+
Mem xBase = ptr(zsp, int32_t(frame.extraRegSaveOffset()));
|
519
|
+
|
520
|
+
uint32_t xInst;
|
521
|
+
uint32_t xSize;
|
522
|
+
|
523
|
+
for (RegGroup group : Support::EnumValues<RegGroup, RegGroup(1), RegGroup::kMaxVirt>{}) {
|
524
|
+
Support::BitWordIterator<RegMask> it(frame.savedRegs(group));
|
525
|
+
if (it.hasNext()) {
|
526
|
+
X86Internal_setupSaveRestoreInfo(group, frame, xReg, xInst, xSize);
|
527
|
+
do {
|
528
|
+
xReg.setId(it.next());
|
529
|
+
ASMJIT_PROPAGATE(emitter->emit(xInst, xReg, xBase));
|
530
|
+
xBase.addOffsetLo32(int32_t(xSize));
|
531
|
+
} while (it.hasNext());
|
532
|
+
}
|
533
|
+
}
|
534
|
+
}
|
535
|
+
|
536
|
+
// Emit 'emms' and/or 'vzeroupper'.
|
537
|
+
if (frame.hasMmxCleanup()) ASMJIT_PROPAGATE(emitter->emms());
|
538
|
+
if (frame.hasAvxCleanup()) ASMJIT_PROPAGATE(emitter->vzeroupper());
|
539
|
+
|
540
|
+
if (frame.hasPreservedFP()) {
|
541
|
+
// Emit 'mov zsp, zbp' or 'lea zsp, [zbp - x]'
|
542
|
+
int32_t count = int32_t(frame.pushPopSaveSize() - registerSize);
|
543
|
+
if (!count)
|
544
|
+
ASMJIT_PROPAGATE(emitter->mov(zsp, zbp));
|
545
|
+
else
|
546
|
+
ASMJIT_PROPAGATE(emitter->lea(zsp, ptr(zbp, -count)));
|
547
|
+
}
|
548
|
+
else {
|
549
|
+
if (frame.hasDynamicAlignment() && frame.hasDAOffset()) {
|
550
|
+
// Emit 'mov zsp, [zsp + DsaSlot]'.
|
551
|
+
Mem saMem = ptr(zsp, int32_t(frame.daOffset()));
|
552
|
+
ASMJIT_PROPAGATE(emitter->mov(zsp, saMem));
|
553
|
+
}
|
554
|
+
else if (frame.hasStackAdjustment()) {
|
555
|
+
// Emit 'add zsp, StackAdjustment'.
|
556
|
+
ASMJIT_PROPAGATE(emitter->add(zsp, int32_t(frame.stackAdjustment())));
|
557
|
+
}
|
558
|
+
}
|
559
|
+
|
560
|
+
// Emit 'pop gp' sequence.
|
561
|
+
if (gpSaved) {
|
562
|
+
i = gpSaved;
|
563
|
+
regId = 16;
|
564
|
+
|
565
|
+
do {
|
566
|
+
regId--;
|
567
|
+
if (i & 0x8000) {
|
568
|
+
gpReg.setId(regId);
|
569
|
+
ASMJIT_PROPAGATE(emitter->pop(gpReg));
|
570
|
+
}
|
571
|
+
i <<= 1;
|
572
|
+
} while (regId != 0);
|
573
|
+
}
|
574
|
+
|
575
|
+
// Emit 'pop zbp'.
|
576
|
+
if (frame.hasPreservedFP())
|
577
|
+
ASMJIT_PROPAGATE(emitter->pop(zbp));
|
578
|
+
|
579
|
+
// Emit 'ret' or 'ret x'.
|
580
|
+
if (frame.hasCalleeStackCleanup())
|
581
|
+
ASMJIT_PROPAGATE(emitter->emit(Inst::kIdRet, int(frame.calleeStackCleanup())));
|
582
|
+
else
|
583
|
+
ASMJIT_PROPAGATE(emitter->emit(Inst::kIdRet));
|
584
|
+
|
585
|
+
return kErrorOk;
|
586
|
+
}
|
587
|
+
|
588
|
+
static Error ASMJIT_CDECL Emitter_emitProlog(BaseEmitter* emitter, const FuncFrame& frame) {
|
589
|
+
EmitHelper emitHelper(emitter, frame.isAvxEnabled(), frame.isAvx512Enabled());
|
590
|
+
return emitHelper.emitProlog(frame);
|
591
|
+
}
|
592
|
+
|
593
|
+
static Error ASMJIT_CDECL Emitter_emitEpilog(BaseEmitter* emitter, const FuncFrame& frame) {
|
594
|
+
EmitHelper emitHelper(emitter, frame.isAvxEnabled(), frame.isAvx512Enabled());
|
595
|
+
return emitHelper.emitEpilog(frame);
|
596
|
+
}
|
597
|
+
|
598
|
+
static Error ASMJIT_CDECL Emitter_emitArgsAssignment(BaseEmitter* emitter, const FuncFrame& frame, const FuncArgsAssignment& args) {
|
599
|
+
EmitHelper emitHelper(emitter, frame.isAvxEnabled(), frame.isAvx512Enabled());
|
600
|
+
return emitHelper.emitArgsAssignment(frame, args);
|
601
|
+
}
|
602
|
+
|
603
|
+
void assignEmitterFuncs(BaseEmitter* emitter) {
|
604
|
+
emitter->_funcs.emitProlog = Emitter_emitProlog;
|
605
|
+
emitter->_funcs.emitEpilog = Emitter_emitEpilog;
|
606
|
+
emitter->_funcs.emitArgsAssignment = Emitter_emitArgsAssignment;
|
607
|
+
|
608
|
+
#ifndef ASMJIT_NO_LOGGING
|
609
|
+
emitter->_funcs.formatInstruction = FormatterInternal::formatInstruction;
|
610
|
+
#endif
|
611
|
+
|
612
|
+
#ifndef ASMJIT_NO_VALIDATION
|
613
|
+
emitter->_funcs.validate = InstInternal::validate;
|
614
|
+
#endif
|
615
|
+
}
|
616
|
+
|
617
|
+
ASMJIT_END_SUB_NAMESPACE
|
618
|
+
|
619
|
+
#endif // !ASMJIT_NO_X86
|
@@ -0,0 +1,60 @@
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
2
|
+
//
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
4
|
+
// SPDX-License-Identifier: Zlib
|
5
|
+
|
6
|
+
#ifndef ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED
|
7
|
+
#define ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED
|
8
|
+
|
9
|
+
#include "../core/api-config.h"
|
10
|
+
|
11
|
+
#include "../core/emithelper_p.h"
|
12
|
+
#include "../core/func.h"
|
13
|
+
#include "../x86/x86emitter.h"
|
14
|
+
#include "../x86/x86operand.h"
|
15
|
+
|
16
|
+
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
|
17
|
+
|
18
|
+
//! \cond INTERNAL
|
19
|
+
//! \addtogroup asmjit_x86
|
20
|
+
//! \{
|
21
|
+
|
22
|
+
static inline RegType vecTypeIdToRegType(TypeId typeId) noexcept {
|
23
|
+
return uint32_t(typeId) <= uint32_t(TypeId::_kVec128End) ? RegType::kX86_Xmm :
|
24
|
+
uint32_t(typeId) <= uint32_t(TypeId::_kVec256End) ? RegType::kX86_Ymm : RegType::kX86_Zmm;
|
25
|
+
}
|
26
|
+
|
27
|
+
class EmitHelper : public BaseEmitHelper {
|
28
|
+
public:
|
29
|
+
bool _avxEnabled;
|
30
|
+
bool _avx512Enabled;
|
31
|
+
|
32
|
+
inline explicit EmitHelper(BaseEmitter* emitter = nullptr, bool avxEnabled = false, bool avx512Enabled = false) noexcept
|
33
|
+
: BaseEmitHelper(emitter),
|
34
|
+
_avxEnabled(avxEnabled || avx512Enabled),
|
35
|
+
_avx512Enabled(avx512Enabled) {}
|
36
|
+
|
37
|
+
Error emitRegMove(
|
38
|
+
const Operand_& dst_,
|
39
|
+
const Operand_& src_, TypeId typeId, const char* comment = nullptr) override;
|
40
|
+
|
41
|
+
Error emitArgMove(
|
42
|
+
const BaseReg& dst_, TypeId dstTypeId,
|
43
|
+
const Operand_& src_, TypeId srcTypeId, const char* comment = nullptr) override;
|
44
|
+
|
45
|
+
Error emitRegSwap(
|
46
|
+
const BaseReg& a,
|
47
|
+
const BaseReg& b, const char* comment = nullptr) override;
|
48
|
+
|
49
|
+
Error emitProlog(const FuncFrame& frame);
|
50
|
+
Error emitEpilog(const FuncFrame& frame);
|
51
|
+
};
|
52
|
+
|
53
|
+
void assignEmitterFuncs(BaseEmitter* emitter);
|
54
|
+
|
55
|
+
//! \}
|
56
|
+
//! \endcond
|
57
|
+
|
58
|
+
ASMJIT_END_SUB_NAMESPACE
|
59
|
+
|
60
|
+
#endif // ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED
|