From 611ae424864b724e483ec24103dbb1d67566c125 Mon Sep 17 00:00:00 2001 From: Paul Guyot Date: Sun, 22 Feb 2026 11:18:31 +0100 Subject: [PATCH] Optimize garbage collection with a generational GC Running jit tests with AtomVM is now 20% faster. Implement BEAM's `fullsweep_after` `spawn_opt/1` option and `process_flag/2` flag. Also fix `process_flag/2` spec. Also fix a bug where a finishing process in spawning state wasn't properly removed from the processes list. Signed-off-by: Paul Guyot --- doc/src/memory-management.md | 37 ++ doc/src/programmers-guide.md | 1 + libs/estdlib/src/erlang.erl | 5 +- libs/jit/src/jit_aarch64.erl | 16 +- libs/jit/src/jit_armv6m.erl | 14 +- libs/jit/src/jit_riscv32.erl | 16 +- libs/jit/src/jit_x86_64.erl | 24 +- src/libAtomVM/context.c | 25 + src/libAtomVM/context.h | 2 + src/libAtomVM/defaultatoms.def | 1 + src/libAtomVM/erl_nif_priv.h | 10 + src/libAtomVM/jit.c | 36 +- src/libAtomVM/memory.c | 491 ++++++++++++++++-- src/libAtomVM/memory.h | 22 + src/libAtomVM/nifs.c | 16 + tests/erlang_tests/CMakeLists.txt | 2 + tests/erlang_tests/test_heap_growth.erl | 12 +- .../test_process_flag_fullsweep_after.erl | 73 +++ tests/libs/jit/jit_aarch64_tests.erl | 252 ++++----- tests/libs/jit/jit_armv6m_tests.erl | 458 ++++++++-------- tests/libs/jit/jit_riscv32_tests.erl | 430 +++++++-------- tests/libs/jit/jit_tests.erl | 28 +- tests/libs/jit/jit_tests_common.erl | 5 +- tests/libs/jit/jit_x86_64_tests.erl | 304 +++++------ tests/test-heap.c | 264 ++++++++++ tests/test.c | 1 + 26 files changed, 1714 insertions(+), 831 deletions(-) create mode 100644 tests/erlang_tests/test_process_flag_fullsweep_after.erl diff --git a/doc/src/memory-management.md b/doc/src/memory-management.md index 77ed91f2b8..17042182a6 100644 --- a/doc/src/memory-management.md +++ b/doc/src/memory-management.md @@ -922,3 +922,40 @@ match binaries, as with the case of refc binaries on the process heap. #### Deletion Once all terms have been copied from the old heap to the new heap, and once the MSO list has been swept for unreachable references, the old heap is simply discarded via the `free` function. + +### Generational Garbage Collection + +The garbage collection described above is a *full sweep*: every live term is copied from the old heap to the new heap and the entire old heap is freed. While correct, this can be expensive for processes with large heaps, because long-lived data that has already survived previous collections must be copied again each time. + +AtomVM implements *generational* (or *minor*) garbage collection to reduce this cost, using the same approach as BEAM. The key observation is that most terms die young: they are allocated, used briefly, and become garbage. Terms that have survived at least one collection are likely to survive many more. Generational GC exploits this by dividing the heap into two generations: + +* **Young generation**: recently allocated terms, between the *high water mark* and the current heap pointer. +* **Old (mature) generation**: terms that have survived at least one minor collection, stored in a separate old heap. + +#### High Water Mark + +After each garbage collection, the heap pointer position is recorded as the *high water mark*. On the next collection, terms allocated below the high water mark (i.e., terms that existed at the time of the previous collection) are considered mature. Terms allocated above the high water mark are young. + +#### Minor Collection + +During a minor collection: + +1. A new young heap is allocated. +2. Mature terms (below the high water mark) are *promoted*: copied to the old heap rather than the new young heap. +3. Young terms that are still reachable are copied to the new young heap. +4. Both the new young heap and the newly promoted old region are scanned for references, since promoted terms may reference young terms and vice versa. +5. Only the young MSO list is swept; the old MSO list is preserved. +6. The previous heap is freed, but the old heap persists across minor collections. + +Because the old heap is not scanned for garbage during a minor collection, the cost is proportional to the size of the young generation rather than the entire heap. + +#### When Full vs. Minor Collection Occurs + +AtomVM keeps a counter (`gc_count`) of how many minor collections have occurred since the last full sweep. A full sweep is forced when: + +* The process has never been garbage collected (no high water mark exists). +* `gc_count` reaches the `fullsweep_after` threshold. +* The old heap does not have enough space to accommodate promoted terms. +* A `MEMORY_FORCE_SHRINK` request is made (e.g., via `erlang:garbage_collect/0`). + +The `fullsweep_after` value can be set per-process via [`spawn_opt`](./programmers-guide.md#spawning-processes) or [`erlang:process_flag/2`](./apidocs/erlang/estdlib/erlang.md#process_flag2). The default value is 65535, meaning full sweeps are infrequent under normal operation. Setting it to `0` disables generational collection entirely, forcing a full sweep on every garbage collection event. diff --git a/doc/src/programmers-guide.md b/doc/src/programmers-guide.md index 32524b1462..9593357759 100644 --- a/doc/src/programmers-guide.md +++ b/doc/src/programmers-guide.md @@ -365,6 +365,7 @@ The [options](./apidocs/erlang/estdlib/erlang.md#spawn_option) argument is a pro |-----|------------|---------------|-------------| | `min_heap_size` | `non_neg_integer()` | none | Minimum heap size of the process. The heap will shrink no smaller than this size. | | `max_heap_size` | `non_neg_integer()` | unbounded | Maximum heap size of the process. The heap will grow no larger than this size. | +| `fullsweep_after` | `non_neg_integer()` | 65535 | Maximum number of [minor garbage collections](./memory-management.md#generational-garbage-collection) before a full sweep is forced. Set to `0` to disable generational garbage collection. | | `link` | `boolean()` | `false` | Whether to link the spawned process to the spawning process. | | `monitor` | `boolean()` | `false` | Whether to link the spawning process should monitor the spawned process. | | `atomvm_heap_growth` | `bounded_free \| minimum \| fibonacci` | `bounded_free` | [Strategy](./memory-management.md#heap-growth-strategies) to grow the heap of the process. | diff --git a/libs/estdlib/src/erlang.erl b/libs/estdlib/src/erlang.erl index e7a9b35468..010a897e84 100644 --- a/libs/estdlib/src/erlang.erl +++ b/libs/estdlib/src/erlang.erl @@ -177,6 +177,7 @@ -type spawn_option() :: {min_heap_size, pos_integer()} | {max_heap_size, pos_integer()} + | {fullsweep_after, non_neg_integer()} | {atomvm_heap_growth, atomvm_heap_growth_strategy()} | link | monitor. @@ -1308,7 +1309,9 @@ group_leader(_Leader, _Pid) -> %% %% @end %%----------------------------------------------------------------------------- --spec process_flag(Flag :: trap_exit, Value :: boolean()) -> pid(). +-spec process_flag + (trap_exit, boolean()) -> boolean(); + (fullsweep_after, non_neg_integer()) -> non_neg_integer(). process_flag(_Flag, _Value) -> erlang:nif_error(undefined). diff --git a/libs/jit/src/jit_aarch64.erl b/libs/jit/src/jit_aarch64.erl index 703a93e18b..d49b95aaa6 100644 --- a/libs/jit/src/jit_aarch64.erl +++ b/libs/jit/src/jit_aarch64.erl @@ -164,16 +164,16 @@ | {maybe_free_aarch64_register(), '&', non_neg_integer(), '!=', integer()} | {{free, aarch64_register()}, '==', {free, aarch64_register()}}. -% ctx->e is 0x28 -% ctx->x is 0x30 +% ctx->e is 0x50 +% ctx->x is 0x58 -define(WORD_SIZE, 8). -define(CTX_REG, r0). -define(JITSTATE_REG, r1). -define(NATIVE_INTERFACE_REG, r2). --define(Y_REGS, {?CTX_REG, 16#28}). --define(X_REG(N), {?CTX_REG, 16#30 + (N * ?WORD_SIZE)}). --define(CP, {?CTX_REG, 16#B8}). --define(FP_REGS, {?CTX_REG, 16#C0}). +-define(Y_REGS, {?CTX_REG, 16#50}). +-define(X_REG(N), {?CTX_REG, 16#58 + (N * ?WORD_SIZE)}). +-define(CP, {?CTX_REG, 16#E0}). +-define(FP_REGS, {?CTX_REG, 16#E8}). -define(FP_REG_OFFSET(State, F), (F * case (State)#state.variant band ?JIT_VARIANT_FLOAT32 of @@ -181,8 +181,8 @@ _ -> 4 end) ). --define(BS, {?CTX_REG, 16#C8}). --define(BS_OFFSET, {?CTX_REG, 16#D0}). +-define(BS, {?CTX_REG, 16#F0}). +-define(BS_OFFSET, {?CTX_REG, 16#F8}). -define(JITSTATE_MODULE, {?JITSTATE_REG, 0}). -define(JITSTATE_CONTINUATION, {?JITSTATE_REG, 16#8}). -define(JITSTATE_REDUCTIONCOUNT, {?JITSTATE_REG, 16#10}). diff --git a/libs/jit/src/jit_armv6m.erl b/libs/jit/src/jit_armv6m.erl index 80f76e1e7e..a7d5d99d05 100644 --- a/libs/jit/src/jit_armv6m.erl +++ b/libs/jit/src/jit_armv6m.erl @@ -166,15 +166,15 @@ | {{free, armv6m_register()}, '==', {free, armv6m_register()}}. % ctx->e is 0x28 -% ctx->x is 0x30 +% ctx->x is 0x2C -define(CTX_REG, r0). -define(NATIVE_INTERFACE_REG, r2). --define(Y_REGS, {?CTX_REG, 16#14}). --define(X_REG(N), {?CTX_REG, 16#18 + (N * 4)}). --define(CP, {?CTX_REG, 16#5C}). --define(FP_REGS, {?CTX_REG, 16#60}). --define(BS, {?CTX_REG, 16#64}). --define(BS_OFFSET, {?CTX_REG, 16#68}). +-define(Y_REGS, {?CTX_REG, 16#28}). +-define(X_REG(N), {?CTX_REG, 16#2C + (N * 4)}). +-define(CP, {?CTX_REG, 16#70}). +-define(FP_REGS, {?CTX_REG, 16#74}). +-define(BS, {?CTX_REG, 16#78}). +-define(BS_OFFSET, {?CTX_REG, 16#7C}). % JITSTATE is on stack, accessed via stack offset % These macros now expect a register that contains the jit_state pointer -define(JITSTATE_MODULE(Reg), {Reg, 0}). diff --git a/libs/jit/src/jit_riscv32.erl b/libs/jit/src/jit_riscv32.erl index 4a57d91d3e..c77a104844 100644 --- a/libs/jit/src/jit_riscv32.erl +++ b/libs/jit/src/jit_riscv32.erl @@ -195,16 +195,16 @@ | {{free, riscv32_register()}, '==', {free, riscv32_register()}}. % Context offsets (32-bit architecture) -% ctx->e is 0x14 -% ctx->x is 0x18 +% ctx->e is 0x28 +% ctx->x is 0x2C -define(CTX_REG, a0). -define(NATIVE_INTERFACE_REG, a2). --define(Y_REGS, {?CTX_REG, 16#14}). --define(X_REG(N), {?CTX_REG, 16#18 + (N * 4)}). --define(CP, {?CTX_REG, 16#5C}). --define(FP_REGS, {?CTX_REG, 16#60}). --define(BS, {?CTX_REG, 16#64}). --define(BS_OFFSET, {?CTX_REG, 16#68}). +-define(Y_REGS, {?CTX_REG, 16#28}). +-define(X_REG(N), {?CTX_REG, 16#2C + (N * 4)}). +-define(CP, {?CTX_REG, 16#70}). +-define(FP_REGS, {?CTX_REG, 16#74}). +-define(BS, {?CTX_REG, 16#78}). +-define(BS_OFFSET, {?CTX_REG, 16#7C}). % JITSTATE is in a1 register (no prolog, following aarch64 model) -define(JITSTATE_REG, a1). % Return address register (like LR in AArch64) diff --git a/libs/jit/src/jit_x86_64.erl b/libs/jit/src/jit_x86_64.erl index e5d36d5369..240d40e334 100644 --- a/libs/jit/src/jit_x86_64.erl +++ b/libs/jit/src/jit_x86_64.erl @@ -150,19 +150,19 @@ -define(WORD_SIZE, 8). % Following offsets are verified with static asserts in jit.c -% ctx->e is 0x28 -% ctx->x is 0x30 -% ctx->cp is 0xB8 -% ctx->fr is 0xC0 -% ctx->bs is 0xC8 -% ctx->bs_offset is 0xD0 +% ctx->e is 0x50 +% ctx->x is 0x58 +% ctx->cp is 0xE0 +% ctx->fr is 0xE8 +% ctx->bs is 0xF0 +% ctx->bs_offset is 0xF8 -define(CTX_REG, rdi). -define(JITSTATE_REG, rsi). -define(NATIVE_INTERFACE_REG, rdx). --define(Y_REGS, {16#28, ?CTX_REG}). --define(X_REG(N), {16#30 + (N * ?WORD_SIZE), ?CTX_REG}). --define(CP, {16#B8, ?CTX_REG}). --define(FP_REGS, {16#C0, ?CTX_REG}). +-define(Y_REGS, {16#50, ?CTX_REG}). +-define(X_REG(N), {16#58 + (N * ?WORD_SIZE), ?CTX_REG}). +-define(CP, {16#E0, ?CTX_REG}). +-define(FP_REGS, {16#E8, ?CTX_REG}). -define(FP_REG_OFFSET(State, F), (F * case (State)#state.variant band ?JIT_VARIANT_FLOAT32 of @@ -170,8 +170,8 @@ _ -> 4 end) ). --define(BS, {16#C8, ?CTX_REG}). --define(BS_OFFSET, {16#D0, ?CTX_REG}). +-define(BS, {16#F0, ?CTX_REG}). +-define(BS_OFFSET, {16#F8, ?CTX_REG}). -define(JITSTATE_MODULE, {0, ?JITSTATE_REG}). -define(JITSTATE_CONTINUATION, {16#8, ?JITSTATE_REG}). -define(JITSTATE_REMAINING_REDUCTIONS, {16#10, ?JITSTATE_REG}). diff --git a/src/libAtomVM/context.c b/src/libAtomVM/context.c index 0e35082ad1..825db02f0e 100644 --- a/src/libAtomVM/context.c +++ b/src/libAtomVM/context.c @@ -81,6 +81,8 @@ Context *context_new(GlobalContext *glb) ctx->min_heap_size = 0; ctx->max_heap_size = 0; ctx->heap_growth_strategy = BoundedFreeHeapGrowth; + ctx->fullsweep_after = 65535; + ctx->gc_count = 0; ctx->has_min_heap_size = 0; ctx->has_max_heap_size = 0; @@ -136,6 +138,14 @@ Context *context_new(GlobalContext *glb) void context_destroy(Context *ctx) { + // If the process was never scheduled (still in Spawning state), + // it is still in the waiting_processes list and must be removed. + if (ctx->flags & Spawning) { + SMP_SPINLOCK_LOCK(&ctx->global->processes_spinlock); + list_remove(&ctx->processes_list_head); + SMP_SPINLOCK_UNLOCK(&ctx->global->processes_spinlock); + } + // Another process can get an access to our mailbox until this point. struct ListHead *processes_table_list = synclist_wrlock(&ctx->global->processes_table); UNUSED(processes_table_list); @@ -525,6 +535,7 @@ bool context_get_process_info(Context *ctx, term *out, size_t *term_size, term a case MESSAGE_QUEUE_LEN_ATOM: case REGISTERED_NAME_ATOM: case MEMORY_ATOM: + case FULLSWEEP_AFTER_ATOM: ret_size = TUPLE_SIZE(2); break; case LINKS_ATOM: { @@ -675,6 +686,12 @@ bool context_get_process_info(Context *ctx, term *out, size_t *term_size, term a break; } + case FULLSWEEP_AFTER_ATOM: { + term_put_tuple_element(ret, 0, FULLSWEEP_AFTER_ATOM); + term_put_tuple_element(ret, 1, term_from_int(ctx->fullsweep_after)); + break; + } + case CURRENT_STACKTRACE_ATOM: { term_put_tuple_element(ret, 0, CURRENT_STACKTRACE_ATOM); // FIXME: since it's not possible how to build stacktrace here with the current API, @@ -1209,6 +1226,14 @@ COLD_FUNC void context_dump(Context *ctx) ct++; } + fprintf(stderr, "\n\nHeap\n----\n"); + fprintf(stderr, "young heap: %zu words\n", (size_t) (ctx->heap.heap_end - ctx->heap.heap_start)); + if (ctx->heap.old_heap_start) { + fprintf(stderr, "old heap: %zu words (used: %zu)\n", + (size_t) (ctx->heap.old_heap_end - ctx->heap.old_heap_start), + (size_t) (ctx->heap.old_heap_ptr - ctx->heap.old_heap_start)); + } + fprintf(stderr, "\n\nMailbox\n-------\n"); mailbox_crashdump(ctx); diff --git a/src/libAtomVM/context.h b/src/libAtomVM/context.h index 52ac76d3bd..24238f93e4 100644 --- a/src/libAtomVM/context.h +++ b/src/libAtomVM/context.h @@ -113,6 +113,8 @@ struct Context size_t min_heap_size; size_t max_heap_size; enum HeapGrowthStrategy heap_growth_strategy; + unsigned int fullsweep_after; + unsigned int gc_count; // saved state when scheduled out Module *saved_module; diff --git a/src/libAtomVM/defaultatoms.def b/src/libAtomVM/defaultatoms.def index 03236eb45e..5549b02e98 100644 --- a/src/libAtomVM/defaultatoms.def +++ b/src/libAtomVM/defaultatoms.def @@ -207,6 +207,7 @@ X(EMU_ATOM, "\x3", "emu") X(JIT_ATOM, "\x3", "jit") X(EMU_FLAVOR_ATOM, "\xA", "emu_flavor") X(CODE_SERVER_ATOM, "\xB", "code_server") +X(FULLSWEEP_AFTER_ATOM, "\xF", "fullsweep_after") X(LOAD_ATOM, "\x4", "load") X(JIT_X86_64_ATOM, "\xA", "jit_x86_64") X(JIT_AARCH64_ATOM, "\xB", "jit_aarch64") diff --git a/src/libAtomVM/erl_nif_priv.h b/src/libAtomVM/erl_nif_priv.h index 008dca8a8b..86d83ccb90 100644 --- a/src/libAtomVM/erl_nif_priv.h +++ b/src/libAtomVM/erl_nif_priv.h @@ -63,6 +63,11 @@ static inline void erl_nif_env_partial_init_from_globalcontext(ErlNifEnv *env, G env->heap.heap_start = NULL; env->heap.heap_ptr = NULL; env->heap.heap_end = NULL; + env->heap.high_water_mark = NULL; + env->heap.old_heap_start = NULL; + env->heap.old_heap_ptr = NULL; + env->heap.old_heap_end = NULL; + env->heap.old_mso_list = term_nil(); env->stack_pointer = NULL; env->x[0] = term_nil(); env->x[1] = term_nil(); @@ -76,6 +81,11 @@ static inline void erl_nif_env_partial_init_from_resource(ErlNifEnv *env, void * env->heap.heap_start = NULL; env->heap.heap_ptr = NULL; env->heap.heap_end = NULL; + env->heap.high_water_mark = NULL; + env->heap.old_heap_start = NULL; + env->heap.old_heap_ptr = NULL; + env->heap.old_heap_end = NULL; + env->heap.old_mso_list = term_nil(); env->stack_pointer = NULL; env->x[0] = term_nil(); env->x[1] = term_nil(); diff --git a/src/libAtomVM/jit.c b/src/libAtomVM/jit.c index 21feac6264..262fb9e102 100644 --- a/src/libAtomVM/jit.c +++ b/src/libAtomVM/jit.c @@ -68,23 +68,23 @@ _Static_assert( // Verify offsets in jit_x86_64.erl #if JIT_ARCH_TARGET == JIT_ARCH_X86_64 || JIT_ARCH_TARGET == JIT_ARCH_AARCH64 -_Static_assert(offsetof(Context, e) == 0x28, "ctx->e is 0x28 in jit/src/jit_{aarch64,x86_64}.erl"); -_Static_assert(offsetof(Context, x) == 0x30, "ctx->x is 0x30 in jit/src/jit_{aarch64,x86_64}.erl"); -_Static_assert(offsetof(Context, cp) == 0xB8, "ctx->cp is 0xB8 in jit/src/jit_{aarch64,x86_64}.erl"); -_Static_assert(offsetof(Context, fr) == 0xC0, "ctx->fr is 0xC0 in jit/src/jit_{aarch64,x86_64}.erl"); -_Static_assert(offsetof(Context, bs) == 0xC8, "ctx->bs is 0xC8 in jit/src/jit_{aarch64,x86_64}.erl"); -_Static_assert(offsetof(Context, bs_offset) == 0xD0, "ctx->bs_offset is 0xD0 in jit/src/jit_{aarch64,x86_64}.erl"); +_Static_assert(offsetof(Context, e) == 0x50, "ctx->e is 0x50 in jit/src/jit_{aarch64,x86_64}.erl"); +_Static_assert(offsetof(Context, x) == 0x58, "ctx->x is 0x58 in jit/src/jit_{aarch64,x86_64}.erl"); +_Static_assert(offsetof(Context, cp) == 0xE0, "ctx->cp is 0xE0 in jit/src/jit_{aarch64,x86_64}.erl"); +_Static_assert(offsetof(Context, fr) == 0xE8, "ctx->fr is 0xE8 in jit/src/jit_{aarch64,x86_64}.erl"); +_Static_assert(offsetof(Context, bs) == 0xF0, "ctx->bs is 0xF0 in jit/src/jit_{aarch64,x86_64}.erl"); +_Static_assert(offsetof(Context, bs_offset) == 0xF8, "ctx->bs_offset is 0xF8 in jit/src/jit_{aarch64,x86_64}.erl"); _Static_assert(offsetof(JITState, module) == 0x0, "jit_state->module is 0x0 in jit/src/jit_{aarch64,x86_64}.erl"); _Static_assert(offsetof(JITState, continuation) == 0x8, "jit_state->continuation is 0x8 in jit/src/jit_{aarch64,x86_64}.erl"); _Static_assert(offsetof(JITState, remaining_reductions) == 0x10, "jit_state->remaining_reductions is 0x10 in jit/src/jit_{aarch64,x86_64}.erl"); #elif JIT_ARCH_TARGET == JIT_ARCH_ARMV6M -_Static_assert(offsetof(Context, e) == 0x14, "ctx->e is 0x14 in jit/src/jit_armv6m.erl"); -_Static_assert(offsetof(Context, x) == 0x18, "ctx->x is 0x18 in jit/src/jit_armv6m.erl"); -_Static_assert(offsetof(Context, cp) == 0x5C, "ctx->cp is 0x5C in jit/src/jit_armv6m.erl"); -_Static_assert(offsetof(Context, fr) == 0x60, "ctx->fr is 0x60 in jit/src/jit_armv6m.erl"); -_Static_assert(offsetof(Context, bs) == 0x64, "ctx->bs is 0x64 in jit/src/jit_armv6m.erl"); -_Static_assert(offsetof(Context, bs_offset) == 0x68, "ctx->bs_offset is 0x68 in jit/src/jit_armv6m.erl"); +_Static_assert(offsetof(Context, e) == 0x28, "ctx->e is 0x28 in jit/src/jit_armv6m.erl"); +_Static_assert(offsetof(Context, x) == 0x2C, "ctx->x is 0x2C in jit/src/jit_armv6m.erl"); +_Static_assert(offsetof(Context, cp) == 0x70, "ctx->cp is 0x70 in jit/src/jit_armv6m.erl"); +_Static_assert(offsetof(Context, fr) == 0x74, "ctx->fr is 0x74 in jit/src/jit_armv6m.erl"); +_Static_assert(offsetof(Context, bs) == 0x78, "ctx->bs is 0x78 in jit/src/jit_armv6m.erl"); +_Static_assert(offsetof(Context, bs_offset) == 0x7C, "ctx->bs_offset is 0x7C in jit/src/jit_armv6m.erl"); _Static_assert(offsetof(JITState, module) == 0x0, "jit_state->module is 0x0 in jit/src/jit_armv6m.erl"); _Static_assert(offsetof(JITState, continuation) == 0x4, "jit_state->continuation is 0x4 in jit/src/jit_armv6m.erl"); @@ -93,12 +93,12 @@ _Static_assert(offsetof(JITState, remaining_reductions) == 0x8, "jit_state->rema _Static_assert(sizeof(size_t) == 4, "size_t is expected to be 32 bits"); #elif JIT_ARCH_TARGET == JIT_ARCH_RISCV32 -_Static_assert(offsetof(Context, e) == 0x14, "ctx->e is 0x14 in jit/src/jit_riscv32.erl"); -_Static_assert(offsetof(Context, x) == 0x18, "ctx->x is 0x18 in jit/src/jit_riscv32.erl"); -_Static_assert(offsetof(Context, cp) == 0x5C, "ctx->cp is 0x5C in jit/src/jit_riscv32.erl"); -_Static_assert(offsetof(Context, fr) == 0x60, "ctx->fr is 0x60 in jit/src/jit_riscv32.erl"); -_Static_assert(offsetof(Context, bs) == 0x64, "ctx->bs is 0x64 in jit/src/jit_riscv32.erl"); -_Static_assert(offsetof(Context, bs_offset) == 0x68, "ctx->bs_offset is 0x68 in jit/src/jit_riscv32.erl"); +_Static_assert(offsetof(Context, e) == 0x28, "ctx->e is 0x28 in jit/src/jit_riscv32.erl"); +_Static_assert(offsetof(Context, x) == 0x2C, "ctx->x is 0x2C in jit/src/jit_riscv32.erl"); +_Static_assert(offsetof(Context, cp) == 0x70, "ctx->cp is 0x70 in jit/src/jit_riscv32.erl"); +_Static_assert(offsetof(Context, fr) == 0x74, "ctx->fr is 0x74 in jit/src/jit_riscv32.erl"); +_Static_assert(offsetof(Context, bs) == 0x78, "ctx->bs is 0x78 in jit/src/jit_riscv32.erl"); +_Static_assert(offsetof(Context, bs_offset) == 0x7C, "ctx->bs_offset is 0x7C in jit/src/jit_riscv32.erl"); _Static_assert(offsetof(JITState, module) == 0x0, "jit_state->module is 0x0 in jit/src/jit_riscv32.erl"); _Static_assert(offsetof(JITState, continuation) == 0x4, "jit_state->continuation is 0x4 in jit/src/jit_riscv32.erl"); diff --git a/src/libAtomVM/memory.c b/src/libAtomVM/memory.c index 7c545b9d49..01d662e157 100644 --- a/src/libAtomVM/memory.c +++ b/src/libAtomVM/memory.c @@ -46,12 +46,14 @@ #ifdef ENABLE_REALLOC_GC #define MEMORY_SHRINK memory_shrink #else -#define MEMORY_SHRINK memory_gc +#define MEMORY_SHRINK memory_full_gc #endif static void memory_scan_and_copy(HeapFragment *old_fragment, term *mem_start, const term *mem_end, term **new_heap_pos, term *mso_list, bool move); static term memory_shallow_copy_term(HeapFragment *old_fragment, term t, term **new_heap, bool move); static enum MemoryGCResult memory_gc(Context *ctx, size_t new_size, size_t num_roots, term *roots); +static enum MemoryGCResult memory_full_gc(Context *ctx, size_t new_size, size_t num_roots, term *roots); +static enum MemoryGCResult memory_minor_gc(Context *ctx, size_t new_size, size_t num_roots, term *roots); #ifdef ENABLE_REALLOC_GC static enum MemoryGCResult memory_shrink(Context *ctx, size_t new_size, size_t num_roots, term *roots); static void memory_scan_and_rewrite(size_t count, term *terms, const term *old_start, const term *old_end, intptr_t delta, bool is_heap); @@ -76,6 +78,11 @@ void memory_init_heap_root_fragment(Heap *heap, HeapFragment *root, size_t size) heap->heap_start = root->storage; heap->heap_ptr = heap->heap_start; heap->heap_end = heap->heap_start + size; + heap->high_water_mark = NULL; + heap->old_heap_start = NULL; + heap->old_heap_ptr = NULL; + heap->old_heap_end = NULL; + heap->old_mso_list = term_nil(); } #ifdef ENABLE_REALLOC_GC @@ -204,42 +211,55 @@ enum MemoryGCResult memory_ensure_free_with_roots(Context *c, size_t size, size_ if (UNLIKELY(c->has_max_heap_size && (target_size > c->max_heap_size))) { return MEMORY_GC_DENIED_ALLOCATION; } - if (UNLIKELY(memory_gc(c, target_size, num_roots, roots) != MEMORY_GC_OK)) { + enum MemoryGCResult gc_result; + if (alloc_mode == MEMORY_FORCE_SHRINK) { + gc_result = memory_full_gc(c, target_size, num_roots, roots); + if (gc_result == MEMORY_GC_OK) { + c->heap.high_water_mark = c->heap.heap_ptr; + c->gc_count = 0; + } + } else { + gc_result = memory_gc(c, target_size, num_roots, roots); + } + if (UNLIKELY(gc_result != MEMORY_GC_OK)) { // TODO: handle this more gracefully TRACE("Unable to allocate memory for GC. target_size=%zu\n", target_size); return MEMORY_GC_ERROR_FAILED_ALLOCATION; } - should_gc = alloc_mode == MEMORY_FORCE_SHRINK; - size_t new_memory_size = memory_heap_memory_size(&c->heap); - size_t new_target_size = new_memory_size; - size_t new_free_space = context_avail_free_memory(c); - switch (c->heap_growth_strategy) { - case BoundedFreeHeapGrowth: { - size_t maximum_free_space = 2 * (size + MIN_FREE_SPACE_SIZE); - should_gc = should_gc || (alloc_mode != MEMORY_NO_SHRINK && new_free_space > maximum_free_space); - if (should_gc) { - new_target_size = (new_memory_size - new_free_space) + maximum_free_space; - } - } break; - case MinimumHeapGrowth: - should_gc = should_gc || (alloc_mode != MEMORY_NO_SHRINK && new_free_space > 0); - if (should_gc) { - new_target_size = new_memory_size - new_free_space + size; - } - break; - case FibonacciHeapGrowth: - should_gc = should_gc || (new_memory_size > FIBONACCI_HEAP_GROWTH_REDUCTION_THRESHOLD && new_free_space >= 3 * new_memory_size / 4); - if (should_gc) { - new_target_size = next_fibonacci_heap_size(new_memory_size - new_free_space + size); - } - break; - } - if (should_gc) { - new_target_size = MAX(c->has_min_heap_size ? c->min_heap_size : 0, new_target_size); - if (new_target_size != new_memory_size) { - if (UNLIKELY(MEMORY_SHRINK(c, new_target_size, num_roots, roots) != MEMORY_GC_OK)) { - TRACE("Unable to allocate memory for GC shrink. new_memory_size=%zu new_free_space=%zu size=%u\n", new_memory_size, new_free_space, (unsigned int) size); - return MEMORY_GC_ERROR_FAILED_ALLOCATION; + { + should_gc = alloc_mode == MEMORY_FORCE_SHRINK; + size_t new_memory_size = memory_heap_memory_size(&c->heap); + size_t new_free_space = context_avail_free_memory(c); + size_t new_target_size = new_memory_size; + switch (c->heap_growth_strategy) { + case BoundedFreeHeapGrowth: { + size_t maximum_free_space = 2 * (size + MIN_FREE_SPACE_SIZE); + should_gc = should_gc || (alloc_mode != MEMORY_NO_SHRINK && new_free_space > maximum_free_space); + if (should_gc) { + new_target_size = (new_memory_size - new_free_space) + maximum_free_space; + } + } break; + case MinimumHeapGrowth: + should_gc = should_gc || (alloc_mode != MEMORY_NO_SHRINK && new_free_space > 0); + if (should_gc) { + new_target_size = new_memory_size - new_free_space + size; + } + break; + case FibonacciHeapGrowth: + should_gc = should_gc || (new_memory_size > FIBONACCI_HEAP_GROWTH_REDUCTION_THRESHOLD && new_free_space >= 3 * new_memory_size / 4); + if (should_gc) { + new_target_size = next_fibonacci_heap_size(new_memory_size - new_free_space + size); + } + break; + } + if (should_gc) { + new_target_size = MAX(c->has_min_heap_size ? c->min_heap_size : 0, new_target_size); + if (new_target_size != new_memory_size) { + if (UNLIKELY(MEMORY_SHRINK(c, new_target_size, num_roots, roots) != MEMORY_GC_OK)) { + TRACE("Unable to allocate memory for GC shrink. new_memory_size=%zu new_free_space=%zu size=%u\n", new_memory_size, new_free_space, (unsigned int) size); + return MEMORY_GC_ERROR_FAILED_ALLOCATION; + } + c->heap.high_water_mark = c->heap.heap_ptr; } } } @@ -257,13 +277,46 @@ static inline void push_to_stack(term **stack, term value) static enum MemoryGCResult memory_gc(Context *ctx, size_t new_size, size_t num_roots, term *roots) { - TRACE("Going to perform gc on process %i\n", ctx->process_id); + bool force_full = ctx->fullsweep_after == 0 || ctx->gc_count >= ctx->fullsweep_after; + if (ctx->heap.high_water_mark == NULL || force_full) { + enum MemoryGCResult result = memory_full_gc(ctx, new_size, num_roots, roots); + if (result == MEMORY_GC_OK) { + ctx->heap.high_water_mark = ctx->heap.heap_ptr; + ctx->gc_count = 0; + } + return result; + } + return memory_minor_gc(ctx, new_size, num_roots, roots); +} + +static enum MemoryGCResult memory_full_gc(Context *ctx, size_t new_size, size_t num_roots, term *roots) +{ + TRACE("Going to perform full gc on process %i\n", ctx->process_id); term old_mso_list = ctx->heap.root->mso_list; + term old_old_mso_list = ctx->heap.old_mso_list; term *old_stack_ptr = context_stack_base(ctx); term *old_heap_end = ctx->heap.heap_end; HeapFragment *old_root_fragment = ctx->heap.root; + // Chain old heap into fragment list so all terms are from-space + HeapFragment *old_chain_tail = NULL; + if (ctx->heap.old_heap_start) { + HeapFragment *old_heap_fragment = OLD_HEAP_TO_FRAGMENT(ctx->heap.old_heap_start); + old_heap_fragment->heap_end = ctx->heap.old_heap_ptr; + old_heap_fragment->next = NULL; + // Append at the end of the fragment chain + old_chain_tail = old_root_fragment; + while (old_chain_tail->next != NULL) { + old_chain_tail = old_chain_tail->next; + } + old_chain_tail->next = old_heap_fragment; + } + if (UNLIKELY(memory_init_heap(&ctx->heap, new_size) != MEMORY_GC_OK)) { + // Undo fragment chain modification so the context remains consistent + if (old_chain_tail) { + old_chain_tail->next = NULL; + } return MEMORY_GC_ERROR_FAILED_ALLOCATION; } // We need old heap fragment to only copy terms that were in the heap (as opposed to in messages) @@ -320,10 +373,18 @@ static enum MemoryGCResult memory_gc(Context *ctx, size_t new_size, size_t num_r ctx->heap.heap_ptr = temp_end; memory_sweep_mso_list(old_mso_list, ctx->global, false); + memory_sweep_mso_list(old_old_mso_list, ctx->global, false); ctx->heap.root->mso_list = new_mso_list; + // old heap fragment is already chained into old_root_fragment, freed together memory_destroy_heap_fragment(old_root_fragment); + // Reset old generation + ctx->heap.old_heap_start = NULL; + ctx->heap.old_heap_ptr = NULL; + ctx->heap.old_heap_end = NULL; + ctx->heap.old_mso_list = term_nil(); + return MEMORY_GC_OK; } @@ -904,6 +965,368 @@ HOT_FUNC static term memory_shallow_copy_term(HeapFragment *old_fragment, term t } } +HOT_FUNC static inline bool memory_is_in_old_heap(const Heap *heap, const term *ptr) +{ + return ptr >= heap->old_heap_start && ptr < heap->old_heap_end; +} + +HOT_FUNC static term memory_shallow_copy_term_generational( + HeapFragment *old_fragment, const Heap *heap, term t, + term **new_young_heap, term **old_heap_ptr) +{ + switch (t & TERM_PRIMARY_MASK) { + case TERM_PRIMARY_IMMED: + return t; + + case TERM_PRIMARY_CP: + return t; + + case TERM_PRIMARY_BOXED: { + term *boxed_value = term_to_term_ptr(t); + + if (memory_is_in_old_heap(heap, boxed_value)) { + return t; + } + + if (old_fragment != NULL && !memory_heap_fragment_contains_pointer(old_fragment, boxed_value)) { + return t; + } + + if (memory_is_moved_marker(boxed_value)) { + return memory_dereference_moved_marker(boxed_value); + } + + int boxed_size = term_boxed_size(t) + 1; + + if (boxed_size == 1) { + return ((term) &empty_tuple) | TERM_PRIMARY_BOXED; + } + + term *dest; + if (boxed_value >= heap->heap_start && boxed_value < heap->high_water_mark) { + dest = *old_heap_ptr; + *old_heap_ptr += boxed_size; + } else { + dest = *new_young_heap; + *new_young_heap += boxed_size; + } + + for (int i = 0; i < boxed_size; i++) { + dest[i] = boxed_value[i]; + } + + term new_term = ((term) dest) | TERM_PRIMARY_BOXED; + memory_replace_with_moved_marker(boxed_value, new_term); + return new_term; + } + case TERM_PRIMARY_LIST: { + term *list_ptr = term_get_list_ptr(t); + + if (memory_is_in_old_heap(heap, list_ptr)) { + return t; + } + + if (old_fragment != NULL && !memory_heap_fragment_contains_pointer(old_fragment, list_ptr)) { + return t; + } + + if (memory_is_moved_marker(list_ptr)) { + return memory_dereference_moved_marker(list_ptr); + } + + term *dest; + if (list_ptr >= heap->heap_start && list_ptr < heap->high_water_mark) { + dest = *old_heap_ptr; + *old_heap_ptr += 2; + } else { + dest = *new_young_heap; + *new_young_heap += 2; + } + + dest[0] = list_ptr[0]; + dest[1] = list_ptr[1]; + + term new_term = ((term) dest) | 0x1; + memory_replace_with_moved_marker(list_ptr, new_term); + return new_term; + } + default: + UNREACHABLE(); + } +} + +static void memory_scan_and_copy_generational( + HeapFragment *old_fragment, const Heap *heap, + term *mem_start, const term *mem_end, + term **new_young_heap, term **old_heap_ptr, + term *young_mso_list, term *old_mso_list) +{ + term *ptr = mem_start; + + while (ptr < mem_end) { + term t = *ptr; + switch (t & TERM_PRIMARY_MASK) { + case TERM_PRIMARY_IMMED: + ptr++; + break; + case TERM_PRIMARY_CP: { + size_t arity = term_get_size_from_boxed_header(t); + switch (t & TERM_BOXED_TAG_MASK) { + case TERM_BOXED_TUPLE: { + for (size_t i = 1; i <= arity; i++) { + ptr[i] = memory_shallow_copy_term_generational(old_fragment, heap, ptr[i], new_young_heap, old_heap_ptr); + } + break; + } + case TERM_BOXED_BIN_MATCH_STATE: { + ptr[1] = memory_shallow_copy_term_generational(old_fragment, heap, ptr[1], new_young_heap, old_heap_ptr); + break; + } + case TERM_BOXED_POSITIVE_INTEGER: + case TERM_BOXED_NEGATIVE_INTEGER: + case TERM_BOXED_EXTERNAL_PID: + case TERM_BOXED_EXTERNAL_PORT: + case TERM_BOXED_EXTERNAL_REF: + case TERM_BOXED_FLOAT: + case TERM_BOXED_HEAP_BINARY: + break; + + case TERM_BOXED_REF: { + term ref = ((term) ptr) | TERM_PRIMARY_BOXED; + if (term_is_resource_reference(ref)) { + term *target_mso = memory_is_in_old_heap(heap, ptr) ? old_mso_list : young_mso_list; + *target_mso = term_list_init_prepend(ptr + REFERENCE_RESOURCE_CONS_OFFSET, ref, *target_mso); + refc_binary_increment_refcount((struct RefcBinary *) term_resource_refc_binary_ptr(ref)); + } + break; + } + + case TERM_BOXED_FUN: { + for (size_t i = 3; i <= arity; i++) { + ptr[i] = memory_shallow_copy_term_generational(old_fragment, heap, ptr[i], new_young_heap, old_heap_ptr); + } + break; + } + + case TERM_BOXED_REFC_BINARY: { + term ref = ((term) ptr) | TERM_PRIMARY_BOXED; + if (!term_refc_binary_is_const(ref)) { + term *target_mso = memory_is_in_old_heap(heap, ptr) ? old_mso_list : young_mso_list; + *target_mso = term_list_init_prepend(ptr + REFC_BINARY_CONS_OFFSET, ref, *target_mso); + refc_binary_increment_refcount((struct RefcBinary *) term_refc_binary_ptr(ref)); + } + break; + } + + case TERM_BOXED_SUB_BINARY: { + ptr[3] = memory_shallow_copy_term_generational(old_fragment, heap, ptr[3], new_young_heap, old_heap_ptr); + break; + } + + case TERM_BOXED_MAP: { + size_t map_size = arity - 1; + size_t keys_offset = term_get_map_keys_offset(); + size_t value_offset = term_get_map_value_offset(); + ptr[keys_offset] = memory_shallow_copy_term_generational(old_fragment, heap, ptr[keys_offset], new_young_heap, old_heap_ptr); + for (size_t i = value_offset; i < value_offset + map_size; ++i) { + ptr[i] = memory_shallow_copy_term_generational(old_fragment, heap, ptr[i], new_young_heap, old_heap_ptr); + } + break; + } + + default: + fprintf(stderr, "- Found unknown boxed type: %" TERM_X_FMT "\n", (t >> 2) & 0xF); + AVM_ABORT(); + } + ptr += arity + 1; + break; + } + case TERM_PRIMARY_LIST: + *ptr = memory_shallow_copy_term_generational(old_fragment, heap, t, new_young_heap, old_heap_ptr); + ptr++; + break; + case TERM_PRIMARY_BOXED: + *ptr = memory_shallow_copy_term_generational(old_fragment, heap, t, new_young_heap, old_heap_ptr); + ptr++; + break; + default: + UNREACHABLE(); + } + } +} + +static enum MemoryGCResult memory_minor_gc(Context *ctx, size_t new_size, size_t num_roots, term *roots) +{ + TRACE("Going to perform minor gc on process %i\n", ctx->process_id); + + term old_young_mso_list = ctx->heap.root->mso_list; + term *old_stack_ptr = context_stack_base(ctx); + term *old_heap_end = ctx->heap.heap_end; + HeapFragment *old_root_fragment = ctx->heap.root; + term *high_water_mark = ctx->heap.high_water_mark; + + size_t mature_size = high_water_mark - ctx->heap.heap_start; + + // Save old heap state before memory_init_heap clears it + term *saved_old_heap_start = ctx->heap.old_heap_start; + term *saved_old_heap_ptr = ctx->heap.old_heap_ptr; + term *saved_old_heap_end = ctx->heap.old_heap_end; + term saved_old_mso_list = ctx->heap.old_mso_list; + + bool newly_allocated_old_heap = false; + + if (saved_old_heap_start == NULL) { + if (mature_size > 0) { + HeapFragment *old_fragment = (HeapFragment *) malloc(sizeof(HeapFragment) + mature_size * sizeof(term)); + if (IS_NULL_PTR(old_fragment)) { + goto fallback_full_gc; + } + old_fragment->next = NULL; + saved_old_heap_start = old_fragment->storage; + saved_old_heap_ptr = old_fragment->storage; + saved_old_heap_end = old_fragment->storage + mature_size; + newly_allocated_old_heap = true; + } + } else { + size_t old_free = saved_old_heap_end - saved_old_heap_ptr; + if (old_free < mature_size) { + goto fallback_full_gc; + } + } + + if (UNLIKELY(memory_init_heap(&ctx->heap, new_size) != MEMORY_GC_OK)) { + if (newly_allocated_old_heap) { + free(OLD_HEAP_TO_FRAGMENT(saved_old_heap_start)); + } + return MEMORY_GC_ERROR_FAILED_ALLOCATION; + } + old_root_fragment->heap_end = old_heap_end; + + { + Heap gen_heap = { 0 }; + gen_heap.heap_start = old_root_fragment->storage; + gen_heap.high_water_mark = high_water_mark; + gen_heap.old_heap_start = saved_old_heap_start; + gen_heap.old_heap_ptr = saved_old_heap_ptr; + gen_heap.old_heap_end = saved_old_heap_end; + + term *new_young_heap = ctx->heap.heap_start; + term *old_heap_ptr = saved_old_heap_ptr; + + // Root scanning: stack + term *stack_ptr = new_young_heap + new_size; + while (old_stack_ptr > ctx->e) { + term new_root = memory_shallow_copy_term_generational( + old_root_fragment, &gen_heap, *(--old_stack_ptr), + &ctx->heap.heap_ptr, &old_heap_ptr); + push_to_stack(&stack_ptr, new_root); + } + ctx->e = stack_ptr; + + struct ListHead *item; + LIST_FOR_EACH (item, &ctx->dictionary) { + struct DictEntry *entry = GET_LIST_ENTRY(item, struct DictEntry, head); + entry->key = memory_shallow_copy_term_generational( + old_root_fragment, &gen_heap, entry->key, + &ctx->heap.heap_ptr, &old_heap_ptr); + entry->value = memory_shallow_copy_term_generational( + old_root_fragment, &gen_heap, entry->value, + &ctx->heap.heap_ptr, &old_heap_ptr); + } + + LIST_FOR_EACH (item, &ctx->extended_x_regs) { + struct ExtendedRegister *ext_reg = GET_LIST_ENTRY(item, struct ExtendedRegister, head); + ext_reg->value = memory_shallow_copy_term_generational( + old_root_fragment, &gen_heap, ext_reg->value, + &ctx->heap.heap_ptr, &old_heap_ptr); + } + + ctx->exit_reason = memory_shallow_copy_term_generational( + old_root_fragment, &gen_heap, ctx->exit_reason, + &ctx->heap.heap_ptr, &old_heap_ptr); + ctx->group_leader = memory_shallow_copy_term_generational( + old_root_fragment, &gen_heap, ctx->group_leader, + &ctx->heap.heap_ptr, &old_heap_ptr); + + for (size_t i = 0; i < num_roots; i++) { + roots[i] = memory_shallow_copy_term_generational( + old_root_fragment, &gen_heap, roots[i], + &ctx->heap.heap_ptr, &old_heap_ptr); + } + + // Dual scan loop on new young heap and promoted old region + { + term *young_scan = new_young_heap; + term *young_end = ctx->heap.heap_ptr; + term *old_scan = saved_old_heap_ptr; + term *old_end = old_heap_ptr; + term new_young_mso_list = term_nil(); + term new_old_mso_list = saved_old_mso_list; + + do { + term *next_young_end = young_end; + term *next_old_end = old_end; + + if (young_scan < young_end) { + memory_scan_and_copy_generational( + old_root_fragment, &gen_heap, + young_scan, young_end, + &next_young_end, &old_heap_ptr, + &new_young_mso_list, &new_old_mso_list); + young_scan = young_end; + young_end = next_young_end; + next_old_end = old_heap_ptr; + } + + if (old_scan < old_end) { + memory_scan_and_copy_generational( + old_root_fragment, &gen_heap, + old_scan, old_end, + &young_end, &old_heap_ptr, + &new_young_mso_list, &new_old_mso_list); + old_scan = old_end; + old_end = old_heap_ptr; + next_young_end = young_end; + } + + young_end = next_young_end; + old_end = next_old_end > old_heap_ptr ? next_old_end : old_heap_ptr; + } while (young_scan != young_end || old_scan != old_end); + + ctx->heap.heap_ptr = young_end; + + memory_sweep_mso_list(old_young_mso_list, ctx->global, false); + ctx->heap.root->mso_list = new_young_mso_list; + ctx->heap.old_mso_list = new_old_mso_list; + } + + ctx->heap.old_heap_start = saved_old_heap_start; + ctx->heap.old_heap_ptr = old_heap_ptr; + ctx->heap.old_heap_end = saved_old_heap_end; + ctx->heap.high_water_mark = ctx->heap.heap_ptr; + ctx->gc_count++; + + memory_destroy_heap_fragment(old_root_fragment); + + return MEMORY_GC_OK; + } + +fallback_full_gc: + // Restore old heap pointers + ctx->heap.old_heap_start = saved_old_heap_start; + ctx->heap.old_heap_ptr = saved_old_heap_ptr; + ctx->heap.old_heap_end = saved_old_heap_end; + ctx->heap.old_mso_list = saved_old_mso_list; + { + enum MemoryGCResult result = memory_full_gc(ctx, new_size, num_roots, roots); + if (result == MEMORY_GC_OK) { + ctx->heap.high_water_mark = ctx->heap.heap_ptr; + ctx->gc_count = 0; + } + return result; + } +} + void memory_heap_append_fragment(Heap *heap, HeapFragment *fragment, term mso_list) { // The fragment we are appending may have next fragments diff --git a/src/libAtomVM/memory.h b/src/libAtomVM/memory.h index e7317bebd4..7969753fa5 100644 --- a/src/libAtomVM/memory.h +++ b/src/libAtomVM/memory.h @@ -85,6 +85,11 @@ struct Heap term *heap_start; term *heap_ptr; term *heap_end; + term *high_water_mark; + term *old_heap_start; + term *old_heap_ptr; + term *old_heap_end; + term old_mso_list; }; #ifndef TYPEDEF_HEAP @@ -180,6 +185,9 @@ static inline size_t memory_heap_memory_size(const Heap *heap) if (heap->root->next) { result += memory_heap_fragment_memory_size(heap->root->next); } + if (heap->old_heap_start) { + result += heap->old_heap_end - heap->old_heap_start; + } return result; } @@ -358,6 +366,12 @@ static inline void memory_destroy_heap_fragment(HeapFragment *fragment) free((void *) fragment); } +/** + * @brief Recover the HeapFragment pointer from an old_heap_start pointer. + */ +#define OLD_HEAP_TO_FRAGMENT(ptr) \ + ((HeapFragment *) ((char *) (ptr) -offsetof(HeapFragment, storage))) + /** * @brief Destroy a root heap. First sweep its mso list. * @@ -371,6 +385,10 @@ static inline void memory_destroy_heap_fragment(HeapFragment *fragment) static inline void memory_destroy_heap(Heap *heap, GlobalContext *global) { memory_sweep_mso_list(heap->root->mso_list, global, false); + if (heap->old_heap_start) { + memory_sweep_mso_list(heap->old_mso_list, global, false); + free(OLD_HEAP_TO_FRAGMENT(heap->old_heap_start)); + } memory_destroy_heap_fragment(heap->root); } @@ -386,6 +404,10 @@ static inline void memory_destroy_heap(Heap *heap, GlobalContext *global) static inline void memory_destroy_heap_from_task(Heap *heap, GlobalContext *global) { memory_sweep_mso_list(heap->root->mso_list, global, true); + if (heap->old_heap_start) { + memory_sweep_mso_list(heap->old_mso_list, global, true); + free(OLD_HEAP_TO_FRAGMENT(heap->old_heap_start)); + } memory_destroy_heap_fragment(heap->root); } #endif diff --git a/src/libAtomVM/nifs.c b/src/libAtomVM/nifs.c index d559e4a5b6..6103344aca 100644 --- a/src/libAtomVM/nifs.c +++ b/src/libAtomVM/nifs.c @@ -1297,6 +1297,7 @@ static term do_spawn(Context *ctx, Context *new_ctx, size_t arity, size_t n_free { term min_heap_size_term = interop_proplist_get_value(opts_term, MIN_HEAP_SIZE_ATOM); term max_heap_size_term = interop_proplist_get_value(opts_term, MAX_HEAP_SIZE_ATOM); + term fullsweep_after_term = interop_proplist_get_value(opts_term, FULLSWEEP_AFTER_ATOM); term link_term = interop_proplist_get_value(opts_term, LINK_ATOM); term monitor_term = interop_proplist_get_value(opts_term, MONITOR_ATOM); term heap_growth_strategy = interop_proplist_get_value_default(opts_term, ATOMVM_HEAP_GROWTH_ATOM, BOUNDED_FREE_ATOM); @@ -1338,6 +1339,13 @@ static term do_spawn(Context *ctx, Context *new_ctx, size_t arity, size_t n_free RAISE_ERROR(BADARG_ATOM); } } + if (fullsweep_after_term != term_nil()) { + if (UNLIKELY(!term_is_integer(fullsweep_after_term) || term_to_int(fullsweep_after_term) < 0)) { + context_destroy(new_ctx); + RAISE_ERROR(BADARG_ATOM); + } + new_ctx->fullsweep_after = term_to_int(fullsweep_after_term); + } int size = 0; for (uint32_t i = 0; i < n_freeze; i++) { @@ -2898,6 +2906,14 @@ static term nif_erlang_process_flag(Context *ctx, int argc, term argv[]) } return prev; } + case FULLSWEEP_AFTER_ATOM: { + if (UNLIKELY(!term_is_integer(value) || term_to_int(value) < 0)) { + RAISE_ERROR(BADARG_ATOM); + } + term prev = term_from_int(ctx->fullsweep_after); + ctx->fullsweep_after = term_to_int(value); + return prev; + } } // TODO: check erlang:process_flag/3 implementation diff --git a/tests/erlang_tests/CMakeLists.txt b/tests/erlang_tests/CMakeLists.txt index 2d96b4a1a4..61499366fe 100644 --- a/tests/erlang_tests/CMakeLists.txt +++ b/tests/erlang_tests/CMakeLists.txt @@ -572,6 +572,7 @@ compile_erlang(link_kill_parent) compile_erlang(link_throw) compile_erlang(unlink_error) compile_erlang(trap_exit_flag) +compile_erlang(test_process_flag_fullsweep_after) compile_erlang(test_exit1) compile_erlang(test_exit2) @@ -1125,6 +1126,7 @@ set(erlang_test_beams link_throw.beam unlink_error.beam trap_exit_flag.beam + test_process_flag_fullsweep_after.beam test_exit1.beam test_exit2.beam diff --git a/tests/erlang_tests/test_heap_growth.erl b/tests/erlang_tests/test_heap_growth.erl index a42d224cbd..71ba73ee57 100644 --- a/tests/erlang_tests/test_heap_growth.erl +++ b/tests/erlang_tests/test_heap_growth.erl @@ -43,7 +43,7 @@ test_grow_beyond_min_heap_size() -> % do something with Var to avoid compiler optimizations true = 200 =:= length(Var) end, - [monitor, {min_heap_size, 100}] + [monitor, {min_heap_size, 100}, {fullsweep_after, 0}] ), ok = receive @@ -70,7 +70,7 @@ test_bounded_free_strategy(UseDefault) -> true = X3 < X2, true = X3 - X1 - erts_debug:flat_size(Var1) < 32 end, - [monitor | Opt] + [monitor, {fullsweep_after, 0} | Opt] ), ok = receive @@ -107,7 +107,7 @@ test_minimum_strategy() -> end, 20 = erts_debug:flat_size(Var1) end, - [monitor, {atomvm_heap_growth, minimum}] + [monitor, {atomvm_heap_growth, minimum}, {fullsweep_after, 0}] ), % Get heap size from the outside to have no influence on the heap Pid1 ! {step, 1}, @@ -172,7 +172,7 @@ test_fibonacci_strategy() -> NewHeap = allocate_until_heap_size_changes(MaxHeap), true = NewHeap < MaxHeap end, - [monitor, link, {atomvm_heap_growth, fibonacci}] + [monitor, link, {atomvm_heap_growth, fibonacci}, {fullsweep_after, 0}] ), % Test large increments no longer follow fibonacci {Pid2, Ref2} = spawn_opt( @@ -182,7 +182,7 @@ test_fibonacci_strategy() -> NewHeap = allocate_until_heap_size_changes(MaxHeap), true = NewHeap < MaxHeap end, - [monitor, link, {atomvm_heap_growth, fibonacci}] + [monitor, link, {atomvm_heap_growth, fibonacci}, {fullsweep_after, 0}] ), ok = receive @@ -278,7 +278,7 @@ test_messages_get_gcd() -> fun() -> loop([]) end, - [monitor, {atomvm_heap_growth, minimum}] + [monitor, {atomvm_heap_growth, minimum}, {fullsweep_after, 0}] ), FinalHeapSize = loop_send(Pid1, 20), Pid1 ! quit, diff --git a/tests/erlang_tests/test_process_flag_fullsweep_after.erl b/tests/erlang_tests/test_process_flag_fullsweep_after.erl new file mode 100644 index 0000000000..bf50e11a91 --- /dev/null +++ b/tests/erlang_tests/test_process_flag_fullsweep_after.erl @@ -0,0 +1,73 @@ +% +% This file is part of AtomVM. +% +% Copyright 2026 Paul Guyot +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. +% +% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later +% + +-module(test_process_flag_fullsweep_after). + +-export([start/0]). + +start() -> + case get_otp_version() > 23 of + true -> + ok = test_process_flag_fullsweep_after(), + ok = test_spawn_opt_fullsweep_after(); + false -> + % Can we please get rid of OTP < 24 support? + ok + end, + 0. + +test_process_flag_fullsweep_after() -> + OldVal = erlang:process_flag(fullsweep_after, 10), + 10 = erlang:process_flag(fullsweep_after, 0), + 0 = erlang:process_flag(fullsweep_after, OldVal), + ok = expect_badarg(fun() -> erlang:process_flag(fullsweep_after, -1) end), + ok = expect_badarg(fun() -> erlang:process_flag(fullsweep_after, foo) end), + ok. + +test_spawn_opt_fullsweep_after() -> + Parent = self(), + spawn_opt( + fun() -> + {fullsweep_after, Val} = erlang:process_info(self(), fullsweep_after), + Parent ! {fullsweep_after, Val} + end, + [{fullsweep_after, 42}] + ), + receive + {fullsweep_after, 42} -> ok + after 500 -> timeout + end, + ok = expect_badarg(fun() -> spawn_opt(fun() -> ok end, [{fullsweep_after, -1}]) end), + ok = expect_badarg(fun() -> spawn_opt(fun() -> ok end, [{fullsweep_after, foo}]) end), + ok. + +expect_badarg(Fun) -> + try + Fun(), + unexpected + catch + error:badarg -> ok + end. + +get_otp_version() -> + case erlang:system_info(machine) of + "BEAM" -> list_to_integer(erlang:system_info(otp_release)); + _ -> atomvm + end. diff --git a/tests/libs/jit/jit_aarch64_tests.erl b/tests/libs/jit/jit_aarch64_tests.erl index 6e287ac1c7..1591eb716c 100644 --- a/tests/libs/jit/jit_aarch64_tests.erl +++ b/tests/libs/jit/jit_aarch64_tests.erl @@ -116,9 +116,9 @@ call_primitive_6_args_test() -> Stream = ?BACKEND:stream(State4), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: 927ef4e7 and x7, x7, #0xfffffffffffffffc\n" - " 8: f9401c08 ldr x8, [x0, #56]\n" + " 8: f9403008 ldr x8, [x0, #96]\n" " c: f940b850 ldr x16, [x2, #368]\n" " 10: a9bf03fe stp x30, x0, [sp, #-16]!\n" " 14: a9bf0be1 stp x1, x2, [sp, #-16]!\n" @@ -259,7 +259,7 @@ call_primitive_last_5_args_test() -> ]), Stream = ?BACKEND:stream(State2), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: f9404c48 ldr x8, [x2, #152]\n" " 8: d2800102 mov x2, #0x8 // #8\n" " c: d2805963 mov x3, #0x2cb // #715\n" @@ -371,9 +371,9 @@ move_to_cp_test() -> Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f94000e7 ldr x7, [x7]\n" - " 8: f9005c07 str x7, [x0, #184]" + " 8: f9007007 str x7, [x0, #224]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream). @@ -383,9 +383,9 @@ increment_sp_test() -> Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: 9100e0e7 add x7, x7, #0x38\n" - " 8: f9001407 str x7, [x0, #40]" + " 8: f9002807 str x7, [x0, #80]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream). @@ -409,8 +409,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: b6f80047 tbz x7, #63, 0x10\n" " c: 91000908 add x8, x8, #0x2" >>, @@ -427,8 +427,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: eb0800ff cmp x7, x8\n" " c: 5400004a b.ge 0x14 // b.tcont\n" " 10: 91000908 add x8, x8, #0x2" @@ -446,8 +446,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: b5000047 cbnz x7, 0x10\n" " c: 91000908 add x8, x8, #0x2" >>, @@ -464,8 +464,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: b5000047 cbnz x7, 0x10\n" " c: 91000908 add x8, x8, #0x2" >>, @@ -482,8 +482,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 35000047 cbnz w7, 0x10\n" " c: 91000908 add x8, x8, #0x2" >>, @@ -500,8 +500,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 35000047 cbnz w7, 0x10\n" " c: 91000908 add x8, x8, #0x2" >>, @@ -518,8 +518,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f100ecff cmp x7, #0x3b\n" " c: 54000040 b.eq 0x14 // b.none\n" " 10: 91000908 add x8, x8, #0x2" @@ -537,8 +537,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f100ecff cmp x7, #0x3b\n" " c: 54000040 b.eq 0x14 // b.none\n" " 10: 91000908 add x8, x8, #0x2" @@ -556,8 +556,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 7100a8ff cmp w7, #0x2a\n" " c: 54000040 b.eq 0x14 // b.none\n" " 10: 91000908 add x8, x8, #0x2" @@ -575,8 +575,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 7100a8ff cmp w7, #0x2a\n" " c: 54000040 b.eq 0x14 // b.none\n" " 10: 91000908 add x8, x8, #0x2" @@ -594,8 +594,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f100ecff cmp x7, #0x3b\n" " c: 54000041 b.ne 0x14 // b.any\n" " 10: 91000908 add x8, x8, #0x2" @@ -613,8 +613,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f100ecff cmp x7, #0x3b\n" " c: 54000041 b.ne 0x14 // b.any\n" " 10: 91000908 add x8, x8, #0x2" @@ -632,8 +632,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 7100a8ff cmp w7, #0x2a\n" " c: 54000041 b.ne 0x14 // b.any\n" " 10: 91000908 add x8, x8, #0x2" @@ -651,8 +651,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 7100a8ff cmp w7, #0x2a\n" " c: 54000041 b.ne 0x14 // b.any\n" " 10: 91000908 add x8, x8, #0x2" @@ -670,8 +670,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 37000047 tbnz w7, #0, 0x10\n" " c: 91000908 add x8, x8, #0x2" >>, @@ -688,8 +688,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 37000047 tbnz w7, #0, 0x10\n" " c: 91000908 add x8, x8, #0x2" >>, @@ -706,8 +706,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 36000047 tbz w7, #0, 0x10\n" " c: 91000908 add x8, x8, #0x2" >>, @@ -724,8 +724,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 36000047 tbz w7, #0, 0x10\n" " c: 91000908 add x8, x8, #0x2" >>, @@ -742,8 +742,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f24008ff tst x7, #0x7\n" " c: 54000040 b.eq 0x14 // b.none\n" " 10: 91000908 add x8, x8, #0x2" @@ -761,8 +761,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: d28000a9 mov x9, #0x5 // #5\n" " c: ea0900ff tst x7, x9\n" " 10: 54000040 b.eq 0x18 // b.none\n" @@ -781,8 +781,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f24008ff tst x7, #0x7\n" " c: 54000040 b.eq 0x14 // b.none\n" " 10: 91000908 add x8, x8, #0x2" @@ -800,8 +800,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 92400ce9 and x9, x7, #0xf\n" " c: f1003d3f cmp x9, #0xf\n" " 10: 54000040 b.eq 0x18 // b.none\n" @@ -820,8 +820,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: 92400ce7 and x7, x7, #0xf\n" " c: f1003cff cmp x7, #0xf\n" " 10: 54000040 b.eq 0x18 // b.none\n" @@ -840,8 +840,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f10190ff cmp x7, #0x64\n" " c: 5400004d b.le 0x14\n" " 10: 91000908 add x8, x8, #0x2" @@ -859,8 +859,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f10190ff cmp x7, #0x64\n" " c: 5400004d b.le 0x14\n" " 10: 91000908 add x8, x8, #0x2" @@ -878,8 +878,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f10190ff cmp x7, #0x64\n" " c: 5400004a b.ge 0x14 // b.tcont\n" " 10: 91000908 add x8, x8, #0x2" @@ -897,8 +897,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f10190ff cmp x7, #0x64\n" " c: 5400004a b.ge 0x14 // b.tcont\n" " 10: 91000908 add x8, x8, #0x2" @@ -926,8 +926,8 @@ if_else_block_test() -> Stream = ?BACKEND:stream(State3), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401c08 ldr x8, [x0, #56]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9403008 ldr x8, [x0, #96]\n" " 8: f100ecff cmp x7, #0x3b\n" " c: 54000061 b.ne 0x18 // b.any\n" " 10: 91000908 add x8, x8, #0x2\n" @@ -945,7 +945,7 @@ shift_right_test_() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: d343fce7 lsr x7, x7, #3" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream) @@ -958,7 +958,7 @@ shift_right_test_() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: d343fce8 lsr x8, x7, #3" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream) @@ -972,7 +972,7 @@ shift_left_test() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: d37df0e7 lsl x7, x7, #3" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream). @@ -1083,7 +1083,7 @@ call_bif_with_large_literal_integer_test() -> " 5c: a9bf0be1 stp x1, x2, [sp, #-16]!\n" " 60: d2800001 mov x1, #0x0 // #0\n" " 64: d2800022 mov x2, #0x1 // #1\n" - " 68: f9401803 ldr x3, [x0, #48]\n" + " 68: f9402c03 ldr x3, [x0, #88]\n" " 6c: aa0803e4 mov x4, x8\n" " 70: d63f00e0 blr x7\n" " 74: aa0003e7 mov x7, x0\n" @@ -1093,7 +1093,7 @@ call_bif_with_large_literal_integer_test() -> " 84: f9401847 ldr x7, [x2, #48]\n" " 88: d2801102 mov x2, #0x88 // #136\n" " 8c: d61f00e0 br x7\n" - " 90: f9001807 str x7, [x0, #48]" + " 90: f9002c07 str x7, [x0, #88]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream). @@ -1107,12 +1107,12 @@ get_list_test() -> ?BACKEND:assert_all_native_free(State5), Stream = ?BACKEND:stream(State5), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: 927ef4e7 and x7, x7, #0xfffffffffffffffc\n" - " 8: f9401408 ldr x8, [x0, #40]\n" + " 8: f9402808 ldr x8, [x0, #80]\n" " c: f94004e9 ldr x9, [x7, #8]\n" " 10: f9000509 str x9, [x8, #8]\n" - " 14: f9401408 ldr x8, [x0, #40]\n" + " 14: f9402808 ldr x8, [x0, #80]\n" " 18: f94000e9 ldr x9, [x7]\n" " 1c: f9000109 str x9, [x8]" >>, @@ -1157,7 +1157,7 @@ is_integer_test() -> Dump = << " 0: 14000001 b 0x4\n" " 4: 14000050 b 0x144\n" - " 8: f9401807 ldr x7, [x0, #48]\n" + " 8: f9402c07 ldr x7, [x0, #88]\n" " c: 92400ce8 and x8, x7, #0xf\n" " 10: f1003d1f cmp x8, #0xf\n" " 14: 54000180 b.eq 0x44 // b.none\n" @@ -1213,7 +1213,7 @@ is_number_test() -> Dump = << " 0: 14000001 b 0x4\n" " 4: 14000053 b 0x150\n" - " 8: f9401807 ldr x7, [x0, #48]\n" + " 8: f9402c07 ldr x7, [x0, #88]\n" " c: 92400ce8 and x8, x7, #0xf\n" " 10: f1003d1f cmp x8, #0xf\n" " 14: 540001e0 b.eq 0x50 // b.none\n" @@ -1253,7 +1253,7 @@ is_boolean_test() -> Dump = << " 0: 14000001 b 0x4\n" " 4: 14000047 b 0x120\n" - " 8: f9401807 ldr x7, [x0, #48]\n" + " 8: f9402c07 ldr x7, [x0, #88]\n" " c: f1012cff cmp x7, #0x4b\n" " 10: 54000080 b.eq 0x20\n" " 14: f1002cff cmp x7, #0xb\n" @@ -1432,9 +1432,9 @@ gc_bif2_test() -> " 28: a9bf0be1 stp x1, x2, [sp, #-16]!\n" " 2c: d2800001 mov x1, #0x0 // #0\n" " 30: d2800062 mov x2, #0x3 // #3\n" - " 34: f9401403 ldr x3, [x0, #40]\n" + " 34: f9402803 ldr x3, [x0, #80]\n" " 38: f9400063 ldr x3, [x3]\n" - " 3c: f9401804 ldr x4, [x0, #48]\n" + " 3c: f9402c04 ldr x4, [x0, #88]\n" " 40: d63f00e0 blr x7\n" " 44: aa0003e7 mov x7, x0\n" " 48: a8c10be1 ldp x1, x2, [sp], #16\n" @@ -1484,7 +1484,7 @@ call_ext_test() -> " 28: d3689ce7 lsl x7, x7, #24\n" " 2c: d2802610 mov x16, #0x130 // #304\n" " 30: aa1000e7 orr x7, x7, x16\n" - " 34: f9005c07 str x7, [x0, #184]\n" + " 34: f9007007 str x7, [x0, #224]\n" " 38: f9401047 ldr x7, [x2, #32]\n" " 3c: d2800042 mov x2, #0x2 // #2\n" " 40: d28000a3 mov x3, #0x5 // #5\n" @@ -1531,7 +1531,7 @@ call_fun_test() -> " 14: f9000427 str x7, [x1, #8]\n" " 18: f9400847 ldr x7, [x2, #16]\n" " 1c: d61f00e0 br x7\n" - " 20: f9401807 ldr x7, [x0, #48]\n" + " 20: f9402c07 ldr x7, [x0, #88]\n" " 24: aa0703e8 mov x8, x7\n" " 28: 92400509 and x9, x8, #0x3\n" " 2c: f100093f cmp x9, #0x2\n" @@ -1556,7 +1556,7 @@ call_fun_test() -> " 78: d3689d08 lsl x8, x8, #24\n" " 7c: d2804c10 mov x16, #0x260 // #608\n" " 80: aa100108 orr x8, x8, x16\n" - " 84: f9005c08 str x8, [x0, #184]\n" + " 84: f9007008 str x8, [x0, #224]\n" " 88: f9408048 ldr x8, [x2, #256]\n" " 8c: aa0703e2 mov x2, x7\n" " 90: d2800003 mov x3, #0x0 // #0\n" @@ -1578,12 +1578,12 @@ move_to_vm_register_test_() -> [ ?_test(begin move_to_vm_register_test0(State0, 0, {x_reg, 0}, << - " 0: f900181f str xzr, [x0, #48]" + " 0: f9002c1f str xzr, [x0, #88]" >>) end), ?_test(begin move_to_vm_register_test0(State0, 0, {x_reg, extra}, << - " 0: f900581f str xzr, [x0, #176]" + " 0: f9006c1f str xzr, [x0, #216]" >>) end), ?_test(begin @@ -1593,13 +1593,13 @@ move_to_vm_register_test_() -> end), ?_test(begin move_to_vm_register_test0(State0, 0, {y_reg, 2}, << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f90008ff str xzr, [x7, #16]" >>) end), ?_test(begin move_to_vm_register_test0(State0, 0, {y_reg, 20}, << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f90050ff str xzr, [x7, #160]" >>) end), @@ -1607,26 +1607,26 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 42, {x_reg, 0}, << " 0: d2800547 mov x7, #0x2a // #42\n" - " 4: f9001807 str x7, [x0, #48]" + " 4: f9002c07 str x7, [x0, #88]" >>) end), ?_test(begin move_to_vm_register_test0(State0, 42, {x_reg, extra}, << " 0: d2800547 mov x7, #0x2a // #42\n" - " 4: f9005807 str x7, [x0, #176]" + " 4: f9006c07 str x7, [x0, #216]" >>) end), ?_test(begin move_to_vm_register_test0(State0, 42, {y_reg, 2}, << " 0: d2800547 mov x7, #0x2a // #42\n" - " 4: f9401408 ldr x8, [x0, #40]\n" + " 4: f9402808 ldr x8, [x0, #80]\n" " 8: f9000907 str x7, [x8, #16]" >>) end), ?_test(begin move_to_vm_register_test0(State0, 42, {y_reg, 20}, << " 0: d2800547 mov x7, #0x2a // #42\n" - " 4: f9401408 ldr x8, [x0, #40]\n" + " 4: f9402808 ldr x8, [x0, #80]\n" " 8: f9005107 str x7, [x8, #160]" >>) end), @@ -1640,14 +1640,14 @@ move_to_vm_register_test_() -> %% Test: x_reg to x_reg ?_test(begin move_to_vm_register_test0(State0, {x_reg, 1}, {x_reg, 2}, << - " 0: f9401c07 ldr x7, [x0, #56]\n" - " 4: f9002007 str x7, [x0, #64]" + " 0: f9403007 ldr x7, [x0, #96]\n" + " 4: f9003407 str x7, [x0, #104]" >>) end), %% Test: x_reg to ptr ?_test(begin move_to_vm_register_test0(State0, {x_reg, 1}, {ptr, r8}, << - " 0: f9401c07 ldr x7, [x0, #56]\n" + " 0: f9403007 ldr x7, [x0, #96]\n" " 4: f9000107 str x7, [x8]" >>) end), @@ -1655,42 +1655,42 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, {ptr, r9}, {x_reg, 3}, << " 0: f9400127 ldr x7, [x9]\n" - " 4: f9002407 str x7, [x0, #72]" + " 4: f9003807 str x7, [x0, #112]" >>) end), %% Test: x_reg to y_reg ?_test(begin move_to_vm_register_test0(State0, {x_reg, 0}, {y_reg, 1}, << - " 0: f9401807 ldr x7, [x0, #48]\n" - " 4: f9401408 ldr x8, [x0, #40]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" + " 4: f9402808 ldr x8, [x0, #80]\n" " 8: f9000507 str x7, [x8, #8]" >>) end), %% Test: y_reg to x_reg ?_test(begin move_to_vm_register_test0(State0, {y_reg, 0}, {x_reg, 3}, << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f94000e7 ldr x7, [x7]\n" - " 8: f9002407 str x7, [x0, #72]" + " 8: f9003807 str x7, [x0, #112]" >>) end), %% Test: y_reg to y_reg ?_test(begin move_to_vm_register_test0(State0, {y_reg, 1}, {x_reg, 3}, << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f94004e7 ldr x7, [x7, #8]\n" - " 8: f9002407 str x7, [x0, #72]" + " 8: f9003807 str x7, [x0, #112]" >>) end), %% Test: Native register to x_reg ?_test(begin move_to_vm_register_test0(State0, r10, {x_reg, 0}, << - " 0: f900180a str x10, [x0, #48]" + " 0: f9002c0a str x10, [x0, #88]" >>) end), ?_test(begin move_to_vm_register_test0(State0, r10, {x_reg, extra}, << - " 0: f900580a str x10, [x0, #176]" + " 0: f9006c0a str x10, [x0, #216]" >>) end), %% Test: Native register to ptr @@ -1702,7 +1702,7 @@ move_to_vm_register_test_() -> %% Test: Native register to y_reg ?_test(begin move_to_vm_register_test0(State0, r10, {y_reg, 0}, << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f90000ea str x10, [x7]" >>) end), @@ -1713,7 +1713,7 @@ move_to_vm_register_test_() -> " 4: f2b35787 movk x7, #0x9abc, lsl #16\n" " 8: f2cacf07 movk x7, #0x5678, lsl #32\n" " c: f2e24687 movk x7, #0x1234, lsl #48\n" - " 10: f9001807 str x7, [x0, #48]" + " 10: f9002c07 str x7, [x0, #88]" >>) end), ?_test(begin @@ -1722,7 +1722,7 @@ move_to_vm_register_test_() -> " 4: f2b35787 movk x7, #0x9abc, lsl #16\n" " 8: f2cacf07 movk x7, #0x5678, lsl #32\n" " c: f2e24687 movk x7, #0x1234, lsl #48\n" - " 10: f9005807 str x7, [x0, #176]\n" + " 10: f9006c07 str x7, [x0, #216]\n" >>) end), ?_test(begin @@ -1731,7 +1731,7 @@ move_to_vm_register_test_() -> " 4: f2b35787 movk x7, #0x9abc, lsl #16\n" " 8: f2cacf07 movk x7, #0x5678, lsl #32\n" " c: f2e24687 movk x7, #0x1234, lsl #48\n" - " 10: f9401408 ldr x8, [x0, #40]\n" + " 10: f9402808 ldr x8, [x0, #80]\n" " 14: f9000907 str x7, [x8, #16]" >>) end), @@ -1741,7 +1741,7 @@ move_to_vm_register_test_() -> " 4: f2b35787 movk x7, #0x9abc, lsl #16\n" " 8: f2cacf07 movk x7, #0x5678, lsl #32\n" " c: f2e24687 movk x7, #0x1234, lsl #48\n" - " 10: f9401408 ldr x8, [x0, #40]\n" + " 10: f9402808 ldr x8, [x0, #80]\n" " 14: f9005107 str x7, [x8, #160]" >>) end), @@ -1758,24 +1758,24 @@ move_to_vm_register_test_() -> %% Test: x_reg to y_reg (high index) ?_test(begin move_to_vm_register_test0(State0, {x_reg, 15}, {y_reg, 31}, << - " 0: f9405407 ldr x7, [x0, #168]\n" - " 4: f9401408 ldr x8, [x0, #40]\n" + " 0: f9406807 ldr x7, [x0, #208]\n" + " 4: f9402808 ldr x8, [x0, #80]\n" " 8: f9007d07 str x7, [x8, #248]" >>) end), %% Test: y_reg to x_reg (high index) ?_test(begin move_to_vm_register_test0(State0, {y_reg, 31}, {x_reg, 15}, << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f9407ce7 ldr x7, [x7, #248]\n" - " 8: f9005407 str x7, [x0, #168]" + " 8: f9006807 str x7, [x0, #208]" >>) end), %% Test: Negative immediate to x_reg ?_test(begin move_to_vm_register_test0(State0, -1, {x_reg, 0}, << " 0: 92800007 mov x7, #0xffffffffffffffff // #-1\n" - " 4: f9001807 str x7, [x0, #48]" + " 4: f9002c07 str x7, [x0, #88]" >>) end), %% Test: ptr with offset to fp_reg (term_to_float) @@ -1786,9 +1786,9 @@ move_to_vm_register_test_() -> ), Stream = ?BACKEND:stream(State2), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: f94004e7 ldr x7, [x7, #8]\n" - " 8: f9406008 ldr x8, [x0, #192]\n" + " 8: f9407408 ldr x8, [x0, #232]\n" " c: f9000d07 str x7, [x8, #24]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream) @@ -1812,7 +1812,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, r8, 2, {x_reg, 0}, << " 0: f9400907 ldr x7, [x8, #16]\n" - " 4: f9001807 str x7, [x0, #48]" + " 4: f9002c07 str x7, [x0, #88]" >>) end), %% move_array_element: reg[x] to ptr @@ -1825,7 +1825,7 @@ move_array_element_test_() -> %% move_array_element: reg[x] to y_reg ?_test(begin move_array_element_test0(State0, r8, 1, {y_reg, 2}, << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f9400508 ldr x8, [x8, #8]\n" " 8: f90008e8 str x8, [x7, #16]" >>) @@ -1839,7 +1839,7 @@ move_array_element_test_() -> %% move_array_element: reg[x] to y_reg ?_test(begin move_array_element_test0(State0, r8, 7, {y_reg, 31}, << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f9401d08 ldr x8, [x8, #56]\n" " 8: f9007ce8 str x8, [x7, #248]" >>) @@ -1848,7 +1848,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, r8, 7, {x_reg, 15}, << " 0: f9401d07 ldr x7, [x8, #56]\n" - " 4: f9005407 str x7, [x0, #168]" + " 4: f9006807 str x7, [x0, #208]" >>) end), %% move_array_element: reg_x[reg_y] to x_reg @@ -1857,7 +1857,7 @@ move_array_element_test_() -> move_array_element_test0(State1, r8, {free, Reg}, {x_reg, 2}, << " 0: f9401107 ldr x7, [x8, #32]\n" " 4: f8677907 ldr x7, [x8, x7, lsl #3]\n" - " 8: f9002007 str x7, [x0, #64]" + " 8: f9003407 str x7, [x0, #104]" >>) end), %% move_array_element: reg_x[reg_y] to pointer (large x reg) @@ -1874,7 +1874,7 @@ move_array_element_test_() -> {State1, Reg} = ?BACKEND:get_array_element(State0, r8, 4), move_array_element_test0(State1, r8, {free, Reg}, {y_reg, 31}, << " 0: f9401107 ldr x7, [x8, #32]\n" - " 4: f9401408 ldr x8, [x0, #40]\n" + " 4: f9402808 ldr x8, [x0, #80]\n" " 8: f8677907 ldr x7, [x8, x7, lsl #3]\n" " c: f9007d07 str x7, [x8, #248]" >>) @@ -1914,7 +1914,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, r8, 2), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: f9000907 str x7, [x8, #16]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream) @@ -1924,7 +1924,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, r8, r9), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: f8297907 str x7, [x8, x9, lsl #3]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream) @@ -1944,7 +1944,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {y_reg, 2}, r8, r9), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f94008e7 ldr x7, [x7, #16]\n" " 8: f8297907 str x7, [x8, x9, lsl #3]" >>, @@ -1955,7 +1955,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, r8, 2, 1), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: f9000d07 str x7, [x8, #24]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream) @@ -1968,7 +1968,7 @@ move_to_array_element_test_() -> State3 = ?BACKEND:move_to_array_element(State2, {x_reg, 0}, r8, r9, 1), Stream = ?BACKEND:stream(State3), Dump = << - " 0: f9401807 ldr x7, [x0, #48]\n" + " 0: f9402c07 ldr x7, [x0, #88]\n" " 4: 9100052a add x10, x9, #0x1\n" " 8: f82a7907 str x7, [x8, x10, lsl #3]" >>, @@ -2024,7 +2024,7 @@ move_to_native_register_test_() -> Stream = ?BACKEND:stream(State1), ?assertEqual(r7, Reg), Dump = << - " 0: f9402407 ldr x7, [x0, #72]" + " 0: f9403807 ldr x7, [x0, #112]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream) end), @@ -2034,7 +2034,7 @@ move_to_native_register_test_() -> Stream = ?BACKEND:stream(State1), ?assertEqual(r7, Reg), Dump = << - " 0: f9401407 ldr x7, [x0, #40]\n" + " 0: f9402807 ldr x7, [x0, #80]\n" " 4: f9400ce7 ldr x7, [x7, #24]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream) @@ -2071,7 +2071,7 @@ move_to_native_register_test_() -> State1 = ?BACKEND:move_to_native_register(State0, {x_reg, 2}, r8), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9402008 ldr x8, [x0, #64]" + " 0: f9403408 ldr x8, [x0, #104]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream) end), @@ -2080,7 +2080,7 @@ move_to_native_register_test_() -> State1 = ?BACKEND:move_to_native_register(State0, {y_reg, 2}, r8), Stream = ?BACKEND:stream(State1), Dump = << - " 0: f9401408 ldr x8, [x0, #40]\n" + " 0: f9402808 ldr x8, [x0, #80]\n" " 4: f9400908 ldr x8, [x8, #16]" >>, jit_tests_common:assert_stream(aarch64, Dump, Stream) diff --git a/tests/libs/jit/jit_armv6m_tests.erl b/tests/libs/jit/jit_armv6m_tests.erl index 244f77f2cb..c6ac6643c6 100644 --- a/tests/libs/jit/jit_armv6m_tests.erl +++ b/tests/libs/jit/jit_armv6m_tests.erl @@ -117,10 +117,10 @@ call_primitive_6_args_test() -> Stream = ?BACKEND:stream(State4), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 2603 movs r6, #3\n" " 4: 43b7 bics r7, r6\n" - " 6: 69c6 ldr r6, [r0, #28]\n" + " 6: 6b06 ldr r6, [r0, #48]\n" " 8: 25b8 movs r5, #184 ; 0xb8\n" " a: 5955 ldr r5, [r2, r5]\n" " c: b405 push {r0, r2}\n" @@ -305,7 +305,7 @@ call_primitive_last_5_args_test() -> Stream = ?BACKEND:stream(State2), Dump = << % {State1, RegA} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}), - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" % State2 = ?BACKEND:call_primitive_last(State1, ?PRIM_RAISE_ERROR_TUPLE, [... " 2: 6cd6 ldr r6, [r2, #76] ; 0x4c\n" " 4: b082 sub sp, #8\n" @@ -442,9 +442,9 @@ move_to_cp_test() -> Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6946 ldr r6, [r0, #20]\n" + " 0: 6a86 ldr r6, [r0, #40]\n" " 2: 6837 ldr r7, [r6, #0]\n" - " 4: 65c7 str r7, [r0, #92] ; 0x5c" + " 4: 6707 str r7, [r0, #112]" >>, jit_tests_common:assert_stream(arm, Dump, Stream). @@ -454,9 +454,9 @@ increment_sp_test() -> Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6947 ldr r7, [r0, #20]\n" + " 0: 6a87 ldr r7, [r0, #40]\n" " 2: 371c adds r7, #28\n" - " 4: 6147 str r7, [r0, #20]" + " 4: 6287 str r7, [r0, #40]" >>, jit_tests_common:assert_stream(arm, Dump, Stream). @@ -480,8 +480,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f00 cmp r7, #0\n" " 6: d500 bpl.n 0xa\n" " 8: 3602 adds r6, #2" @@ -499,8 +499,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 42b7 cmp r7, r6\n" " 6: da00 bge.n 0xa\n" " 8: 3602 adds r6, #2" @@ -518,8 +518,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f2a cmp r7, #42 ; 0x2a\n" " 6: da00 bge.n 0xa\n" " 8: 3602 adds r6, #2" @@ -538,8 +538,8 @@ if_block_test_() -> State2 = ?BACKEND:jump_to_offset(State1, 16#100), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2580 movs r5, #128 ; 0x80\n" " 6: 00ed lsls r5, r5, #3\n" " 8: 42af cmp r7, r5\n" @@ -560,8 +560,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f00 cmp r7, #0\n" " 6: d100 bne.n 0xa\n" " 8: 3602 adds r6, #2" @@ -579,8 +579,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f00 cmp r7, #0\n" " 6: d100 bne.n 0xa\n" " 8: 3602 adds r6, #2" @@ -598,8 +598,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2501 movs r5, #1\n" " 6: 426d negs r5, r5\n" " 8: 42af cmp r7, r5\n" @@ -619,8 +619,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f00 cmp r7, #0\n" " 6: d100 bne.n 0xa\n" " 8: 3602 adds r6, #2" @@ -638,8 +638,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f00 cmp r7, #0\n" " 6: d100 bne.n 0xa\n" " 8: 3602 adds r6, #2" @@ -657,8 +657,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f3b cmp r7, #59 ; 0x3b\n" " 6: d000 beq.n 0xa\n" " 8: 3602 adds r6, #2" @@ -676,8 +676,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f3b cmp r7, #59 ; 0x3b\n" " 6: d000 beq.n 0xa\n" " 8: 3602 adds r6, #2" @@ -695,8 +695,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f2a cmp r7, #42 ; 0x2a\n" " 6: d000 beq.n 0xa\n" " 8: 3602 adds r6, #2" @@ -716,8 +716,8 @@ if_block_test_() -> State2 = ?BACKEND:jump_to_offset(State1, 16#100), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 4d02 ldr r5, [pc, #8] ; (0x10)\n" " 6: 42af cmp r7, r5\n" " 8: d000 beq.n 0xc\n" @@ -739,8 +739,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f2a cmp r7, #42 ; 0x2a\n" " 6: d000 beq.n 0xa\n" " 8: 3602 adds r6, #2" @@ -758,8 +758,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f3b cmp r7, #59 ; 0x3b\n" " 6: d100 bne.n 0xa\n" " 8: 3602 adds r6, #2" @@ -777,8 +777,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f3b cmp r7, #59 ; 0x3b\n" " 6: d100 bne.n 0xa\n" " 8: 3602 adds r6, #2" @@ -796,8 +796,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f2a cmp r7, #42 ; 0x2a\n" " 6: d100 bne.n 0xa\n" " 8: 3602 adds r6, #2" @@ -815,8 +815,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f2a cmp r7, #42 ; 0x2a\n" " 6: d100 bne.n 0xa\n" " 8: 3602 adds r6, #2" @@ -834,8 +834,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 07fd lsls r5, r7, #31\n" " 6: d400 bmi.n 0xa\n" " 8: 3602 adds r6, #2" @@ -853,8 +853,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 07fd lsls r5, r7, #31\n" " 6: d400 bmi.n 0xa\n" " 8: 3602 adds r6, #2" @@ -872,8 +872,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 07fd lsls r5, r7, #31\n" " 6: d500 bpl.n 0xa\n" " 8: 3602 adds r6, #2" @@ -891,8 +891,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 07fd lsls r5, r7, #31\n" " 6: d500 bpl.n 0xa\n" " 8: 3602 adds r6, #2" @@ -910,8 +910,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 077d lsls r5, r7, #29\n" " 6: d000 beq.n 0xa\n" " 8: 3602 adds r6, #2" @@ -929,8 +929,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2505 movs r5, #5\n" " 6: 422f tst r7, r5\n" " 8: d000 beq.n 0xc\n" @@ -949,8 +949,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 077d lsls r5, r7, #29\n" " 6: d000 beq.n 0xa\n" " 8: 3602 adds r6, #2" @@ -968,8 +968,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 43fd mvns r5, r7\n" " 6: 072d lsls r5, r5, #28\n" " 8: d000 beq.n 0xc\n" @@ -988,8 +988,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 43ff mvns r7, r7\n" " 6: 073f lsls r7, r7, #28\n" " 8: d000 beq.n 0xc\n" @@ -1008,8 +1008,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 463d mov r5, r7\n" " 6: 243f movs r4, #63 ; 0x3f\n" " 8: 4025 ands r5, r4\n" @@ -1030,8 +1030,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 42b7 cmp r7, r6\n" " 6: da00 bge.n 0xa\n" " 8: 3602 adds r6, #2" @@ -1055,8 +1055,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 253f movs r5, #63 ; 0x3f\n" " 6: 402f ands r7, r5\n" " 8: 2f08 cmp r7, #8\n" @@ -1076,8 +1076,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f64 cmp r7, #100 ; 0x64\n" " 6: dd00 ble.n 0xa\n" " 8: 3602 adds r6, #2" @@ -1095,8 +1095,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f64 cmp r7, #100 ; 0x64\n" " 6: dd00 ble.n 0xa\n" " 8: 3602 adds r6, #2" @@ -1115,8 +1115,8 @@ if_block_test_() -> State2 = ?BACKEND:jump_to_offset(State1, 16#100), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2580 movs r5, #128 ; 0x80\n" " 6: 00ed lsls r5, r5, #3\n" " 8: 42af cmp r7, r5\n" @@ -1138,8 +1138,8 @@ if_block_test_() -> State2 = ?BACKEND:jump_to_offset(State1, 16#100), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2580 movs r5, #128 ; 0x80\n" " 6: 00ed lsls r5, r5, #3\n" " 8: 42af cmp r7, r5\n" @@ -1161,8 +1161,8 @@ if_block_test_() -> State2 = ?BACKEND:jump_to_offset(State1, 16#100), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 4d02 ldr r5, [pc, #8] ; (0x10)\n" " 6: 42af cmp r7, r5\n" " 8: dd00 ble.n 0xc\n" @@ -1186,8 +1186,8 @@ if_block_test_() -> State2 = ?BACKEND:jump_to_offset(State1, 16#100), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 4d02 ldr r5, [pc, #8] ; (0x10)\n" " 6: 42af cmp r7, r5\n" " 8: dd00 ble.n 0xc\n" @@ -1220,8 +1220,8 @@ bitwise_and_optimization_test_() -> ), Stream = ?BACKEND:stream(State3), Dump = << - " 0: 6b07 ldr r7, [r0, #48] ; 0x30\n" - " 2: 6b46 ldr r6, [r0, #52] ; 0x34\n" + " 0: 6c47 ldr r7, [r0, #68]\n" + " 2: 6c86 ldr r6, [r0, #72]\n" " 4: 07bd lsls r5, r7, #30\n" " 6: d000 beq.n 0xa\n" " 8: 3602 adds r6, #2" @@ -1240,8 +1240,8 @@ bitwise_and_optimization_test_() -> ), Stream = ?BACKEND:stream(State3), Dump = << - " 0: 6b07 ldr r7, [r0, #48] ; 0x30\n" - " 2: 6b46 ldr r6, [r0, #52] ; 0x34\n" + " 0: 6c47 ldr r7, [r0, #68]\n" + " 2: 6c86 ldr r6, [r0, #72]\n" " 4: 073d lsls r5, r7, #28\n" " 6: d000 beq.n 0xa\n" " 8: 3602 adds r6, #2" @@ -1260,8 +1260,8 @@ bitwise_and_optimization_test_() -> ), Stream = ?BACKEND:stream(State3), Dump = << - " 0: 6b07 ldr r7, [r0, #48] ; 0x30\n" - " 2: 6b46 ldr r6, [r0, #52] ; 0x34\n" + " 0: 6c47 ldr r7, [r0, #68]\n" + " 2: 6c86 ldr r6, [r0, #72]\n" " 4: 06bd lsls r5, r7, #26\n" " 6: d000 beq.n 0xa\n" " 8: 3602 adds r6, #2" @@ -1280,8 +1280,8 @@ bitwise_and_optimization_test_() -> ), Stream = ?BACKEND:stream(State3), Dump = << - " 0: 6b07 ldr r7, [r0, #48] ; 0x30\n" - " 2: 6b46 ldr r6, [r0, #52] ; 0x34\n" + " 0: 6c47 ldr r7, [r0, #68]\n" + " 2: 6c86 ldr r6, [r0, #72]\n" " 4: 2505 movs r5, #5\n" " 6: 422f tst r7, r5\n" " 8: d000 beq.n 0xc\n" @@ -1309,8 +1309,8 @@ if_else_block_test() -> Stream = ?BACKEND:stream(State3), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" " 4: 2f3b cmp r7, #59 ; 0x3b\n" " 6: d101 bne.n 0xc\n" " 8: 3602 adds r6, #2\n" @@ -1328,7 +1328,7 @@ shift_right_test_() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 08ff lsrs r7, r7, #3" >>, jit_tests_common:assert_stream(arm, Dump, Stream) @@ -1341,7 +1341,7 @@ shift_right_test_() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 08fe lsrs r6, r7, #3" >>, jit_tests_common:assert_stream(arm, Dump, Stream) @@ -1355,7 +1355,7 @@ shift_left_test() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 00ff lsls r7, r7, #3" >>, jit_tests_common:assert_stream(arm, Dump, Stream). @@ -1658,7 +1658,7 @@ call_bif_with_large_literal_integer_test() -> " 1e: 9500 str r5, [sp, #0]\n" " 20: 2100 movs r1, #0\n" " 22: 2201 movs r2, #1\n" - " 24: 6983 ldr r3, [r0, #24]\n" + " 24: 6ac3 ldr r3, [r0, #44]\n" " 26: 47b8 blx r7\n" " 28: 4607 mov r7, r0\n" " 2a: b002 add sp, #8\n" @@ -1673,7 +1673,7 @@ call_bif_with_large_literal_integer_test() -> " 3c: bdf2 pop {r1, r4, r5, r6, r7, pc}\n" " 3e: 0000 movs r0, r0\n" " 40: e895 3b7f ldmia.w r5, {r0, r1, r2, r3, r4, r5, r6, r8, r9, fp, ip, sp}\n" - " 44: 6187 str r7, [r0, #24]" + " 44: 62c7 str r7, [r0, #44]" >>, jit_tests_common:assert_stream(arm, Dump, Stream). @@ -1687,14 +1687,14 @@ get_list_test() -> ?BACKEND:assert_all_native_free(State5), Stream = ?BACKEND:stream(State5), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 2603 movs r6, #3\n" " 4: 43b7 bics r7, r6\n" " 6: 687d ldr r5, [r7, #4]\n" - " 8: 6946 ldr r6, [r0, #20]\n" + " 8: 6a86 ldr r6, [r0, #40]\n" " a: 6075 str r5, [r6, #4]\n" " c: 683d ldr r5, [r7, #0]\n" - " e: 6946 ldr r6, [r0, #20]\n" + " e: 6a86 ldr r6, [r0, #40]\n" " 10: 6035 str r5, [r6, #0]" >>, jit_tests_common:assert_stream(arm, Dump, Stream). @@ -1728,7 +1728,7 @@ is_integer_test() -> State5 = ?BACKEND:update_branches(State4), Stream = ?BACKEND:stream(State5), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 43fe mvns r6, r7\n" " 4: 0736 lsls r6, r6, #28\n" " 6: d015 beq.n 0x34\n" @@ -1792,7 +1792,7 @@ is_number_test() -> State5 = ?BACKEND:update_branches(State4), Stream = ?BACKEND:stream(State5), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 43fe mvns r6, r7\n" " 4: 0736 lsls r6, r6, #28\n" " 6: d01b beq.n 0x40\n" @@ -1855,7 +1855,7 @@ is_boolean_test() -> " 12: 46c0 nop\n" " 14: 00ec lsls r4, r5, #3\n" " 16: 0000 movs r0, r0\n" - " 18: 6987 ldr r7, [r0, #24]\n" + " 18: 6ac7 ldr r7, [r0, #44]\n" " 1a: 2f4b cmp r7, #75\n" " 1c: d006 beq.n 0x2c\n" " 1e: 2f0b cmp r7, #11\n" @@ -1896,7 +1896,7 @@ is_boolean_far_test() -> " 12: 46c0 nop\n" " 14: 0fec lsrs r4, r5, #31\n" " 16: 0000 movs r0, r0\n" - " 18: 6987 ldr r7, [r0, #24]\n" + " 18: 6ac7 ldr r7, [r0, #44]\n" " 1a: 2f4b cmp r7, #75\n" " 1c: d006 beq.n 0x2c\n" " 1e: 2f0b cmp r7, #11\n" @@ -1931,7 +1931,7 @@ is_boolean_far_unaligned_test() -> Stream = ?BACKEND:stream(State5), Dump = << " 0: 4770 bx lr\n" - " 2: 6987 ldr r7, [r0, #24]\n" + " 2: 6ac7 ldr r7, [r0, #44]\n" " 4: 2f4b cmp r7, #75 @ 0x4b\n" " 6: d007 beq.n 0x18\n" " 8: 2f0b cmp r7, #11\n" @@ -1973,7 +1973,7 @@ is_boolean_far_known_test() -> " 12: 46c0 nop\n" " 14: 0fec lsrs r4, r5, #31\n" " 16: 0000 movs r0, r0\n" - " 18: 6987 ldr r7, [r0, #24]\n" + " 18: 6ac7 ldr r7, [r0, #44]\n" " 1a: 2f4b cmp r7, #75\n" " 1c: d006 beq.n 0x2c\n" " 1e: 2f0b cmp r7, #11\n" @@ -2021,7 +2021,7 @@ is_boolean_far_known_unaligned_test() -> " 14: 46c0 nop\n" " 16: 0fea lsrs r2, r5, #31\n" " 18: 0000 movs r0, r0\n" - " 1a: 6987 ldr r7, [r0, #24]\n" + " 1a: 6ac7 ldr r7, [r0, #44]\n" " 1c: 2f4b cmp r7, #75\n" " 1e: d007 beq.n 0x30\n" " 20: 2f0b cmp r7, #11\n" @@ -2291,11 +2291,11 @@ gc_bif2_test() -> " c: bc05 pop {r0, r2}\n" " e: b405 push {r0, r2}\n" " 10: b082 sub sp, #8\n" - " 12: 6986 ldr r6, [r0, #24]\n" + " 12: 6ac6 ldr r6, [r0, #44]\n" " 14: 9600 str r6, [sp, #0]\n" " 16: 2100 movs r1, #0\n" " 18: 2203 movs r2, #3\n" - " 1a: 6946 ldr r6, [r0, #20]\n" + " 1a: 6a86 ldr r6, [r0, #40]\n" " 1c: 6833 ldr r3, [r6, #0]\n" " 1e: 47b8 blx r7\n" " 20: 4607 mov r7, r0\n" @@ -2358,7 +2358,7 @@ call_ext_test() -> " 24: 063f lsls r7, r7, #24\n" " 26: 4e07 ldr r6, [pc, #28] ; (0x44)\n" " 28: 4337 orrs r7, r6\n" - " 2a: 65c7 str r7, [r0, #92] ; 0x5c\n" + " 2a: 6707 str r7, [r0, #112]\n" " 2c: 6917 ldr r7, [r2, #16]\n" " 2e: b082 sub sp, #8\n" " 30: 2601 movs r6, #1\n" @@ -2422,7 +2422,7 @@ call_fun_test() -> " 18: bdf2 pop {r1, r4, r5, r6, r7, pc}\n" " 1a: 46c0 nop ; (mov r8, r8)\n" " 1c: b5f2 push {r1, r4, r5, r6, r7, lr}\n" - " 1e: 6987 ldr r7, [r0, #24]\n" + " 1e: 6ac7 ldr r7, [r0, #44]\n" " 20: 463e mov r6, r7\n" " 22: 4635 mov r5, r6\n" " 24: 2403 movs r4, #3\n" @@ -2463,7 +2463,7 @@ call_fun_test() -> " 6a: 0636 lsls r6, r6, #24\n" " 6c: 4d05 ldr r5, [pc, #20] ; (0x84)\n" " 6e: 432e orrs r6, r5\n" - " 70: 65c6 str r6, [r0, #92] ; 0x5c\n" + " 70: 6706 str r6, [r0, #112]\n" " 72: 2680 movs r6, #128 ; 0x80\n" " 74: 5996 ldr r6, [r2, r6]\n" " 76: 463a mov r2, r7\n" @@ -2495,14 +2495,14 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 0, {x_reg, 0}, << " 0: 2700 movs r7, #0\n" - " 2: 6187 str r7, [r0, #24]\n" + " 2: 62c7 str r7, [r0, #44]\n" " 4: e07c b.n 0x100" >>) end), ?_test(begin move_to_vm_register_test0(State0, 0, {x_reg, extra}, << " 0: 2700 movs r7, #0\n" - " 2: 6587 str r7, [r0, #88] ; 0x58\n" + " 2: 66c7 str r7, [r0, #108]\n" " 4: e07c b.n 0x100" >>) end), @@ -2516,7 +2516,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 0, {y_reg, 2}, << " 0: 2600 movs r6, #0\n" - " 2: 6947 ldr r7, [r0, #20]\n" + " 2: 6a87 ldr r7, [r0, #40]\n" " 4: 60be str r6, [r7, #8]\n" " 6: e07b b.n 0x100" >>) @@ -2524,7 +2524,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 0, {y_reg, 20}, << " 0: 2600 movs r6, #0\n" - " 2: 6947 ldr r7, [r0, #20]\n" + " 2: 6a87 ldr r7, [r0, #40]\n" " 4: 653e str r6, [r7, #80] ; 0x50\n" " 6: e07b b.n 0x100" >>) @@ -2533,21 +2533,21 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 42, {x_reg, 0}, << " 0: 272a movs r7, #42 ; 0x2a\n" - " 2: 6187 str r7, [r0, #24]\n" + " 2: 62c7 str r7, [r0, #44]\n" " 4: e07c b.n 0x100" >>) end), ?_test(begin move_to_vm_register_test0(State0, 42, {x_reg, extra}, << " 0: 272a movs r7, #42 ; 0x2a\n" - " 2: 6587 str r7, [r0, #88] ; 0x58\n" + " 2: 66c7 str r7, [r0, #108]\n" " 4: e07c b.n 0x100" >>) end), ?_test(begin move_to_vm_register_test0(State0, 42, {y_reg, 2}, << " 0: 262a movs r6, #42 ; 0x2a\n" - " 2: 6947 ldr r7, [r0, #20]\n" + " 2: 6a87 ldr r7, [r0, #40]\n" " 4: 60be str r6, [r7, #8]\n" " 6: e07b b.n 0x100" >>) @@ -2555,7 +2555,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 42, {y_reg, 20}, << " 0: 262a movs r6, #42 ; 0x2a\n" - " 2: 6947 ldr r7, [r0, #20]\n" + " 2: 6a87 ldr r7, [r0, #40]\n" " 4: 653e str r6, [r7, #80] ; 0x50\n" " 6: e07b b.n 0x100" >>) @@ -2571,15 +2571,15 @@ move_to_vm_register_test_() -> %% Test: x_reg to x_reg ?_test(begin move_to_vm_register_test0(State0, {x_reg, 1}, {x_reg, 2}, << - " 0: 69c7 ldr r7, [r0, #28]\n" - " 2: 6207 str r7, [r0, #32]\n" + " 0: 6b07 ldr r7, [r0, #48]\n" + " 2: 6347 str r7, [r0, #52]\n" " 4: e07c b.n 0x100" >>) end), %% Test: x_reg to ptr ?_test(begin move_to_vm_register_test0(State0, {x_reg, 1}, {ptr, r1}, << - " 0: 69c7 ldr r7, [r0, #28]\n" + " 0: 6b07 ldr r7, [r0, #48]\n" " 2: 600f str r7, [r1, #0]\n" " 4: e07c b.n 0x100" >>) @@ -2588,15 +2588,15 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, {ptr, r4}, {x_reg, 3}, << " 0: 6827 ldr r7, [r4, #0]\n" - " 2: 6247 str r7, [r0, #36] ; 0x24\n" + " 2: 6387 str r7, [r0, #56]\n" " 4: e07c b.n 0x100" >>) end), %% Test: x_reg to y_reg ?_test(begin move_to_vm_register_test0(State0, {x_reg, 0}, {y_reg, 1}, << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 6946 ldr r6, [r0, #20]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6a86 ldr r6, [r0, #40]\n" " 4: 6077 str r7, [r6, #4]\n" " 6: e07b b.n 0x100" >>) @@ -2604,31 +2604,31 @@ move_to_vm_register_test_() -> %% Test: y_reg to x_reg ?_test(begin move_to_vm_register_test0(State0, {y_reg, 0}, {x_reg, 3}, << - " 0: 6946 ldr r6, [r0, #20]\n" + " 0: 6a86 ldr r6, [r0, #40]\n" " 2: 6837 ldr r7, [r6, #0]\n" - " 4: 6247 str r7, [r0, #36] ; 0x24\n" + " 4: 6387 str r7, [r0, #56]\n" " 6: e07b b.n 0x100" >>) end), %% Test: y_reg to y_reg ?_test(begin move_to_vm_register_test0(State0, {y_reg, 1}, {x_reg, 3}, << - " 0: 6946 ldr r6, [r0, #20]\n" + " 0: 6a86 ldr r6, [r0, #40]\n" " 2: 6877 ldr r7, [r6, #4]\n" - " 4: 6247 str r7, [r0, #36] ; 0x24\n" + " 4: 6387 str r7, [r0, #56]\n" " 6: e07b b.n 0x100" >>) end), %% Test: Native register to x_reg ?_test(begin move_to_vm_register_test0(State0, r5, {x_reg, 0}, << - " 0: 6185 str r5, [r0, #24]\n" + " 0: 62c5 str r5, [r0, #44]\n" " 2: e07d b.n 0x100" >>) end), ?_test(begin move_to_vm_register_test0(State0, r6, {x_reg, extra}, << - " 0: 6586 str r6, [r0, #88] ; 0x58\n" + " 0: 66c6 str r6, [r0, #108]\n" " 2: e07d b.n 0x100" >>) end), @@ -2642,7 +2642,7 @@ move_to_vm_register_test_() -> %% Test: Native register to y_reg ?_test(begin move_to_vm_register_test0(State0, r1, {y_reg, 0}, << - " 0: 6947 ldr r7, [r0, #20]\n" + " 0: 6a87 ldr r7, [r0, #40]\n" " 2: 6039 str r1, [r7, #0]\n" " 4: e07c b.n 0x100" >>) @@ -2651,7 +2651,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 16#12345678, {x_reg, 0}, << " 0: 4f01 ldr r7, [pc, #4] ; (0x8)\n" - " 2: 6187 str r7, [r0, #24]\n" + " 2: 62c7 str r7, [r0, #44]\n" " 4: e07c b.n 0x100\n" " 6: 0000 movs r0, r0\n" " 8: 5678 ldrsb r0, [r7, r1]\n" @@ -2669,7 +2669,7 @@ move_to_vm_register_test_() -> Dump = << " 0: 6019 str r1, [r3, #0]\n" " 2: 4f01 ldr r7, [pc, #4] ; (0x8)\n" - " 4: 6187 str r7, [r0, #24]\n" + " 4: 62c7 str r7, [r0, #44]\n" " 6: e07b b.n 0x100\n" " 8: 5678 ldrsb r0, [r7, r1]\n" " a: 1234 asrs r4, r6, #8" @@ -2679,7 +2679,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 16#12345678, {x_reg, extra}, << " 0: 4f01 ldr r7, [pc, #4] ; (0x8)\n" - " 2: 6587 str r7, [r0, #88] ; 0x58\n" + " 2: 66c7 str r7, [r0, #108]\n" " 4: e07c b.n 0x100\n" " 6: 0000 movs r0, r0\n" " 8: 5678 ldrsb r0, [r7, r1]\n" @@ -2689,7 +2689,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 16#12345678, {y_reg, 2}, << " 0: 4f01 ldr r7, [pc, #4] ; (0x8)\n" - " 2: 6946 ldr r6, [r0, #20]\n" + " 2: 6a86 ldr r6, [r0, #40]\n" " 4: 60b7 str r7, [r6, #8]\n" " 6: e07b b.n 0x100\n" " 8: 5678 ldrsb r0, [r7, r1]\n" @@ -2699,7 +2699,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 16#12345678, {y_reg, 20}, << " 0: 4f01 ldr r7, [pc, #4] ; (0x8)\n" - " 2: 6946 ldr r6, [r0, #20]\n" + " 2: 6a86 ldr r6, [r0, #40]\n" " 4: 6537 str r7, [r6, #80] ; 0x50\n" " 6: e07b b.n 0x100\n" " 8: 5678 ldrsb r0, [r7, r1]\n" @@ -2720,8 +2720,8 @@ move_to_vm_register_test_() -> %% Test: x_reg to y_reg (high index) ?_test(begin move_to_vm_register_test0(State0, {x_reg, 15}, {y_reg, 31}, << - " 0: 6d47 ldr r7, [r0, #84] ; 0x54\n" - " 2: 6946 ldr r6, [r0, #20]\n" + " 0: 6e87 ldr r7, [r0, #104]\n" + " 2: 6a86 ldr r6, [r0, #40]\n" " 4: 67f7 str r7, [r6, #124] ; 0x7c\n" " 6: e07b b.n 0x100" >>) @@ -2729,9 +2729,9 @@ move_to_vm_register_test_() -> %% Test: y_reg to x_reg (high index) ?_test(begin move_to_vm_register_test0(State0, {y_reg, 31}, {x_reg, 15}, << - " 0: 6946 ldr r6, [r0, #20]\n" + " 0: 6a86 ldr r6, [r0, #40]\n" " 2: 6ff7 ldr r7, [r6, #124] ; 0x7c\n" - " 4: 6547 str r7, [r0, #84] ; 0x54\n" + " 4: 6687 str r7, [r0, #104]\n" " 6: e07b b.n 0x100" >>) end), @@ -2739,7 +2739,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 42, {y_reg, 32}, << " 0: 262a movs r6, #42 ; 0x2a\n" - " 2: 6947 ldr r7, [r0, #20]\n" + " 2: 6a87 ldr r7, [r0, #40]\n" " 4: 2580 movs r5, #128 ; 0x80\n" " 6: 443d add r5, r7\n" " 8: 602e str r6, [r5, #0]\n" @@ -2751,7 +2751,7 @@ move_to_vm_register_test_() -> move_to_vm_register_test0(State0, -1, {x_reg, 0}, << " 0: 2701 movs r7, #1\n" " 2: 427f negs r7, r7\n" - " 4: 6187 str r7, [r0, #24]\n" + " 4: 62c7 str r7, [r0, #44]\n" " 6: e07b b.n 0x100" >>) end) @@ -2774,7 +2774,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, r3, 2, {x_reg, 0}, << " 0: 689f ldr r7, [r3, #8]\n" - " 2: 6187 str r7, [r0, #24]" + " 2: 62c7 str r7, [r0, #44]" >>) end), %% move_array_element: reg[x] to ptr @@ -2788,7 +2788,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, r3, 1, {y_reg, 2}, << " 0: 685e ldr r6, [r3, #4]\n" - " 2: 6947 ldr r7, [r0, #20]\n" + " 2: 6a87 ldr r7, [r0, #40]\n" " 4: 60be str r6, [r7, #8]" >>) end), @@ -2802,7 +2802,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, r3, 7, {y_reg, 31}, << " 0: 69de ldr r6, [r3, #28]\n" - " 2: 6947 ldr r7, [r0, #20]\n" + " 2: 6a87 ldr r7, [r0, #40]\n" " 4: 67fe str r6, [r7, #124] ; 0x7c" >>) end), @@ -2810,7 +2810,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, r3, 7, {x_reg, 15}, << " 0: 69df ldr r7, [r3, #28]\n" - " 2: 6547 str r7, [r0, #84] ; 0x54" + " 2: 6687 str r7, [r0, #104]" >>) end), %% move_array_element: reg_x[reg_y] to x_reg @@ -2820,7 +2820,7 @@ move_array_element_test_() -> " 0: 691f ldr r7, [r3, #16]\n" " 2: 00bf lsls r7, r7, #2\n" " 4: 59df ldr r7, [r3, r7]\n" - " 6: 6207 str r7, [r0, #32]" + " 6: 6347 str r7, [r0, #52]" >>) end), %% move_array_element: reg_x[reg_y] to pointer (large x reg) @@ -2840,7 +2840,7 @@ move_array_element_test_() -> " 0: 691f ldr r7, [r3, #16]\n" " 2: 00bf lsls r7, r7, #2\n" " 4: 59df ldr r7, [r3, r7]\n" - " 6: 6946 ldr r6, [r0, #20]\n" + " 6: 6a86 ldr r6, [r0, #40]\n" " 8: 67f7 str r7, [r6, #124] ; 0x7c" >>) end), @@ -2848,9 +2848,9 @@ move_array_element_test_() -> ?_test(begin {State1, BaseReg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}), move_array_element_test0(State1, BaseReg, 2, {x_reg, 5}, << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 68be ldr r6, [r7, #8]\n" - " 4: 62c6 str r6, [r0, #44] ; 0x2c" + " 4: 6406 str r6, [r0, #64]" >>) end), %% move_array_element: reg[32] to x_reg (large offset, index 32, offset 128) @@ -2859,7 +2859,7 @@ move_array_element_test_() -> " 0: 2704 movs r7, #4\n" " 2: 441f add r7, r3\n" " 4: 6ffe ldr r6, [r7, #124] ; 0x7c\n" - " 6: 6186 str r6, [r0, #24]" + " 6: 62c6 str r6, [r0, #44]" >>) end), %% move_array_element: reg[32] to ptr (large offset) @@ -2877,7 +2877,7 @@ move_array_element_test_() -> " 0: 2604 movs r6, #4\n" " 2: 441e add r6, r3\n" " 4: 6ff6 ldr r6, [r6, #124] ; 0x7c\n" - " 6: 6947 ldr r7, [r0, #20]\n" + " 6: 6a87 ldr r7, [r0, #40]\n" " 8: 60be str r6, [r7, #8]" >>) end) @@ -2929,7 +2929,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, r3, 2), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 609f str r7, [r3, #8]" >>, jit_tests_common:assert_stream(arm, Dump, Stream) @@ -2939,7 +2939,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, r3, 32), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 2604 movs r6, #4\n" " 4: 441e add r6, r3\n" " 6: 67f7 str r7, [r6, #124] ; 0x7c" @@ -2951,7 +2951,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, r3, r4), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 4626 mov r6, r4\n" " 4: 00b6 lsls r6, r6, #2\n" " 6: 519f str r7, [r3, r6]" @@ -2975,7 +2975,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {y_reg, 2}, r3, r4), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6946 ldr r6, [r0, #20]\n" + " 0: 6a86 ldr r6, [r0, #40]\n" " 2: 68b7 ldr r7, [r6, #8]\n" " 4: 4626 mov r6, r4\n" " 6: 00b6 lsls r6, r6, #2\n" @@ -2988,7 +2988,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, r3, 2, 1), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 609f str r7, [r3, #8]" >>, jit_tests_common:assert_stream(arm, Dump, Stream) @@ -3001,7 +3001,7 @@ move_to_array_element_test_() -> State3 = ?BACKEND:move_to_array_element(State2, {x_reg, 0}, r3, r4, 1), Stream = ?BACKEND:stream(State3), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" " 2: 1c66 adds r6, r4, #1\n" " 4: 00b6 lsls r6, r6, #2\n" " 6: 519f str r7, [r3, r6]" @@ -3094,7 +3094,7 @@ move_to_native_register_test_() -> Stream = ?BACKEND:stream(State1), ?assertEqual(r7, Reg), Dump = << - " 0: 6a47 ldr r7, [r0, #36] ; 0x24" + " 0: 6b87 ldr r7, [r0, #56]" >>, jit_tests_common:assert_stream(arm, Dump, Stream) end), @@ -3104,7 +3104,7 @@ move_to_native_register_test_() -> Stream = ?BACKEND:stream(State1), ?assertEqual(r7, Reg), Dump = << - " 0: 6946 ldr r6, [r0, #20]\n" + " 0: 6a86 ldr r6, [r0, #40]\n" " 2: 68f7 ldr r7, [r6, #12]" >>, jit_tests_common:assert_stream(arm, Dump, Stream) @@ -3141,7 +3141,7 @@ move_to_native_register_test_() -> State1 = ?BACKEND:move_to_native_register(State0, {x_reg, 2}, r3), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6a03 ldr r3, [r0, #32]" + " 0: 6b43 ldr r3, [r0, #52]" >>, jit_tests_common:assert_stream(arm, Dump, Stream) end), @@ -3150,7 +3150,7 @@ move_to_native_register_test_() -> State1 = ?BACKEND:move_to_native_register(State0, {y_reg, 2}, r1), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 6947 ldr r7, [r0, #20]\n" + " 0: 6a87 ldr r7, [r0, #40]\n" " 2: 68b9 ldr r1, [r7, #8]" >>, jit_tests_common:assert_stream(arm, Dump, Stream) @@ -3163,8 +3163,8 @@ move_to_native_register_test_() -> ), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 6e06 ldr r6, [r0, #96] ; 0x60\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6f46 ldr r6, [r0, #116]\n" " 4: 687d ldr r5, [r7, #4]\n" " 6: 61b5 str r5, [r6, #24]\n" " 8: 68bd ldr r5, [r7, #8]\n" @@ -3444,7 +3444,7 @@ set_args1_y_reg_test() -> " 2: 00bf lsls r7, r7, #2\n" " 4: 59d7 ldr r7, [r2, r7]\n" " 6: b405 push {r0, r2}\n" - " 8: 6946 ldr r6, [r0, #20]\n" + " 8: 6a86 ldr r6, [r0, #40]\n" " a: 6970 ldr r0, [r6, #20]\n" " c: 47b8 blx r7\n" " e: 4607 mov r7, r0\n" @@ -3460,7 +3460,7 @@ large_y_reg_read_test() -> Stream = ?BACKEND:stream(State1), % Expected: uses helper with temp register since offset 128 > 124 Dump = << - " 0: 6946 ldr r6, [r0, #20]\n" + " 0: 6a86 ldr r6, [r0, #40]\n" " 2: 2780 movs r7, #128 ; 0x80\n" " 4: 4437 add r7, r6\n" " 6: 683f ldr r7, [r7, #0]" @@ -3478,8 +3478,8 @@ large_y_reg_write_test() -> Stream = ?BACKEND:stream(State2), % Expected: uses helper with two temp registers since we have registers available Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 6946 ldr r6, [r0, #20]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6a86 ldr r6, [r0, #40]\n" " 4: 25a0 movs r5, #160 ; 0xa0\n" " 6: 4435 add r5, r6\n" " 8: 602f str r7, [r5, #0]" @@ -3500,12 +3500,12 @@ large_y_reg_read_register_exhaustion_test() -> Stream = ?BACKEND:stream(StateFinal), % Expected: uses IP_REG (r12) fallback sequence Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" - " 4: 6a05 ldr r5, [r0, #32]\n" - " 6: 6a44 ldr r4, [r0, #36] ; 0x24\n" - " 8: 6a83 ldr r3, [r0, #40] ; 0x28\n" - " a: 6941 ldr r1, [r0, #20]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" + " 4: 6b45 ldr r5, [r0, #52]\n" + " 6: 6b84 ldr r4, [r0, #56]\n" + " 8: 6bc3 ldr r3, [r0, #60]\n" + " a: 6a81 ldr r1, [r0, #40]\n" " c: 468c mov ip, r1\n" " e: 218c movs r1, #140 ; 0x8c\n" " 10: 4461 add r1, ip\n" @@ -3529,12 +3529,12 @@ large_y_reg_write_register_exhaustion_test() -> Stream = ?BACKEND:stream(StateFinal), % Expected: uses IP_REG (r12) fallback sequence Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" - " 4: 6a05 ldr r5, [r0, #32]\n" - " 6: 6a44 ldr r4, [r0, #36] ; 0x24\n" - " 8: 6a83 ldr r3, [r0, #40] ; 0x28\n" - " a: 6941 ldr r1, [r0, #20]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" + " 4: 6b45 ldr r5, [r0, #52]\n" + " 6: 6b84 ldr r4, [r0, #56]\n" + " 8: 6bc3 ldr r3, [r0, #60]\n" + " a: 6a81 ldr r1, [r0, #40]\n" " c: 468c mov ip, r1\n" " e: 21c8 movs r1, #200 ; 0xc8\n" " 10: 4461 add r1, ip\n" @@ -3549,7 +3549,7 @@ y_reg_boundary_direct_test() -> Stream = ?BACKEND:stream(State1), % Expected: uses direct addressing since 31 * 4 = 124 <= 124 Dump = << - " 0: 6946 ldr r6, [r0, #20]\n" + " 0: 6a86 ldr r6, [r0, #40]\n" " 2: 6ff7 ldr r7, [r6, #124] ; 0x7c" >>, jit_tests_common:assert_stream(arm, Dump, Stream), @@ -3578,12 +3578,12 @@ and_register_exhaustion_negative_test() -> {StateResult, r7} = ?BACKEND:and_(StateNoRegs, {free, r7}, -4), Stream = ?BACKEND:stream(StateResult), ExpectedDump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" - " 4: 6a05 ldr r5, [r0, #32]\n" - " 6: 6a44 ldr r4, [r0, #36] ; 0x24\n" - " 8: 6a83 ldr r3, [r0, #40] ; 0x28\n" - " a: 6ac1 ldr r1, [r0, #44] ; 0x2c\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" + " 4: 6b45 ldr r5, [r0, #52]\n" + " 6: 6b84 ldr r4, [r0, #56]\n" + " 8: 6bc3 ldr r3, [r0, #60]\n" + " a: 6c01 ldr r1, [r0, #64]\n" " c: 4684 mov ip, r0\n" " e: 2003 movs r0, #3\n" " 10: 4387 bics r7, r0\n" @@ -3604,12 +3604,12 @@ and_register_exhaustion_positive_test() -> {StateResult, r7} = ?BACKEND:and_(StateNoRegs, {free, r7}, 16#3F), Stream = ?BACKEND:stream(StateResult), ExpectedDump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" - " 4: 6a05 ldr r5, [r0, #32]\n" - " 6: 6a44 ldr r4, [r0, #36] ; 0x24\n" - " 8: 6a83 ldr r3, [r0, #40] ; 0x28\n" - " a: 6ac1 ldr r1, [r0, #44] ; 0x2c\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" + " 4: 6b45 ldr r5, [r0, #52]\n" + " 6: 6b84 ldr r4, [r0, #56]\n" + " 8: 6bc3 ldr r3, [r0, #60]\n" + " a: 6c01 ldr r1, [r0, #64]\n" " c: 4684 mov ip, r0\n" " e: 203f movs r0, #63 ; 0x3f\n" " 10: 4007 ands r7, r0\n" @@ -3692,9 +3692,9 @@ call_func_ptr_stack_alignment_test() -> Stream = ?BACKEND:stream(State4), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" - " 4: 6a05 ldr r5, [r0, #32]\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" + " 4: 6b45 ldr r5, [r0, #52]\n" " 6: b4ed push {r0, r2, r3, r5, r6, r7}\n" " 8: 202a movs r0, #42 ; 0x2a\n" " a: 4798 blx r3\n" @@ -3731,12 +3731,12 @@ call_func_ptr_register_exhaustion_test_() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" - " 4: 6a05 ldr r5, [r0, #32]\n" - " 6: 6a44 ldr r4, [r0, #36] ; 0x24\n" - " 8: 6a83 ldr r3, [r0, #40] ; 0x28\n" - " a: 6ac1 ldr r1, [r0, #44] ; 0x2c\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" + " 4: 6b45 ldr r5, [r0, #52]\n" + " 6: 6b84 ldr r4, [r0, #56]\n" + " 8: 6bc3 ldr r3, [r0, #60]\n" + " a: 6c01 ldr r1, [r0, #64]\n" " c: b4b7 push {r0, r1, r2, r4, r5, r7}\n" " e: b082 sub sp, #8\n" " 10: 2101 movs r1, #1\n" @@ -3760,12 +3760,12 @@ call_func_ptr_register_exhaustion_test_() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" - " 4: 6a05 ldr r5, [r0, #32]\n" - " 6: 6a44 ldr r4, [r0, #36] ; 0x24\n" - " 8: 6a83 ldr r3, [r0, #40] ; 0x28\n" - " a: 6ac1 ldr r1, [r0, #44] ; 0x2c\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" + " 4: 6b45 ldr r5, [r0, #52]\n" + " 6: 6b84 ldr r4, [r0, #56]\n" + " 8: 6bc3 ldr r3, [r0, #60]\n" + " a: 6c01 ldr r1, [r0, #64]\n" " c: b4b7 push {r0, r1, r2, r4, r5, r7}\n" " e: b082 sub sp, #8\n" " 10: 9100 str r1, [sp, #0]\n" @@ -3788,12 +3788,12 @@ call_func_ptr_register_exhaustion_test_() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" - " 4: 6a05 ldr r5, [r0, #32]\n" - " 6: 6a44 ldr r4, [r0, #36] ; 0x24\n" - " 8: 6a83 ldr r3, [r0, #40] ; 0x28\n" - " a: 6ac1 ldr r1, [r0, #44] ; 0x2c\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" + " 4: 6b45 ldr r5, [r0, #52]\n" + " 6: 6b84 ldr r4, [r0, #56]\n" + " 8: 6bc3 ldr r3, [r0, #60]\n" + " a: 6c01 ldr r1, [r0, #64]\n" " c: b4b7 push {r0, r1, r2, r4, r5, r7}\n" " e: b082 sub sp, #8\n" " 10: 2401 movs r4, #1\n" @@ -3819,12 +3819,12 @@ call_func_ptr_register_exhaustion_test_() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" - " 4: 6a05 ldr r5, [r0, #32]\n" - " 6: 6a44 ldr r4, [r0, #36] ; 0x24\n" - " 8: 6a83 ldr r3, [r0, #40] ; 0x28\n" - " a: 6ac1 ldr r1, [r0, #44] ; 0x2c\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" + " 4: 6b45 ldr r5, [r0, #52]\n" + " 6: 6b84 ldr r4, [r0, #56]\n" + " 8: 6bc3 ldr r3, [r0, #60]\n" + " a: 6c01 ldr r1, [r0, #64]\n" " c: b4ff push {r0, r1, r2, r3, r4, r5, r6, r7}\n" " e: 460c mov r4, r1\n" " 10: 4630 mov r0, r6\n" @@ -3845,12 +3845,12 @@ call_func_ptr_register_exhaustion_test_() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 6987 ldr r7, [r0, #24]\n" - " 2: 69c6 ldr r6, [r0, #28]\n" - " 4: 6a05 ldr r5, [r0, #32]\n" - " 6: 6a44 ldr r4, [r0, #36] ; 0x24\n" - " 8: 6a83 ldr r3, [r0, #40] ; 0x28\n" - " a: 6ac1 ldr r1, [r0, #44] ; 0x2c\n" + " 0: 6ac7 ldr r7, [r0, #44]\n" + " 2: 6b06 ldr r6, [r0, #48]\n" + " 4: 6b45 ldr r5, [r0, #52]\n" + " 6: 6b84 ldr r4, [r0, #56]\n" + " 8: 6bc3 ldr r3, [r0, #60]\n" + " a: 6c01 ldr r1, [r0, #64]\n" " c: b4ff push {r0, r1, r2, r3, r4, r5, r6, r7}\n" " e: 6894 ldr r4, [r2, #8]\n" " 10: 4630 mov r0, r6\n" @@ -3941,10 +3941,10 @@ add_beam_test() -> % label 1 % {move,{integer,9},{x,1}}. " 30: 279f movs r7, #159 ; 0x9f\n" - " 32: 61c7 str r7, [r0, #28]\n" + " 32: 6307 str r7, [r0, #48]\n" % {move,{integer,8},{x,0}} " 34: 278f movs r7, #143 ; 0x8f\n" - " 36: 6187 str r7, [r0, #24]\n" + " 36: 62c7 str r7, [r0, #44]\n" % {call_only,2,{f,2}}. " 38: 9e00 ldr r6, [sp, #0]\n" " 3a: 68b7 ldr r7, [r6, #8]\n" @@ -3993,7 +3993,7 @@ add_beam_test() -> % {init_yregs,{list,[{y,0}]}}. %% move_to_vm_register(State8, ?TERM_NIL, {y_reg, 0}), " 8c: 263b movs r6, #59 ; 0x3b\n" - " 8e: 6947 ldr r7, [r0, #20]\n" + " 8e: 6a87 ldr r7, [r0, #40]\n" " 90: 603e str r6, [r7, #0]\n" % {call,1,{f,3}} %% call_or_schedule_next(State9, 3), @@ -4003,7 +4003,7 @@ add_beam_test() -> " 98: 063f lsls r7, r7, #24\n" " 9a: 4e0c ldr r6, [pc, #48] ; (0xcc)\n" " 9c: 4337 orrs r7, r6\n" - " 9e: 65c7 str r7, [r0, #92] ; 0x5c\n" + " 9e: 6707 str r7, [r0, #112]\n" " a0: 9e00 ldr r6, [sp, #0]\n" " a2: 68b7 ldr r7, [r6, #8]\n" " a4: 3f01 subs r7, #1\n" diff --git a/tests/libs/jit/jit_riscv32_tests.erl b/tests/libs/jit/jit_riscv32_tests.erl index 6cb8dea8b1..6ed21328dd 100644 --- a/tests/libs/jit/jit_riscv32_tests.erl +++ b/tests/libs/jit/jit_riscv32_tests.erl @@ -134,11 +134,11 @@ call_primitive_6_args_test() -> Stream = ?BACKEND:stream(State4), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" " 4: 4f0d li t5,3\n" " 6: ffff4f13 not t5,t5\n" " a: 01efffb3 and t6,t6,t5\n" - " e: 01c52f03 lw t5,28(a0)\n" + " e: 03052f03 lw t5,48(a0)\n" " 12: 0b800e93 li t4,184\n" " 16: 9eb2 add t4,t4,a2\n" " 18: 000eae83 lw t4,0(t4)\n" @@ -324,7 +324,7 @@ call_primitive_last_5_args_test() -> ]), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" " 4: 04c62f03 lw t5,76(a2)\n" " 8: 4621 li a2,8\n" " a: 2cb00693 li a3,715\n" @@ -449,9 +449,9 @@ move_to_cp_test() -> Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01452f03 lw t5,20(a0)\n" + " 0: 02852f03 lw t5,40(a0)\n" " 4: 000f2f83 lw t6,0(t5)\n" - " 8: 05f52e23 sw t6,92(a0)" + " 8: 07f52823 sw t6,112(a0)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream). @@ -461,9 +461,9 @@ increment_sp_test() -> Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01452f83 lw t6,20(a0)\n" + " 0: 02852f83 lw t6,40(a0)\n" " 4: 0ff1 addi t6,t6,28\n" - " 6: 01f52a23 sw t6,20(a0)" + " 6: 03f52423 sw t6,40(a0)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream). @@ -487,8 +487,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 000fd363 bgez t6,0xe\n" " c: 0f09 addi t5,t5,2" >>, @@ -505,8 +505,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 01efd363 bge t6,t5,0xe\n" " c: 0f09 addi t5,t5,2" >>, @@ -523,8 +523,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 02a00e93 li t4,42\n" " c: 01dfd363 bge t6,t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -543,8 +543,8 @@ if_block_test_() -> State2 = ?BACKEND:jump_to_offset(State1, 16#100), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 40000e93 li t4,1024\n" " c: 01dfd363 bge t6,t4,0x12\n" " 10: 0f09 addi t5,t5,2\n" @@ -563,8 +563,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 000f9363 bnez t6,0xe\n" " c: 0f09 addi t5,t5,2" >>, @@ -581,8 +581,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 000f9363 bnez t6,0xe\n" " c: 0f09 addi t5,t5,2" >>, @@ -599,8 +599,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 5efd li t4,-1\n" " a: 01df9363 bne t6,t4,0x10\n" " e: 0f09 addi t5,t5,2" @@ -618,8 +618,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 000f9363 bnez t6,0xe\n" " c: 0f09 addi t5,t5,2" >>, @@ -636,8 +636,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 000f9363 bnez t6,0xe\n" " c: 0f09 addi t5,t5,2" >>, @@ -654,8 +654,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 03b00e93 li t4,59\n" " c: 01df8363 beq t6,t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -673,8 +673,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 03b00e93 li t4,59\n" " c: 01df8363 beq t6,t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -692,8 +692,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 02a00e93 li t4,42\n" " c: 01df8363 beq t6,t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -713,8 +713,8 @@ if_block_test_() -> State2 = ?BACKEND:jump_to_offset(State1, 16#100), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 7cb00e93 li t4,1995\n" " c: 01df8363 beq t6,t4,0x12\n" " 10: 0f05 addi t5,t5,1\n" @@ -732,8 +732,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 02a00e93 li t4,42\n" " c: 01df8363 beq t6,t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -751,8 +751,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 03b00e93 li t4,59\n" " c: 01df9363 bne t6,t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -770,8 +770,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 03b00e93 li t4,59\n" " c: 01df9363 bne t6,t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -789,8 +789,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 02a00e93 li t4,42\n" " c: 01df9363 bne t6,t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -808,8 +808,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 02a00e93 li t4,42\n" " c: 01df9363 bne t6,t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -827,8 +827,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 01ff9e93 slli t4,t6,0x1f\n" " c: 000ec363 bltz t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -846,8 +846,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 01ff9e93 slli t4,t6,0x1f\n" " c: 000ec363 bltz t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -865,8 +865,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 01ff9e93 slli t4,t6,0x1f\n" " c: 000ed363 bgez t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -884,8 +884,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 01ff9e93 slli t4,t6,0x1f\n" " c: 000ed363 bgez t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -903,8 +903,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 007ffe93 andi t4,t6,7\n" " c: 000e8363 beqz t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -922,8 +922,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 005ffe93 andi t4,t6,5\n" " c: 000e8363 beqz t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -941,8 +941,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 007ffe93 andi t4,t6,7\n" " c: 000e8363 beqz t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -960,8 +960,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: ffffce93 not t4,t6\n" " c: 0ef2 slli t4,t4,0x1c\n" " e: 000e8363 beqz t4,0x14\n" @@ -980,8 +980,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: ffffcf93 not t6,t6\n" " c: 0ff2 slli t6,t6,0x1c\n" " e: 000f8363 beqz t6,0x14\n" @@ -1000,8 +1000,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 8efe mv t4,t6\n" " a: 03f00e13 li t3,63\n" " e: 01cefeb3 and t4,t4,t3\n" @@ -1022,8 +1022,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 01efd363 bge t6,t5,0xe\n" " c: 0f09 addi t5,t5,2" >>, @@ -1046,8 +1046,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 03f00e93 li t4,63\n" " c: 01dfffb3 and t6,t6,t4\n" " 10: 4ea1 li t4,8\n" @@ -1068,8 +1068,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 003ffe93 andi t4,t6,3\n" " c: 000e8363 beqz t4,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -1087,8 +1087,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 06400e93 li t4,100\n" " c: 01fed363 bge t4,t6,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -1106,8 +1106,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 06400e93 li t4,100\n" " c: 01fed363 bge t4,t6,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -1125,8 +1125,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 40000e93 li t4,1024\n" " c: 01fed363 bge t4,t6,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -1144,8 +1144,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" " 8: 40000e93 li t4,1024\n" " c: 01fed363 bge t4,t6,0x12\n" " 10: 0f09 addi t5,t5,2" @@ -1173,8 +1173,8 @@ if_else_block_test() -> Stream = ?BACKEND:stream(State3), Dump = << - "0: 01852f83 lw t6,24(a0)\n" - "4: 01c52f03 lw t5,28(a0)\n" + "0: 02c52f83 lw t6,44(a0)\n" + "4: 03052f03 lw t5,48(a0)\n" "8: 03b00e93 li t4,59\n" "c: 01df9463 bne t6,t4,0x14\n" "10: 0f09 addi t5,t5,2\n" @@ -1192,7 +1192,7 @@ shift_right_test_() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" " 4: 003fdf93 srli t6,t6,0x3" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream) @@ -1205,7 +1205,7 @@ shift_right_test_() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" " 4: 003fdf13 srli t5,t6,0x3" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream) @@ -1219,7 +1219,7 @@ shift_left_test() -> Stream = ?BACKEND:stream(State2), Dump = << - "0: 01852f83 lw t6,24(a0)\n" + "0: 02c52f83 lw t6,44(a0)\n" "4: 0f8e slli t6,t6,0x3" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream). @@ -1402,7 +1402,7 @@ call_bif_with_large_literal_integer_test() -> " 52: c632 sw a2,12(sp)\n" " 54: 4581 li a1,0\n" " 56: 4605 li a2,1\n" - " 58: 4d14 lw a3,24(a0)\n" + " 58: 5554 lw a3,44(a0)\n" " 5a: 877a mv a4,t5\n" " 5c: 9f82 jalr t6\n" " 5e: 8faa mv t6,a0\n" @@ -1415,7 +1415,7 @@ call_bif_with_large_literal_integer_test() -> " 6e: 01862f83 lw t6,24(a2)\n" " 72: 07200613 li a2,114\n" " 76: 8f82 jr t6\n" - " 78: 01f52c23 sw t6,24(a0)" + " 78: 03f52623 sw t6,44(a0)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream). @@ -1430,15 +1430,15 @@ get_list_test() -> Stream = ?BACKEND:stream(State5), Dump = << - "0: 01852f83 lw t6,24(a0)\n" + "0: 02c52f83 lw t6,44(a0)\n" "4: 4f0d li t5,3\n" "6: ffff4f13 not t5,t5\n" "a: 01efffb3 and t6,t6,t5\n" "e: 004fae83 lw t4,4(t6)\n" - "12: 01452f03 lw t5,20(a0)\n" + "12: 02852f03 lw t5,40(a0)\n" "16: 01df2223 sw t4,4(t5)\n" "1a: 000fae83 lw t4,0(t6)\n" - "1e: 01452f03 lw t5,20(a0)\n" + "1e: 02852f03 lw t5,40(a0)\n" "22: 01df2023 sw t4,0(t5)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream). @@ -1480,7 +1480,7 @@ is_integer_test() -> " 6: ffff .insn 2, 0xffff\n" " 8: 00000697 auipc a3,0x0\n" " c: 0f868067 jr 248(a3) # 0x100\n" - " 10: 01852f83 lw t6,24(a0)\n" + " 10: 02c52f83 lw t6,44(a0)\n" " 14: ffffcf13 not t5,t6\n" " 18: 0f72 slli t5,t5,0x1c\n" " 1a: 020f0f63 beqz t5,0x58\n" @@ -1549,7 +1549,7 @@ is_number_test() -> " 6: ffff .insn 2, 0xffff\n" " 8: 00000697 auipc a3,0x0\n" " c: 0f868067 jr 248(a3) # 0x100\n" - " 10: 01852f83 lw t6,24(a0)\n" + " 10: 02c52f83 lw t6,44(a0)\n" " 14: ffffcf13 not t5,t6\n" " 18: 0f72 slli t5,t5,0x1c\n" " 1a: 040f0763 beqz t5,0x68\n" @@ -1602,7 +1602,7 @@ is_boolean_test() -> " 6: ffff .insn 2, 0xffff\n" " 8: 00000697 auipc a3,0x0\n" " c: 0f868067 jr 248(a3) # 0x100\n" - " 10: 01852f83 lw t6,24(a0)\n" + " 10: 02c52f83 lw t6,44(a0)\n" " 14: 04b00f13 li t5,75\n" " 18: 01ef8963 beq t6,t5,0x2a\n" " 1c: 4f2d li t5,11\n" @@ -1636,7 +1636,7 @@ is_boolean_far_test() -> " 6: ffff .insn 2, 0xffff\n" " 8: 00001697 auipc a3,0x1\n" " c: ff868067 jr -8(a3) # 0x1000\n" - " 10: 01852f83 lw t6,24(a0)\n" + " 10: 02c52f83 lw t6,44(a0)\n" " 14: 04b00f13 li t5,75\n" " 18: 01ef8963 beq t6,t5,0x2a\n" " 1c: 4f2d li t5,11\n" @@ -1669,7 +1669,7 @@ is_boolean_far_known_test() -> " 6: ffff .insn 2, 0xffff\n" " 8: 00001697 auipc a3,0x1\n" " c: ff868067 jr -8(a3) # 0x1000\n" - " 10: 01852f83 lw t6,24(a0)\n" + " 10: 02c52f83 lw t6,44(a0)\n" " 14: 04b00f13 li t5,75\n" " 18: 01ef8963 beq t6,t5,0x2a\n" " 1c: 4f2d li t5,11\n" @@ -1925,9 +1925,9 @@ gc_bif2_test() -> " 2a: c632 sw a2,12(sp)\n" " 2c: 4581 li a1,0\n" " 2e: 460d li a2,3\n" - " 30: 01452f03 lw t5,20(a0)\n" + " 30: 02852f03 lw t5,40(a0)\n" " 34: 000f2683 lw a3,0(t5)\n" - " 38: 4d18 lw a4,24(a0)\n" + " 38: 5558 lw a4,44(a0)\n" " 3a: 9f82 jalr t6\n" " 3c: 8faa mv t6,a0\n" " 3e: 4082 lw ra,0(sp)\n" @@ -1994,7 +1994,7 @@ call_ext_test() -> " 2a: 11800f93 li t6,280\n" " 2e: 00000013 nop\n" " 32: 01ff6f33 or t5,t5,t6\n" - " 36: 05e52e23 sw t5,92(a0)\n" + " 36: 07e52823 sw t5,112(a0)\n" " 3a: 01062f83 lw t6,16(a2)\n" " 3e: 4609 li a2,2\n" " 40: 4695 li a3,5\n" @@ -2044,7 +2044,7 @@ call_fun_test() -> " 16: 01f5a223 sw t6,4(a1)\n" " 1a: 00862f83 lw t6,8(a2)\n" " 1e: 8f82 jr t6\n" - " 20: 01852f83 lw t6,24(a0)\n" + " 20: 02c52f83 lw t6,44(a0)\n" " 24: 8f7e mv t5,t6\n" " 26: 8efa mv t4,t5\n" " 28: 4e0d li t3,3\n" @@ -2076,7 +2076,7 @@ call_fun_test() -> " 7c: 27000f13 li t5,624\n" " 80: 00000013 nop\n" " 84: 01eeeeb3 or t4,t4,t5\n" - " 88: 05d52e23 sw t4,92(a0)\n" + " 88: 07d52823 sw t4,112(a0)\n" " 8c: 08000f13 li t5,128\n" " 90: 9f32 add t5,t5,a2\n" " 92: 000f2f03 lw t5,0(t5)\n" @@ -2102,14 +2102,14 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 0, {x_reg, 0}, << " 0: 4f81 li t6,0\n" - " 2: 01f52c23 sw t6,24(a0)\n" + " 2: 03f52623 sw t6,44(a0)\n" " 6: a8ed j 0x100" >>) end), ?_test(begin move_to_vm_register_test0(State0, 0, {x_reg, extra}, << " 0: 4f81 li t6,0\n" - " 2: 05f52c23 sw t6,88(a0)\n" + " 2: 07f52623 sw t6,108(a0)\n" " 6: a8ed j 0x100" >>) end), @@ -2123,7 +2123,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 0, {y_reg, 2}, << " 0: 4f01 li t5,0\n" - " 2: 01452f83 lw t6,20(a0)\n" + " 2: 02852f83 lw t6,40(a0)\n" " 6: 01efa423 sw t5,8(t6)\n" " a: a8dd j 0x100" >>) @@ -2131,7 +2131,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 0, {y_reg, 20}, << " 0: 4f01 li t5,0\n" - " 2: 01452f83 lw t6,20(a0)\n" + " 2: 02852f83 lw t6,40(a0)\n" " 6: 05efa823 sw t5,80(t6)\n" " a: a8dd j 0x100" >>) @@ -2140,21 +2140,21 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 42, {x_reg, 0}, << " 0: 02a00f93 li t6,42\n" - " 4: 01f52c23 sw t6,24(a0)\n" + " 4: 03f52623 sw t6,44(a0)\n" " 8: a8e5 j 0x100" >>) end), ?_test(begin move_to_vm_register_test0(State0, 42, {x_reg, extra}, << " 0: 02a00f93 li t6,42\n" - " 4: 05f52c23 sw t6,88(a0)\n" + " 4: 07f52623 sw t6,108(a0)\n" " 8: a8e5 j 0x100" >>) end), ?_test(begin move_to_vm_register_test0(State0, 42, {y_reg, 2}, << " 0: 02a00f13 li t5,42\n" - " 4: 01452f83 lw t6,20(a0)\n" + " 4: 02852f83 lw t6,40(a0)\n" " 8: 01efa423 sw t5,8(t6)\n" " c: a8d5 j 0x100" >>) @@ -2162,7 +2162,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 42, {y_reg, 20}, << " 0: 02a00f13 li t5,42\n" - " 4: 01452f83 lw t6,20(a0)\n" + " 4: 02852f83 lw t6,40(a0)\n" " 8: 05efa823 sw t5,80(t6)\n" " c: a8d5 j 0x100" >>) @@ -2178,15 +2178,15 @@ move_to_vm_register_test_() -> %% Test: x_reg to x_reg ?_test(begin move_to_vm_register_test0(State0, {x_reg, 1}, {x_reg, 2}, << - " 0: 01c52f83 lw t6,28(a0)\n" - " 4: 03f52023 sw t6,32(a0)\n" + " 0: 03052f83 lw t6,48(a0)\n" + " 4: 03f52a23 sw t6,52(a0)\n" " 8: a8e5 j 0x100" >>) end), %% Test: x_reg to ptr ?_test(begin move_to_vm_register_test0(State0, {x_reg, 1}, {ptr, a1}, << - " 0: 01c52f83 lw t6,28(a0)\n" + " 0: 03052f83 lw t6,48(a0)\n" " 4: 01f5a023 sw t6,0(a1)\n" " 8: a8e5 j 0x100" >>) @@ -2195,15 +2195,15 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, {ptr, t3}, {x_reg, 3}, << " 0: 000e2f83 lw t6,0(t3)\n" - " 4: 03f52223 sw t6,36(a0)\n" + " 4: 03f52c23 sw t6,56(a0)\n" " 8: a8e5 j 0x100" >>) end), %% Test: x_reg to y_reg ?_test(begin move_to_vm_register_test0(State0, {x_reg, 0}, {y_reg, 1}, << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01452f03 lw t5,20(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 02852f03 lw t5,40(a0)\n" " 8: 01ff2223 sw t6,4(t5)\n" " c: a8d5 j 0x100" >>) @@ -2211,31 +2211,31 @@ move_to_vm_register_test_() -> %% Test: y_reg to x_reg ?_test(begin move_to_vm_register_test0(State0, {y_reg, 0}, {x_reg, 3}, << - " 0: 01452f03 lw t5,20(a0)\n" + " 0: 02852f03 lw t5,40(a0)\n" " 4: 000f2f83 lw t6,0(t5)\n" - " 8: 03f52223 sw t6,36(a0)\n" + " 8: 03f52c23 sw t6,56(a0)\n" " c: a8d5 j 0x100" >>) end), %% Test: y_reg to y_reg ?_test(begin move_to_vm_register_test0(State0, {y_reg, 1}, {x_reg, 3}, << - " 0: 01452f03 lw t5,20(a0)\n" + " 0: 02852f03 lw t5,40(a0)\n" " 4: 004f2f83 lw t6,4(t5)\n" - " 8: 03f52223 sw t6,36(a0)\n" + " 8: 03f52c23 sw t6,56(a0)\n" " c: a8d5 j 0x100" >>) end), %% Test: Native register to x_reg ?_test(begin move_to_vm_register_test0(State0, t4, {x_reg, 0}, << - " 0: 01d52c23 sw t4,24(a0)\n" + " 0: 03d52623 sw t4,44(a0)\n" " 4: a8f5 j 0x100" >>) end), ?_test(begin move_to_vm_register_test0(State0, t5, {x_reg, extra}, << - " 0: 05e52c23 sw t5,88(a0)\n" + " 0: 07e52623 sw t5,108(a0)\n" " 4: a8f5 j 0x100" >>) end), @@ -2249,7 +2249,7 @@ move_to_vm_register_test_() -> %% Test: Native register to y_reg ?_test(begin move_to_vm_register_test0(State0, a1, {y_reg, 0}, << - " 0: 01452f83 lw t6,20(a0)\n" + " 0: 02852f83 lw t6,40(a0)\n" " 4: 00bfa023 sw a1,0(t6)\n" " 8: a8e5 j 0x100" >>) @@ -2259,7 +2259,7 @@ move_to_vm_register_test_() -> move_to_vm_register_test0(State0, 16#12345678, {x_reg, 0}, << " 0: 12345fb7 lui t6,0x12345\n" " 4: 678f8f93 addi t6,t6,1656 # 0x12345678\n" - " 8: 01f52c23 sw t6,24(a0)\n" + " 8: 03f52623 sw t6,44(a0)\n" " c: a8d5 j 0x100" >>) end), @@ -2267,7 +2267,7 @@ move_to_vm_register_test_() -> move_to_vm_register_test0(State0, 16#12345678, {x_reg, extra}, << " 0: 12345fb7 lui t6,0x12345\n" " 4: 678f8f93 addi t6,t6,1656 # 0x12345678\n" - " 8: 05f52c23 sw t6,88(a0)\n" + " 8: 07f52623 sw t6,108(a0)\n" " c: a8d5 j 0x100" >>) end), @@ -2275,7 +2275,7 @@ move_to_vm_register_test_() -> move_to_vm_register_test0(State0, 16#12345678, {y_reg, 2}, << " 0: 12345fb7 lui t6,0x12345\n" " 4: 678f8f93 addi t6,t6,1656 # 0x12345678\n" - " 8: 01452f03 lw t5,20(a0)\n" + " 8: 02852f03 lw t5,40(a0)\n" " c: 01ff2423 sw t6,8(t5)\n" " 10: a8c5 j 0x100" >>) @@ -2284,7 +2284,7 @@ move_to_vm_register_test_() -> move_to_vm_register_test0(State0, 16#12345678, {y_reg, 20}, << " 0: 12345fb7 lui t6,0x12345\n" " 4: 678f8f93 addi t6,t6,1656 # 0x12345678\n" - " 8: 01452f03 lw t5,20(a0)\n" + " 8: 02852f03 lw t5,40(a0)\n" " c: 05ff2823 sw t6,80(t5)\n" " 10: a8c5 j 0x100" >>) @@ -2301,8 +2301,8 @@ move_to_vm_register_test_() -> %% Test: x_reg to y_reg (high index) ?_test(begin move_to_vm_register_test0(State0, {x_reg, 15}, {y_reg, 31}, << - " 0: 05452f83 lw t6,84(a0)\n" - " 4: 01452f03 lw t5,20(a0)\n" + " 0: 06852f83 lw t6,104(a0)\n" + " 4: 02852f03 lw t5,40(a0)\n" " 8: 07ff2e23 sw t6,124(t5)\n" " c: a8d5 j 0x100" >>) @@ -2310,9 +2310,9 @@ move_to_vm_register_test_() -> %% Test: y_reg to x_reg (high index) ?_test(begin move_to_vm_register_test0(State0, {y_reg, 31}, {x_reg, 15}, << - " 0: 01452f03 lw t5,20(a0)\n" + " 0: 02852f03 lw t5,40(a0)\n" " 4: 07cf2f83 lw t6,124(t5)\n" - " 8: 05f52a23 sw t6,84(a0)\n" + " 8: 07f52423 sw t6,104(a0)\n" " c: a8d5 j 0x100" >>) end), @@ -2320,7 +2320,7 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, 42, {y_reg, 32}, << " 0: 02a00f13 li t5,42\n" - " 4: 01452f83 lw t6,20(a0)\n" + " 4: 02852f83 lw t6,40(a0)\n" " 8: 08000e93 li t4,128\n" " c: 9efe add t4,t4,t6\n" " e: 01eea023 sw t5,0(t4)\n" @@ -2331,21 +2331,21 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, -1, {x_reg, 0}, << " 0: 5ffd li t6,-1\n" - " 2: 01f52c23 sw t6,24(a0)\n" + " 2: 03f52623 sw t6,44(a0)\n" " 6: a8ed j 0x100" >>) end), ?_test(begin move_to_vm_register_test0(State0, -100, {x_reg, 0}, << " 0: f9c00f93 li t6,-100\n" - " 4: 01f52c23 sw t6,24(a0)\n" + " 4: 03f52623 sw t6,44(a0)\n" " 8: a8e5 j 0x100" >>) end), ?_test(begin move_to_vm_register_test0(State0, -1000, {x_reg, 0}, << " 0: c1800f93 li t6,-1000\n" - " 4: 01f52c23 sw t6,24(a0)\n" + " 4: 03f52623 sw t6,44(a0)\n" " 8: a8e5 j 0x100" >>) end) @@ -2368,7 +2368,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, a3, 2, {x_reg, 0}, << " 0: 0086af83 lw t6,8(a3)\n" - " 4: 01f52c23 sw t6,24(a0)" + " 4: 03f52623 sw t6,44(a0)" >>) end), %% move_array_element: reg[x] to ptr @@ -2382,7 +2382,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, a3, 1, {y_reg, 2}, << " 0: 0046af03 lw t5,4(a3)\n" - " 4: 01452f83 lw t6,20(a0)\n" + " 4: 02852f83 lw t6,40(a0)\n" " 8: 01efa423 sw t5,8(t6)" >>) end), @@ -2396,7 +2396,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, a3, 7, {y_reg, 31}, << " 0: 01c6af03 lw t5,28(a3)\n" - " 4: 01452f83 lw t6,20(a0)\n" + " 4: 02852f83 lw t6,40(a0)\n" " 8: 07efae23 sw t5,124(t6)" >>) end), @@ -2404,7 +2404,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, a3, 7, {x_reg, 15}, << " 0: 01c6af83 lw t6,28(a3)\n" - " 4: 05f52a23 sw t6,84(a0)" + " 4: 07f52423 sw t6,104(a0)" >>) end), %% move_array_element: reg_x[reg_y] to x_reg @@ -2415,7 +2415,7 @@ move_array_element_test_() -> " 4: 0f8a slli t6,t6,0x2\n" " 6: 01f68fb3 add t6,a3,t6\n" " a: 000faf83 lw t6,0(t6)\n" - " e: 03f52023 sw t6,32(a0)" + " e: 03f52a23 sw t6,52(a0)" >>) end), %% move_array_element: reg_x[reg_y] to pointer (large x reg) @@ -2437,7 +2437,7 @@ move_array_element_test_() -> " 4: 0f8a slli t6,t6,0x2\n" " 6: 01f68fb3 add t6,a3,t6\n" " a: 000faf83 lw t6,0(t6)\n" - " e: 01452f03 lw t5,20(a0)\n" + " e: 02852f03 lw t5,40(a0)\n" " 12: 07ff2e23 sw t6,124(t5)" >>) end), @@ -2445,9 +2445,9 @@ move_array_element_test_() -> ?_test(begin {State1, BaseReg} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}), move_array_element_test0(State1, BaseReg, 2, {x_reg, 5}, << - " 0: 01852f83 lw t6,24(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" " 4: 008faf03 lw t5,8(t6)\n" - " 8: 03e52623 sw t5,44(a0)" + " 8: 05e52023 sw t5,64(a0)" >>) end) ] @@ -2485,7 +2485,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, a3, 2), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" " 4: 01f6a423 sw t6,8(a3)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream) @@ -2495,7 +2495,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, a3, t3), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" " 4: 8f72 mv t5,t3\n" " 6: 0f0a slli t5,t5,0x2\n" " 8: 01e68f33 add t5,a3,t5\n" @@ -2521,7 +2521,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {y_reg, 2}, a3, t3), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01452f03 lw t5,20(a0)\n" + " 0: 02852f03 lw t5,40(a0)\n" " 4: 008f2f83 lw t6,8(t5)\n" " 8: 8f72 mv t5,t3\n" " a: 0f0a slli t5,t5,0x2\n" @@ -2535,7 +2535,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, a3, 2, 1), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" " 4: 01f6a423 sw t6,8(a3)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream) @@ -2548,7 +2548,7 @@ move_to_array_element_test_() -> State3 = ?BACKEND:move_to_array_element(State2, {x_reg, 0}, a3, t3, 1), Stream = ?BACKEND:stream(State3), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" " 4: 001e0f13 addi t5,t3,1\n" " 8: 0f0a slli t5,t5,0x2\n" " a: 01e68f33 add t5,a3,t5\n" @@ -2640,7 +2640,7 @@ move_to_native_register_test_() -> Stream = ?BACKEND:stream(State1), ?assertEqual(t6, Reg), Dump = << - " 0: 02c52f83 lw t6,44(a0)" + " 0: 04052f83 lw t6,64(a0)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream) end), @@ -2650,7 +2650,7 @@ move_to_native_register_test_() -> Stream = ?BACKEND:stream(State1), ?assertEqual(t6, Reg), Dump = << - " 0: 01452f03 lw t5,20(a0)\n" + " 0: 02852f03 lw t5,40(a0)\n" " 4: 00cf2f83 lw t6,12(t5)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream) @@ -2687,7 +2687,7 @@ move_to_native_register_test_() -> State1 = ?BACKEND:move_to_native_register(State0, {x_reg, 2}, a3), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 5114 lw a3,32(a0)" + " 0: 5954 lw a3,52(a0)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream) end), @@ -2696,7 +2696,7 @@ move_to_native_register_test_() -> State1 = ?BACKEND:move_to_native_register(State0, {y_reg, 2}, a1), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 01452f83 lw t6,20(a0)\n" + " 0: 02852f83 lw t6,40(a0)\n" " 4: 008fa583 lw a1,8(t6)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream) @@ -2709,8 +2709,8 @@ move_to_native_register_test_() -> ), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 06052f03 lw t5,96(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 07452f03 lw t5,116(a0)\n" " 8: 004fae83 lw t4,4(t6)\n" " c: 01df2c23 sw t4,24(t5)\n" " 10: 008fae83 lw t4,8(t6)\n" @@ -2890,7 +2890,7 @@ set_args1_y_reg_test() -> " 10: c22a sw a0,4(sp)\n" " 12: c42e sw a1,8(sp)\n" " 14: c632 sw a2,12(sp)\n" - " 16: 01452f03 lw t5,20(a0)\n" + " 16: 02852f03 lw t5,40(a0)\n" " 1a: 014f2503 lw a0,20(t5)\n" " 1e: 9f82 jalr t6\n" " 20: 8faa mv t6,a0\n" @@ -2910,7 +2910,7 @@ large_y_reg_read_test() -> Stream = ?BACKEND:stream(State1), % Expected: uses helper with temp register for large offset Dump = << - " 0: 01452f03 lw t5,20(a0)\n" + " 0: 02852f03 lw t5,40(a0)\n" " 4: 1ec00f93 li t6,492\n" " 8: 9ffa add t6,t6,t5\n" " a: 000faf83 lw t6,0(t6)" @@ -2927,7 +2927,7 @@ large_y_reg_write_test() -> % Expected: uses helper with temp registers for large offset Dump = << " 0: 02a00f13 li t5,42\n" - " 4: 01452f83 lw t6,20(a0)\n" + " 4: 02852f83 lw t6,40(a0)\n" " 8: 1ec00e93 li t4,492\n" " c: 9efe add t4,t4,t6\n" " e: 01eea023 sw t5,0(t4)" @@ -2948,12 +2948,12 @@ large_y_reg_read_register_exhaustion_test() -> Stream = ?BACKEND:stream(StateFinal), % Expected: uses t0+t1 fallback sequence when temps are exhausted Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" - " 8: 02052e83 lw t4,32(a0)\n" - " c: 02452e03 lw t3,36(a0)\n" - " 10: 02852383 lw t2,40(a0)\n" - " 14: 01452283 lw t0,20(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" + " 8: 03452e83 lw t4,52(a0)\n" + " c: 03852e03 lw t3,56(a0)\n" + " 10: 03c52383 lw t2,60(a0)\n" + " 14: 02852283 lw t0,40(a0)\n" " 18: 08c00313 li t1,140\n" " 1c: 9316 add t1,t1,t0\n" " 1e: 00032303 lw t1,0(t1)" @@ -2976,12 +2976,12 @@ large_y_reg_write_register_exhaustion_test() -> Stream = ?BACKEND:stream(StateFinal), % Expected: uses t1/t0 fallback sequence Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" - " 8: 02052e83 lw t4,32(a0)\n" - " c: 02452e03 lw t3,36(a0)\n" - " 10: 02852383 lw t2,40(a0)\n" - " 14: 01452303 lw t1,20(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" + " 8: 03452e83 lw t4,52(a0)\n" + " c: 03852e03 lw t3,56(a0)\n" + " 10: 03c52383 lw t2,60(a0)\n" + " 14: 02852303 lw t1,40(a0)\n" " 18: 0c800293 li t0,200\n" " 1c: 929a add t0,t0,t1\n" " 1e: 01f2a023 sw t6,0(t0)" @@ -2995,7 +2995,7 @@ y_reg_boundary_direct_test() -> Stream = ?BACKEND:stream(State1), % Expected: uses direct addressing since 31 * 4 = 124 < 2048 Dump = << - " 0: 01452f03 lw t5,20(a0)\n" + " 0: 02852f03 lw t5,40(a0)\n" " 4: 07cf2f83 lw t6,124(t5)" >>, jit_tests_common:assert_stream(riscv32, Dump, Stream), @@ -3024,12 +3024,12 @@ and_register_exhaustion_negative_test() -> {StateResult, t6} = ?BACKEND:and_(StateNoRegs, {free, t6}, -4), Stream = ?BACKEND:stream(StateResult), ExpectedDump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" - " 8: 02052e83 lw t4,32(a0)\n" - " c: 02452e03 lw t3,36(a0)\n" - " 10: 02852383 lw t2,40(a0)\n" - " 14: 02c52303 lw t1,44(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" + " 8: 03452e83 lw t4,52(a0)\n" + " c: 03852e03 lw t3,56(a0)\n" + " 10: 03c52383 lw t2,60(a0)\n" + " 14: 04052303 lw t1,64(a0)\n" " 18: 428d li t0,3\n" " 1a: fff2c293 not t0,t0\n" " 1e: 005fffb3 and t6,t6,t0" @@ -3049,12 +3049,12 @@ and_register_exhaustion_positive_test() -> {StateResult, t6} = ?BACKEND:and_(StateNoRegs, {free, t6}, 16#3F), Stream = ?BACKEND:stream(StateResult), ExpectedDump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" - " 8: 02052e83 lw t4,32(a0)\n" - " c: 02452e03 lw t3,36(a0)\n" - " 10: 02852383 lw t2,40(a0)\n" - " 14: 02c52303 lw t1,44(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" + " 8: 03452e83 lw t4,52(a0)\n" + " c: 03852e03 lw t3,56(a0)\n" + " 10: 03c52383 lw t2,60(a0)\n" + " 14: 04052303 lw t1,64(a0)\n" " 18: 03f00293 li t0,63\n" " 1c: 005fffb3 and t6,t6,t0" >>, @@ -3144,10 +3144,10 @@ call_func_ptr_stack_alignment_test() -> Stream = ?BACKEND:stream(State5), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" - " 8: 02052e83 lw t4,32(a0)\n" - " c: 02452e03 lw t3,36(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" + " 8: 03452e83 lw t4,52(a0)\n" + " c: 03852e03 lw t3,56(a0)\n" " 10: 1101 addi sp,sp,-32\n" " 12: c006 sw ra,0(sp)\n" " 14: c22a sw a0,4(sp)\n" @@ -3198,12 +3198,12 @@ call_func_ptr_register_exhaustion_test_() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" - " 8: 02052e83 lw t4,32(a0)\n" - " c: 02452e03 lw t3,36(a0)\n" - " 10: 02852383 lw t2,40(a0)\n" - " 14: 02c52303 lw t1,44(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" + " 8: 03452e83 lw t4,52(a0)\n" + " c: 03852e03 lw t3,56(a0)\n" + " 10: 03c52383 lw t2,60(a0)\n" + " 14: 04052303 lw t1,64(a0)\n" " 18: 1101 addi sp,sp,-32\n" " 1a: c006 sw ra,0(sp)\n" " 1c: c22a sw a0,4(sp)\n" @@ -3239,12 +3239,12 @@ call_func_ptr_register_exhaustion_test_() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" - " 8: 02052e83 lw t4,32(a0)\n" - " c: 02452e03 lw t3,36(a0)\n" - " 10: 02852383 lw t2,40(a0)\n" - " 14: 02c52303 lw t1,44(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" + " 8: 03452e83 lw t4,52(a0)\n" + " c: 03852e03 lw t3,56(a0)\n" + " 10: 03c52383 lw t2,60(a0)\n" + " 14: 04052303 lw t1,64(a0)\n" " 18: 1101 addi sp,sp,-32\n" " 1a: c006 sw ra,0(sp)\n" " 1c: c22a sw a0,4(sp)\n" @@ -3280,12 +3280,12 @@ call_func_ptr_register_exhaustion_test_() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" - " 8: 02052e83 lw t4,32(a0)\n" - " c: 02452e03 lw t3,36(a0)\n" - " 10: 02852383 lw t2,40(a0)\n" - " 14: 02c52303 lw t1,44(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" + " 8: 03452e83 lw t4,52(a0)\n" + " c: 03852e03 lw t3,56(a0)\n" + " 10: 03c52383 lw t2,60(a0)\n" + " 14: 04052303 lw t1,64(a0)\n" " 18: 1101 addi sp,sp,-32\n" " 1a: c006 sw ra,0(sp)\n" " 1c: c22a sw a0,4(sp)\n" @@ -3322,12 +3322,12 @@ call_func_ptr_register_exhaustion_test_() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" - " 8: 02052e83 lw t4,32(a0)\n" - " c: 02452e03 lw t3,36(a0)\n" - " 10: 02852383 lw t2,40(a0)\n" - " 14: 02c52303 lw t1,44(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" + " 8: 03452e83 lw t4,52(a0)\n" + " c: 03852e03 lw t3,56(a0)\n" + " 10: 03c52383 lw t2,60(a0)\n" + " 14: 04052303 lw t1,64(a0)\n" " 18: fd010113 addi sp,sp,-48\n" " 1c: c006 sw ra,0(sp)\n" " 1e: c22a sw a0,4(sp)\n" @@ -3368,12 +3368,12 @@ call_func_ptr_register_exhaustion_test_() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 01852f83 lw t6,24(a0)\n" - " 4: 01c52f03 lw t5,28(a0)\n" - " 8: 02052e83 lw t4,32(a0)\n" - " c: 02452e03 lw t3,36(a0)\n" - " 10: 02852383 lw t2,40(a0)\n" - " 14: 02c52303 lw t1,44(a0)\n" + " 0: 02c52f83 lw t6,44(a0)\n" + " 4: 03052f03 lw t5,48(a0)\n" + " 8: 03452e83 lw t4,52(a0)\n" + " c: 03852e03 lw t3,56(a0)\n" + " 10: 03c52383 lw t2,60(a0)\n" + " 14: 04052303 lw t1,64(a0)\n" " 18: fd010113 addi sp,sp,-48\n" " 1c: c006 sw ra,0(sp)\n" " 1e: c22a sw a0,4(sp)\n" @@ -3490,10 +3490,10 @@ add_beam_test() -> % label 1 % {move,{integer,9},{x,1}}. " 20: 09f00f93 li t6,159\n" - " 24: 01f52e23 sw t6,28(a0)\n" + " 24: 03f52823 sw t6,48(a0)\n" % {move,{integer,8},{x,0}} " 28: 08f00f93 li t6,143\n" - " 2c: 01f52c23 sw t6,24(a0)\n" + " 2c: 03f52623 sw t6,44(a0)\n" % {call_only,2,{f,2}}. " 30: 0085af83 lw t6,8(a1)\n" " 34: 1ffd addi t6,t6,-1\n" @@ -3534,7 +3534,7 @@ add_beam_test() -> % {init_yregs,{list,[{y,0}]}}. %% move_to_vm_register(State8, ?TERM_NIL, {y_reg, 0}), " 8c: 03b00f13 li t5,59\n" - " 90: 01452f83 lw t6,20(a0)\n" + " 90: 02852f83 lw t6,40(a0)\n" " 94: 01efa023 sw t5,0(t6)\n" % {call,1,{f,3}} %% call_or_schedule_next(State9, 3), @@ -3544,7 +3544,7 @@ add_beam_test() -> " a2: 36800f93 li t6,872\n" " a6: 00000013 nop\n" " aa: 01ff6f33 or t5,t5,t6\n" - " ae: 05e52e23 sw t5,92(a0)\n" + " ae: 07e52823 sw t5,112(a0)\n" " b2: 0085af83 lw t6,8(a1)\n" " b6: 1ffd addi t6,t6,-1\n" " b8: 01f5a423 sw t6,8(a1)\n" diff --git a/tests/libs/jit/jit_tests.erl b/tests/libs/jit/jit_tests.erl index 7a201fa3ad..ef85ac0026 100644 --- a/tests/libs/jit/jit_tests.erl +++ b/tests/libs/jit/jit_tests.erl @@ -174,11 +174,11 @@ term_to_int_verify_is_match_state_typed_optimization_x86_64_test() -> ), % Check the reading of x[1] is immediatly followed by a shift right. - % 15c: 4c 8b 5f 38 mov 0x38(%rdi),%r11 + % 15c: 4c 8b 5f 60 mov 0x60(%rdi),%r11 % 160: 49 c1 eb 04 shr $0x4,%r11 % As opposed to testing its type - % 15c: 4c 8b 5f 38 mov 0x38(%rdi),%r11 + % 15c: 4c 8b 5f 60 mov 0x60(%rdi),%r11 % 160: 4d 89 da mov %r11,%r10 % 163: 41 80 e2 0f and $0xf,%r10b % 167: 41 80 fa 0f cmp $0xf,%r10b @@ -187,29 +187,29 @@ term_to_int_verify_is_match_state_typed_optimization_x86_64_test() -> % 172: 49 c1 eb 04 shr $0x4,%r11 ?assertMatch( {_, 8}, - binary:match(CompiledCode, <<16#4c, 16#8b, 16#5f, 16#38, 16#49, 16#c1, 16#eb, 16#04>>) + binary:match(CompiledCode, <<16#4c, 16#8b, 16#5f, 16#60, 16#49, 16#c1, 16#eb, 16#04>>) ), % Check call to bs_start_match3 is followed by a skip of verify_is_boxed - % 100: 48 8b 77 30 mov 0x30(%rdi),%rsi + % 100: 48 8b 77 58 mov 0x58(%rdi),%rsi % 104: 48 c7 c2 00 00 00 00 mov $0x0,%rdx % 10b: ff d0 callq *%rax % 10d: 5a pop %rdx % 10e: 5e pop %rsi % 10f: 5f pop %rdi - % 110: 48 89 47 40 mov %rax,0x40(%rdi) - % 114: 48 8b 47 40 mov 0x40(%rdi),%rax + % 110: 48 89 47 68 mov %rax,0x68(%rdi) + % 114: 48 8b 47 68 mov 0x68(%rdi),%rax % 118: 48 83 e0 fc and $0xfffffffffffffffc,%rax % As opposed to: - % 100: 48 8b 77 30 mov 0x30(%rdi),%rsi + % 100: 48 8b 77 58 mov 0x58(%rdi),%rsi % 104: 48 c7 c2 00 00 00 00 mov $0x0,%rdx % 10b: ff d0 callq *%rax % 10d: 5a pop %rdx % 10e: 5e pop %rsi % 10f: 5f pop %rdi - % 110: 48 89 47 40 mov %rax,0x40(%rdi) - % 114: 48 8b 47 40 mov 0x40(%rdi),%rax + % 110: 48 89 47 68 mov %rax,0x68(%rdi) + % 114: 48 8b 47 68 mov 0x68(%rdi),%rax % 118: 49 89 c3 mov %rax,%r11 % 11b: 41 80 e3 03 and $0x3,%r11b % 11f: 41 80 fb 02 cmp $0x2,%r11b @@ -223,8 +223,8 @@ term_to_int_verify_is_match_state_typed_optimization_x86_64_test() -> {_, 28}, binary:match( CompiledCode, - <<16#48, 16#8b, 16#77, 16#30, 16#48, 16#c7, 16#c2, 16#00, 16#00, 16#00, 16#00, 16#ff, - 16#d0, 16#5a, 16#5e, 16#5f, 16#48, 16#89, 16#47, 16#40, 16#48, 16#8b, 16#47, 16#40, + <<16#48, 16#8b, 16#77, 16#58, 16#48, 16#c7, 16#c2, 16#00, 16#00, 16#00, 16#00, 16#ff, + 16#d0, 16#5a, 16#5e, 16#5f, 16#48, 16#89, 16#47, 16#68, 16#48, 16#8b, 16#47, 16#68, 16#48, 16#83, 16#e0, 16#fc>> ) ), @@ -240,7 +240,7 @@ verify_is_function_typed_optimization_x86_64_test() -> % for call % b6: 48 8b 42 10 mov 0x10(%rdx),%rax % ba: ff e0 jmpq *%rax - % bc: 48 8b 47 38 mov 0x38(%rdi),%rax + % bc: 48 8b 47 60 mov 0x60(%rdi),%rax % c0: 4c 8b 1e mov (%rsi),%r11 % c3: 45 8b 1b mov (%r11),%r11d % c6: 49 c1 e3 18 shl $0x18,%r11 @@ -249,7 +249,7 @@ verify_is_function_typed_optimization_x86_64_test() -> % As opposed to: % b6: 48 8b 42 10 mov 0x10(%rdx),%rax % ba: ff e0 jmpq *%rax - % bc: 48 8b 47 38 mov 0x38(%rdi),%rax + % bc: 48 8b 47 60 mov 0x60(%rdi),%rax % c0: 49 89 c3 mov %rax,%r11 % c3: 4d 89 da mov %r11,%r10 % c6: 41 80 e2 03 and $0x3,%r10b @@ -280,7 +280,7 @@ verify_is_function_typed_optimization_x86_64_test() -> {_, 20}, binary:match( CompiledCode, - <<16#48, 16#8b, 16#42, 16#10, 16#ff, 16#e0, 16#48, 16#8b, 16#47, 16#38, 16#4c, 16#8b, + <<16#48, 16#8b, 16#42, 16#10, 16#ff, 16#e0, 16#48, 16#8b, 16#47, 16#60, 16#4c, 16#8b, 16#1e, 16#45, 16#8b, 16#1b, 16#49, 16#c1, 16#e3, 16#18>> ) ), diff --git a/tests/libs/jit/jit_tests_common.erl b/tests/libs/jit/jit_tests_common.erl index 9482a047d2..f0b29ee4ff 100644 --- a/tests/libs/jit/jit_tests_common.erl +++ b/tests/libs/jit/jit_tests_common.erl @@ -178,7 +178,10 @@ assert_stream(Arch, Dump, Stream) -> true -> ok; false -> - diff_disasm(Arch, Expected, Stream), + case erlang:system_info(machine) of + "BEAM" -> diff_disasm(Arch, Expected, Stream); + "ATOM" -> ok + end, ?assertEqual(Expected, Stream) end. diff --git a/tests/libs/jit/jit_x86_64_tests.erl b/tests/libs/jit/jit_x86_64_tests.erl index d6ebef1ffb..42de891954 100644 --- a/tests/libs/jit/jit_x86_64_tests.erl +++ b/tests/libs/jit/jit_x86_64_tests.erl @@ -184,36 +184,36 @@ call_primitive_few_regs_test() -> Stream = ?BACKEND:stream(State7), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" - " 8: 4c 8b 57 40 mov 0x40(%rdi),%r10\n" - " c: 4c 8b 4f 48 mov 0x48(%rdi),%r9\n" - " 10: 4c 8b 47 50 mov 0x50(%rdi),%r8\n" - " 14: 48 8b 4f 58 mov 0x58(%rdi),%rcx\n" - " 18: 57 push %rdi\n" - " 19: 56 push %rsi\n" - " 1a: 52 push %rdx\n" - " 1b: 41 51 push %r9\n" - " 1d: 41 52 push %r10\n" - " 1f: 41 53 push %r11\n" - " 21: 50 push %rax\n" - " 22: 48 8b 92 c8 01 00 00 mov 0x1c8(%rdx),%rdx\n" - " 29: 52 push %rdx\n" - " 2a: 48 89 c7 mov %rax,%rdi\n" - " 2d: 4c 89 de mov %r11,%rsi\n" - " 30: 4c 89 c2 mov %r8,%rdx\n" - " 33: 4c 87 c9 xchg %r9,%rcx\n" - " 36: 4d 89 c8 mov %r9,%r8\n" - " 39: 58 pop %rax\n" - " 3a: ff d0 callq *%rax\n" - " 3c: 49 89 c0 mov %rax,%r8\n" - " 3f: 58 pop %rax\n" - " 40: 41 5b pop %r11\n" - " 42: 41 5a pop %r10\n" - " 44: 41 59 pop %r9\n" - " 46: 5a pop %rdx\n" - " 47: 5e pop %rsi\n" - " 48: 5f pop %rdi" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" + " 8: 4c 8b 57 68 mov 0x68(%rdi),%r10\n" + " c: 4c 8b 4f 70 mov 0x70(%rdi),%r9\n" + " 10: 4c 8b 47 78 mov 0x78(%rdi),%r8\n" + " 14: 48 8b 8f 80 00 00 00 mov 0x80(%rdi),%rcx\n" + " 1b: 57 push %rdi\n" + " 1c: 56 push %rsi\n" + " 1d: 52 push %rdx\n" + " 1e: 41 51 push %r9\n" + " 20: 41 52 push %r10\n" + " 22: 41 53 push %r11\n" + " 24: 50 push %rax\n" + " 25: 48 8b 92 c8 01 00 00 mov 0x1c8(%rdx),%rdx\n" + " 2c: 52 push %rdx\n" + " 2d: 48 89 c7 mov %rax,%rdi\n" + " 30: 4c 89 de mov %r11,%rsi\n" + " 33: 4c 89 c2 mov %r8,%rdx\n" + " 36: 4c 87 c9 xchg %r9,%rcx\n" + " 39: 4d 89 c8 mov %r9,%r8\n" + " 3c: 58 pop %rax\n" + " 3d: ff d0 callq *%rax\n" + " 3f: 49 89 c0 mov %rax,%r8\n" + " 42: 58 pop %rax\n" + " 43: 41 5b pop %r11\n" + " 45: 41 5a pop %r10\n" + " 47: 41 59 pop %r9\n" + " 49: 5a pop %rdx\n" + " 4a: 5e pop %rsi\n" + " 4b: 5f pop %rdi" >>, jit_tests_common:assert_stream(x86_64, Dump, Stream). @@ -341,9 +341,9 @@ move_to_cp_test() -> Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 48 8b 00 mov (%rax),%rax\n" - " 7: 48 89 87 b8 00 00 00 mov %rax,0xb8(%rdi)\n" + " 7: 48 89 87 e0 00 00 00 mov %rax,0xe0(%rdi)\n" >>, jit_tests_common:assert_stream(x86_64, Dump, Stream). @@ -353,9 +353,9 @@ increment_sp_test() -> Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 48 83 c0 38 add $0x38,%rax\n" - " 8: 48 89 47 28 mov %rax,0x28(%rdi)\n" + " 8: 48 89 47 50 mov %rax,0x50(%rdi)\n" >>, jit_tests_common:assert_stream(x86_64, Dump, Stream). @@ -379,8 +379,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 85 c0 test %rax,%rax\n" " b: 7d 04 jge 0x11\n" " d: 49 83 c3 02 add $0x2,%r11" @@ -398,8 +398,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 4c 39 d8 cmp %r11,%rax\n" " b: 7d 04 jge 0x11\n" " d: 49 83 c3 02 add $0x2,%r11" @@ -417,8 +417,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 85 c0 test %rax,%rax\n" " b: 75 04 jne 0x11\n" " d: 49 83 c3 02 add $0x2,%r11" @@ -436,8 +436,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 85 c0 test %rax,%rax\n" " b: 75 04 jne 0x11\n" " d: 49 83 c3 02 add $0x2,%r11" @@ -455,8 +455,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 85 c0 test %eax,%eax\n" " a: 75 04 jne 0x10\n" " c: 49 83 c3 02 add $0x2,%r11" @@ -474,8 +474,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 85 c0 test %eax,%eax\n" " a: 75 04 jne 0x10\n" " c: 49 83 c3 02 add $0x2,%r11" @@ -493,8 +493,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 83 f8 3b cmp $0x3b,%rax\n" " c: 74 04 je 0x12\n" " e: 49 83 c3 02 add $0x2,%r11" @@ -512,8 +512,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 83 f8 3b cmp $0x3b,%rax\n" " c: 74 04 je 0x12\n" " e: 49 83 c3 02 add $0x2,%r11" @@ -531,8 +531,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 83 f8 2a cmp $0x2a,%eax\n" " b: 74 04 je 0x11\n" " d: 49 83 c3 02 add $0x2,%r11" @@ -550,8 +550,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 83 f8 2a cmp $0x2a,%eax\n" " b: 74 04 je 0x11\n" " d: 49 83 c3 02 add $0x2,%r11" @@ -569,8 +569,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 83 f8 3b cmp $0x3b,%rax\n" " c: 75 04 jne 0x12\n" " e: 49 83 c3 02 add $0x2,%r11" @@ -588,8 +588,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 83 f8 3b cmp $0x3b,%rax\n" " c: 75 04 jne 0x12\n" " e: 49 83 c3 02 add $0x2,%r11" @@ -607,8 +607,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 83 f8 2a cmp $0x2a,%eax\n" " b: 75 04 jne 0x11\n" " d: 49 83 c3 02 add $0x2,%r11" @@ -626,8 +626,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 83 f8 2a cmp $0x2a,%eax\n" " b: 75 04 jne 0x11\n" " d: 49 83 c3 02 add $0x2,%r11" @@ -645,8 +645,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 84 c0 test %al,%al\n" " a: 75 04 jne 0x10\n" " c: 49 83 c3 02 add $0x2,%r11" @@ -664,8 +664,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 84 c0 test %al,%al\n" " a: 75 04 jne 0x10\n" " c: 49 83 c3 02 add $0x2,%r11" @@ -683,8 +683,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 84 c0 test %al,%al\n" " a: 74 04 je 0x10\n" " c: 49 83 c3 02 add $0x2,%r11" @@ -702,8 +702,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 84 c0 test %al,%al\n" " a: 74 04 je 0x10\n" " c: 49 83 c3 02 add $0x2,%r11" @@ -721,8 +721,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: a8 07 test $0x7,%al\n" " a: 74 04 je 0x10\n" " c: 49 83 c3 02 add $0x2,%r11" @@ -740,8 +740,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: a8 07 test $0x7,%al\n" " a: 74 04 je 0x10\n" " c: 49 83 c3 02 add $0x2,%r11" @@ -759,8 +759,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 49 89 c2 mov %rax,%r10\n" " b: 41 80 e2 0f and $0xf,%r10b\n" " f: 41 80 fa 0f cmp $0xf,%r10b\n" @@ -780,8 +780,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 24 0f and $0xf,%al\n" " a: 80 f8 0f cmp $0xf,%al\n" " d: 74 04 je 0x13\n" @@ -800,8 +800,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 83 f8 64 cmp $0x64,%rax\n" " c: 7e 04 jle 0x12\n" " e: 49 83 c3 02 add $0x2,%r11" @@ -819,8 +819,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 83 f8 64 cmp $0x64,%rax\n" " c: 7e 04 jle 0x12\n" " e: 49 83 c3 02 add $0x2,%r11" @@ -838,8 +838,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 83 f8 64 cmp $0x64,%rax\n" " c: 7d 04 jge 0x12\n" " e: 49 83 c3 02 add $0x2,%r11" @@ -857,8 +857,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 83 f8 64 cmp $0x64,%rax\n" " c: 7d 04 jge 0x12\n" " e: 49 83 c3 02 add $0x2,%r11" @@ -876,8 +876,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 49 ba 00 00 00 00 01 movabs $0x100000000,%r10\n" " f: 00 00 00 \n" " 12: 4c 39 d0 cmp %r10,%rax\n" @@ -897,8 +897,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 49 ba 00 00 00 00 01 movabs $0x100000000,%r10\n" " f: 00 00 00 \n" " 12: 4c 39 d0 cmp %r10,%rax\n" @@ -918,8 +918,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 49 ba 00 00 00 00 01 movabs $0x100000000,%r10\n" " f: 00 00 00 \n" " 12: 4c 39 d0 cmp %r10,%rax\n" @@ -939,8 +939,8 @@ if_block_test_() -> ), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 49 ba 00 00 00 00 01 movabs $0x100000000,%r10\n" " f: 00 00 00 \n" " 12: 4c 39 d0 cmp %r10,%rax\n" @@ -970,8 +970,8 @@ if_else_block_test() -> Stream = ?BACKEND:stream(State3), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 38 mov 0x38(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 60 mov 0x60(%rdi),%r11\n" " 8: 48 83 f8 3b cmp $0x3b,%rax\n" " c: 75 06 jne 0x14\n" " e: 49 83 c3 02 add $0x2,%r11\n" @@ -989,7 +989,7 @@ shift_right_test_() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " 4: 48 c1 e8 03 shr $0x3,%rax" >>, jit_tests_common:assert_stream(x86_64, Dump, Stream) @@ -1002,7 +1002,7 @@ shift_right_test_() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " 4: 49 89 c3 mov %rax,%r11\n" " 7: 49 c1 eb 03 shr $0x3,%r11" >>, @@ -1017,7 +1017,7 @@ shift_left_test() -> Stream = ?BACKEND:stream(State2), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " 4: 48 c1 e0 03 shl $0x3,%rax" >>, jit_tests_common:assert_stream(x86_64, Dump, Stream). @@ -1130,7 +1130,7 @@ call_bif_with_large_literal_integer_test() -> " 36: 52 push %rdx\n" " 37: 48 c7 c6 00 00 00 00 mov $0x0,%rsi\n" " 3e: 48 c7 c2 01 00 00 00 mov $0x1,%rdx\n" - " 45: 48 8b 4f 30 mov 0x30(%rdi),%rcx\n" + " 45: 48 8b 4f 58 mov 0x58(%rdi),%rcx\n" " 49: 4d 89 d8 mov %r11,%r8\n" " 4c: ff d0 callq *%rax\n" " 4e: 5a pop %rdx\n" @@ -1141,7 +1141,7 @@ call_bif_with_large_literal_integer_test() -> " 56: 48 8b 42 30 mov 0x30(%rdx),%rax\n" " 5a: 48 c7 c2 5a 00 00 00 mov $0x5a,%rdx\n" " 61: ff e0 jmpq *%rax\n" - " 63: 48 89 47 30 mov %rax,0x30(%rdi)" + " 63: 48 89 47 58 mov %rax,0x58(%rdi)" >>, jit_tests_common:assert_stream(x86_64, Dump, Stream). @@ -1155,12 +1155,12 @@ get_list_test() -> ?BACKEND:assert_all_native_free(State5), Stream = ?BACKEND:stream(State5), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " 4: 48 83 e0 fc and $0xfffffffffffffffc,%rax\n" - " 8: 4c 8b 5f 28 mov 0x28(%rdi),%r11\n" + " 8: 4c 8b 5f 50 mov 0x50(%rdi),%r11\n" " c: 4c 8b 50 08 mov 0x8(%rax),%r10\n" " 10: 4d 89 53 08 mov %r10,0x8(%r11)\n" - " 14: 4c 8b 5f 28 mov 0x28(%rdi),%r11\n" + " 14: 4c 8b 5f 50 mov 0x50(%rdi),%r11\n" " 18: 4c 8b 10 mov (%rax),%r10\n" " 1b: 4d 89 13 mov %r10,(%r11)\n" >>, @@ -1205,7 +1205,7 @@ is_integer_test() -> Dump = << " 0: e9 ff ff ff ff jmpq 0x4\n" " 5: e9 36 01 00 00 jmpq 0x140\n" - " a: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " a: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " e: 49 89 c3 mov %rax,%r11\n" " 11: 41 80 e3 0f and $0xf,%r11b\n" " 15: 41 80 fb 0f cmp $0xf,%r11b\n" @@ -1262,7 +1262,7 @@ is_number_test() -> Dump = << " 0: e9 ff ff ff ff jmpq 0x4\n" " 5: e9 43 01 00 00 jmpq 0x14d\n" - " a: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " a: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " e: 49 89 c3 mov %rax,%r11\n" " 11: 41 80 e3 0f and $0xf,%r11b\n" " 15: 41 80 fb 0f cmp $0xf,%r11b\n" @@ -1304,7 +1304,7 @@ is_boolean_test() -> Dump = << " 0: e9 ff ff ff ff jmpq 0x4\n" " 5: e9 15 01 00 00 jmpq 0x11f\n" - " a: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " a: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " e: 48 83 f8 4b cmp $0x4b,%rax\n" " 12: 74 0b je 0x1f\n" " 14: 48 83 f8 0b cmp $0xb,%rax\n" @@ -1331,7 +1331,7 @@ call_ext_test() -> " 19: 8b 00 mov (%rax),%eax\n" " 1b: 48 c1 e0 18 shl $0x18,%rax\n" " 1f: 48 0d 1c 01 00 00 or $0x11c,%rax\n" - " 25: 48 89 87 b8 00 00 00 mov %rax,0xb8(%rdi)\n" + " 25: 48 89 87 e0 00 00 00 mov %rax,0xe0(%rdi)\n" " 2c: 48 8b 42 20 mov 0x20(%rdx),%rax\n" " 30: 48 c7 c2 02 00 00 00 mov $0x2,%rdx\n" " 37: 48 c7 c1 05 00 00 00 mov $0x5,%rcx\n" @@ -1376,7 +1376,7 @@ call_fun_test() -> " c: 48 89 46 08 mov %rax,0x8(%rsi)\n" " 10: 48 8b 42 10 mov 0x10(%rdx),%rax\n" " 14: ff e0 jmpq *%rax\n" - " 16: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " 16: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " 1a: 49 89 c3 mov %rax,%r11\n" " 1d: 4d 89 da mov %r11,%r10\n" " 20: 41 80 e2 03 and $0x3,%r10b\n" @@ -1402,7 +1402,7 @@ call_fun_test() -> " 75: 45 8b 1b mov (%r11),%r11d\n" " 78: 49 c1 e3 18 shl $0x18,%r11\n" " 7c: 49 81 cb 78 02 00 00 or $0x278,%r11\n" - " 83: 4c 89 9f b8 00 00 00 mov %r11,0xb8(%rdi)\n" + " 83: 4c 89 9f e0 00 00 00 mov %r11,0xe0(%rdi)\n" " 8a: 4c 8b 9a 00 01 00 00 mov 0x100(%rdx),%r11\n" " 91: 48 89 c2 mov %rax,%rdx\n" " 94: 48 c7 c1 00 00 00 00 mov $0x0,%rcx\n" @@ -1424,12 +1424,12 @@ move_to_vm_register_test_() -> [ ?_test(begin move_to_vm_register_test0(State0, 0, {x_reg, 0}, << - " 0: 48 83 67 30 00 andq $0x0,0x30(%rdi)" + " 0: 48 83 67 58 00 andq $0x0,0x58(%rdi)" >>) end), ?_test(begin move_to_vm_register_test0(State0, 0, {x_reg, extra}, << - " 0: 48 83 a7 b0 00 00 00 andq $0x0,0xb0(%rdi)\n" + " 0: 48 83 a7 d8 00 00 00 andq $0x0,0xd8(%rdi)\n" " 7: 00 " >>) end), @@ -1440,13 +1440,13 @@ move_to_vm_register_test_() -> end), ?_test(begin move_to_vm_register_test0(State0, 0, {y_reg, 2}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 48 83 60 10 00 andq $0x0,0x10(%rax)" >>) end), ?_test(begin move_to_vm_register_test0(State0, 0, {y_reg, 20}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 48 83 a0 a0 00 00 00 andq $0x0,0xa0(%rax)\n" " b: 00 " >>) @@ -1454,26 +1454,26 @@ move_to_vm_register_test_() -> %% Test: Immediate to x_reg ?_test(begin move_to_vm_register_test0(State0, 42, {x_reg, 0}, << - " 0: 48 c7 47 30 2a 00 00 movq $0x2a,0x30(%rdi)\n" + " 0: 48 c7 47 58 2a 00 00 movq $0x2a,0x58(%rdi)\n" " 7: 00 " >>) end), ?_test(begin move_to_vm_register_test0(State0, 42, {x_reg, extra}, << - " 0: 48 c7 87 b0 00 00 00 movq $0x2a,0xb0(%rdi)\n" + " 0: 48 c7 87 d8 00 00 00 movq $0x2a,0xd8(%rdi)\n" " 7: 2a 00 00 00 " >>) end), ?_test(begin move_to_vm_register_test0(State0, 42, {y_reg, 2}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 48 c7 40 10 2a 00 00 movq $0x2a,0x10(%rax)\n" " b: 00 " >>) end), ?_test(begin move_to_vm_register_test0(State0, 42, {y_reg, 20}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 48 c7 80 a0 00 00 00 movq $0x2a,0xa0(%rax)\n" " b: 2a 00 00 00 " >>) @@ -1488,14 +1488,14 @@ move_to_vm_register_test_() -> %% Test: x_reg to x_reg ?_test(begin move_to_vm_register_test0(State0, {x_reg, 1}, {x_reg, 2}, << - " 0: 48 8b 47 38 mov 0x38(%rdi),%rax\n" - " 4: 48 89 47 40 mov %rax,0x40(%rdi)" + " 0: 48 8b 47 60 mov 0x60(%rdi),%rax\n" + " 4: 48 89 47 68 mov %rax,0x68(%rdi)" >>) end), %% Test: x_reg to ptr ?_test(begin move_to_vm_register_test0(State0, {x_reg, 1}, {ptr, r8}, << - " 0: 48 8b 47 38 mov 0x38(%rdi),%rax\n" + " 0: 48 8b 47 60 mov 0x60(%rdi),%rax\n" " 4: 49 89 00 mov %rax,(%r8)" >>) end), @@ -1503,42 +1503,42 @@ move_to_vm_register_test_() -> ?_test(begin move_to_vm_register_test0(State0, {ptr, r9}, {x_reg, 3}, << " 0: 49 8b 01 mov (%r9),%rax\n" - " 3: 48 89 47 48 mov %rax,0x48(%rdi)" + " 3: 48 89 47 70 mov %rax,0x70(%rdi)" >>) end), %% Test: x_reg to y_reg ?_test(begin move_to_vm_register_test0(State0, {x_reg, 0}, {y_reg, 1}, << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" - " 4: 4c 8b 5f 28 mov 0x28(%rdi),%r11\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" + " 4: 4c 8b 5f 50 mov 0x50(%rdi),%r11\n" " 8: 49 89 43 08 mov %rax,0x8(%r11)" >>) end), %% Test: y_reg to x_reg ?_test(begin move_to_vm_register_test0(State0, {y_reg, 0}, {x_reg, 3}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 48 8b 00 mov (%rax),%rax\n" - " 7: 48 89 47 48 mov %rax,0x48(%rdi)" + " 7: 48 89 47 70 mov %rax,0x70(%rdi)" >>) end), %% Test: y_reg to y_reg ?_test(begin move_to_vm_register_test0(State0, {y_reg, 1}, {x_reg, 3}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 48 8b 40 08 mov 0x8(%rax),%rax\n" - " 8: 48 89 47 48 mov %rax,0x48(%rdi)" + " 8: 48 89 47 70 mov %rax,0x70(%rdi)" >>) end), %% Test: Native register to x_reg ?_test(begin move_to_vm_register_test0(State0, rax, {x_reg, 0}, << - " 0: 48 89 47 30 mov %rax,0x30(%rdi)" + " 0: 48 89 47 58 mov %rax,0x58(%rdi)" >>) end), ?_test(begin move_to_vm_register_test0(State0, rax, {x_reg, extra}, << - " 0: 48 89 87 b0 00 00 00 mov %rax,0xb0(%rdi)" + " 0: 48 89 87 d8 00 00 00 mov %rax,0xd8(%rdi)" >>) end), %% Test: Atom register to ptr @@ -1550,7 +1550,7 @@ move_to_vm_register_test_() -> %% Test: Native register to y_reg ?_test(begin move_to_vm_register_test0(State0, rax, {y_reg, 0}, << - " 0:\t48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0:\t48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4:\t48 89 00 mov %rax,(%rax)" >>) end), @@ -1559,19 +1559,19 @@ move_to_vm_register_test_() -> move_to_vm_register_test0(State0, 16#123456789abcdef0, {x_reg, 0}, << " 0: 48 b8 f0 de bc 9a 78 movabs $0x123456789abcdef0,%rax\n" " 7: 56 34 12 \n" - " a: 48 89 47 30 mov %rax,0x30(%rdi)" + " a: 48 89 47 58 mov %rax,0x58(%rdi)" >>) end), ?_test(begin move_to_vm_register_test0(State0, 16#123456789abcdef0, {x_reg, extra}, << " 0: 48 b8 f0 de bc 9a 78 movabs $0x123456789abcdef0,%rax\n" " 7: 56 34 12 \n" - " a: 48 89 87 b0 00 00 00 mov %rax,0xb0(%rdi)" + " a: 48 89 87 d8 00 00 00 mov %rax,0xd8(%rdi)" >>) end), ?_test(begin move_to_vm_register_test0(State0, 16#123456789abcdef0, {y_reg, 2}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 49 bb f0 de bc 9a 78 movabs $0x123456789abcdef0,%r11\n" " b: 56 34 12 \n" " e: 4c 89 58 10 mov %r11,0x10(%rax)" @@ -1579,7 +1579,7 @@ move_to_vm_register_test_() -> end), ?_test(begin move_to_vm_register_test0(State0, 16#123456789abcdef0, {y_reg, 20}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 49 bb f0 de bc 9a 78 movabs $0x123456789abcdef0,%r11\n" " b: 56 34 12 \n" " e: 4c 89 98 a0 00 00 00 mov %r11,0xa0(%rax)" @@ -1596,30 +1596,30 @@ move_to_vm_register_test_() -> %% Test: x_reg to y_reg (high index) ?_test(begin move_to_vm_register_test0(State0, {x_reg, 15}, {y_reg, 31}, << - " 0: 48 8b 87 a8 00 00 00 mov 0xa8(%rdi),%rax\n" - " 7: 4c 8b 5f 28 mov 0x28(%rdi),%r11\n" + " 0: 48 8b 87 d0 00 00 00 mov 0xd0(%rdi),%rax\n" + " 7: 4c 8b 5f 50 mov 0x50(%rdi),%r11\n" " b: 49 89 83 f8 00 00 00 mov %rax,0xf8(%r11)" >>) end), ?_test(begin move_to_vm_register_test0(State0, {x_reg, extra}, {y_reg, 31}, << - " 0: 48 8b 87 b0 00 00 00 mov 0xb0(%rdi),%rax\n" - " 7: 4c 8b 5f 28 mov 0x28(%rdi),%r11\n" + " 0: 48 8b 87 d8 00 00 00 mov 0xd8(%rdi),%rax\n" + " 7: 4c 8b 5f 50 mov 0x50(%rdi),%r11\n" " b: 49 89 83 f8 00 00 00 mov %rax,0xf8(%r11)" >>) end), %% Test: y_reg to x_reg (high index) ?_test(begin move_to_vm_register_test0(State0, {y_reg, 31}, {x_reg, 15}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 48 8b 80 f8 00 00 00 mov 0xf8(%rax),%rax\n" - " b: 48 89 87 a8 00 00 00 mov %rax,0xa8(%rdi)" + " b: 48 89 87 d0 00 00 00 mov %rax,0xd0(%rdi)" >>) end), %% Test: Negative immediate to x_reg ?_test(begin move_to_vm_register_test0(State0, -1, {x_reg, 0}, << - " 0: 48 c7 47 30 ff ff ff movq $0xffffffffffffffff,0x30(%rdi)\n" + " 0: 48 c7 47 58 ff ff ff movq $0xffffffffffffffff,0x58(%rdi)\n" " 7: ff " >>) end), @@ -1631,9 +1631,9 @@ move_to_vm_register_test_() -> ), Stream = ?BACKEND:stream(State2), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " 4: 48 8b 40 08 mov 0x8(%rax),%rax\n" - " 8: 4c 8b 9f c0 00 00 00 mov 0xc0(%rdi),%r11\n" + " 8: 4c 8b 9f e8 00 00 00 mov 0xe8(%rdi),%r11\n" " f: 49 89 43 18 mov %rax,0x18(%r11)" >>, jit_tests_common:assert_stream(x86_64, Dump, Stream) @@ -1657,7 +1657,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, r8, 2, {x_reg, 0}, << " 0: 49 8b 40 10 mov 0x10(%r8),%rax\n" - " 4: 48 89 47 30 mov %rax,0x30(%rdi)" + " 4: 48 89 47 58 mov %rax,0x58(%rdi)" >>) end), %% move_array_element: reg[x] to ptr @@ -1670,7 +1670,7 @@ move_array_element_test_() -> %% move_array_element: reg[x] to y_reg ?_test(begin move_array_element_test0(State0, r8, 1, {y_reg, 2}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 4d 8b 58 08 mov 0x8(%r8),%r11\n" " 8: 4c 89 58 10 mov %r11,0x10(%rax)" >>) @@ -1684,7 +1684,7 @@ move_array_element_test_() -> %% move_array_element: reg[x] to y_reg (high index) ?_test(begin move_array_element_test0(State0, r8, 7, {y_reg, 31}, << - " 0: 48 8b 47 28 mov 0x28(%rdi),%rax\n" + " 0: 48 8b 47 50 mov 0x50(%rdi),%rax\n" " 4: 4d 8b 58 38 mov 0x38(%r8),%r11\n" " 8: 4c 89 98 f8 00 00 00 mov %r11,0xf8(%rax)" >>) @@ -1693,7 +1693,7 @@ move_array_element_test_() -> ?_test(begin move_array_element_test0(State0, r8, 7, {x_reg, 15}, << " 0: 49 8b 40 38 mov 0x38(%r8),%rax\n" - " 4: 48 89 87 a8 00 00 00 mov %rax,0xa8(%rdi)" + " 4: 48 89 87 d0 00 00 00 mov %rax,0xd0(%rdi)" >>) end), %% move_array_element: reg_x[reg_y] to x_reg @@ -1704,7 +1704,7 @@ move_array_element_test_() -> " 4: 48 c1 e0 03 shl $0x3,%rax\n" " 8: 4c 01 c0 add %r8,%rax\n" " b: 48 8b 00 mov (%rax),%rax\n" - " e: 48 89 47 40 mov %rax,0x40(%rdi)\n" + " e: 48 89 47 68 mov %rax,0x68(%rdi)\n" >>) end), %% move_array_element: reg_x[reg_y] to pointer (large x reg) @@ -1723,7 +1723,7 @@ move_array_element_test_() -> {State1, Reg} = ?BACKEND:get_array_element(State0, r8, 4), move_array_element_test0(State1, r8, {free, Reg}, {y_reg, 31}, << " 0: 49 8b 40 20 mov 0x20(%r8),%rax\n" - " 4: 4c 8b 5f 28 mov 0x28(%rdi),%r11\n" + " 4: 4c 8b 5f 50 mov 0x50(%rdi),%r11\n" " 8: 48 c1 e0 03 shl $0x3,%rax\n" " c: 4c 01 c0 add %r8,%rax\n" " f: 48 8b 00 mov (%rax),%rax\n" @@ -1765,7 +1765,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, r8, 2), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " 4: 49 89 40 10 mov %rax,0x10(%r8)" >>, jit_tests_common:assert_stream(x86_64, Dump, Stream) @@ -1775,7 +1775,7 @@ move_to_array_element_test_() -> State1 = ?BACKEND:move_to_array_element(State0, {x_reg, 0}, r8, 2, 1), Stream = ?BACKEND:stream(State1), Dump = << - " 0: 48 8b 47 30 mov 0x30(%rdi),%rax\n" + " 0: 48 8b 47 58 mov 0x58(%rdi),%rax\n" " 4: 49 89 40 18 mov %rax,0x18(%r8)" >>, jit_tests_common:assert_stream(x86_64, Dump, Stream) diff --git a/tests/test-heap.c b/tests/test-heap.c index 2378bce25b..bcc08188e1 100644 --- a/tests/test-heap.c +++ b/tests/test-heap.c @@ -108,6 +108,265 @@ void test_gc_ref_count(void) assert(list_is_empty(refc_binaries)); } +void test_generational_gc_basic(void) +{ + GlobalContext *glb = globalcontext_new(); + Context *ctx = context_new(glb); + ctx->heap_growth_strategy = MinimumHeapGrowth; + + // Allocate a tuple and GC to set HWM + enum MemoryGCResult res = memory_ensure_free(ctx, TUPLE_SIZE(2)); + assert(res == MEMORY_GC_OK); + + term tuple1 = term_alloc_tuple(2, &ctx->heap); + term_put_tuple_element(tuple1, 0, term_from_int(42)); + term_put_tuple_element(tuple1, 1, term_from_int(43)); + + term roots[2]; + roots[0] = tuple1; + roots[1] = term_nil(); + + // First GC sets HWM + res = memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 2, roots, MEMORY_CAN_SHRINK); + assert(res == MEMORY_GC_OK); + assert(ctx->heap.high_water_mark != NULL); + tuple1 = roots[0]; + assert(term_get_tuple_arity(tuple1) == 2); + assert(term_get_tuple_element(tuple1, 0) == term_from_int(42)); + assert(term_get_tuple_element(tuple1, 1) == term_from_int(43)); + + // Allocate more data above HWM + term tuple2 = term_alloc_tuple(2, &ctx->heap); + term_put_tuple_element(tuple2, 0, term_from_int(100)); + term_put_tuple_element(tuple2, 1, tuple1); + roots[1] = tuple2; + + // Second GC should be minor (HWM is set, gc_count < fullsweep_after) + res = memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 2, roots, MEMORY_CAN_SHRINK); + assert(res == MEMORY_GC_OK); + tuple1 = roots[0]; + tuple2 = roots[1]; + + // Verify data survived + assert(term_get_tuple_arity(tuple1) == 2); + assert(term_get_tuple_element(tuple1, 0) == term_from_int(42)); + assert(term_get_tuple_element(tuple1, 1) == term_from_int(43)); + assert(term_get_tuple_arity(tuple2) == 2); + assert(term_get_tuple_element(tuple2, 0) == term_from_int(100)); + assert(term_get_tuple_element(tuple2, 1) == tuple1); + + context_destroy(ctx); + globalcontext_destroy(glb); +} + +void test_generational_gc_promotion(void) +{ + GlobalContext *glb = globalcontext_new(); + Context *ctx = context_new(glb); + ctx->heap_growth_strategy = MinimumHeapGrowth; + + // Allocate and GC to promote data to mature + enum MemoryGCResult res = memory_ensure_free(ctx, TUPLE_SIZE(2)); + assert(res == MEMORY_GC_OK); + + term tuple1 = term_alloc_tuple(2, &ctx->heap); + term_put_tuple_element(tuple1, 0, term_from_int(1)); + term_put_tuple_element(tuple1, 1, term_from_int(2)); + + term roots[1]; + roots[0] = tuple1; + + // First GC: sets HWM + res = memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, roots, MEMORY_CAN_SHRINK); + assert(res == MEMORY_GC_OK); + tuple1 = roots[0]; + + // Allocate young data + term tuple2 = term_alloc_tuple(2, &ctx->heap); + term_put_tuple_element(tuple2, 0, term_from_int(3)); + term_put_tuple_element(tuple2, 1, tuple1); + roots[0] = tuple2; + + // Second GC: minor GC should promote tuple1 to old heap + res = memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, roots, MEMORY_NO_SHRINK); + assert(res == MEMORY_GC_OK); + assert(ctx->heap.old_heap_start != NULL); + assert(ctx->heap.old_heap_ptr > ctx->heap.old_heap_start); + + // Verify data is intact + tuple2 = roots[0]; + assert(term_get_tuple_element(tuple2, 0) == term_from_int(3)); + tuple1 = term_get_tuple_element(tuple2, 1); + assert(term_get_tuple_element(tuple1, 0) == term_from_int(1)); + assert(term_get_tuple_element(tuple1, 1) == term_from_int(2)); + + context_destroy(ctx); + globalcontext_destroy(glb); +} + +void test_generational_gc_major_on_force_shrink(void) +{ + GlobalContext *glb = globalcontext_new(); + Context *ctx = context_new(glb); + ctx->heap_growth_strategy = MinimumHeapGrowth; + + // Build up an old heap + enum MemoryGCResult res = memory_ensure_free(ctx, TUPLE_SIZE(2)); + assert(res == MEMORY_GC_OK); + + term tuple1 = term_alloc_tuple(2, &ctx->heap); + term_put_tuple_element(tuple1, 0, term_from_int(1)); + term_put_tuple_element(tuple1, 1, term_from_int(2)); + + term roots[1]; + roots[0] = tuple1; + + // First GC: sets HWM + res = memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, roots, MEMORY_CAN_SHRINK); + assert(res == MEMORY_GC_OK); + tuple1 = roots[0]; + + // Allocate young, then minor GC to promote + term tuple2 = term_alloc_tuple(2, &ctx->heap); + term_put_tuple_element(tuple2, 0, term_from_int(3)); + term_put_tuple_element(tuple2, 1, tuple1); + roots[0] = tuple2; + + res = memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, roots, MEMORY_NO_SHRINK); + assert(res == MEMORY_GC_OK); + assert(ctx->heap.old_heap_start != NULL); + + // FORCE_SHRINK triggers major GC which frees old heap + res = memory_ensure_free_with_roots(ctx, 0, 1, roots, MEMORY_FORCE_SHRINK); + assert(res == MEMORY_GC_OK); + assert(ctx->heap.old_heap_start == NULL); + + // Data should still be intact + tuple2 = roots[0]; + assert(term_get_tuple_element(tuple2, 0) == term_from_int(3)); + tuple1 = term_get_tuple_element(tuple2, 1); + assert(term_get_tuple_element(tuple1, 0) == term_from_int(1)); + assert(term_get_tuple_element(tuple1, 1) == term_from_int(2)); + + context_destroy(ctx); + globalcontext_destroy(glb); +} + +void test_generational_gc_mso(void) +{ + GlobalContext *glb = globalcontext_new(); + Context *ctx = context_new(glb); + ctx->heap_growth_strategy = MinimumHeapGrowth; + + struct ListHead *refc_binaries = synclist_nolock(&glb->refc_binaries); + assert(list_is_empty(refc_binaries)); + + // Allocate a refc binary and GC to set HWM + enum MemoryGCResult res = memory_ensure_free(ctx, TERM_BOXED_REFC_BINARY_SIZE + TUPLE_SIZE(1)); + assert(res == MEMORY_GC_OK); + + term refc = term_alloc_refc_binary(42, false, &ctx->heap, glb); + struct RefcBinary *refc_ptr = term_refc_binary_ptr(refc); + assert(refc_ptr->ref_count == 1); + + term tuple1 = term_alloc_tuple(1, &ctx->heap); + term_put_tuple_element(tuple1, 0, refc); + + term roots[2]; + roots[0] = tuple1; + roots[1] = term_nil(); + + // First GC: sets HWM, tuple1+refc are below HWM after this + res = memory_ensure_free_with_roots(ctx, TERM_BOXED_REFC_BINARY_SIZE + TUPLE_SIZE(2), 2, roots, MEMORY_CAN_SHRINK); + assert(res == MEMORY_GC_OK); + assert(refc_ptr->ref_count == 1); + tuple1 = roots[0]; + + // Allocate a second refc binary (young) and a tuple referencing both + term refc2 = term_alloc_refc_binary(43, false, &ctx->heap, glb); + struct RefcBinary *refc2_ptr = term_refc_binary_ptr(refc2); + + term tuple2 = term_alloc_tuple(2, &ctx->heap); + term_put_tuple_element(tuple2, 0, refc2); + term_put_tuple_element(tuple2, 1, tuple1); + roots[0] = tuple2; + roots[1] = term_nil(); + + // Minor GC: refc (via tuple1) should be promoted to old heap, refc2 stays young + res = memory_ensure_free_with_roots(ctx, TERM_BOXED_REFC_BINARY_SIZE + TUPLE_SIZE(2), 2, roots, MEMORY_NO_SHRINK); + assert(res == MEMORY_GC_OK); + assert(refc_ptr->ref_count == 1); + assert(refc2_ptr->ref_count == 1); + assert(ctx->heap.old_heap_start != NULL); + + // Drop refc2: keep only tuple1 (from old heap) via a new young tuple + tuple2 = roots[0]; + tuple1 = term_get_tuple_element(tuple2, 1); + roots[0] = tuple1; + roots[1] = term_nil(); + res = memory_ensure_free_with_roots(ctx, 1, 2, roots, MEMORY_NO_SHRINK); + assert(res == MEMORY_GC_OK); + + // refc should still be alive in old heap + assert(refc_ptr->ref_count == 1); + + // Major GC: drop everything + roots[0] = term_nil(); + res = memory_ensure_free_with_roots(ctx, 0, 1, roots, MEMORY_FORCE_SHRINK); + assert(res == MEMORY_GC_OK); + + refc_binaries = synclist_nolock(&glb->refc_binaries); + assert(list_is_empty(refc_binaries)); + + context_destroy(ctx); + globalcontext_destroy(glb); +} + +void test_fullsweep_after_zero(void) +{ + GlobalContext *glb = globalcontext_new(); + Context *ctx = context_new(glb); + ctx->heap_growth_strategy = MinimumHeapGrowth; + ctx->fullsweep_after = 0; + + // Allocate and GC + enum MemoryGCResult res = memory_ensure_free(ctx, TUPLE_SIZE(2)); + assert(res == MEMORY_GC_OK); + + term tuple1 = term_alloc_tuple(2, &ctx->heap); + term_put_tuple_element(tuple1, 0, term_from_int(42)); + term_put_tuple_element(tuple1, 1, term_from_int(43)); + + term roots[1]; + roots[0] = tuple1; + + // With fullsweep_after=0, GC should always be full, never creating old heap + res = memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, roots, MEMORY_CAN_SHRINK); + assert(res == MEMORY_GC_OK); + assert(ctx->heap.old_heap_start == NULL); + + tuple1 = roots[0]; + term tuple2 = term_alloc_tuple(2, &ctx->heap); + term_put_tuple_element(tuple2, 0, term_from_int(100)); + term_put_tuple_element(tuple2, 1, tuple1); + roots[0] = tuple2; + + // Second GC: still full sweep + res = memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, roots, MEMORY_CAN_SHRINK); + assert(res == MEMORY_GC_OK); + assert(ctx->heap.old_heap_start == NULL); + + // Verify data intact + tuple2 = roots[0]; + assert(term_get_tuple_element(tuple2, 0) == term_from_int(100)); + tuple1 = term_get_tuple_element(tuple2, 1); + assert(term_get_tuple_element(tuple1, 0) == term_from_int(42)); + assert(term_get_tuple_element(tuple1, 1) == term_from_int(43)); + + context_destroy(ctx); + globalcontext_destroy(glb); +} + int main(int argc, char **argv) { UNUSED(argc); @@ -115,6 +374,11 @@ int main(int argc, char **argv) test_memory_ensure_free(); test_gc_ref_count(); + test_generational_gc_basic(); + test_generational_gc_promotion(); + test_generational_gc_major_on_force_shrink(); + test_generational_gc_mso(); + test_fullsweep_after_zero(); return EXIT_SUCCESS; } diff --git a/tests/test.c b/tests/test.c index 8ed932e7fc..75d7fca0d1 100644 --- a/tests/test.c +++ b/tests/test.c @@ -581,6 +581,7 @@ struct Test tests[] = { TEST_CASE_EXPECTED(link_throw, 1), TEST_CASE_EXPECTED(unlink_error, 1), TEST_CASE(trap_exit_flag), + TEST_CASE(test_process_flag_fullsweep_after), TEST_CASE(test_exit1), TEST_CASE(test_exit2), TEST_CASE_COND(test_stacktrace, 0, SKIP_STACKTRACES),