diff --git a/.gitignore b/.gitignore index 4481f7683..222e7fa1e 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,7 @@ demos/curl/* !demos/curl/curl_client.c !demos/curl/curl_config.h !demos/curl/curl_syslink.h +!demos/curl/_mingw.h # stb -- a collection of single-file public-domain headers. # `setup.py` pulls the upstream archive from the vendor-deps # release and drops a curated set of headers into `demos/stb/`; diff --git a/Cargo.lock b/Cargo.lock index 31e32e57e..0ccc8659a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "badc" -version = "0.1.1" +version = "0.1.2" dependencies = [ "hashbrown", "libm", diff --git a/Cargo.toml b/Cargo.toml index 64a7ddb52..46aa8a094 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "badc" -version = "0.1.1" +version = "0.1.2" edition = "2024" license = "MIT" description = "A quick, slim cross-platform C compiler (also a compiler-as-library) (C99, C11, and more) with a JIT and native ELF / PE / Mach-O backends." diff --git a/demos/curl/_mingw.h b/demos/curl/_mingw.h new file mode 100644 index 000000000..6074c9db8 --- /dev/null +++ b/demos/curl/_mingw.h @@ -0,0 +1,6 @@ +/* Demo-local <_mingw.h>. MinGW's internal glue header; the demo + * defines __MINGW32__ only to select curl's MinGW code paths, and the + * bundled headers already carry the referenced surface. */ +#ifndef CURL_DEMO_MINGW_H +#define CURL_DEMO_MINGW_H +#endif diff --git a/demos/raylib/include/X11/Xresource.h b/demos/raylib/include/X11/Xresource.h new file mode 100644 index 000000000..498a9f667 --- /dev/null +++ b/demos/raylib/include/X11/Xresource.h @@ -0,0 +1,10 @@ +/* Xrm (resource manager) surface for the RGFW desktop backend. This + * shim tree keeps the Xrm types and prototypes in Xutil.h; the system + * header split is not mirrored here. */ +#ifndef _X11_XRESOURCE_H_ +#define _X11_XRESOURCE_H_ + +#include +#include + +#endif diff --git a/demos/raylib/include/minwinbase.h b/demos/raylib/include/minwinbase.h new file mode 100644 index 000000000..1e19cdc35 --- /dev/null +++ b/demos/raylib/include/minwinbase.h @@ -0,0 +1,6 @@ +/* Demo-local . The Windows SDK sub-header split is not + * mirrored here; the bundled carries the surface. */ +#ifndef RGFW_DEMO_MINWINBASE_H +#define RGFW_DEMO_MINWINBASE_H +#include +#endif diff --git a/demos/raylib/include/minwindef.h b/demos/raylib/include/minwindef.h new file mode 100644 index 000000000..3f7a5dbec --- /dev/null +++ b/demos/raylib/include/minwindef.h @@ -0,0 +1,6 @@ +/* Demo-local . The Windows SDK sub-header split is not + * mirrored here; the bundled carries the surface. */ +#ifndef RGFW_DEMO_MINWINDEF_H +#define RGFW_DEMO_MINWINDEF_H +#include +#endif diff --git a/demos/raylib/include/sdkddkver.h b/demos/raylib/include/sdkddkver.h new file mode 100644 index 000000000..aa685d684 --- /dev/null +++ b/demos/raylib/include/sdkddkver.h @@ -0,0 +1,6 @@ +/* Demo-local . The Windows SDK sub-header split is not + * mirrored here; the bundled carries the surface. */ +#ifndef RGFW_DEMO_SDKDDKVER_H +#define RGFW_DEMO_SDKDDKVER_H +#include +#endif diff --git a/demos/sqlite3/smoke.py b/demos/sqlite3/smoke.py index 9d0e49e17..25cc10dcf 100755 --- a/demos/sqlite3/smoke.py +++ b/demos/sqlite3/smoke.py @@ -92,6 +92,10 @@ def build_shell(badc: Path, combined: bytes, out_path: Path, optimize: bool) -> cmd: list[str | os.PathLike[str]] = [str(badc)] if optimize: cmd.append("-O") + # stdin input has no source directory, so shell.c's quoted + # `#include "sqlite3.h"` needs the demo directory on the search + # path (gcc would need the same -I for a stdin pipeline). + cmd += ["-I", str(Path(__file__).resolve().parent)] cmd += ["-include", "msvc_compat.h", "-", "-o", str(out_path)] cmd += [f"-D{d}" for d in BUILD_DEFINES] subprocess.run(cmd, input=combined, check=True) diff --git a/headers/include/AvailabilityMacros.h b/headers/include/AvailabilityMacros.h new file mode 100644 index 000000000..d28233877 --- /dev/null +++ b/headers/include/AvailabilityMacros.h @@ -0,0 +1,54 @@ +// AvailabilityMacros.h -- macOS version gates. Version constants and +// the MIN_REQUIRED/MAX_ALLOWED derivation follow the SDK header; the +// compiler predefines __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +// to match the LC_BUILD_VERSION minimum it stamps. + +#pragma once + +#ifdef __APPLE__ + +#include + +// Encoded MMmm(pp): 10.x as 10x0 through 10.9, 10MM00/MM0000 after. +// Values from the SDK's . +#define MAC_OS_X_VERSION_10_0 1000 +#define MAC_OS_X_VERSION_10_1 1010 +#define MAC_OS_X_VERSION_10_2 1020 +#define MAC_OS_X_VERSION_10_3 1030 +#define MAC_OS_X_VERSION_10_4 1040 +#define MAC_OS_X_VERSION_10_5 1050 +#define MAC_OS_X_VERSION_10_6 1060 +#define MAC_OS_X_VERSION_10_7 1070 +#define MAC_OS_X_VERSION_10_8 1080 +#define MAC_OS_X_VERSION_10_9 1090 +#define MAC_OS_X_VERSION_10_10 101000 +#define MAC_OS_X_VERSION_10_11 101100 +#define MAC_OS_X_VERSION_10_12 101200 +#define MAC_OS_X_VERSION_10_13 101300 +#define MAC_OS_X_VERSION_10_14 101400 +#define MAC_OS_X_VERSION_10_15 101500 +#define MAC_OS_X_VERSION_10_16 101600 +#define MAC_OS_VERSION_11_0 110000 +#define MAC_OS_VERSION_12_0 120000 +#define MAC_OS_VERSION_13_0 130000 +#define MAC_OS_VERSION_14_0 140000 + +#ifndef MAC_OS_X_VERSION_MIN_REQUIRED +#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +#define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +#else +#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_5 +#endif +#endif + +#ifndef MAC_OS_X_VERSION_MAX_ALLOWED +#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_VERSION_14_0 +#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_MIN_REQUIRED +#else +#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_VERSION_14_0 +#endif +#endif + +// TODO: AVAILABLE_MAC_OS_X_VERSION_* attribute decorators. + +#endif diff --git a/headers/include/CoreFoundation/CoreFoundation.h b/headers/include/CoreFoundation/CoreFoundation.h new file mode 100644 index 000000000..49ea993c2 --- /dev/null +++ b/headers/include/CoreFoundation/CoreFoundation.h @@ -0,0 +1,24 @@ +/* Minimal Apple CoreFoundation surface (). +** Opaque CF*Ref handles are pointers; libSystem provides the runtime. +** Only the types and calls the bundled demos reference are declared. */ +#pragma once + +#ifdef __APPLE__ + +typedef const void *CFTypeRef; +typedef struct __CFString *CFStringRef; +typedef struct __CFDictionary *CFDictionaryRef; +typedef struct __CFAllocator *CFAllocatorRef; +typedef long CFIndex; +typedef unsigned long CFTypeID; + +#pragma dylib(corefoundation, "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation") +#pragma binding(corefoundation::CFRelease, "_CFRelease") +#pragma binding(corefoundation::CFRetain, "_CFRetain") +#pragma binding(corefoundation::CFGetTypeID, "_CFGetTypeID") + +void CFRelease(CFTypeRef cf); +CFTypeRef CFRetain(CFTypeRef cf); +CFTypeID CFGetTypeID(CFTypeRef cf); + +#endif diff --git a/headers/include/SystemConfiguration/SCDynamicStoreCopySpecific.h b/headers/include/SystemConfiguration/SCDynamicStoreCopySpecific.h new file mode 100644 index 000000000..d946acd61 --- /dev/null +++ b/headers/include/SystemConfiguration/SCDynamicStoreCopySpecific.h @@ -0,0 +1,17 @@ +/* Apple SystemConfiguration dynamic-store queries +** (). Declares the +** subset the bundled demos reach for; the framework supplies the code. */ +#pragma once + +#ifdef __APPLE__ + +#include + +typedef struct __SCDynamicStore *SCDynamicStoreRef; + +#pragma dylib(systemconfiguration, "/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration") +#pragma binding(systemconfiguration::SCDynamicStoreCopyProxies, "_SCDynamicStoreCopyProxies") + +CFDictionaryRef SCDynamicStoreCopyProxies(SCDynamicStoreRef store); + +#endif diff --git a/headers/include/TargetConditionals.h b/headers/include/TargetConditionals.h new file mode 100644 index 000000000..d96886b60 --- /dev/null +++ b/headers/include/TargetConditionals.h @@ -0,0 +1,44 @@ +/* Apple platform-dispatch macros. The SDK header classifies the +** compilation target; code gates on TARGET_OS_* after including it +** unconditionally under __APPLE__. badc targets macOS only, so the +** macOS values are fixed; every other platform macro is 0. On +** non-Apple targets everything is 0, matching code that includes +** this header without an __APPLE__ guard. */ +#pragma once + +#ifdef __APPLE__ +#define TARGET_OS_MAC 1 +#define TARGET_OS_OSX 1 +#else +#define TARGET_OS_MAC 0 +#define TARGET_OS_OSX 0 +#endif +#define TARGET_OS_WIN32 0 +#define TARGET_OS_WINDOWS 0 +#define TARGET_OS_UNIX 0 +#define TARGET_OS_LINUX 0 +#define TARGET_OS_IPHONE 0 +#define TARGET_OS_IOS 0 +#define TARGET_OS_WATCH 0 +#define TARGET_OS_TV 0 +#define TARGET_OS_VISION 0 +#define TARGET_OS_SIMULATOR 0 +#define TARGET_OS_EMBEDDED 0 +#define TARGET_OS_MACCATALYST 0 +#define TARGET_OS_DRIVERKIT 0 + +#ifdef __aarch64__ +#define TARGET_CPU_ARM64 1 +#define TARGET_CPU_X86_64 0 +#else +#define TARGET_CPU_ARM64 0 +#define TARGET_CPU_X86_64 1 +#endif +#define TARGET_CPU_ARM 0 +#define TARGET_CPU_X86 0 +#define TARGET_CPU_PPC 0 +#define TARGET_CPU_PPC64 0 + +#define TARGET_RT_LITTLE_ENDIAN 1 +#define TARGET_RT_BIG_ENDIAN 0 +#define TARGET_RT_64_BIT 1 diff --git a/headers/include/aclapi.h b/headers/include/aclapi.h new file mode 100644 index 000000000..c3ea72f71 --- /dev/null +++ b/headers/include/aclapi.h @@ -0,0 +1,7 @@ +// aclapi.h -- access-control-list editing (advapi32). Consumers so far +// reach only the security types. TODO: SetEntriesInAclW, +// GetNamedSecurityInfoW, SetNamedSecurityInfoW. + +#pragma once + +#include diff --git a/headers/include/bcrypt.h b/headers/include/bcrypt.h new file mode 100644 index 000000000..d4c2e7b1b --- /dev/null +++ b/headers/include/bcrypt.h @@ -0,0 +1,6 @@ +/* Windows CNG (). The bound surface lives in the bundled +** ; this header resolves the SDK's include split. */ +#pragma once +#ifdef _WIN32 +#include +#endif diff --git a/headers/include/conio.h b/headers/include/conio.h index c2442b70d..c8a4ad798 100644 --- a/headers/include/conio.h +++ b/headers/include/conio.h @@ -1,7 +1,7 @@ #pragma once -// MSVC CRT direct-console I/O (`_getch` family) plus the `_locking` -// mode constants. These entry points live in msvcrt.dll; the -// underscore-prefixed names are the spellings the CRT exports. +// MSVC CRT direct-console I/O (`_getch` family). These entry points +// live in msvcrt.dll; the underscore-prefixed names are the spellings +// the CRT exports. #ifdef _WIN32 // `wchar_t` () and `wint_t` () back the wide // console entry points below. @@ -30,11 +30,7 @@ int _ungetch(int c); wint_t _ungetwch(wint_t c); int _kbhit(void); -// `_locking` mode argument (MSVC ). Values pinned by -// the CRT. -#define _LK_UNLCK 0 -#define _LK_LOCK 1 -#define _LK_NBLCK 2 -#define _LK_RLCK 3 -#define _LK_NBRLCK 4 +// Callers historically reached the `_locking` mode constants through +// this header; they live in their CRT home now. +#include #endif diff --git a/headers/include/crt_externs.h b/headers/include/crt_externs.h new file mode 100644 index 000000000..9b50aca62 --- /dev/null +++ b/headers/include/crt_externs.h @@ -0,0 +1,19 @@ +/* Apple : accessors for the process argument and +** environment vectors, which a Mach-O image reaches through +** libSystem rather than as data symbols. */ +#pragma once + +#ifdef __APPLE__ + +#pragma dylib(libc, "/usr/lib/libSystem.B.dylib") +#pragma binding(libc::_NSGetEnviron, "__NSGetEnviron") +#pragma binding(libc::_NSGetArgc, "__NSGetArgc") +#pragma binding(libc::_NSGetArgv, "__NSGetArgv") +#pragma binding(libc::_NSGetProgname, "__NSGetProgname") + +char ***_NSGetEnviron(void); +int *_NSGetArgc(void); +char ***_NSGetArgv(void); +char **_NSGetProgname(void); + +#endif diff --git a/headers/include/crtdbg.h b/headers/include/crtdbg.h new file mode 100644 index 000000000..5ca655977 --- /dev/null +++ b/headers/include/crtdbg.h @@ -0,0 +1,37 @@ +// crtdbg.h -- CRT debug-heap and report interface. badc never defines +// _DEBUG, so this is the release shape of the UCRT header: report +// constants keep their values, entry points fold to the same no-op +// macros the UCRT uses. TODO: the _DEBUG report/heap entry points. + +#pragma once + +#ifdef _WIN32 +#include + +typedef void *_HFILE; + +#define _CRT_WARN 0 +#define _CRT_ERROR 1 +#define _CRT_ASSERT 2 +#define _CRT_ERRCNT 3 + +#define _CRTDBG_MODE_FILE 0x1 +#define _CRTDBG_MODE_DEBUG 0x2 +#define _CRTDBG_MODE_WNDW 0x4 +#define _CRTDBG_REPORT_MODE -1 + +#define _CRTDBG_INVALID_HFILE ((_HFILE)(intptr_t)-1) +#define _CRTDBG_HFILE_ERROR ((_HFILE)(intptr_t)-2) +#define _CRTDBG_FILE_STDOUT ((_HFILE)(intptr_t)-4) +#define _CRTDBG_FILE_STDERR ((_HFILE)(intptr_t)-5) +#define _CRTDBG_REPORT_FILE ((_HFILE)(intptr_t)-6) + +#define _CrtSetReportMode(t, f) ((int)0) +#define _CrtSetReportFile(t, f) ((_HFILE)0) +#define _CrtSetDbgFlag(f) ((int)0) +#define _CrtCheckMemory() ((int)1) +#define _CrtDumpMemoryLeaks() ((int)0) +#define _CrtDbgBreak() ((void)0) +#define _ASSERT(expr) ((void)0) +#define _ASSERTE(expr) ((void)0) +#endif diff --git a/headers/include/direct.h b/headers/include/direct.h new file mode 100644 index 000000000..0310a74f3 --- /dev/null +++ b/headers/include/direct.h @@ -0,0 +1,18 @@ +/* MSVC directory-management (): underscored POSIX-shaped +** calls over msvcrt. */ +#pragma once + +#ifdef _WIN32 + +#pragma dylib(msvcrt, "msvcrt.dll") +#pragma binding(msvcrt::_mkdir, "_mkdir") +#pragma binding(msvcrt::_rmdir, "_rmdir") +#pragma binding(msvcrt::_chdir, "_chdir") +#pragma binding(msvcrt::_getcwd, "_getcwd") + +int _mkdir(char *path); +int _rmdir(char *path); +int _chdir(char *path); +char *_getcwd(char *buf, int size); + +#endif diff --git a/headers/include/fcntl.h b/headers/include/fcntl.h index 0e83890d1..4241a4f21 100644 --- a/headers/include/fcntl.h +++ b/headers/include/fcntl.h @@ -206,7 +206,7 @@ int openat(int dirfd, const char *path, int flags, ...); #pragma binding(libc::splice, "splice") #pragma binding(libc::posix_fadvise, "posix_fadvise") #pragma binding(libc::posix_fallocate, "posix_fallocate") -int fcntl(int fd, int cmd, int arg); +int fcntl(int fd, int cmd, ...); int openat(int dirfd, const char *path, int flags, ...); // Move data between two descriptors, one of which must be a pipe; the // `off_*` parameters are in/out file offsets or null. diff --git a/headers/include/fenv.h b/headers/include/fenv.h new file mode 100644 index 000000000..5ca418f5a --- /dev/null +++ b/headers/include/fenv.h @@ -0,0 +1,72 @@ +/* C99 7.6 floating-point environment: the rounding-mode and +** exception-flag surface. Macro values must match the CRT that +** implements the functions: hardware encodings on Linux/macOS +** (x87/SSE control word on x86_64, FPCR on aarch64), the UCRT's +** abstract values on Windows. fegetenv/feholdexcept and the +** environment object are TODO. */ +#pragma once + +#ifdef _WIN32 +#define FE_TONEAREST 0x000 +#define FE_DOWNWARD 0x100 +#define FE_UPWARD 0x200 +#define FE_TOWARDZERO 0x300 +#define FE_INEXACT 0x01 +#define FE_UNDERFLOW 0x02 +#define FE_OVERFLOW 0x04 +#define FE_DIVBYZERO 0x08 +#define FE_INVALID 0x10 +#define FE_ALL_EXCEPT 0x1f +#elif defined(__aarch64__) +#define FE_TONEAREST 0x000000 +#define FE_UPWARD 0x400000 +#define FE_DOWNWARD 0x800000 +#define FE_TOWARDZERO 0xc00000 +#define FE_INVALID 0x01 +#define FE_DIVBYZERO 0x02 +#define FE_OVERFLOW 0x04 +#define FE_UNDERFLOW 0x08 +#define FE_INEXACT 0x10 +#define FE_ALL_EXCEPT 0x1f +#else +#define FE_TONEAREST 0x000 +#define FE_DOWNWARD 0x400 +#define FE_UPWARD 0x800 +#define FE_TOWARDZERO 0xc00 +#define FE_INVALID 0x01 +#define FE_DIVBYZERO 0x04 +#define FE_OVERFLOW 0x08 +#define FE_UNDERFLOW 0x10 +#define FE_INEXACT 0x20 +#define FE_ALL_EXCEPT 0x3d +#endif + +#ifdef __APPLE__ +#pragma dylib(libc, "/usr/lib/libSystem.B.dylib") +#pragma binding(libc::fegetround, "_fegetround") +#pragma binding(libc::fesetround, "_fesetround") +#pragma binding(libc::feclearexcept, "_feclearexcept") +#pragma binding(libc::fetestexcept, "_fetestexcept") +#pragma binding(libc::feraiseexcept, "_feraiseexcept") +#elif defined(__linux__) +#pragma dylib(libm, "libm.so.6") +#pragma binding(libm::fegetround, "fegetround") +#pragma binding(libm::fesetround, "fesetround") +#pragma binding(libm::feclearexcept, "feclearexcept") +#pragma binding(libm::fetestexcept, "fetestexcept") +#pragma binding(libm::feraiseexcept, "feraiseexcept") +#elif defined(_WIN32) +/* Legacy msvcrt.dll predates C99 fenv; the UCRT exports it. */ +#pragma dylib(ucrtbase, "ucrtbase.dll") +#pragma binding(ucrtbase::fegetround, "fegetround") +#pragma binding(ucrtbase::fesetround, "fesetround") +#pragma binding(ucrtbase::feclearexcept, "feclearexcept") +#pragma binding(ucrtbase::fetestexcept, "fetestexcept") +#pragma binding(ucrtbase::feraiseexcept, "feraiseexcept") +#endif + +int fegetround(void); +int fesetround(int round); +int feclearexcept(int excepts); +int fetestexcept(int excepts); +int feraiseexcept(int excepts); diff --git a/headers/include/intrin.h b/headers/include/intrin.h new file mode 100644 index 000000000..d83d2abef --- /dev/null +++ b/headers/include/intrin.h @@ -0,0 +1,26 @@ +/* MSVC compiler intrinsics (). Only the byte-swap family +** has a CRT export to bind; the remaining intrinsics are +** compiler-generated and stay undeclared so their use fails loudly +** at compile time rather than miscompiling. TODO: lower the +** barrier / bit-scan / mul128 families in the compiler. */ +#pragma once + +#ifdef _WIN32 + +/* The byte-swap trio lives in the UCRT, not legacy msvcrt.dll +** (probed on both Windows boxes). */ +#pragma dylib(ucrtbase, "ucrtbase.dll") +#pragma binding(ucrtbase::_byteswap_ushort, "_byteswap_ushort") +#pragma binding(ucrtbase::_byteswap_ulong, "_byteswap_ulong") +#pragma binding(ucrtbase::_byteswap_uint64, "_byteswap_uint64") + +unsigned short _byteswap_ushort(unsigned short value); +unsigned long _byteswap_ulong(unsigned long value); +unsigned long long _byteswap_uint64(unsigned long long value); + +/* Compiler-reordering fence. c5 does not reorder memory accesses +** across calls, so an opaque no-op call carries the required +** ordering. TODO: a fence IR op once pass-level reordering exists. */ +static void _ReadWriteBarrier(void) {} + +#endif diff --git a/headers/include/io.h b/headers/include/io.h new file mode 100644 index 000000000..d60e7c1d9 --- /dev/null +++ b/headers/include/io.h @@ -0,0 +1,43 @@ +/* MSVC low-level I/O (). Underscored POSIX-shaped calls over +** msvcrt. The C99-visible stream API lives in ; this header +** carries the fd-level surface Windows sources reach for directly. */ +#pragma once + +#ifdef _WIN32 + +#pragma dylib(msvcrt, "msvcrt.dll") +#pragma binding(msvcrt::_open, "_open") +#pragma binding(msvcrt::_close, "_close") +#pragma binding(msvcrt::_read, "_read") +#pragma binding(msvcrt::_write, "_write") +#pragma binding(msvcrt::_lseek, "_lseek") +#pragma binding(msvcrt::_lseeki64, "_lseeki64") +#pragma binding(msvcrt::_unlink, "_unlink") +#pragma binding(msvcrt::_chmod, "_chmod") +#pragma binding(msvcrt::_dup, "_dup") +#pragma binding(msvcrt::_dup2, "_dup2") +#pragma binding(msvcrt::_fileno, "_fileno") +#pragma binding(msvcrt::_isatty, "_isatty") +#pragma binding(msvcrt::_setmode, "_setmode") +#pragma binding(msvcrt::_access, "_access") +#pragma binding(msvcrt::_commit, "_commit") + +int _open(char *path, int oflag, int pmode); +int _close(int fd); +int _read(int fd, void *buf, unsigned int count); +int _write(int fd, void *buf, unsigned int count); +long _lseek(int fd, long offset, int origin); +long long _lseeki64(int fd, long long offset, int origin); +int _unlink(char *path); +int _chmod(char *path, int mode); +int _dup(int fd); +int _dup2(int fd1, int fd2); +int _isatty(int fd); +int _setmode(int fd, int mode); +int _access(char *path, int mode); +int _commit(int fd); + +#define _S_IREAD 0400 +#define _S_IWRITE 0200 + +#endif diff --git a/headers/include/linux/auxvec.h b/headers/include/linux/auxvec.h new file mode 100644 index 000000000..d0c02409d --- /dev/null +++ b/headers/include/linux/auxvec.h @@ -0,0 +1,35 @@ +// linux/auxvec.h -- ELF auxiliary-vector entry types, from the kernel +// uapi header of the same name. + +#pragma once + +#ifdef __linux__ +#define AT_NULL 0 +#define AT_IGNORE 1 +#define AT_EXECFD 2 +#define AT_PHDR 3 +#define AT_PHENT 4 +#define AT_PHNUM 5 +#define AT_PAGESZ 6 +#define AT_BASE 7 +#define AT_FLAGS 8 +#define AT_ENTRY 9 +#define AT_NOTELF 10 +#define AT_UID 11 +#define AT_EUID 12 +#define AT_GID 13 +#define AT_EGID 14 +#define AT_PLATFORM 15 +#define AT_HWCAP 16 +#define AT_CLKTCK 17 +#define AT_SECURE 23 +#define AT_BASE_PLATFORM 24 +#define AT_RANDOM 25 +#define AT_HWCAP2 26 +#define AT_RSEQ_FEATURE_SIZE 27 +#define AT_RSEQ_ALIGN 28 +#define AT_HWCAP3 29 +#define AT_HWCAP4 30 +#define AT_EXECFN 31 +#define AT_MINSIGSTKSZ 51 +#endif diff --git a/headers/include/linux/fs.h b/headers/include/linux/fs.h new file mode 100644 index 000000000..567a7855c --- /dev/null +++ b/headers/include/linux/fs.h @@ -0,0 +1,22 @@ +// linux/fs.h -- filesystem ioctls from the kernel uapi header. The +// values expand the kernel's _IOW('\x94', nr, size) encoding: +// dir 1 (write) << 30 | size << 16 | 0x94 << 8 | nr. TODO: the +// FS_IOC_* attribute ioctls. + +#pragma once + +#ifdef __linux__ +#include + +struct file_clone_range { + int64_t src_fd; + uint64_t src_offset; + uint64_t src_length; + uint64_t dest_offset; +}; + +// _IOW(0x94, 9, int) +#define FICLONE 0x40049409 +// _IOW(0x94, 13, struct file_clone_range) +#define FICLONERANGE 0x4020940d +#endif diff --git a/headers/include/linux/limits.h b/headers/include/linux/limits.h new file mode 100644 index 000000000..526efa69c --- /dev/null +++ b/headers/include/linux/limits.h @@ -0,0 +1,29 @@ +// linux/limits.h -- kernel uapi limits. The names and +// also define are guarded so either include order +// holds. + +#pragma once + +#ifdef __linux__ +#define NR_OPEN 1024 +#ifndef NGROUPS_MAX +#define NGROUPS_MAX 65536 +#endif +#ifndef ARG_MAX +#define ARG_MAX 131072 +#endif +#define LINK_MAX 127 +#define MAX_CANON 255 +#define MAX_INPUT 255 +#ifndef NAME_MAX +#define NAME_MAX 255 +#endif +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif +#define PIPE_BUF 4096 +#define XATTR_NAME_MAX 255 +#define XATTR_SIZE_MAX 65536 +#define XATTR_LIST_MAX 65536 +#define RTSIG_MAX 32 +#endif diff --git a/headers/include/linux/memfd.h b/headers/include/linux/memfd.h new file mode 100644 index 000000000..0f3b73228 --- /dev/null +++ b/headers/include/linux/memfd.h @@ -0,0 +1,30 @@ +// linux/memfd.h -- memfd_create flags from the kernel uapi header; +// the entry point itself is bound in . The MFD_HUGE_* +// values encode log2(page size) in the top field, per the kernel's +// hugetlb_encode.h. + +#pragma once + +#ifdef __linux__ +#define MFD_CLOEXEC 0x0001U +#define MFD_ALLOW_SEALING 0x0002U +#define MFD_HUGETLB 0x0004U +#define MFD_NOEXEC_SEAL 0x0008U +#define MFD_EXEC 0x0010U + +#define MFD_HUGE_SHIFT 26 +#define MFD_HUGE_MASK 0x3f + +#define MFD_HUGE_64KB (16U << MFD_HUGE_SHIFT) +#define MFD_HUGE_512KB (19U << MFD_HUGE_SHIFT) +#define MFD_HUGE_1MB (20U << MFD_HUGE_SHIFT) +#define MFD_HUGE_2MB (21U << MFD_HUGE_SHIFT) +#define MFD_HUGE_8MB (23U << MFD_HUGE_SHIFT) +#define MFD_HUGE_16MB (24U << MFD_HUGE_SHIFT) +#define MFD_HUGE_32MB (25U << MFD_HUGE_SHIFT) +#define MFD_HUGE_256MB (28U << MFD_HUGE_SHIFT) +#define MFD_HUGE_512MB (29U << MFD_HUGE_SHIFT) +#define MFD_HUGE_1GB (30U << MFD_HUGE_SHIFT) +#define MFD_HUGE_2GB (31U << MFD_HUGE_SHIFT) +#define MFD_HUGE_16GB (34U << MFD_HUGE_SHIFT) +#endif diff --git a/headers/include/linux/sched.h b/headers/include/linux/sched.h new file mode 100644 index 000000000..513358c52 --- /dev/null +++ b/headers/include/linux/sched.h @@ -0,0 +1,15 @@ +// linux/sched.h -- scheduling policies from the kernel uapi header. +// The glibc-visible trio carries the same values as ; +// SCHED_NORMAL is the kernel spelling of SCHED_OTHER. TODO: the +// CLONE_* flags and struct clone_args. + +#pragma once + +#ifdef __linux__ +#define SCHED_NORMAL 0 +#define SCHED_FIFO 1 +#define SCHED_RR 2 +#define SCHED_BATCH 3 +#define SCHED_IDLE 5 +#define SCHED_DEADLINE 6 +#endif diff --git a/headers/include/linux/wait.h b/headers/include/linux/wait.h new file mode 100644 index 000000000..b5bbcab6d --- /dev/null +++ b/headers/include/linux/wait.h @@ -0,0 +1,12 @@ +// linux/wait.h -- the waitid id-type selectors from the kernel uapi +// header. P_PIDFD (Linux 5.4) has no glibc counterpart; +// the first three shadow the idtype_t enumerators with equal values. + +#pragma once + +#ifdef __linux__ +#define P_ALL 0 +#define P_PID 1 +#define P_PGID 2 +#define P_PIDFD 3 +#endif diff --git a/headers/include/lmcons.h b/headers/include/lmcons.h new file mode 100644 index 000000000..a05058c06 --- /dev/null +++ b/headers/include/lmcons.h @@ -0,0 +1,12 @@ +// lmcons.h -- LAN Manager name-length limits (character counts, +// excluding the terminator). + +#pragma once + +#ifdef _WIN32 +#define CNLEN 15 +#define DNLEN CNLEN +#define UNLEN 256 +#define GNLEN UNLEN +#define PWLEN 256 +#endif diff --git a/headers/include/mach-o/loader.h b/headers/include/mach-o/loader.h new file mode 100644 index 000000000..752623ad2 --- /dev/null +++ b/headers/include/mach-o/loader.h @@ -0,0 +1,133 @@ +// mach-o/loader.h -- Mach-O file-format structures and constants, the +// subset consumers reach for (headers, segment/section layout). Values +// match the macOS SDK's ; the format is fixed, so the +// definitions are usable on any host. No bindings -- data layout only. + +#pragma once + +#include + +// integer_t-based ids; protection bits. +typedef int cpu_type_t; +typedef int cpu_subtype_t; +typedef int vm_prot_t; + +struct mach_header { + uint32_t magic; + cpu_type_t cputype; + cpu_subtype_t cpusubtype; + uint32_t filetype; + uint32_t ncmds; + uint32_t sizeofcmds; + uint32_t flags; +}; + +#define MH_MAGIC 0xfeedface +#define MH_CIGAM 0xcefaedfe + +struct mach_header_64 { + uint32_t magic; + cpu_type_t cputype; + cpu_subtype_t cpusubtype; + uint32_t filetype; + uint32_t ncmds; + uint32_t sizeofcmds; + uint32_t flags; + uint32_t reserved; +}; + +#define MH_MAGIC_64 0xfeedfacf +#define MH_CIGAM_64 0xcffaedfe + +// mach_header filetype values. +#define MH_OBJECT 0x1 +#define MH_EXECUTE 0x2 +#define MH_DYLIB 0x6 +#define MH_DYLINKER 0x7 +#define MH_BUNDLE 0x8 +#define MH_DSYM 0xa + +struct load_command { + uint32_t cmd; + uint32_t cmdsize; +}; + +#define LC_SEGMENT 0x1 +#define LC_SYMTAB 0x2 +#define LC_UUID 0x1b +#define LC_SEGMENT_64 0x19 + +struct segment_command { + uint32_t cmd; + uint32_t cmdsize; + char segname[16]; + uint32_t vmaddr; + uint32_t vmsize; + uint32_t fileoff; + uint32_t filesize; + vm_prot_t maxprot; + vm_prot_t initprot; + uint32_t nsects; + uint32_t flags; +}; + +struct segment_command_64 { + uint32_t cmd; + uint32_t cmdsize; + char segname[16]; + uint64_t vmaddr; + uint64_t vmsize; + uint64_t fileoff; + uint64_t filesize; + vm_prot_t maxprot; + vm_prot_t initprot; + uint32_t nsects; + uint32_t flags; +}; + +struct section { + char sectname[16]; + char segname[16]; + uint32_t addr; + uint32_t size; + uint32_t offset; + uint32_t align; + uint32_t reloff; + uint32_t nreloc; + uint32_t flags; + uint32_t reserved1; + uint32_t reserved2; +}; + +struct section_64 { + char sectname[16]; + char segname[16]; + uint64_t addr; + uint64_t size; + uint32_t offset; + uint32_t align; + uint32_t reloff; + uint32_t nreloc; + uint32_t flags; + uint32_t reserved1; + uint32_t reserved2; + uint32_t reserved3; +}; + +struct symtab_command { + uint32_t cmd; + uint32_t cmdsize; + uint32_t symoff; + uint32_t nsyms; + uint32_t stroff; + uint32_t strsize; +}; + +#define SEG_PAGEZERO "__PAGEZERO" +#define SEG_TEXT "__TEXT" +#define SECT_TEXT "__text" +#define SEG_DATA "__DATA" +#define SECT_DATA "__data" +#define SECT_BSS "__bss" +#define SECT_COMMON "__common" +#define SEG_LINKEDIT "__LINKEDIT" diff --git a/headers/include/mach/mach.h b/headers/include/mach/mach.h index 02e497af9..8bffc96c4 100644 --- a/headers/include/mach/mach.h +++ b/headers/include/mach/mach.h @@ -4,12 +4,17 @@ #pragma once #ifdef __APPLE__ -// Mach kernel scalar types (all 32-bit on Darwin). +// Mach kernel scalar types (32-bit on Darwin; the mach_vm_* pair is +// 64-bit). typedef unsigned int mach_port_t; typedef mach_port_t task_t; typedef mach_port_t thread_t; typedef int kern_return_t; typedef unsigned int mach_msg_type_number_t; +typedef unsigned int natural_t; +typedef int integer_t; +typedef unsigned long long mach_vm_size_t; +typedef unsigned long long mach_vm_address_t; // An out-of-line array of thread ports returned by task_threads(). typedef thread_t *thread_array_t; diff --git a/headers/include/mach/task.h b/headers/include/mach/task.h new file mode 100644 index 000000000..a9a16f85f --- /dev/null +++ b/headers/include/mach/task.h @@ -0,0 +1,88 @@ +// mach/task.h -- task introspection: the task_info() flavor consumers +// reach for. Layouts and flavor values from the SDK's +// . TODO: the remaining flavors. + +#pragma once + +#ifdef __APPLE__ +#include +#include + +typedef natural_t task_flavor_t; +typedef integer_t *task_info_t; + +#define TASK_VM_INFO 22 + +// Mach info structs are 4-byte packed; the count encodes the struct +// revision in natural_t units. +#pragma pack(push, 4) +struct task_vm_info { + mach_vm_size_t virtual_size; + integer_t region_count; + integer_t page_size; + mach_vm_size_t resident_size; + mach_vm_size_t resident_size_peak; + mach_vm_size_t device; + mach_vm_size_t device_peak; + mach_vm_size_t internal; + mach_vm_size_t internal_peak; + mach_vm_size_t external; + mach_vm_size_t external_peak; + mach_vm_size_t reusable; + mach_vm_size_t reusable_peak; + mach_vm_size_t purgeable_volatile_pmap; + mach_vm_size_t purgeable_volatile_resident; + mach_vm_size_t purgeable_volatile_virtual; + mach_vm_size_t compressed; + mach_vm_size_t compressed_peak; + mach_vm_size_t compressed_lifetime; + // rev1 + mach_vm_size_t phys_footprint; + // rev2 + mach_vm_address_t min_address; + mach_vm_address_t max_address; + // rev3 + int64_t ledger_phys_footprint_peak; + int64_t ledger_purgeable_nonvolatile; + int64_t ledger_purgeable_novolatile_compressed; + int64_t ledger_purgeable_volatile; + int64_t ledger_purgeable_volatile_compressed; + int64_t ledger_tag_network_nonvolatile; + int64_t ledger_tag_network_nonvolatile_compressed; + int64_t ledger_tag_network_volatile; + int64_t ledger_tag_network_volatile_compressed; + int64_t ledger_tag_media_footprint; + int64_t ledger_tag_media_footprint_compressed; + int64_t ledger_tag_media_nofootprint; + int64_t ledger_tag_media_nofootprint_compressed; + int64_t ledger_tag_graphics_footprint; + int64_t ledger_tag_graphics_footprint_compressed; + int64_t ledger_tag_graphics_nofootprint; + int64_t ledger_tag_graphics_nofootprint_compressed; + int64_t ledger_tag_neural_footprint; + int64_t ledger_tag_neural_footprint_compressed; + int64_t ledger_tag_neural_nofootprint; + int64_t ledger_tag_neural_nofootprint_compressed; + // rev4 + uint64_t limit_bytes_remaining; + // rev5 + integer_t decompressions; + // rev6 + int64_t ledger_swapins; + // rev7 + int64_t ledger_tag_neural_nofootprint_total; + int64_t ledger_tag_neural_nofootprint_peak; +}; +#pragma pack(pop) + +typedef struct task_vm_info task_vm_info_data_t; +typedef struct task_vm_info *task_vm_info_t; + +#define TASK_VM_INFO_COUNT \ + ((mach_msg_type_number_t)(sizeof(task_vm_info_data_t) / sizeof(natural_t))) + +#pragma binding(libc::task_info, "_task_info") + +kern_return_t task_info(task_t task, task_flavor_t flavor, task_info_t info, + mach_msg_type_number_t *count); +#endif diff --git a/headers/include/net/ethernet.h b/headers/include/net/ethernet.h new file mode 100644 index 000000000..0080b02ee --- /dev/null +++ b/headers/include/net/ethernet.h @@ -0,0 +1,47 @@ +// net/ethernet.h -- Ethernet frame constants and address structures. + +#pragma once + +#if defined(__APPLE__) || defined(__linux__) + +#include + +// Octet counts and frame limits; identical in glibc +// (via ) and Darwin . +#define ETHER_ADDR_LEN 6 +#define ETHER_TYPE_LEN 2 +#define ETHER_CRC_LEN 4 +#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) +#define ETHER_MIN_LEN 64 +#define ETHER_MAX_LEN 1518 + +#define ETHERTYPE_IP 0x0800 +#define ETHERTYPE_ARP 0x0806 +#define ETHERTYPE_REVARP 0x8035 +#define ETHERTYPE_VLAN 0x8100 +#define ETHERTYPE_IPV6 0x86dd + +struct ether_addr { + uint8_t ether_addr_octet[ETHER_ADDR_LEN]; +}; + +struct ether_header { + uint8_t ether_dhost[ETHER_ADDR_LEN]; + uint8_t ether_shost[ETHER_ADDR_LEN]; + uint16_t ether_type; +}; + +#ifdef __linux__ +// glibc's header pulls these from . +#define ETH_ALEN 6 +#define ETH_HLEN 14 +#define ETH_ZLEN 60 +#define ETH_DATA_LEN 1500 +#define ETH_FRAME_LEN 1514 +#define ETH_P_ALL 0x0003 +#define ETH_P_IP 0x0800 +#define ETH_P_ARP 0x0806 +#define ETH_P_IPV6 0x86dd +#endif + +#endif diff --git a/headers/include/os/lock.h b/headers/include/os/lock.h new file mode 100644 index 000000000..cc85e7b80 --- /dev/null +++ b/headers/include/os/lock.h @@ -0,0 +1,23 @@ +/* Apple : the os_unfair_lock primitive. Opaque one-word +** lock; libSystem provides the operations. */ +#pragma once + +#ifdef __APPLE__ + +typedef struct os_unfair_lock_s { + unsigned int _os_unfair_lock_opaque; +} os_unfair_lock, *os_unfair_lock_t; + +#define OS_UNFAIR_LOCK_INIT \ + ((os_unfair_lock){0}) + +#pragma dylib(libc, "/usr/lib/libSystem.B.dylib") +#pragma binding(libc::os_unfair_lock_lock, "_os_unfair_lock_lock") +#pragma binding(libc::os_unfair_lock_unlock, "_os_unfair_lock_unlock") +#pragma binding(libc::os_unfair_lock_trylock, "_os_unfair_lock_trylock") + +void os_unfair_lock_lock(os_unfair_lock_t lock); +void os_unfair_lock_unlock(os_unfair_lock_t lock); +int os_unfair_lock_trylock(os_unfair_lock_t lock); + +#endif diff --git a/headers/include/os/log.h b/headers/include/os/log.h new file mode 100644 index 000000000..bb6320267 --- /dev/null +++ b/headers/include/os/log.h @@ -0,0 +1,42 @@ +// os/log.h -- unified logging. The SDK macro compiles the format via +// __builtin_os_log_format; badc routes through _os_log_internal, the +// exported variadic entry point older deployment targets use. Its +// first argument must be an address inside the calling image (sender +// attribution); a NULL faults in libtrace, so each including unit +// carries a static anchor byte. + +#pragma once + +#ifdef __APPLE__ +#include + +typedef struct os_log_s *os_log_t; +typedef uint8_t os_log_type_t; + +#define OS_LOG_TYPE_DEFAULT 0x00 +#define OS_LOG_TYPE_INFO 0x01 +#define OS_LOG_TYPE_DEBUG 0x02 +#define OS_LOG_TYPE_ERROR 0x10 +#define OS_LOG_TYPE_FAULT 0x11 + +#pragma dylib(libc, "/usr/lib/libSystem.B.dylib") +#pragma binding(libc::os_log_create, "_os_log_create") +#pragma binding(libc::_os_log_internal, "__os_log_internal") +#pragma binding(data libc::_os_log_default, "__os_log_default") + +extern struct os_log_s _os_log_default; +#define OS_LOG_DEFAULT (&_os_log_default) + +os_log_t os_log_create(const char *subsystem, const char *category); +void _os_log_internal(void *dso, os_log_t log, os_log_type_t type, const char *message, ...); + +static char __badc_os_log_anchor; + +#define os_log_with_type(log, type, ...) \ + _os_log_internal(&__badc_os_log_anchor, (log), (type), __VA_ARGS__) +#define os_log(log, ...) os_log_with_type((log), OS_LOG_TYPE_DEFAULT, __VA_ARGS__) +#define os_log_info(log, ...) os_log_with_type((log), OS_LOG_TYPE_INFO, __VA_ARGS__) +#define os_log_debug(log, ...) os_log_with_type((log), OS_LOG_TYPE_DEBUG, __VA_ARGS__) +#define os_log_error(log, ...) os_log_with_type((log), OS_LOG_TYPE_ERROR, __VA_ARGS__) +#define os_log_fault(log, ...) os_log_with_type((log), OS_LOG_TYPE_FAULT, __VA_ARGS__) +#endif diff --git a/headers/include/pathcch.h b/headers/include/pathcch.h new file mode 100644 index 000000000..8e77e7fb6 --- /dev/null +++ b/headers/include/pathcch.h @@ -0,0 +1,7 @@ +// pathcch.h -- wide path-combining API (api-ms-win-core-path). badc's +// carries the PathCch* prototypes, their bindings, and +// PATHCCH_ALLOW_LONG_PATHS. + +#pragma once + +#include diff --git a/headers/include/psapi.h b/headers/include/psapi.h new file mode 100644 index 000000000..1fc702e86 --- /dev/null +++ b/headers/include/psapi.h @@ -0,0 +1,27 @@ +// psapi.h -- process status API, the process-memory counters subset. +// Since PSAPI_VERSION 2 the SDK routes these through kernel32's K32* +// exports; the binding goes there directly. + +#pragma once + +#ifdef _WIN32 +#include + +typedef struct _PROCESS_MEMORY_COUNTERS { + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; +} PROCESS_MEMORY_COUNTERS, *PPROCESS_MEMORY_COUNTERS; + +#pragma dylib(kernel32, "kernel32.dll") +#pragma binding(kernel32::GetProcessMemoryInfo, "K32GetProcessMemoryInfo") + +BOOL GetProcessMemoryInfo(HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); +#endif diff --git a/headers/include/sched.h b/headers/include/sched.h index c6c6f896e..70368b0b9 100644 --- a/headers/include/sched.h +++ b/headers/include/sched.h @@ -30,11 +30,9 @@ struct sched_param { #pragma binding(libc::sched_yield, "_sched_yield") #pragma binding(libc::sched_get_priority_max, "_sched_get_priority_max") #pragma binding(libc::sched_get_priority_min, "_sched_get_priority_min") -#pragma binding(libc::sched_setscheduler, "_sched_setscheduler") -#pragma binding(libc::sched_getscheduler, "_sched_getscheduler") -#pragma binding(libc::sched_setparam, "_sched_setparam") -#pragma binding(libc::sched_getparam, "_sched_getparam") -#pragma binding(libc::sched_rr_get_interval, "_sched_rr_get_interval") +// libSystem exports none of sched_setscheduler / sched_getscheduler / +// sched_setparam / sched_getparam / sched_rr_get_interval; leaving +// them unbound makes a use fail at link rather than at load. #endif #ifdef __linux__ diff --git a/headers/include/sddl.h b/headers/include/sddl.h new file mode 100644 index 000000000..b11942009 --- /dev/null +++ b/headers/include/sddl.h @@ -0,0 +1,18 @@ +// sddl.h -- security-descriptor string format (advapi32). TODO: the +// SID string conversions. + +#pragma once + +#ifdef _WIN32 +#include + +#define SDDL_REVISION_1 1 +#define SDDL_REVISION SDDL_REVISION_1 + +#pragma dylib(advapi32, "advapi32.dll") +#pragma binding(advapi32::ConvertStringSecurityDescriptorToSecurityDescriptorW, "ConvertStringSecurityDescriptorToSecurityDescriptorW") + +BOOL ConvertStringSecurityDescriptorToSecurityDescriptorW( + LPCWSTR StringSecurityDescriptor, DWORD StringSDRevision, + void **SecurityDescriptor, ULONG *SecurityDescriptorSize); +#endif diff --git a/headers/include/shlwapi.h b/headers/include/shlwapi.h new file mode 100644 index 000000000..522c5666e --- /dev/null +++ b/headers/include/shlwapi.h @@ -0,0 +1,7 @@ +// shlwapi.h -- shell light-weight path utilities. Consumers so far +// reach only the surface; the PathCch* replacements live +// in . TODO: the PathIsRelativeW family. + +#pragma once + +#include diff --git a/headers/include/stdio.h b/headers/include/stdio.h index c15e99e3a..170b187f4 100644 --- a/headers/include/stdio.h +++ b/headers/include/stdio.h @@ -243,29 +243,31 @@ typedef struct __c5_fpos_t fpos_t; #pragma binding(msvcrt::wprintf, "wprintf") #pragma binding(msvcrt::fprintf, "fprintf") #pragma binding(msvcrt::sprintf, "sprintf") -// MSVC renamed the safe forms; the original `snprintf` only landed -// in msvcrt circa VS2015. `_snprintf` is the universally available -// spelling and behaves the same way for our usage (no NUL guarantee -// on overflow, but neither does our other targets' `snprintf` once -// the buffer fills). Note that msvcrt's printf family prints -// infinity / NaN as `1.#INF` / `1.#IND` / `1.#QNAN` rather than -// C99 `inf` / `nan`; programs that classify formatted output -// by a digit-prefix regex misclassify the msvcrt output as -// numeric. -// Routing through `ucrtbase._snprintf` would emit the C99 -// spelling but that entry point fails with -// STATUS_ENTRYPOINT_NOT_FOUND at PE load time on the GitHub -// Windows runners -- the documented UCRT import path is via the -// `api-ms-win-crt-stdio-l1-1-0.dll` proxy set, not ucrtbase -// directly. Tracked under the TODO marker until c5 grows +// The original `snprintf` only landed in msvcrt circa VS2015, and +// `_snprintf` deviates from C99 7.19.6.5 (returns -1 and omits the +// NUL on truncation). The standard `snprintf` / `vsnprintf` +// spellings carry no binding here: they resolve at link time against +// the conforming definitions in the auto-linked runtime, which wrap +// `_vsnprintf` + `_vscprintf`. The underscored spellings keep the +// msvcrt entry points for source written against msvcrt semantics. +// Note that msvcrt's printf family prints infinity / NaN as +// `1.#INF` / `1.#IND` / `1.#QNAN` rather than C99 `inf` / `nan`; +// programs that classify formatted output by a digit-prefix regex +// misclassify the msvcrt output as numeric. +// Routing through `ucrtbase` would emit the C99 spelling but its +// entry points fail with STATUS_ENTRYPOINT_NOT_FOUND at PE load +// time on the GitHub Windows runners -- the documented UCRT import +// path is via the `api-ms-win-crt-stdio-l1-1-0.dll` proxy set, not +// ucrtbase directly. Tracked under the TODO marker until c5 grows // support for the UCRT proxy DLLs. -#pragma binding(msvcrt::snprintf, "_snprintf") #pragma binding(msvcrt::_snprintf, "_snprintf") +#pragma binding(msvcrt::_vsnprintf,"_vsnprintf") #pragma binding(msvcrt::vprintf, "vprintf") #pragma binding(msvcrt::vfprintf, "vfprintf") #pragma binding(msvcrt::vsprintf, "vsprintf") -#pragma binding(msvcrt::vsnprintf, "_vsnprintf") -#pragma binding(msvcrt::_vsnprintf,"_vsnprintf") +// The runtime's `vsnprintf` needs a prototype on Windows; every +// other target binds the name straight to libc. +int vsnprintf(char *buf, int size, char *fmt, char *ap); #pragma binding(msvcrt::scanf, "scanf") #pragma binding(msvcrt::fscanf, "fscanf") #pragma binding(msvcrt::sscanf, "sscanf") @@ -291,7 +293,9 @@ typedef struct __c5_fpos_t fpos_t; #pragma binding(msvcrt::fseek, "fseek") #pragma binding(msvcrt::ftell, "ftell") #pragma binding(msvcrt::_fseeki64, "_fseeki64") -#pragma binding(msvcrt::_ftelli64, "_ftelli64") +// The legacy msvcrt.dll exports no _ftelli64 (unlike _fseeki64); UCRT does. +#pragma dylib(ucrtbase, "ucrtbase.dll") +#pragma binding(ucrtbase::_ftelli64, "_ftelli64") #pragma binding(msvcrt::fgetpos, "fgetpos") #pragma binding(msvcrt::fsetpos, "fsetpos") #pragma binding(msvcrt::rewind, "rewind") @@ -369,7 +373,7 @@ typedef struct __c5_fpos_t fpos_t; // SDK macros. badc's time_t is 64-bit on Windows, so the ABI matches. #pragma binding(msvcrt::localtime_s, "_localtime64_s") #pragma binding(msvcrt::gmtime_s, "_gmtime64_s") -#pragma binding(msvcrt::ctime_s, "ctime_s") +#pragma binding(msvcrt::ctime_s, "_ctime64_s") #pragma binding(msvcrt::asctime_s, "asctime_s") #pragma binding(msvcrt::strerror_s, "strerror_s") #pragma binding(msvcrt::_strdup, "_strdup") @@ -402,7 +406,12 @@ typedef struct __c5_fpos_t fpos_t; #pragma binding(msvcrt::_unlink, "_unlink") #pragma binding(msvcrt::_getcwd, "_getcwd") #pragma binding(msvcrt::_chdir, "_chdir") +// The legacy arm64 msvcrt.dll does not export `_getpid`; UCRT does. +#if defined(__aarch64__) +#pragma binding(ucrtbase::_getpid, "_getpid") +#else #pragma binding(msvcrt::_getpid, "_getpid") +#endif #pragma binding(msvcrt::_dup, "_dup") #pragma binding(msvcrt::_dup2, "_dup2") #pragma binding(msvcrt::_fdopen, "_fdopen") @@ -410,9 +419,10 @@ typedef struct __c5_fpos_t fpos_t; // form, so the portable spelling binds to the same entry point. #pragma binding(msvcrt::fdopen, "_fdopen") #pragma binding(msvcrt::fileno, "_fileno") -#pragma binding(msvcrt::_byteswap_ulong, "_byteswap_ulong") -#pragma binding(msvcrt::_byteswap_uint64, "_byteswap_uint64") -#pragma binding(msvcrt::_byteswap_ushort, "_byteswap_ushort") +// The legacy msvcrt.dll exports no _byteswap_*; UCRT does. +#pragma binding(ucrtbase::_byteswap_ulong, "_byteswap_ulong") +#pragma binding(ucrtbase::_byteswap_uint64, "_byteswap_uint64") +#pragma binding(ucrtbase::_byteswap_ushort, "_byteswap_ushort") // `__acrt_iob_func(int)` is the CRT helper that returns a // FILE * to the requested standard stream (0=stdin, 1=stdout, // 2=stderr). Used by `__c5_lazy_stream` above to back the @@ -797,9 +807,12 @@ static char *__c5_lazy_stream(int idx) { // Windows-flavoured sources spell the v* names with a leading underscore // (`#define vsnprintf _vsnprintf` is a common MSVC idiom). Alias the // underscored spellings to the canonical names so they resolve through the -// same per-target bindings -- on Windows the canonical names already bind -// to the underscored CRT entry points. +// same per-target bindings. On Windows `_vsnprintf` stays a direct msvcrt +// binding with msvcrt semantics; the canonical `vsnprintf` is the C99 +// definition in the auto-linked runtime. #define _vfprintf vfprintf #define _vprintf vprintf #define _vsprintf vsprintf +#ifndef _WIN32 #define _vsnprintf vsnprintf +#endif diff --git a/headers/include/stdlib.h b/headers/include/stdlib.h index f7a56aa68..73453b7b6 100644 --- a/headers/include/stdlib.h +++ b/headers/include/stdlib.h @@ -90,7 +90,10 @@ #pragma binding(libc::strtol, "strtol") #pragma binding(libc::strtoll, "strtoll") #pragma binding(libc::strtod, "strtod") -#pragma binding(libc::strtof, "strtof") +// The prototype below declares `strtof` as returning double (c5 +// aliases `float` to `double`), so the binding must target the +// double-returning entry point; libc's own `strtof` returns `float`. +#pragma binding(libc::strtof, "strtod") #pragma binding(libc::strtold, "strtold") #pragma binding(libc::abs, "abs") #pragma binding(libc::abort, "abort") @@ -155,7 +158,9 @@ #pragma binding(msvcrt::strtoull, "_strtoui64") #pragma binding(msvcrt::_strtoui64, "_strtoui64") #pragma binding(msvcrt::strtod, "strtod") -#pragma binding(msvcrt::strtof, "strtof") +// msvcrt.dll exports no `strtof` (a UCRT addition); `strtof` routes +// through `strtod`, matching the double-returning prototype below. +#pragma binding(msvcrt::strtof, "strtod") // msvcrt.dll has no `strtold`; UCRT exports it but the // universally-available CRT here does not. Programs that // need `long double` parsing on Windows pin to UCRT. @@ -163,11 +168,12 @@ #pragma binding(msvcrt::abort, "abort") #pragma binding(msvcrt::system, "system") #pragma binding(msvcrt::getenv, "getenv") -// POSIX putenv is msvcrt's underscored `_putenv`; msvcrt's `setenv` -// is `_putenv_s`. Same shapes: (string) -> int and -// (name, value, overwrite) -> int. +// POSIX putenv is msvcrt's underscored `_putenv` (a `(string) -> int` +// shape). msvcrt's `_putenv_s(name, value)` has no overwrite flag and +// always replaces; setenv honors POSIX overwrite via the inline wrapper +// below (declared here, defined after getenv/_putenv_s are in scope). #pragma binding(msvcrt::putenv, "_putenv") -#pragma binding(msvcrt::setenv, "_putenv_s") +#pragma binding(msvcrt::_putenv_s, "_putenv_s") #pragma binding(msvcrt::_wputenv_s, "_wputenv_s") #pragma binding(msvcrt::qsort, "qsort") #pragma binding(msvcrt::bsearch, "bsearch") @@ -326,7 +332,20 @@ _Noreturn int abort(); _Noreturn int exit(int status); int system(char *cmd); char *getenv(char *name); +#ifdef _WIN32 +int _putenv_s(char *name, char *value); +// POSIX setenv (IEEE Std 1003.1): overwrite == 0 leaves an existing +// binding untouched and returns 0. Inline so the compiled, JIT, and +// interpreter paths share one definition without a runtime import. +static inline int setenv(char *name, char *value, int overwrite) { + if (overwrite == 0 && getenv(name) != 0) { + return 0; + } + return _putenv_s(name, value); +} +#else int setenv(char *name, char *value, int overwrite); +#endif int putenv(char *string); // Multibyte / wide-character string conversion (C99 7.20.8). `wchar_t` // and `size_t` come from . diff --git a/headers/include/string.h b/headers/include/string.h index a247effe6..057bfe5a8 100644 --- a/headers/include/string.h +++ b/headers/include/string.h @@ -181,6 +181,14 @@ char *strchrnul(const char *s, int c); char *memrchr(char *s, int c, int n); void explicit_bzero(void *s, size_t n); #endif +// C11 K.3.7.4.1, visible on the Annex-K opt-in like the platform +// header; libSystem exports it, glibc does not. +#if defined(__APPLE__) && defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 +#pragma binding(libc::memset_s, "_memset_s") +typedef int errno_t; +typedef size_t rsize_t; +errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n); +#endif #ifdef _WIN32 // Case-insensitive compares -- msvcrt-only, no POSIX equivalent // in the c5 surface. Names match the underscored entries diff --git a/headers/include/sys/auxv.h b/headers/include/sys/auxv.h new file mode 100644 index 000000000..d5f33f7ae --- /dev/null +++ b/headers/include/sys/auxv.h @@ -0,0 +1,14 @@ +// sys/auxv.h -- read entries from the ELF auxiliary vector (glibc). + +#pragma once + +#ifdef __linux__ +#include + +#pragma dylib(libc, "libc.so.6") +#pragma binding(libc::getauxval, "getauxval") + +// Value of the auxiliary-vector entry `type` (an AT_* constant), or 0 +// with errno ENOENT when the vector carries no such entry. +unsigned long getauxval(unsigned long type); +#endif diff --git a/headers/include/sys/cdefs.h b/headers/include/sys/cdefs.h new file mode 100644 index 000000000..bd9264982 --- /dev/null +++ b/headers/include/sys/cdefs.h @@ -0,0 +1,22 @@ +/* BSD/Darwin : the decoration macros system headers wrap +** declarations in. For a plain C compiler they carry no effect. */ +#pragma once + +#define __BEGIN_DECLS +#define __END_DECLS +#define __THROW +#define __pure +#define __const const +#define __restrict restrict +#define __dead2 +#define __pure2 +#define __unused +#define __used +#define __deprecated +#define __restrict_arr +#define __P(protos) protos +#define __DARWIN_ALIAS(sym) +#define __DARWIN_ALIAS_C(sym) +#define __DARWIN_ALIAS_I(sym) +#define __DARWIN_INODE64(sym) +#define __GNUC_PREREQ(maj, min) 0 diff --git a/headers/include/sys/file.h b/headers/include/sys/file.h new file mode 100644 index 000000000..297f81340 --- /dev/null +++ b/headers/include/sys/file.h @@ -0,0 +1,26 @@ +// sys/file.h -- BSD advisory whole-file locks (flock(2)). + +#pragma once + +#if defined(__APPLE__) || defined(__linux__) + +// Operation bits; identical in Darwin and glibc +// . +#define LOCK_SH 0x01 +#define LOCK_EX 0x02 +#define LOCK_NB 0x04 +#define LOCK_UN 0x08 + +#ifdef __APPLE__ +#pragma dylib(libc, "/usr/lib/libSystem.B.dylib") +#pragma binding(libc::flock, "_flock") +#endif +#ifdef __linux__ +#pragma dylib(libc, "libc.so.6") +#pragma binding(libc::flock, "flock") +#endif + +// Apply or remove an advisory lock on the open file `fd`; `operation` +// is LOCK_SH, LOCK_EX, or LOCK_UN, optionally or'ed with LOCK_NB. +int flock(int fd, int operation); +#endif diff --git a/headers/include/sys/ioctl.h b/headers/include/sys/ioctl.h index 7e2f63271..8f3c32585 100644 --- a/headers/include/sys/ioctl.h +++ b/headers/include/sys/ioctl.h @@ -32,32 +32,46 @@ struct winsize { #define TIOCGWINSZ 0x5413 #endif -int ioctl(int fd, unsigned long request, void *argp); +// POSIX (XSH) and both target libcs declare ioctl variadic; Darwin's +// wrapper reads the argument via va_arg, so a fixed-arity prototype +// passes it where the callee does not look (Darwin arm64 takes +// variadic arguments from the stack). +int ioctl(int fd, unsigned long request, ...); // ioctl request codes referenced by terminal/file modules. Per-target codes. #ifndef FIOASYNC #if defined(__APPLE__) #define FIOASYNC 2147772029 +#elif defined(__linux__) +#define FIOASYNC 0x5452 #endif #endif #ifndef FIOCLEX #if defined(__APPLE__) #define FIOCLEX 536897025 +#elif defined(__linux__) +#define FIOCLEX 0x5451 #endif #endif #ifndef FIONBIO #if defined(__APPLE__) #define FIONBIO 2147772030 +#elif defined(__linux__) +#define FIONBIO 0x5421 #endif #endif #ifndef FIONCLEX #if defined(__APPLE__) #define FIONCLEX 536897026 +#elif defined(__linux__) +#define FIONCLEX 0x5450 #endif #endif #ifndef FIONREAD #if defined(__APPLE__) #define FIONREAD 1074030207 +#elif defined(__linux__) +#define FIONREAD 0x541b #endif #endif #ifdef __APPLE__ diff --git a/headers/include/sys/locking.h b/headers/include/sys/locking.h new file mode 100644 index 000000000..b8b8e772c --- /dev/null +++ b/headers/include/sys/locking.h @@ -0,0 +1,12 @@ +// sys/locking.h -- mode argument of the CRT's `_locking` (declared in +// /). Values pinned by the CRT header of the same name. + +#pragma once + +#ifdef _WIN32 +#define _LK_UNLCK 0 +#define _LK_LOCK 1 +#define _LK_NBLCK 2 +#define _LK_RLCK 3 +#define _LK_NBRLCK 4 +#endif diff --git a/headers/include/sys/mman.h b/headers/include/sys/mman.h index 795004982..4a0dbb5a9 100644 --- a/headers/include/sys/mman.h +++ b/headers/include/sys/mman.h @@ -43,7 +43,7 @@ #pragma dylib(libc, "/usr/lib/libSystem.B.dylib") #pragma binding(libc::mmap, "_mmap") #pragma binding(libc::munmap, "_munmap") -#pragma binding(libc::mremap, "_mremap") +// mremap is Linux-only; unbound here so a use fails at link. #pragma binding(libc::msync, "_msync") #pragma binding(libc::mprotect, "_mprotect") #pragma binding(libc::madvise, "_madvise") @@ -66,10 +66,8 @@ #pragma binding(libc::shm_open, "shm_open") #pragma binding(libc::shm_unlink, "shm_unlink") #pragma binding(libc::memfd_create, "memfd_create") -// memfd_create flags. -#define MFD_CLOEXEC 0x0001 -#define MFD_ALLOW_SEALING 0x0002 -#define MFD_HUGETLB 0x0004 +// The MFD_* flags live in their canonical kernel header. +#include int memfd_create(const char *name, unsigned int flags); #endif @@ -83,6 +81,13 @@ char *mremap(char *old, unsigned long old_size, unsigned long new_size, int flag int msync(char *addr, unsigned long len, int flags); int mprotect(char *addr, unsigned long len, int prot); int madvise(char *addr, unsigned long len, int advice); -// POSIX shared memory objects; mode is mode_t (an unsigned int on the targets). +// POSIX shared memory objects; mode is mode_t (an unsigned int on the +// targets). Darwin declares shm_open variadic and reads the mode via +// va_arg (from the stack on arm64), so the prototype must match; glibc +// declares the fixed three-argument POSIX shape. +#ifdef __APPLE__ +int shm_open(const char *name, int oflag, ...); +#else int shm_open(const char *name, int oflag, int mode); +#endif int shm_unlink(const char *name); diff --git a/headers/include/sys/pidfd.h b/headers/include/sys/pidfd.h new file mode 100644 index 000000000..06a44f1cc --- /dev/null +++ b/headers/include/sys/pidfd.h @@ -0,0 +1,21 @@ +// sys/pidfd.h -- process file descriptors (glibc 2.36, Linux 5.3+). + +#pragma once + +#ifdef __linux__ +#include +#include +#include + +// Matches the kernel uapi definition: O_NONBLOCK on every arch. +#define PIDFD_NONBLOCK O_NONBLOCK + +#pragma dylib(libc, "libc.so.6") +#pragma binding(libc::pidfd_open, "pidfd_open") +#pragma binding(libc::pidfd_getfd, "pidfd_getfd") +#pragma binding(libc::pidfd_send_signal, "pidfd_send_signal") + +int pidfd_open(pid_t pid, unsigned int flags); +int pidfd_getfd(int pidfd, int targetfd, unsigned int flags); +int pidfd_send_signal(int pidfd, int sig, siginfo_t *info, unsigned int flags); +#endif diff --git a/headers/include/sys/sys_domain.h b/headers/include/sys/sys_domain.h new file mode 100644 index 000000000..3010198a6 --- /dev/null +++ b/headers/include/sys/sys_domain.h @@ -0,0 +1,18 @@ +// sys/sys_domain.h -- Darwin AF_SYSTEM kernel-socket domain. + +#pragma once + +#ifdef __APPLE__ +#include + +#define SYSPROTO_EVENT 1 +#define SYSPROTO_CONTROL 2 +#define AF_SYS_CONTROL 2 + +struct sockaddr_sys { + unsigned char ss_len; + unsigned char ss_family; + uint16_t ss_sysaddr; + uint32_t ss_reserved[7]; +}; +#endif diff --git a/headers/include/sys/sysctl.h b/headers/include/sys/sysctl.h new file mode 100644 index 000000000..ffd438e8d --- /dev/null +++ b/headers/include/sys/sysctl.h @@ -0,0 +1,49 @@ +// sys/sysctl.h -- Darwin sysctl(3) MIB interface: the common CTL_KERN +// and CTL_HW names plus the three entry points. TODO: the per-subtree +// name tables. + +#pragma once + +#ifdef __APPLE__ +#include + +#define CTL_MAXNAME 12 +#define CTL_KERN 1 +#define CTL_VM 2 +#define CTL_NET 4 +#define CTL_HW 6 +#define CTL_MACHDEP 7 +#define CTL_USER 8 + +#define KERN_OSTYPE 1 +#define KERN_OSRELEASE 2 +#define KERN_OSREV 3 +#define KERN_VERSION 4 +#define KERN_MAXVNODES 5 +#define KERN_ARGMAX 8 +#define KERN_HOSTNAME 10 +#define KERN_PROC 14 +#define KERN_OSVERSION 65 + +#define HW_MACHINE 1 +#define HW_MODEL 2 +#define HW_NCPU 3 +#define HW_BYTEORDER 4 +#define HW_PHYSMEM 5 +#define HW_USERMEM 6 +#define HW_PAGESIZE 7 +#define HW_MACHINE_ARCH 12 +#define HW_MEMSIZE 24 +#define HW_AVAILCPU 25 + +#pragma dylib(libc, "/usr/lib/libSystem.B.dylib") +#pragma binding(libc::sysctl, "_sysctl") +#pragma binding(libc::sysctlbyname, "_sysctlbyname") +#pragma binding(libc::sysctlnametomib, "_sysctlnametomib") + +int sysctl(int *name, unsigned int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen); +int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp, + size_t newlen); +int sysctlnametomib(const char *name, int *mibp, size_t *sizep); +#endif diff --git a/headers/include/sys/utime.h b/headers/include/sys/utime.h new file mode 100644 index 000000000..b00d5e457 --- /dev/null +++ b/headers/include/sys/utime.h @@ -0,0 +1,24 @@ +// sys/utime.h -- the CRT home of the file-time interface; the POSIX +// spellings live in . The underscored CRT spellings are +// declared here on Windows. + +#pragma once + +#include + +#ifdef _WIN32 +// Same layout as `struct utimbuf`: two 8-byte time_t second counts. +struct _utimbuf { + time_t actime; + time_t modtime; +}; + +#pragma dylib(msvcrt, "msvcrt.dll") +#pragma binding(msvcrt::_utime, "_utime") +#pragma binding(msvcrt::_futime, "_futime") +#pragma binding(msvcrt::_wutime, "_wutime") + +int _utime(const char *path, struct _utimbuf *times); +int _futime(int fd, struct _utimbuf *times); +int _wutime(const unsigned short *path, struct _utimbuf *times); +#endif diff --git a/headers/include/sysexits.h b/headers/include/sysexits.h new file mode 100644 index 000000000..58665f947 --- /dev/null +++ b/headers/include/sysexits.h @@ -0,0 +1,24 @@ +// sysexits.h -- BSD exit-status codes (sysexits(3)). + +#pragma once + +#if defined(__APPLE__) || defined(__linux__) +#define EX_OK 0 +#define EX__BASE 64 +#define EX_USAGE 64 +#define EX_DATAERR 65 +#define EX_NOINPUT 66 +#define EX_NOUSER 67 +#define EX_NOHOST 68 +#define EX_UNAVAILABLE 69 +#define EX_SOFTWARE 70 +#define EX_OSERR 71 +#define EX_OSFILE 72 +#define EX_CANTCREAT 73 +#define EX_IOERR 74 +#define EX_TEMPFAIL 75 +#define EX_PROTOCOL 76 +#define EX_NOPERM 77 +#define EX_CONFIG 78 +#define EX__MAX 78 +#endif diff --git a/headers/include/time.h b/headers/include/time.h index d7689a1bb..0d8245186 100644 --- a/headers/include/time.h +++ b/headers/include/time.h @@ -125,7 +125,7 @@ typedef long clock_t; #pragma binding(libc::clock_gettime, "_clock_gettime") #pragma binding(libc::clock_settime, "_clock_settime") #pragma binding(libc::clock_getres, "_clock_getres") -#pragma binding(libc::clock_nanosleep, "_clock_nanosleep") +// libSystem exports no clock_nanosleep; unbound so a use fails at link. #pragma binding(libc::gettimeofday, "_gettimeofday") #pragma binding(libc::difftime, "_difftime") #pragma binding(libc::mktime, "_mktime") @@ -179,6 +179,13 @@ typedef long clock_t; #pragma binding(msvcrt::gmtime, "gmtime") #pragma binding(msvcrt::strftime, "strftime") #pragma binding(msvcrt::tzset, "_tzset") +// msvcrt.dll exports the tzset outputs as data on both x64 and +// arm64 (probed on the real boxes); bind each as a loader-filled +// import so a read after `tzset()` sees the CRT's values -- the +// same treatment as `environ` (see ). +#pragma binding(data msvcrt::tzname, "_tzname") +#pragma binding(data msvcrt::timezone, "_timezone") +#pragma binding(data msvcrt::daylight, "_daylight") // Windows doesn't ship POSIX `clock_gettime` / `gettimeofday`. SQLite // has its own Win32-specific code path that calls // `GetSystemTimeAsFileTime`; programs that want a portable shape diff --git a/headers/include/unistd.h b/headers/include/unistd.h index fe48dae81..b04d0ad0e 100644 --- a/headers/include/unistd.h +++ b/headers/include/unistd.h @@ -136,7 +136,7 @@ #pragma binding(libc::fpathconf, "_fpathconf") #pragma binding(libc::lockf, "_lockf") #pragma binding(libc::execv, "_execv") -#pragma binding(libc::fexecve, "_fexecve") +// libSystem exports no fexecve; unbound so a use fails at link. #pragma binding(libc::pathconf, "_pathconf") #pragma binding(libc::sysconf, "_sysconf") #pragma binding(libc::getpagesize, "_getpagesize") @@ -257,7 +257,7 @@ extern char **environ; #pragma binding(libc::ttyname, "ttyname") #pragma binding(libc::ttyname_r, "ttyname_r") #pragma binding(libc::ctermid, "ctermid") -#pragma binding(libc::ctermid_r, "ctermid_r") +// glibc exports no ctermid_r; unbound so a use fails at link. #pragma binding(libc::getlogin, "getlogin") #pragma binding(libc::getlogin_r,"getlogin_r") #pragma binding(libc::getgroups, "getgroups") diff --git a/headers/include/versionhelpers.h b/headers/include/versionhelpers.h new file mode 100644 index 000000000..b7301b48d --- /dev/null +++ b/headers/include/versionhelpers.h @@ -0,0 +1,53 @@ +// versionhelpers.h -- OS version predicates, implemented over +// VerifyVersionInfoW exactly as the SDK header does. + +#pragma once + +#ifdef _WIN32 +#include +#include + +static inline BOOL IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, + WORD wServicePackMajor) { + OSVERSIONINFOEXW osvi = {0}; + DWORDLONG mask = 0; + VER_SET_CONDITION(mask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(mask, VER_MINORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + osvi.dwOSVersionInfoSize = sizeof(osvi); + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + return VerifyVersionInfoW(&osvi, + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, + mask) != 0; +} + +static inline BOOL IsWindowsXPOrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0); +} + +static inline BOOL IsWindowsVistaOrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); +} + +static inline BOOL IsWindows7OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0); +} + +static inline BOOL IsWindows7SP1OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1); +} + +static inline BOOL IsWindows8OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0); +} + +static inline BOOL IsWindows8Point1OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0); +} + +// TODO: IsWindows10OrGreater needs the manifest-gated +// RtlGetVersion/VerifyVersionInfo semantics change; IsWindowsServer +// needs VER_PRODUCT_TYPE. +#endif diff --git a/headers/include/winbase.h b/headers/include/winbase.h new file mode 100644 index 000000000..01505546a --- /dev/null +++ b/headers/include/winbase.h @@ -0,0 +1,7 @@ +// winbase.h -- in the SDK this is a sub-header, never +// included standalone; badc keeps the kernel32 surface in +// itself, so this name resolves to it. + +#pragma once + +#include diff --git a/headers/include/windows.h b/headers/include/windows.h index 7165c5fcd..ed14965aa 100644 --- a/headers/include/windows.h +++ b/headers/include/windows.h @@ -1676,8 +1676,10 @@ LONG RegSetValueExW(HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType #pragma binding(kernel32::GetNativeSystemInfo, "GetNativeSystemInfo") #pragma binding(kernel32::GetProcessHeap, "GetProcessHeap") #pragma binding(kernel32::GetProcAddressA, "GetProcAddress") -#pragma binding(kernel32::CharLowerW, "CharLowerW") -#pragma binding(kernel32::CharUpperW, "CharUpperW") +// CharLowerW / CharUpperW are user32.dll exports (winuser.h). +#pragma dylib(user32, "user32.dll") +#pragma binding(user32::CharLowerW, "CharLowerW") +#pragma binding(user32::CharUpperW, "CharUpperW") #pragma binding(kernel32::CreateFileA, "CreateFileA") #pragma binding(kernel32::CreateFileTransactedA, "CreateFileTransactedA") #pragma binding(kernel32::CreateFileTransactedW, "CreateFileTransactedW") @@ -1848,13 +1850,11 @@ LONG RegSetValueExW(HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType #pragma binding(kernel32::TzSpecificLocalTimeToSystemTime, "TzSpecificLocalTimeToSystemTime") #pragma binding(kernel32::GetLocalTime, "GetLocalTime") #pragma binding(kernel32::SetLastError, "SetLastError") -// rpcrt4-resident UUID helpers; sqlite gates these on -// `SQLITE_WIN32_USE_UUID`. The kernel32 dylib hosts the binding -// nominally -- runtime resolution still goes through the -// dispatch table -- but production-quality runs would bind these -// to rpcrt4.dll. -#pragma binding(kernel32::UuidCreate, "UuidCreate") -#pragma binding(kernel32::UuidCreateSequential, "UuidCreateSequential") +// UuidCreate / UuidCreateSequential are rpcrt4.dll exports (rpcdce.h); +// binding them to kernel32 fails at load. +#pragma dylib(rpcrt4, "rpcrt4.dll") +#pragma binding(rpcrt4::UuidCreate, "UuidCreate") +#pragma binding(rpcrt4::UuidCreateSequential, "UuidCreateSequential") // Prototypes mirror the Win32 API shapes documented on MSDN. Where // the real return type is `BOOL` (= int) we keep `int`; where it's diff --git a/headers/include/winioctl.h b/headers/include/winioctl.h new file mode 100644 index 000000000..f9870092f --- /dev/null +++ b/headers/include/winioctl.h @@ -0,0 +1,7 @@ +// winioctl.h -- device I/O control interface. badc's +// carries the FILE_DEVICE_*, FSCTL_*, and reparse-point constants the +// SDK defines here. + +#pragma once + +#include diff --git a/lib/runtime.c b/lib/runtime.c index 21d2ab387..6041f4a24 100644 --- a/lib/runtime.c +++ b/lib/runtime.c @@ -5,13 +5,65 @@ // `embedded_headers` registry) and compiled + linked alongside the // user's translation units. // -// Everything here is gated on `__BADC_C5_START__`, which the driver -// defines only when the image writer emits an entry stub -- i.e. for -// a hosted executable. Shared libraries and passthrough-entry -// subsystems (native / EFI) leave it undefined and link none of it: -// they carry no user-mode CRT import (a kernel-mode driver cannot -// resolve `msvcrt!exit`), and `environ` belongs to the host process, -// not a library that imports it. +// Two gates, both defined by the driver: +// +// * `__BADC_C5_CRT__` -- the image may import the user-mode C +// library (hosted executables and shared libraries; native / EFI +// subsystems and freestanding images leave it undefined -- a +// kernel-mode driver cannot resolve `msvcrt!exit`). +// * `__BADC_C5_START__` -- the image writer emits an entry stub +// (hosted executables only). Shared libraries link the CRT section +// but not the startup section: `environ` belongs to the host +// process, not a library that imports it. + +#ifdef __BADC_C5_CRT__ +#ifdef _WIN32 + +// C99 7.19.6.5p3 / 7.19.6.12p3: snprintf / vsnprintf return the +// length the output would have had without truncation and always +// NUL-terminate a nonempty buffer. msvcrt's `_vsnprintf` returns -1 +// on truncation and omits the NUL, so the standard spellings resolve +// to these definitions (`` declares them without a binding +// on Windows); `_vscprintf` supplies the untruncated length. +#pragma dylib(libc, "msvcrt.dll") +#pragma binding(libc::_vsnprintf, "_vsnprintf") +#pragma binding(libc::_vscprintf, "_vscprintf") + +extern int _vsnprintf(char *buf, unsigned long long count, char *fmt, void *ap); +extern int _vscprintf(char *fmt, void *ap); + +int vsnprintf(char *buf, int size, char *fmt, void *ap) { + int len = _vscprintf(fmt, ap); + if (len < 0) { + return len; + } + if (size > 0) { + _vsnprintf(buf, size, fmt, ap); + if (len >= size) { + buf[size - 1] = 0; + } + } + return len; +} + +// Windows `va_list` is a byte cursor over the home area / stack +// (see ``); the intrinsics take the cursor's address. +#pragma intrinsic("__builtin_va_start") +#pragma intrinsic("__builtin_va_end") +void __builtin_va_start(void **ap, void *last_addr); +void __builtin_va_end(void **ap); + +int snprintf(char *buf, int size, char *fmt, ...) { + void *ap; + int len; + __builtin_va_start(&ap, (void *)&fmt); + len = vsnprintf(buf, size, fmt, ap); + __builtin_va_end(&ap); + return len; +} + +#endif +#endif #ifdef __BADC_C5_START__ @@ -39,11 +91,13 @@ #if !defined(__APPLE__) && !defined(_WIN32) char **environ; #endif -#ifndef __APPLE__ +#if defined(__linux__) // POSIX `tzset` outputs. Like `environ`, the Linux bindings route these // through a COPY relocation against the C library's symbols so a read // after `tzset()` sees what the library wrote; the local slots here are -// the relocation targets. +// the relocation targets. Windows binds them as msvcrt data imports on +// both architectures (see ), so the symbols must stay +// undefined there. char *tzname[2]; long timezone; int daylight; diff --git a/src/c5/ast/mod.rs b/src/c5/ast/mod.rs index c645063a1..d8dc35cbc 100644 --- a/src/c5/ast/mod.rs +++ b/src/c5/ast/mod.rs @@ -340,6 +340,15 @@ pub(crate) enum Expr { array_size: i64, init: LocalInit, }, + /// A variable-length array identifier in a value context (C99 + /// 6.3.2.1p3 decay). The array's storage is at a runtime address + /// held in `ptr_slot`; the walker loads that pointer. `ty` is the + /// decayed element-pointer type. + VlaBase { ptr_slot: i64, ty: i64 }, + /// `sizeof ` -- the runtime byte count the matching + /// `Decl::Vla` stored into `size_slot` (C99 6.5.3.4p2: for a VLA + /// the operand is evaluated and the result is a runtime value). + VlaSizeof { size_slot: i64 }, } /// One item inside a compound statement. C99 6.8.2's @@ -412,6 +421,13 @@ pub(crate) enum Stmt { /// `parse_block_stmt` can capture decls alongside stmts via a /// single stmt-id sequence. Decl(DeclId), + /// Snapshot the per-frame alloca-arena top into `save_slot` on + /// entry to a block that declares a variable-length array. Paired + /// with `VlaScopeExit` so the VLA storage is reclaimed on block + /// exit and, for a loop body, on every iteration (C99 6.2.4p2). + VlaScopeEnter { save_slot: i64 }, + /// Restore the alloca-arena top from `save_slot` on block exit. + VlaScopeExit { save_slot: i64 }, } /// One stored element in a runtime aggregate initializer. @@ -476,10 +492,21 @@ pub(crate) enum Decl { slot_off: i64, init: LocalInit, }, - /// Variable-length array declaration. `dim` is the runtime - /// dimension expression; the walker emits `Inst::AllocaInit` - /// to reserve the matching stack region. C99 6.7.6.2p4. - Vla { sym: u32, dim: ExprId }, + /// Variable-length array declaration (C99 6.7.6.2). `dim` is the + /// runtime element-count expression; `elem_size` is the element's + /// byte size. The walker evaluates `dim * elem_size`, allocates + /// that many bytes from the per-frame alloca arena, stores the + /// base pointer into `ptr_slot`, and the byte count into + /// `size_slot` (read back by `sizeof`). `elem_ty` carries the + /// element type for struct-size remapping. + Vla { + sym: u32, + elem_ty: i64, + elem_size: i64, + ptr_slot: i64, + size_slot: i64, + dim: ExprId, + }, /// Block-scope `static T name [= init];` declaration. C99 /// 6.2.4p3 (lifetime is whole program) + 6.7.8p4 (init must /// be constant). The parser promotes the symbol to the `Glo` @@ -839,10 +866,10 @@ impl Ast { /// tags carried outside the AST (e.g. `FinishedFunction::param_tys`, /// `Symbol::type_`). pub(crate) fn remap_struct_ty(ty: i64, remap: &[usize]) -> i64 { - use crate::c5::compiler::types::UNSIGNED_BIT; use crate::c5::compiler::types::{STRUCT_BASE, STRUCT_STRIDE}; + use crate::c5::compiler::types::{UNSIGNED_BIT, VOLATILE_BIT}; let unsigned = ty & UNSIGNED_BIT; - let stripped = ty & !UNSIGNED_BIT; + let stripped = ty & !(UNSIGNED_BIT | VOLATILE_BIT); if stripped < STRUCT_BASE { return ty; } @@ -876,7 +903,9 @@ fn visit_expr_ty(expr: &mut Expr, f: &mut impl FnMut(&mut i64)) { | Expr::Comma { ty, .. } | Expr::ShortCircuit { ty, .. } | Expr::Intrinsic { ty, .. } - | Expr::Atomic { ty, .. } => f(ty), + | Expr::Atomic { ty, .. } + | Expr::VlaBase { ty, .. } => f(ty), + Expr::VlaSizeof { .. } => {} Expr::Cast { to_ty, .. } => f(to_ty), Expr::CompoundLiteral { ty, init, .. } => { f(ty); @@ -902,7 +931,8 @@ fn visit_decl_ty(decl: &mut Decl, f: &mut impl FnMut(&mut i64)) { } } } - Decl::Vla { .. } | Decl::StaticLocal { .. } => {} + Decl::Vla { elem_ty, .. } => f(elem_ty), + Decl::StaticLocal { .. } => {} } } diff --git a/src/c5/ast/walk.rs b/src/c5/ast/walk.rs index 33e3e4f1c..9e470cd89 100644 --- a/src/c5/ast/walk.rs +++ b/src/c5/ast/walk.rs @@ -12,8 +12,8 @@ use alloc::string::String; use super::super::codegen::Target; use super::super::compiler::types::{ - STRUCT_BASE, STRUCT_STRIDE, UNSIGNED_BIT, is_pointer_ty, is_struct_ty, load_kind, - struct_ptr_depth, + STRUCT_BASE, STRUCT_STRIDE, UNSIGNED_BIT, VOLATILE_BIT, is_pointer_ty, is_struct_ty, + is_volatile_ty, load_kind, strip_unsigned, struct_ptr_depth, }; use super::super::ir::{AtomicRmwOp, BinOp, FunctionSsa, LoadKind, StoreKind}; use super::super::symbol::Symbol; @@ -202,11 +202,9 @@ pub(crate) fn walk_function( // here exactly as they are from the seed loop below. if !is_variadic && !ret_outptr { for (i, &pty) in param_tys.iter().enumerate() { - let stripped = pty & !(1i64 << 30); - let is_pointer = pty & (1i64 << 30) != 0; - if !is_pointer - && (stripped == crate::c5::token::Ty::Float as i64 - || stripped == crate::c5::token::Ty::Double as i64) + let stripped = strip_unsigned(pty); + if stripped == crate::c5::token::Ty::Float as i64 + || stripped == crate::c5::token::Ty::Double as i64 { b.mark_param_fp(i); } @@ -266,7 +264,7 @@ pub(crate) fn walk_function( if local_slot < 0 { continue; } - let stripped = pty & !(1i64 << 30); + let stripped = strip_unsigned(pty); let is_struct_value = stripped >= STRUCT_BASE && ((stripped - STRUCT_BASE) % STRUCT_STRIDE) / 2 == 0; if is_struct_value { @@ -310,15 +308,14 @@ pub(crate) fn walk_function( ) { continue; } - // Pointer-typed parameters carry the pointer marker - // bit; the body reads them as full-width pointers - // (8 bytes), not as the base type's narrow width. - // Without this check `char *fmt` would store only one - // byte and the high bits would diverge from the - // prologue's full-width spill. + // An unsigned-tagged parameter keeps the full 8-byte + // store/load so the body's zero-extending reads see the + // caller's extension rather than a sign-extended narrow + // reload. Pointer tags land in the I64 default arm by + // band value. use crate::c5::token::Ty; - let is_pointer = pty & (1i64 << 30) != 0; - let (store_kind, load_kind) = if is_pointer { + let unsigned = pty & UNSIGNED_BIT != 0; + let (store_kind, load_kind) = if unsigned { ( super::super::ir::StoreKind::I64, super::super::ir::LoadKind::I64, @@ -354,7 +351,7 @@ pub(crate) fn walk_function( if local_slot >= 0 { continue; } - let stripped = pty & !(1i64 << 30); + let stripped = strip_unsigned(pty); let is_struct_value = stripped >= STRUCT_BASE && ((stripped - STRUCT_BASE) % STRUCT_STRIDE) / 2 == 0; if is_struct_value { @@ -709,7 +706,7 @@ impl<'a> Walker<'a> { /// struct id is out of range (defensive -- the parser /// shouldn't emit such a type). fn struct_size(&self, ty: i64) -> i64 { - let stripped = ty & !UNSIGNED_BIT; + let stripped = ty & !(UNSIGNED_BIT | VOLATILE_BIT); if stripped < STRUCT_BASE { return 0; } @@ -720,6 +717,12 @@ impl<'a> Walker<'a> { 0 } } + /// True when the expression's type tag carries the volatile + /// qualifier (C99 6.7.3); `false` for node shapes without a type. + fn expr_is_volatile(&self, id: ExprId) -> bool { + expr_ty(self.ast.expr(id)).is_some_and(is_volatile_ty) + } + /// Walk a statement. Returns `true` when the statement /// terminates the current block (an unconditional return / /// jmp), letting the caller stop iterating siblings that @@ -771,7 +774,7 @@ impl<'a> Walker<'a> { // the result register at full width. `_Bool` is excluded: its // conversion is a boolean `!= 0` (6.3.1.2), not a width mask, // and the rvalue walk already normalizes it to 0/1. - let stripped = self.scalar_return_ty & !UNSIGNED_BIT; + let stripped = self.scalar_return_ty & !(UNSIGNED_BIT | VOLATILE_BIT); let rs = type_size_bytes(self.scalar_return_ty, self.target); if !is_floating_scalar(self.scalar_return_ty) && !is_pointer_ty(self.scalar_return_ty) @@ -1074,6 +1077,17 @@ impl<'a> Walker<'a> { } sorted.sort_by_key(|p| p.0 as u64); } else { + // Signed controlling type: a 4-byte type promotes to + // itself and a sub-int type to signed `int`, so the + // label converts by sign-truncation to 32 bits -- + // `case 0x80000000:` on an `int` switch must match + // the sign-extended INT_MIN discriminant. An 8-byte + // type keeps the full-width label. + if type_size_bytes(disc_ty, self.target) <= 4 { + for c in sorted.iter_mut() { + c.0 = (c.0 as i32) as i64; + } + } sorted.sort_by_key(|p| p.0); } let lt_op = if disc_unsigned { BinOp::Ult } else { BinOp::Lt }; @@ -1136,6 +1150,26 @@ impl<'a> Walker<'a> { self.walk_decl(b, decl_id)?; Ok(false) } + // C99 6.2.4p2: snapshot the alloca-arena top on entry to a + // VLA-declaring block, restore it on exit so the storage is + // reclaimed (per loop iteration for a loop body). + Stmt::VlaScopeEnter { save_slot } => { + let slot = *save_slot; + let top = b.intrinsic( + super::super::op::Intrinsic::AllocaSave as i64, + alloc::vec::Vec::new(), + ); + b.store_local(slot, top, super::super::ir::StoreKind::I64); + Ok(false) + } + Stmt::VlaScopeExit { save_slot } => { + let saved = b.load_local(*save_slot, super::super::ir::LoadKind::I64); + b.intrinsic( + super::super::op::Intrinsic::AllocaRestore as i64, + alloc::vec![saved], + ); + Ok(false) + } } } @@ -1164,10 +1198,34 @@ impl<'a> Walker<'a> { let init_clone = init.clone(); self.emit_local_init(b, slot, ty, &init_clone) } - super::super::ast::Decl::Vla { .. } => Err(WalkError::UnsupportedStmt { - id: 0, - kind: "Decl::Vla", - }), + super::super::ast::Decl::Vla { + elem_size, + ptr_slot, + size_slot, + dim, + .. + } => { + // C99 6.7.6.2: allocate `count * sizeof(elem)` bytes + // from the per-frame alloca arena, store the base + // pointer for decay and the byte count for `sizeof`. + let elem_size = *elem_size; + let ptr_slot = *ptr_slot; + let size_slot = *size_slot; + let dim = *dim; + let n = self.walk_expr_rvalue(b, dim)?; + let bytes = if elem_size == 1 { + n + } else { + b.binop_imm(BinOp::Mul, n, elem_size) + }; + b.store_local(size_slot, bytes, super::super::ir::StoreKind::I64); + let ptr = b.intrinsic( + super::super::op::Intrinsic::Alloca as i64, + alloc::vec![bytes], + ); + b.store_local(ptr_slot, ptr, super::super::ir::StoreKind::I64); + Ok(()) + } super::super::ast::Decl::StaticLocal { .. } => { // C99 6.2.4p3 + 6.7.8p4: storage + initializer // live in the data segment; nothing to emit in @@ -1211,7 +1269,7 @@ impl<'a> Walker<'a> { // A direct `StoreLocal` keeps the slot mem2reg-promotable. // The `F32` s-view store is narrowed by the per-arch emit // when the value is still double. - b.store_local(slot, v, kind); + b.store_local_vol(slot, v, kind, is_volatile_ty(ty)); Ok(()) } super::super::ast::LocalInit::Aggregate { @@ -1254,7 +1312,7 @@ impl<'a> Walker<'a> { continue; } let kind = store_kind_for(elem.ty, self.target); - b.store(addr, v, kind); + b.store_vol(addr, v, kind, is_volatile_ty(elem.ty)); } Ok(()) } @@ -1686,8 +1744,9 @@ impl<'a> Walker<'a> { field_off, bitfield, rhs, - .. + ty, } => { + let vol = is_volatile_ty(*ty) || self.expr_is_volatile(*obj); // C99 6.7.2.1: bitfield write -- load the storage // unit, clear the destination slice, mask + shift // the new value into place, OR the cleared old @@ -1731,7 +1790,7 @@ impl<'a> Walker<'a> { // this read-modify-write, else its store is clobbered. let rhs_v = self.walk_expr_rvalue(b, *rhs)?; let masked = b.binop_imm(BinOp::And, rhs_v, mask); - let old = b.load(addr, load_kind); + let old = b.load_vol(addr, load_kind, vol); let cleared = b.binop_imm(BinOp::And, old, clear_mask); let shifted = if bf.bit_offset > 0 { b.binop_imm(BinOp::Shl, masked, bf.bit_offset as i64) @@ -1739,7 +1798,7 @@ impl<'a> Walker<'a> { masked }; let combined = b.binop(BinOp::Or, cleared, shifted); - b.store(addr, combined, store_kind); + b.store_vol(addr, combined, store_kind, vol); // C99 6.5.16p3: the value of the assignment is the value // stored in the bitfield converted to its declared type -- // the right-aligned masked field value, sign-extended for a @@ -1775,6 +1834,7 @@ impl<'a> Walker<'a> { // promotable. The `F32` s-view is narrowed below before // the store so the assignment yields the f32 value. let kind = store_kind_for(*ty, self.target); + let vol = is_volatile_ty(*ty) || self.expr_is_volatile(*lhs); if let Expr::Ident { class, val, @@ -1792,7 +1852,7 @@ impl<'a> Walker<'a> { if matches!(kind, StoreKind::F32) { value = b.fp_narrow_to_f32(value); } - b.store_local(slot, value, kind); + b.store_local_vol(slot, value, kind, vol); // C99 6.5.16p3: the assignment expression's value has // the converted type of the left operand. The store // truncated the stored bytes; the value carried @@ -1812,7 +1872,7 @@ impl<'a> Walker<'a> { if matches!(kind, StoreKind::F32) { value = b.fp_narrow_to_f32(value); } - b.store(addr, value, kind); + b.store_vol(addr, value, kind, vol); // C99 6.5.16p3: the assignment expression's value has the // converted type of the left operand. The store truncated // the stored bytes; the value carried forward to an @@ -1834,7 +1894,7 @@ impl<'a> Walker<'a> { // substitute the `ShortCircuit` arm uses -- both // arms store the arm result and the merge block // loads it. Width is taken from the result type: - // FP-typed ternary uses `Store { kind: F32 }` / + // an FP-typed ternary uses `StoreLocal { kind: F32 }` / // `LoadLocal { kind: F32 }` so the codegen routes // through the FP register class; everything else // stays on the I64 `StoreLocal` / `LoadLocal` fast @@ -1847,23 +1907,24 @@ impl<'a> Walker<'a> { let slot = b.alloc_synthetic_local(); let load_kind = load_kind_for(*ty, self.target); let store_kind = store_kind_for(*ty, self.target); - // `float` keeps the value in an FP register but its - // 4-byte storage width forces the `LocalAddr` + `Store` - // path (the fused `StoreLocal { F32 }` is not lowered). - // `double` rides the FP register class at its full - // 8-byte width, so the fused `StoreLocal` / `LoadLocal` - // F64 path lowers it in a single `movsd` / `ldr d`. - let is_f32 = matches!(load_kind, super::super::ir::LoadKind::F32); - let is_f64 = matches!(load_kind, super::super::ir::LoadKind::F64); + // An FP-typed result rides the FP register class through + // the fused `StoreLocal` / `LoadLocal` path: the emit + // lowers `F32` (`movss` / `str s`, narrowing an f64 arm + // per C99 6.3.1.5) and `F64` (`movsd` / `ldr d`) each in + // a single instruction. The fused ops keep the synthetic + // merge slot mem2reg-promotable, unlike `LocalAddr` + + // `Store`. Everything else stays on the I64 fast path. + let is_fp = matches!( + load_kind, + super::super::ir::LoadKind::F32 | super::super::ir::LoadKind::F64 + ); let arm_store = |b: &mut super::super::codegen::ssa::build::SsaBuilder, v| { - if is_f32 { - let addr = b.local_addr(slot); - b.store(addr, v, store_kind); - } else if is_f64 { - b.store_local(slot, v, store_kind); + let kind = if is_fp { + store_kind } else { - b.store_local(slot, v, super::super::ir::StoreKind::I64); - } + super::super::ir::StoreKind::I64 + }; + b.store_local(slot, v, kind); }; b.switch_to(then_blk); let then_v = self.walk_expr_rvalue(b, *then_e)?; @@ -1874,11 +1935,12 @@ impl<'a> Walker<'a> { arm_store(b, else_v); b.jmp(after_blk); b.switch_to(after_blk); - if is_f32 || is_f64 { - Ok(b.load_local(slot, load_kind)) + let read_kind = if is_fp { + load_kind } else { - Ok(b.load_local(slot, super::super::ir::LoadKind::I64)) - } + super::super::ir::LoadKind::I64 + }; + Ok(b.load_local(slot, read_kind)) } Expr::Call { callee, args, ty } => { // Out-pointer-returning c5-internal callee: allocate a @@ -2745,7 +2807,8 @@ impl<'a> Walker<'a> { 4 => super::super::ir::LoadKind::U32, _ => super::super::ir::LoadKind::I64, }; - let mut v = b.load(addr, unit_kind); + let vol = is_volatile_ty(*ty) || self.expr_is_volatile(*obj); + let mut v = b.load_vol(addr, unit_kind, vol); if bf.bit_offset > 0 { v = b.binop_imm(BinOp::Shr, v, bf.bit_offset as i64); } @@ -2777,7 +2840,8 @@ impl<'a> Walker<'a> { return Ok(addr); } let kind = load_kind_for(*ty, self.target); - Ok(b.load(addr, kind)) + let vol = is_volatile_ty(*ty) || self.expr_is_volatile(*obj); + Ok(b.load_vol(addr, kind, vol)) } Expr::Index { array, idx, ty } => { let arr = self.walk_expr_rvalue(b, *array)?; @@ -2805,7 +2869,7 @@ impl<'a> Walker<'a> { return Ok(addr); } let kind = load_kind_for(*ty, self.target); - Ok(b.load(addr, kind)) + Ok(b.load_vol(addr, kind, is_volatile_ty(*ty))) } Expr::Cast { child, to_ty } => { let v = self.walk_expr_rvalue(b, *child)?; @@ -2840,6 +2904,8 @@ impl<'a> Walker<'a> { Expr::StrLit { ty, .. } => *ty, Expr::Intrinsic { ty, .. } => *ty, Expr::Atomic { ty, .. } => *ty, + Expr::VlaBase { ty, .. } => *ty, + Expr::VlaSizeof { .. } => Ty::Int as i64, // `&&label` is a `void *` (char-pointer encoding). Expr::LabelAddr(_) => { crate::c5::token::Ty::Char as i64 + crate::c5::token::Ty::Ptr as i64 @@ -2867,7 +2933,7 @@ impl<'a> Walker<'a> { // where the signed convert yields a negative result, // so it takes the unsigned converter. Narrower // unsigned types fit the signed range zero-extended. - let stripped = src_ty & !UNSIGNED_BIT; + let stripped = src_ty & !(UNSIGNED_BIT | VOLATILE_BIT); let unsigned_64 = (src_ty & UNSIGNED_BIT) != 0 && (stripped == Ty::Long as i64 || stripped == Ty::LongLong as i64); let kind = if unsigned_64 { @@ -2889,7 +2955,7 @@ impl<'a> Walker<'a> { // takes the unsigned converter. Narrower unsigned // targets fit the signed range. let d = b.fp_widen_to_f64(v); - let stripped_to = *to_ty & !UNSIGNED_BIT; + let stripped_to = *to_ty & !(UNSIGNED_BIT | VOLATILE_BIT); let target_unsigned_64 = (*to_ty & UNSIGNED_BIT) != 0 && (stripped_to == Ty::Long as i64 || stripped_to == Ty::LongLong as i64); let kind = if target_unsigned_64 { @@ -2926,8 +2992,9 @@ impl<'a> Walker<'a> { // (post-op) value per the same clause. let load_kind = load_kind_for(*ty, self.target); let store_kind = store_kind_for(*ty, self.target); + let vol = is_volatile_ty(*ty) || self.expr_is_volatile(*lhs); let place = self.rmw_place(b, *lhs, store_kind)?; - let old = place.load(b, load_kind); + let old = place.load(b, load_kind, vol); // Constant-rhs short-circuit (mirror of the // `Expr::Binary` path): an integer-literal rhs // routes through `binop_imm` so the per-arch @@ -2992,7 +3059,7 @@ impl<'a> Walker<'a> { } else if imm_safe && let Expr::IntLit { val, .. } = self.ast.expr(*rhs) { b.binop_imm(*op, old, *val) } else { - let rhs_val = self.walk_expr_rvalue(b, *rhs)?; + let mut rhs_val = self.walk_expr_rvalue(b, *rhs)?; // The walked rhs may have constant-folded to // an `Imm` even when the AST shape isn't an // `IntLit`; route through `binop_imm` in that @@ -3001,29 +3068,54 @@ impl<'a> Walker<'a> { if imm_safe && let Some(rk) = b.peek_imm(rhs_val) { b.binop_imm(*op, old, rk) } else { - b.binop(*op, old, rhs_val) + let mut lv = old; + // C99 6.3.1.3 + 6.3.1.8: unsigned divide / + // modulo at a narrower-than-register common + // type masks each operand first, mirroring + // the `Expr::Binary` lowering. Both operand + // types <= 4 bytes means the common type is + // 4 bytes (integer promotion floors at int). + if matches!(*op, BinOp::Divu | BinOp::Modu) { + let rhs_sz = expr_ty(self.ast.expr(*rhs)) + .map_or(8, |t| type_size_bytes(t, self.target)); + if type_size_bytes(*ty, self.target) <= 4 && rhs_sz <= 4 { + lv = b.binop_imm(BinOp::And, lv, 0xffff_ffff); + rhs_val = b.binop_imm(BinOp::And, rhs_val, 0xffff_ffff); + } + } + b.binop(*op, lv, rhs_val) } }; - place.store(b, new_val, store_kind); + place.store(b, new_val, store_kind, vol); // C99 6.5.16.2p3: the value of `E1 op= E2` is the // post-update value of E1 in E1's type. For a // sub-64-bit lvalue the 64-bit binop result is not // narrowed; reload through `load_kind` so the // returned ValueId reflects what was actually // stored (with the kind's sign / zero extension). + // A volatile lvalue is accessed exactly once per read + // and once per write (C99 6.7.3p6); its result is the + // stored value narrowed in a register, never a re-read. Ok(if matches!(load_kind, LoadKind::I64) { new_val + } else if vol { + if is_floating_scalar(*ty) { + new_val + } else { + self.narrow_int_to_ty(b, new_val, Ty::LongLong as i64, *ty) + } } else { - place.load(b, load_kind) + place.load(b, load_kind, false) }) } Expr::PreInc { lvalue, by, ty } => { let kind = load_kind_for(*ty, self.target); let store_kind = store_kind_for(*ty, self.target); + let vol = is_volatile_ty(*ty) || self.expr_is_volatile(*lvalue); let place = self.rmw_place(b, *lvalue, store_kind)?; - let old = place.load(b, kind); + let old = place.load(b, kind, vol); let stepped = self.increment_value(b, old, *by, *ty); - place.store(b, stepped, store_kind); + place.store(b, stepped, store_kind, vol); // C99 6.5.3.1p3 + 6.5.16.2: the value of `++E` is // the post-update value of E in E's type. Reload // through `kind` for sub-64-bit lvalues so a @@ -3031,26 +3123,42 @@ impl<'a> Walker<'a> { // wrapped u8/u16/u32 value rather than the wider // Add result that overflows past the storage width. // A floating result is already at storage width. + // A volatile lvalue is not re-read (C99 6.7.3p6); the + // result is the stored value narrowed in a register. Ok( if matches!(kind, LoadKind::I64) || is_floating_scalar(*ty) { stepped + } else if vol { + self.narrow_int_to_ty(b, stepped, Ty::LongLong as i64, *ty) } else { - place.load(b, kind) + place.load(b, kind, false) }, ) } Expr::PostInc { lvalue, by, ty } => { let kind = load_kind_for(*ty, self.target); let store_kind = store_kind_for(*ty, self.target); + let vol = is_volatile_ty(*ty) || self.expr_is_volatile(*lvalue); let place = self.rmw_place(b, *lvalue, store_kind)?; - let old = place.load(b, kind); + let old = place.load(b, kind, vol); let stepped = self.increment_value(b, old, *by, *ty); - place.store(b, stepped, store_kind); + place.store(b, stepped, store_kind, vol); // C99 6.5.2.4p3: the expression's value is the // pre-update value (`old`). Ok(old) } Expr::Sizeof(s) => Ok(b.imm(s.size_bytes)), + // C99 6.3.2.1p3: a VLA lvalue decays to a pointer to its + // first element -- the runtime base pointer the matching + // `Decl::Vla` stored into `ptr_slot`. + Expr::VlaBase { ptr_slot, .. } => { + Ok(b.load_local(*ptr_slot, super::super::ir::LoadKind::I64)) + } + // C99 6.5.3.4p2: `sizeof ` is the runtime byte count + // the matching `Decl::Vla` stored into `size_slot`. + Expr::VlaSizeof { size_slot } => { + Ok(b.load_local(*size_slot, super::super::ir::LoadKind::I64)) + } Expr::CompoundLiteral { slot_off, ty, @@ -3072,7 +3180,7 @@ impl<'a> Walker<'a> { Ok(b.local_addr(slot)) } else { let kind = load_kind_for(ty, self.target); - Ok(b.load_local(slot, kind)) + Ok(b.load_local_vol(slot, kind, is_volatile_ty(ty))) } } Expr::Comma { lhs, rhs, .. } => { @@ -3665,7 +3773,7 @@ impl<'a> Walker<'a> { return Ok(addr); } let kind = load_kind_for(ty, self.target); - Ok(b.load(addr, kind)) + Ok(b.load_vol(addr, kind, is_volatile_ty(ty))) } } } @@ -3817,23 +3925,24 @@ impl<'a> Walker<'a> { }); } } + let vol = is_volatile_ty(ty); if class == Token::Loc as i64 { let kind = load_kind_for(ty, self.target); - Ok(b.load_local(val, kind)) + Ok(b.load_local_vol(val, kind, vol)) } else if let Some(addr) = glo_addr { let addr_v = match addr { GloAddr::Extern => b.imm_data_extern(_sym), GloAddr::Resolved(off) => b.imm_data(off), }; let kind = load_kind_for(ty, self.target); - Ok(b.load(addr_v, kind)) + Ok(b.load_vol(addr_v, kind, vol)) } else if class == Token::Glo as i64 && is_thread_local { let addr = match self.live_tls_addr(_sym, val) { GloAddr::Extern => b.tls_addr_extern(_sym), GloAddr::Resolved(off) => b.tls_addr(off), }; let kind = load_kind_for(ty, self.target); - Ok(b.load(addr, kind)) + Ok(b.load_vol(addr, kind, vol)) } else if class == Token::Fun as i64 { if val == 0 { Ok(b.imm_code_extern(_sym)) @@ -3883,10 +3992,11 @@ impl RmwPlace { &self, b: &mut super::super::codegen::ssa::build::SsaBuilder, kind: LoadKind, + vol: bool, ) -> super::super::ir::ValueId { match *self { - RmwPlace::Slot(off) => b.load_local(off, kind), - RmwPlace::Addr(addr) => b.load(addr, kind), + RmwPlace::Slot(off) => b.load_local_vol(off, kind, vol), + RmwPlace::Addr(addr) => b.load_vol(addr, kind, vol), RmwPlace::Bitfield { addr, bf } => { // C99 6.7.2.1: load the unit, shift the slice to bit 0, // mask, and sign-extend when the field type is signed. @@ -3896,7 +4006,7 @@ impl RmwPlace { 4 => LoadKind::U32, _ => LoadKind::I64, }; - let mut v = b.load(addr, unit_kind); + let mut v = b.load_vol(addr, unit_kind, vol); if bf.bit_offset > 0 { v = b.binop_imm(BinOp::Shr, v, bf.bit_offset as i64); } @@ -3921,13 +4031,14 @@ impl RmwPlace { b: &mut super::super::codegen::ssa::build::SsaBuilder, value: super::super::ir::ValueId, kind: StoreKind, + vol: bool, ) { match *self { RmwPlace::Slot(off) => { - b.store_local(off, value, kind); + b.store_local_vol(off, value, kind, vol); } RmwPlace::Addr(addr) => { - b.store(addr, value, kind); + b.store_vol(addr, value, kind, vol); } RmwPlace::Bitfield { addr, bf } => { // C99 6.7.2.1: load the unit, clear the slice, mask + shift @@ -3944,7 +4055,7 @@ impl RmwPlace { (1i64 << bf.bit_width) - 1 }; let clear_mask: i64 = !(mask << bf.bit_offset); - let old = b.load(addr, load_kind); + let old = b.load_vol(addr, load_kind, vol); let cleared = b.binop_imm(BinOp::And, old, clear_mask); let masked = b.binop_imm(BinOp::And, value, mask); let shifted = if bf.bit_offset > 0 { @@ -3953,7 +4064,7 @@ impl RmwPlace { masked }; let combined = b.binop(BinOp::Or, cleared, shifted); - b.store(addr, combined, store_kind); + b.store_vol(addr, combined, store_kind, vol); } } } @@ -3968,7 +4079,7 @@ fn load_kind_for(ty: i64, target: Target) -> LoadKind { /// Mirror of [`load_kind_for`] for stores. fn store_kind_for(ty: i64, target: Target) -> StoreKind { - let stripped = ty & !UNSIGNED_BIT; + let stripped = ty & !(UNSIGNED_BIT | VOLATILE_BIT); if is_pointer_ty(ty) { return StoreKind::I64; } @@ -4016,7 +4127,7 @@ fn is_comparison_op(op: BinOp) -> bool { /// Test for floating-point scalar types. fn is_floating_scalar(ty: i64) -> bool { - let stripped = ty & !UNSIGNED_BIT; + let stripped = ty & !(UNSIGNED_BIT | VOLATILE_BIT); stripped == Ty::Float as i64 || stripped == Ty::Double as i64 } @@ -4024,14 +4135,14 @@ fn is_floating_scalar(ty: i64) -> bool { /// float` at type `float` (single precision); the walker tags the /// result and feeds the single-precision codegen path. fn is_float_ty(ty: i64) -> bool { - (ty & !UNSIGNED_BIT) == Ty::Float as i64 + (ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Float as i64 } /// True for the scalar `_Bool` type (not a pointer to one). Used by /// the cast lowering to apply the C99 6.3.1.2 conversion (any /// nonzero scalar becomes 1). fn is_bool_scalar(ty: i64) -> bool { - (ty & !UNSIGNED_BIT) == Ty::Bool as i64 + (ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Bool as i64 } /// Sign- or zero-extend a scalar call result to the full 64-bit @@ -4053,7 +4164,7 @@ fn extend_scalar_call_result( target: Target, ) -> super::super::ir::ValueId { use super::super::ir::BinOp; - let stripped = ty & !UNSIGNED_BIT; + let stripped = ty & !(UNSIGNED_BIT | VOLATILE_BIT); let rs = type_size_bytes(ty, target); if is_floating_scalar(ty) || is_pointer_ty(ty) @@ -4215,9 +4326,12 @@ fn expr_ty(e: &Expr) -> Option { | Expr::Comma { ty, .. } | Expr::ShortCircuit { ty, .. } | Expr::Intrinsic { ty, .. } - | Expr::Atomic { ty, .. } => Some(*ty), + | Expr::Atomic { ty, .. } + | Expr::VlaBase { ty, .. } => Some(*ty), Expr::Cast { to_ty, .. } => Some(*to_ty), Expr::Sizeof(s) => Some(s.result_ty), + // `sizeof ` is a runtime `size_t`; c5 types it as `int`. + Expr::VlaSizeof { .. } => Some(crate::c5::token::Ty::Int as i64), Expr::CompoundLiteral { ty, .. } => Some(*ty), // `&&label` is a `void *` (char-pointer encoding). Expr::LabelAddr(_) => { @@ -4232,7 +4346,7 @@ fn expr_ty(e: &Expr) -> Option { /// the walker can't compute (struct types, function types -- the /// walker doesn't currently consume those in cast positions). fn type_size_bytes(ty: i64, target: Target) -> usize { - let stripped = ty & !UNSIGNED_BIT; + let stripped = ty & !(UNSIGNED_BIT | VOLATILE_BIT); if is_pointer_ty(ty) { return 8; } @@ -4259,7 +4373,7 @@ fn type_size_bytes(ty: i64, target: Target) -> usize { /// signed type. Takes only the common type tag and lets the /// walker apply the mask through `BinopI(And, _, mask)`. fn unsigned_narrow_mask(ty: i64) -> i64 { - let stripped = ty & !UNSIGNED_BIT; + let stripped = ty & !(UNSIGNED_BIT | VOLATILE_BIT); let unsigned = (ty & UNSIGNED_BIT) != 0; if !unsigned { return 0; @@ -4344,6 +4458,8 @@ fn lvalue_shape_label(expr: &Expr) -> &'static str { Expr::ShortCircuit { .. } => "ShortCircuit", Expr::Atomic { .. } => "Atomic", Expr::LabelAddr(_) => "LabelAddr", + Expr::VlaBase { .. } => "VlaBase", + Expr::VlaSizeof { .. } => "VlaSizeof", } } @@ -4469,7 +4585,7 @@ mod tests { .insts .iter() .filter_map(|i| match i { - Inst::LoadLocal { off, kind } => Some((*off, *kind)), + Inst::LoadLocal { off, kind, .. } => Some((*off, *kind)), _ => None, }) .collect(); diff --git a/src/c5/codegen/aarch64/emit.rs b/src/c5/codegen/aarch64/emit.rs index 8a9430a60..e2398e072 100644 --- a/src/c5/codegen/aarch64/emit.rs +++ b/src/c5/codegen/aarch64/emit.rs @@ -2022,7 +2022,9 @@ fn emit_inst( // (it needs the local block_offsets table for its PC-relative // fixup), so it never reaches emit_inst. Inst::LocalAddr(off) => emit_local_addr(code, dst, *off, frame), - Inst::Load { addr, disp, kind } => emit_load( + Inst::Load { + addr, disp, kind, .. + } => emit_load( code, dst, *addr, @@ -2038,15 +2040,16 @@ fn emit_inst( disp, value, kind, + .. } => emit_store( code, dst, *addr, *disp, *value, *kind, alloc, frame, scratch, ), - Inst::LoadLocal { off, kind } => { + Inst::LoadLocal { off, kind, .. } => { emit_load_local(code, dst, *off, *kind, alloc.is_f32(v), frame, scratch) } - Inst::StoreLocal { off, value, kind } => { - emit_store_local(code, dst, *off, *value, *kind, alloc, frame, scratch) - } + Inst::StoreLocal { + off, value, kind, .. + } => emit_store_local(code, dst, *off, *value, *kind, alloc, frame, scratch), Inst::LoadIndexed { base, index, @@ -2641,6 +2644,10 @@ fn emit_va_arg_aapcs64( // __vr_top (+16), 16-byte register stride. The overflow stack uses an // 8-byte stride for both classes (AAPCS64 rounds each variadic // argument to an eightbyte; a double overflow argument occupies one). + // TODO: an HFA composite argument rides the vector save area with + // one 16-byte slot per member (AAPCS64 B.5) and needs per-member + // composition into a contiguous temporary; the descriptor currently + // classes every aggregate as general-register. let (off_field, top_field, reg_step): (u32, u32, u32) = if is_fp { (28, 16, 16) } else { (24, 8, 8) }; // A by-value aggregate (integer class) spans `ceil(size/8)` eightbytes @@ -2675,6 +2682,13 @@ fn emit_va_arg_aapcs64( enc_add_imm(scratch.primary, scratch.primary, reg_advance), ); emit(code, enc_str32_imm(scratch.primary, ap, off_field)); + // AAPCS64 B.5 post-increment check: a composite whose span crosses + // the save area's high edge (offs + span > 0) spilled to the stack + // at the call; take the overflow path. The incremented offset stays + // written back, keeping later register-bank reads exhausted. + emit(code, enc_subs_imm(Reg(31), scratch.primary, 0)); + emit(code, enc_b_cond(Cond::Gt, 0)); + let to_stack_straddle = code.len() - 4; // Land the address uniformly in x16. emit_mov_reg(code, scratch.primary, borrow); emit(code, enc_b(0)); @@ -2683,6 +2697,9 @@ fn emit_va_arg_aapcs64( let stack_lbl = code.len(); let delta = ((stack_lbl - to_stack) / 4) as i32; code[to_stack..to_stack + 4].copy_from_slice(&enc_b_cond(Cond::Ge, delta).to_le_bytes()); + let delta = ((stack_lbl - to_stack_straddle) / 4) as i32; + code[to_stack_straddle..to_stack_straddle + 4] + .copy_from_slice(&enc_b_cond(Cond::Gt, delta).to_le_bytes()); // x16 = __stack ; borrow = __stack + advance (next cursor) ; write back. emit(code, enc_ldr_imm(scratch.primary, ap, 0)); emit(code, enc_add_imm(borrow, scratch.primary, stack_advance)); @@ -3125,6 +3142,47 @@ fn emit_intrinsic( emit(code, enc_str_imm(rd, scratch.primary, 0)); true } + I::AllocaSave => { + // Read the arena top for a VLA block snapshot (C99 6.7.6.2). + if current_alloca_top == 0 { + bail_msg("AllocaSave: AllocaInit didn't run for this function"); + return false; + } + let Some(rd) = int_or_spill_scratch(dst, scratch) else { + bail_msg("AllocaSave: dst not int reg / spill"); + return false; + }; + emit_arena_top_addr(code, scratch.secondary, current_alloca_top); + emit(code, enc_ldr_imm(rd, scratch.secondary, 0)); + spill_local_addr_to_dst(code, dst, rd, frame); + true + } + I::AllocaRestore => { + // Restore the arena top on VLA block exit. + if current_alloca_top == 0 { + bail_msg("AllocaRestore: AllocaInit didn't run for this function"); + return false; + } + if args.len() != 1 { + bail_msg("AllocaRestore: expected 1 arg"); + return false; + } + let v_place = alloc + .places + .get(args[0] as usize) + .copied() + .unwrap_or(Place::None); + let v = match materialize_int(code, v_place, scratch.primary, frame) { + Some(r) => r, + None => { + bail_msg("AllocaRestore: arg not int reg / spill / fp"); + return false; + } + }; + emit_arena_top_addr(code, scratch.secondary, current_alloca_top); + emit(code, enc_str_imm(v, scratch.secondary, 0)); + true + } I::SetjmpAArch64 => { // c5 binds 's setjmp() to this intrinsic on // Windows aarch64 because msvcrt's longjmp routes @@ -3410,9 +3468,7 @@ fn emit_call_ext( // argument-register packing. let aggs = build_arg_aggs(arg_aggs, agg_descs, abi); let plan = super::plan_call_args_aggs(args.len(), fixed, fp_arg_mask, abi, &aggs, false); - if plan.scratch_bytes > 0 { - emit(code, enc_sub_imm(Reg(31), Reg(31), plan.scratch_bytes)); - } + emit_sub_sp_imm(code, plan.scratch_bytes); if !marshal_args( code, &plan, args, alloc, scratch, frame, arg_aggs, agg_descs, ) { @@ -3464,9 +3520,7 @@ fn emit_call_ext( }); emit(code, enc_bl(0)); } - if plan.scratch_bytes > 0 { - emit(code, enc_add_imm(Reg(31), Reg(31), plan.scratch_bytes)); - } + emit_add_sp_imm(code, plan.scratch_bytes); if ret_agg.is_some() { finish_call_result( code, @@ -3615,9 +3669,7 @@ fn emit_call( // the areas then the overflow stack. let plan = super::plan_call_args_aggs(args.len(), fixed_args, fp_arg_mask, abi, &aggs, false); - if plan.scratch_bytes > 0 { - emit(code, enc_sub_imm(Reg(31), Reg(31), plan.scratch_bytes)); - } + emit_sub_sp_imm(code, plan.scratch_bytes); if !marshal_args( code, &plan, args, alloc, scratch, frame, arg_aggs, agg_descs, ) { @@ -3635,9 +3687,7 @@ fn emit_call( kind: BranchKind::Bl, }); emit(code, enc_bl(0)); - if plan.scratch_bytes > 0 { - emit(code, enc_add_imm(Reg(31), Reg(31), plan.scratch_bytes)); - } + emit_add_sp_imm(code, plan.scratch_bytes); finish_call_result( code, ret_agg, @@ -3666,9 +3716,7 @@ fn emit_call( // integer register as its `Imm` bit pattern. Feeding the mask to // the planner routes the FP args to d0..d7 instead of x0..x7. let plan = super::plan_call_args_aggs(args.len(), args.len(), fp_arg_mask, abi, &aggs, false); - if plan.scratch_bytes > 0 { - emit(code, enc_sub_imm(Reg(31), Reg(31), plan.scratch_bytes)); - } + emit_sub_sp_imm(code, plan.scratch_bytes); if !marshal_args( code, &plan, args, alloc, scratch, frame, arg_aggs, agg_descs, ) { @@ -3684,9 +3732,7 @@ fn emit_call( kind: BranchKind::Bl, }); emit(code, enc_bl(0)); - if plan.scratch_bytes > 0 { - emit(code, enc_add_imm(Reg(31), Reg(31), plan.scratch_bytes)); - } + emit_add_sp_imm(code, plan.scratch_bytes); finish_call_result( code, ret_agg, @@ -3769,13 +3815,13 @@ fn finish_call_result( } /// Common return-value bridge shared by `emit_call` and -/// `emit_call_indirect`. The c5-internal calling convention ferries -/// every return value -- including an f64 bit pattern -- through the -/// integer return register x0 (see `emit_return`, which moves an -/// FP-placed return value into x0 via `fmov x0, d`). When the callee -/// returns a floating-point scalar (`fp_return`) the call's result is -/// FP-classed, so the x0 bit pattern is reinterpreted into the FP -/// register file via `fmov d, x0`. +/// `emit_call_indirect`. An integer-classed result rides x0 (AAPCS64 +/// 6.4.1); a floating-point scalar rides d0, whose low 32 bits are the +/// s0 an f32 occupies (AAPCS64 6.4.2), which is where `emit_return` +/// leaves it. When the callee returns a floating-point scalar +/// (`fp_return`) this copies d0 into the FP-classed destination, or +/// bridges it to a GPR via `fmov x, d0` when the destination is +/// integer-classed. fn move_call_result(code: &mut Vec, dst: Place, frame: Frame, fp_return: bool) { if fp_return { // A floating-point scalar result arrives in d0 (C99 6.2.5p10 / @@ -3854,10 +3900,8 @@ fn emit_call_indirect( // for this call. AAPCS64 doesn't assign these scratch // registers to int-arg slots, but the SSA allocator's // caller-saved pool includes them and may park an arg's - // source value in one. The target stage must avoid that - // register; otherwise the materialise below overwrites the - // arg's source before the marshal can push it onto the - // c5-stride stack. + // source value in one. The target stage must avoid those + // registers while the marshal still reads them. let mut arg_source_regs: alloc::vec::Vec = alloc::vec::Vec::with_capacity(args.len()); for &a in args { if let Some(Place::IntReg(r)) = alloc.places.get(a as usize) { @@ -3867,24 +3911,17 @@ fn emit_call_indirect( // Capture the function pointer into a caller-saved scratch // disjoint from the arg sources. Prefer x9, then x10..x15 -- // none are arg-passing registers per AAPCS64, so they are - // safe to clobber via the blr. The blr happens before the - // callee can observe the scratch, so the value reaches the - // indirect branch intact regardless of which scratch holds - // it. + // safe to clobber via the blr. When every candidate holds an + // arg source the marshal still reads, the host-ABI branch + // stages the pointer in a reserved stack cell instead, and the + // c5-stack branch captures after its pushes have consumed the + // sources; a blind fallback here overwrote a live source. const TARGET_SCRATCH_CANDIDATES: &[u8] = &[9, 10, 11, 12, 13, 14, 15]; - let target_reg_idx = TARGET_SCRATCH_CANDIDATES + let free_target_reg = TARGET_SCRATCH_CANDIDATES .iter() .copied() .find(|r| !arg_source_regs.contains(r)) - .unwrap_or(9); - let target_reg = Reg(target_reg_idx); - let target_r = match materialize_int(code, target_place, scratch.primary, frame) { - Some(r) => r, - None => return false, - }; - if target_r.0 != target_reg.0 { - emit_mov_reg(code, target_reg, target_r); - } + .map(Reg); if (callee_variadic && (abi.variadic_on_stack || abi.variadic_int_only || abi.aarch64_host_variadic())) || !aggs.is_empty() @@ -3900,13 +3937,41 @@ fn emit_call_indirect( // stack (Windows arm64, `variadic_int_only`), or both banks then // the stack (Linux aarch64, `aarch64_host_variadic`) -- the same // placement `emit_call` uses for a direct variadic call. The - // target pointer is already captured in `target_reg` (a - // non-arg-passing scratch), so `marshal_args` will not clobber - // it. `blr` through the captured register. - let plan = + // target pointer rides a non-arg-passing scratch that + // `marshal_args` will not clobber, or a reserved stack cell + // above the argument slots when no such scratch is free. + let mut plan = super::plan_call_args_aggs(args.len(), fixed_args, fp_arg_mask, abi, &aggs, false); - if plan.scratch_bytes > 0 { - emit(code, enc_sub_imm(Reg(31), Reg(31), plan.scratch_bytes)); + let staged_off = match free_target_reg { + Some(_) => None, + None => { + // One 16-byte cell keeps SP 16-aligned; the argument + // slots stay below the original scratch_bytes. + plan.scratch_bytes += 16; + Some(plan.scratch_bytes - 16) + } + }; + let target_r = match materialize_int(code, target_place, scratch.primary, frame) { + Some(r) => r, + None => return false, + }; + let target_reg = match free_target_reg { + Some(r) => { + if target_r.0 != r.0 { + emit_mov_reg(code, r, target_r); + } + r + } + None => { + if target_r.0 != scratch.primary.0 { + emit_mov_reg(code, scratch.primary, target_r); + } + scratch.primary + } + }; + emit_sub_sp_imm(code, plan.scratch_bytes); + if let Some(off) = staged_off { + emit_sp_str_x_auto(code, target_reg, off); } if !marshal_args( code, &plan, args, alloc, scratch, frame, arg_aggs, agg_descs, @@ -3914,10 +3979,17 @@ fn emit_call_indirect( return false; } setup_indirect_result(code, ret_agg, ret_slot_off, agg_descs, frame); - emit(code, enc_blr(target_reg)); - if plan.scratch_bytes > 0 { - emit(code, enc_add_imm(Reg(31), Reg(31), plan.scratch_bytes)); - } + // The marshal consumed every argument source, so x9 is free + // to carry the staged pointer to the blr. + let call_reg = match staged_off { + Some(off) => { + emit_sp_ldr_x(code, Reg(9), off); + Reg(9) + } + None => target_reg, + }; + emit(code, enc_blr(call_reg)); + emit_add_sp_imm(code, plan.scratch_bytes); finish_call_result( code, ret_agg, @@ -3967,6 +4039,17 @@ fn emit_call_indirect( emit(code, enc_str_pre(src, Reg(31), -16)); } let pushed_bytes = (args.len() as u32) * 16; + // The pushes consumed every argument source, so x9 holds no live + // value; capture the pointer here, with SP shifted by the pushes. + let target_reg = Reg(9); + let target_r = + match materialize_int_shifted(code, target_place, target_reg, frame, pushed_bytes) { + Some(r) => r, + None => return false, + }; + if target_r.0 != target_reg.0 { + emit_mov_reg(code, target_reg, target_r); + } // Load the prefix into host arg regs from the c5-stride // stack we just laid down. Non-variadic callees expect this // shape; variadic callees ignore the host arg regs but read @@ -3975,9 +4058,7 @@ fn emit_call_indirect( // past 8) stays on the c5 stack at `[sp + i*16]`, which the // callee prologue's overflow restripe loop also reads from. let plan = super::plan_call_args_aggs(args.len(), args.len(), fp_arg_mask, abi, &aggs, false); - if plan.scratch_bytes > 0 { - emit(code, enc_sub_imm(Reg(31), Reg(31), plan.scratch_bytes)); - } + emit_sub_sp_imm(code, plan.scratch_bytes); for (i, &placement) in plan.placements.iter().enumerate() { match placement { super::ArgPlacement::IntReg(r) => { @@ -4004,13 +4085,9 @@ fn emit_call_indirect( } } emit(code, enc_blr(target_reg)); - if plan.scratch_bytes > 0 { - emit(code, enc_add_imm(Reg(31), Reg(31), plan.scratch_bytes)); - } + emit_add_sp_imm(code, plan.scratch_bytes); // Drop the 16-byte-stride argument pushes. - if pushed_bytes > 0 { - emit(code, enc_add_imm(Reg(31), Reg(31), pushed_bytes)); - } + emit_add_sp_imm(code, pushed_bytes); move_call_result(code, dst, frame, fp_return); true } @@ -4152,6 +4229,16 @@ fn atomic_operand_into( .get(value as usize) .copied() .unwrap_or(Place::None); + // An operand the allocator placed in a borrowed working register + // (x9..x12) may already have been overwritten by an earlier + // operand move; read its saved copy from the save area instead + // ([sp+0]=x9 .. [sp+24]=x12, laid out by `atomic_save_working`). + if let Place::IntReg(r) = place + && (9..=12).contains(&r) + { + emit_sp_ldr_x(code, target, (r as u32 - 9) * 8); + return true; + } match materialize_int_shifted(code, place, target, frame, sp_shift) { Some(r) => { if r.0 != target.0 { @@ -4469,6 +4556,25 @@ fn spill_local_addr_to_dst(code: &mut Vec, dst: Place, src: Reg, frame: Fram } } +/// Materialize the per-frame alloca-arena bookkeeping slot address +/// (`fp - top_offset`) into `reg`. Mirrors the `AllocaInit` / +/// `Alloca` address computation for the VLA save / restore ops. +fn emit_arena_top_addr(code: &mut Vec, reg: Reg, top_offset: u32) { + if top_offset < 4096 { + emit(code, enc_sub_imm(reg, Reg(29), top_offset)); + } else { + let high = top_offset & !0xfff; + let low = top_offset & 0xfff; + emit( + code, + super::encode::enc_sub_imm_lsl12(reg, Reg(29), high >> 12), + ); + if low != 0 { + emit(code, enc_sub_imm(reg, reg, low)); + } + } +} + /// `Inst::Extend { value, kind }` -- sign-extend the low bytes of a /// GPR value to 64 bits via the `SXTB` / `SXTH` / `SXTW` aliases. fn emit_extend( @@ -4551,7 +4657,7 @@ fn emit_load( return false; } }; - emit(code, enc_ldr_s_imm(dd, rn, 0)); + emit(code, enc_ldr_s_imm(dd, rn, disp)); if !keep_f32 { emit(code, enc_fcvt_d_s(dd, dd)); } @@ -4571,7 +4677,7 @@ fn emit_load( return false; } }; - emit(code, enc_ldr_d_imm(dd, rn, 0)); + emit(code, enc_ldr_d_imm(dd, rn, disp)); if let Place::Spill(slot) = dst { let sp_off = spill_off(frame, slot); emit_sp_str_d_auto(code, dd, sp_off); diff --git a/src/c5/codegen/aarch64/encode.rs b/src/c5/codegen/aarch64/encode.rs index 3c6e5ab05..89e478f14 100644 --- a/src/c5/codegen/aarch64/encode.rs +++ b/src/c5/codegen/aarch64/encode.rs @@ -695,24 +695,18 @@ pub(crate) fn enc_mrs_tpidr_el0(rt: Reg) -> u32 { /// `LDR
, [, #imm]` -- 64-bit unsigned-offset FP/SIMD /// load. The offset is byte-addressed but encoded as `imm/8`; the -/// caller passes raw bytes (must be multiple of 8 in 0..32760). -/// Used by the variadic-FP packer to pull a c5-stack slot -/// straight into a `dN` register before a libc call. +/// caller passes raw bytes (a multiple of 8, up to 32760). pub(crate) fn enc_ldr_d_imm(dt: u8, rn: Reg, imm: u32) -> u32 { debug_assert!(dt < 32); - debug_assert!(imm.is_multiple_of(8) && imm < 32760); - 0xFD40_0000 | ((imm / 8) << 10) | ((rn.0 as u32) << 5) | (dt as u32) + enc_ldst_scaled(0xFD40_0000, 3, Reg(dt), rn, imm) } /// `LDR , [, #imm]` -- 32-bit unsigned-offset FP/SIMD -/// load. The offset is byte-addressed but encoded as `imm/4`; -/// caller passes raw bytes (must be multiple of 4 in 0..16380). -/// Used by [`LoadKind::F32`] to load a `float`-typed lvalue's storage -/// directly into the `sN` half of `dN` before the widening fcvt. +/// load. The offset is byte-addressed but encoded as `imm/4`; the +/// caller passes raw bytes (a multiple of 4, up to 16380). pub(crate) fn enc_ldr_s_imm(st: u8, rn: Reg, imm: u32) -> u32 { debug_assert!(st < 32); - debug_assert!(imm.is_multiple_of(4) && imm < 16380); - 0xBD40_0000 | ((imm / 4) << 10) | ((rn.0 as u32) << 5) | (st as u32) + enc_ldst_scaled(0xBD40_0000, 2, Reg(st), rn, imm) } /// `STR , [, #imm]` -- 32-bit unsigned-offset FP/SIMD @@ -720,17 +714,14 @@ pub(crate) fn enc_ldr_s_imm(st: u8, rn: Reg, imm: u32) -> u32 { /// to the `StoreKind::F32` lowering. pub(crate) fn enc_str_s_imm(st: u8, rn: Reg, imm: u32) -> u32 { debug_assert!(st < 32); - debug_assert!(imm.is_multiple_of(4) && imm < 16380); - 0xBD00_0000 | ((imm / 4) << 10) | ((rn.0 as u32) << 5) | (st as u32) + enc_ldst_scaled(0xBD00_0000, 2, Reg(st), rn, imm) } /// `STR
, [, #imm]` -- 64-bit unsigned-offset FP/SIMD -/// store, the partner of [`enc_ldr_d_imm`]. Used by the AArch64 -/// setjmp intrinsic to spill d8-d15 into the user's `jmp_buf`. +/// store, the partner of [`enc_ldr_d_imm`]. pub(crate) fn enc_str_d_imm(dt: u8, rn: Reg, imm: u32) -> u32 { debug_assert!(dt < 32); - debug_assert!(imm.is_multiple_of(8) && imm < 32760); - 0xFD00_0000 | ((imm / 8) << 10) | ((rn.0 as u32) << 5) | (dt as u32) + enc_ldst_scaled(0xFD00_0000, 3, Reg(dt), rn, imm) } /// `ADR , label` -- compute a PC-relative byte address (signed @@ -1707,8 +1698,7 @@ pub(crate) fn lower( // `apply_fixups` and re-emit them as // `Build::user_extern_call_sites` entries that the writer // surfaces as `R_AARCH64_CALL26` relocs against the - // callee's symbol. Empty for builds without - // `CompileOptions::no_entry_point`. + // callee's symbol. let extern_pc_lookup: alloc::collections::BTreeMap = program .extern_function_imports .iter() @@ -1866,6 +1856,7 @@ pub(crate) fn lower( copy_relocs: Vec::new(), text: code, data: program.data.clone(), + data_align: program.data_align, bss_size: 0, entry_offset, got_fixups, @@ -1909,7 +1900,9 @@ pub(crate) fn lower( // Overwritten by `lower_for` from `NativeOptions::debug_info`. debug_info: true, merged_dwarf: None, - plt_trampoline_offsets, + // Every import on this single-TU path gets a trampoline (data + // imports ride `ResolvedImports::data_bindings`, not `imports`). + plt_trampoline_offsets: plt_trampoline_offsets.into_iter().map(Some).collect(), }) } diff --git a/src/c5/codegen/jit.rs b/src/c5/codegen/jit.rs index 99fd980e4..613b4b94f 100644 --- a/src/c5/codegen/jit.rs +++ b/src/c5/codegen/jit.rs @@ -125,7 +125,8 @@ mod jit_impl { use super::super::super::error::C5Error; use super::super::super::program::Program; use super::super::Target; - use super::super::{Build, NativeOptions, ResolvedImports, aarch64, x86_64}; + use super::super::{Build, GotFixup, NativeOptions, ResolvedImport, ResolvedImports}; + use super::super::{aarch64, x86_64}; use super::host_target; use alloc::format; use alloc::string::String; @@ -198,19 +199,34 @@ mod jit_impl { 0 } - /// Return the JIT-side thunk address for any libc atexit-shape - /// symbol, otherwise 0. The host's libc atexit registers - /// handler PCs into the host's own `__cxa_finalize` list, but - /// those PCs sit in the JIT mmap region that `JitRegion::drop` - /// unmaps before the host process exits -- so handing the - /// host's atexit address to JIT'd code yields a dangling - /// pointer at process teardown. Intercepting the binding at + /// Replacement for libc's `exit` when JIT'd code resolves the + /// symbol through `dlsym`. C99 7.20.4.3p2: `exit` runs the + /// registered atexit handlers first. `atexit` was intercepted + /// into the JIT-side chain, which the host's `exit` knows + /// nothing about, so drain the chain before terminating with + /// the given status. `_Exit` / `quick_exit` stay on the host + /// symbols -- neither runs atexit handlers (7.20.4.5). + extern "C" fn jit_exit_thunk(status: c_int) -> ! { + drain_jit_atexit_chain(); + std::process::exit(status); + } + + /// Return the JIT-side thunk address for a libc symbol whose + /// host implementation must not be handed to JIT'd code, + /// otherwise 0. The host's libc atexit registers handler PCs + /// into the host's own `__cxa_finalize` list, but those PCs + /// sit in the JIT mmap region that `JitRegion::drop` unmaps + /// before the host process exits -- so handing the host's + /// atexit address to JIT'd code yields a dangling pointer at + /// process teardown; the host's `exit` would skip the + /// intercepted handlers entirely. Intercepting the binding at /// JIT bind_imports time means every JIT'd `atexit` / - /// `__cxa_atexit` call lands on our thunk instead. + /// `__cxa_atexit` / `exit` call lands on our thunk instead. fn atexit_thunk_addr(name: &str) -> u64 { match name { "atexit" => jit_atexit_thunk as *const () as usize as u64, "__cxa_atexit" => jit_cxa_atexit_thunk as *const () as usize as u64, + "exit" => jit_exit_thunk as *const () as usize as u64, _ => 0, } } @@ -259,7 +275,18 @@ mod jit_impl { options: NativeOptions, ) -> Result { let target = host_target()?; - let build = lower_for_jit(program, target, options)?; + let mut build = lower_for_jit(program, target, options)?; + + // Undefined extern functions: the lowering partitioned each + // call / address site targeting a placeholder ent_pc into + // `user_extern_call_sites`, and there is no link step to + // resolve them. Executing such a site would branch to the + // zeroed placeholder, so refuse up front, mirroring the + // linker's diagnosis. + if let Some(site) = build.user_extern_call_sites.first() { + return Err(undefined_reference(&site.symbol_name)); + } + route_jit_data_imports(&mut build)?; // Allocate a writable data region, copy `build.data` in. The // page is RW (no exec permission); an attempt to execute @@ -307,6 +334,20 @@ mod jit_impl { // exactly the way the ELF loader's relocations would. let mut got_region = GotRegion::new(build.imports.imports.len())?; got_region.bind_imports(&build.imports)?; + // A data import's GOT slot must resolve: unlike a function + // import (whose 0 slot faults only if called), the patched + // code loads the slot's value as an object address and + // dereferences it. + for fx in &build.got_fixups { + if fx.is_data_load && got_region.slot_value(fx.import_index) == 0 { + return Err(C5Error::Compile(crate::c5::error::fmt_internal_err( + &format!( + "JIT: unresolved extern data symbol `{}`", + build.imports.imports[fx.import_index].real_symbol, + ), + ))); + } + } let got_vmaddr = got_region.as_ptr() as u64; // Allocate the code region. Patch fixups against the mmap'd @@ -588,6 +629,62 @@ mod jit_impl { Ok(exit_code as i32) } + /// Mirror the linker's undefined-symbol diagnostic wording. + fn undefined_reference(name: &str) -> C5Error { + C5Error::Compile(crate::c5::error::fmt_link_err(&format!( + "undefined reference to `{name}`" + ))) + } + + /// Route `#pragma binding(data ...)` references through the fake + /// GOT. The emitters record each extern-data site as a named + /// [`super::super::UserExternDataRef`]; register the binding's host + /// symbol as a flat-lookup import so `bind_imports` resolves it via + /// the loader and `apply_jit_fixups` rewrites the site into a + /// GOT-slot load -- the JIT equivalent of the loader-bound data + /// import an AOT image gets. A leftover reference has no binding + /// and no definition anywhere: refuse it like the linker would. + fn route_jit_data_imports(build: &mut Build) -> Result<(), C5Error> { + if build.user_extern_data_refs.is_empty() { + return Ok(()); + } + let hosts: alloc::collections::BTreeMap = build + .imports + .data_bindings + .iter() + .map(|(local, host, dylib)| (local.clone(), (host.clone(), *dylib))) + .collect(); + let mut import_for: alloc::collections::BTreeMap = + alloc::collections::BTreeMap::new(); + for r in core::mem::take(&mut build.user_extern_data_refs) { + let Some((host, dylib)) = hosts.get(&r.symbol_name) else { + return Err(undefined_reference(&r.symbol_name)); + }; + let idx = *import_for.entry(r.symbol_name.clone()).or_insert_with(|| { + let i = build.imports.imports.len(); + build.imports.imports.push(ResolvedImport { + binding_idx: i as i64, + local_name: r.symbol_name.clone(), + real_symbol: host.clone(), + dylib_index: *dylib, + flat_lookup: true, + is_variadic: false, + fixed_args: 0, + return_type_tag: 0, + returns_long_double: false, + param_types: alloc::vec::Vec::new(), + }); + i + }); + build.got_fixups.push(GotFixup { + adrp_offset: r.instr_offset, + import_index: idx, + is_data_load: true, + }); + } + Ok(()) + } + fn lower_for_jit( program: &Program, target: Target, @@ -1026,10 +1123,14 @@ mod jit_impl { // with MEM_RELEASE requires size = 0. #[cfg_attr(target_os = "windows", allow(dead_code))] len: usize, - /// Library handles to release on drop. POSIX uses one - /// `dlopen(NULL)` handle (so this is at most one entry); - /// Windows uses one per declared dylib. - lib_handles: Vec<*mut c_void>, + /// Loader handles for both import binding and extern-data + /// resolution, paired with whether Drop must release the handle. + /// POSIX opens each with `dlopen` (owned). Windows takes a + /// non-owned `GetModuleHandleA` handle for an already-loaded + /// module and an owned `LoadLibraryA` handle otherwise; a + /// `GetModuleHandleA` handle carries no refcount, so it must not + /// be freed. Both bind and resolve search the full set. + lib_handles: Vec<(*mut c_void, bool)>, } impl GotRegion { @@ -1119,7 +1220,7 @@ mod jit_impl { "JIT: dlopen(NULL, RTLD_NOW) returned null -- can't resolve libc symbols", ))); } - self.lib_handles.push(handle); + self.lib_handles.push((handle, true)); // On Linux every declared dylib is its own .so (libc.so.6, // libm.so.6, libdl.so.2, ...) -- the Rust test binary @@ -1139,7 +1240,7 @@ mod jit_impl { if let Ok(cs) = CString::new(d.path.as_str()) { let h = unsafe { dlopen(cs.as_ptr(), RTLD_NOW) }; if !h.is_null() { - self.lib_handles.push(h); + self.lib_handles.push((h, true)); } } } @@ -1166,7 +1267,7 @@ mod jit_impl { Ok(cs) => cs, Err(_) => continue, // unreachable: symbol names are static ASCII }; - for h in &self.lib_handles { + for (h, _) in &self.lib_handles { let a = unsafe { dlsym(*h, cs.as_ptr()) } as u64; if a != 0 { addr = a; @@ -1222,10 +1323,10 @@ mod jit_impl { owned = true; } handles.push(h); - if owned { - // Track the handle so Drop releases it. - self.lib_handles.push(h); - } + // Every handle joins the shared set so extern-data + // resolution searches exactly what import binding used; + // `owned` gates release in Drop. + self.lib_handles.push((h, owned)); } for (i, imp) in imports.imports.iter().enumerate() { let mut addr = atexit_thunk_addr(imp.real_symbol.as_str()); @@ -1250,6 +1351,14 @@ mod jit_impl { self.ptr } + /// Read back the resolved address in slot `idx`; 0 means + /// `bind_imports` could not resolve the symbol. + fn slot_value(&self, idx: usize) -> u64 { + // SAFETY: `bind_imports` wrote slot `idx` within the + // region sized from the import count. + unsafe { std::ptr::read_unaligned(self.ptr.add(idx * 8) as *const u64) } + } + /// Resolve a symbol name to its runtime address through the /// loader handles bound by `bind_imports`. Used for /// pointer-to-extern-data initializers; 0 means unresolved. @@ -1270,7 +1379,7 @@ mod jit_impl { Ok(cs) => cs, Err(_) => return 0, }; - for &h in &self.lib_handles { + for &(h, _) in &self.lib_handles { let a = unsafe { dlsym(h, cs.as_ptr()) } as u64; if a != 0 { return a; @@ -1279,16 +1388,17 @@ mod jit_impl { 0 } - /// Windows resolver: best-effort over the handles opened for - /// imports (`LoadLibraryA`). A data symbol in a module that was - /// not an import target won't resolve and the caller errors. + /// Windows resolver over the same handle set `bind_imports` + /// populated (both `GetModuleHandleA` and `LoadLibraryA`), so an + /// extern-data symbol in an already-loaded module resolves. 0 + /// means unresolved and the caller errors. #[cfg(target_os = "windows")] fn resolve_symbol(&self, name: &str) -> u64 { let cs = match CString::new(name) { Ok(cs) => cs, Err(_) => return 0, }; - for &h in &self.lib_handles { + for &(h, _) in &self.lib_handles { let a = unsafe { GetProcAddress(h, cs.as_ptr()) } as u64; if a != 0 { return a; @@ -1306,7 +1416,7 @@ mod jit_impl { fn munmap(addr: *mut c_void, len: usize) -> c_int; fn dlclose(handle: *mut c_void) -> c_int; } - for &h in &self.lib_handles { + for &(h, _) in &self.lib_handles { if !h.is_null() { dlclose(h); } @@ -1315,8 +1425,10 @@ mod jit_impl { } #[cfg(target_os = "windows")] unsafe { - for &h in &self.lib_handles { - if !h.is_null() { + // Release only owned handles; a `GetModuleHandleA` handle + // carries no refcount to drop. + for &(h, owned) in &self.lib_handles { + if owned && !h.is_null() { FreeLibrary(h); } } @@ -1343,14 +1455,26 @@ mod jit_impl { build: &Build, ) -> Result<(), C5Error> { for fx in &build.got_fixups { - patch_got_call( - target, - code, - code_vmaddr, - fx.adrp_offset as u64, - got_vmaddr + (fx.import_index as u64) * 8, - "GOT fixup", - )?; + let slot_vmaddr = got_vmaddr + (fx.import_index as u64) * 8; + if fx.is_data_load { + patch_got_data_load( + target, + code, + code_vmaddr, + fx.adrp_offset as u64, + slot_vmaddr, + "GOT data fixup", + )?; + } else { + patch_got_call( + target, + code, + code_vmaddr, + fx.adrp_offset as u64, + slot_vmaddr, + "GOT fixup", + )?; + } } for fx in &build.data_fixups { patch_addr_load( @@ -1398,8 +1522,11 @@ mod jit_impl { } /// aarch64 `adrp Xd, page; ldr Xd, [Xd, #imm12]` patcher. The - /// loaded value at `target_vmaddr` is the GOT slot's stored - /// libc address; the JIT'd `blr xd` then dispatches there. + /// value loaded from `target_vmaddr` is the GOT slot's stored + /// host address; a call site follows with `blr xd`, a data + /// site continues with the address in `xd`. The destination + /// register is recovered from the placeholder adrp (x16 at + /// call sites, the allocator's choice at data sites). fn patch_adrp_ldr( code: &mut [u8], code_vmaddr: u64, @@ -1424,17 +1551,51 @@ mod jit_impl { &format!("JIT: {label} slot offset {in_page:#x} not 8-aligned"), ))); } - let adrp_word = super::super::aarch64::enc_adrp(super::super::aarch64::Reg::X16, imm21); - let ldr_word = super::super::aarch64::enc_ldr_imm( - super::super::aarch64::Reg::X16, - super::super::aarch64::Reg::X16, - in_page, - ); + let prev_adrp = + u32::from_le_bytes([code[off], code[off + 1], code[off + 2], code[off + 3]]); + let rd = super::super::aarch64::Reg((prev_adrp & 0x1F) as u8); + let adrp_word = super::super::aarch64::enc_adrp(rd, imm21); + let ldr_word = super::super::aarch64::enc_ldr_imm(rd, rd, in_page); code[off..off + 4].copy_from_slice(&adrp_word.to_le_bytes()); code[off + 4..off + 8].copy_from_slice(&ldr_word.to_le_bytes()); Ok(()) } + /// Patch an extern-data reference so the register receives the + /// imported object's address from its GOT slot. aarch64 rewrites + /// the `adrp + add` placeholder into `adrp + ldr` (same shape as + /// a call's slot load); x86_64 flips the emitter's + /// `lea rd, [rip+disp32]` into `mov rd, [rip+disp32]` -- the + /// rewrite the PE writer's IAT data path applies. + fn patch_got_data_load( + target: Target, + code: &mut [u8], + code_vmaddr: u64, + instr_offset: u64, + target_vmaddr: u64, + label: &str, + ) -> Result<(), C5Error> { + match target { + Target::MacOSAarch64 | Target::LinuxAarch64 | Target::WindowsAarch64 => { + patch_adrp_ldr(code, code_vmaddr, instr_offset, target_vmaddr, label) + } + Target::LinuxX64 | Target::WindowsX64 => { + let op_off = instr_offset as usize + 1; + if code[op_off] != 0x8D { + return Err(C5Error::Compile(crate::c5::error::fmt_internal_err( + &format!( + "JIT: {label} expected lea opcode 0x8D at text+{op_off:#x}, \ + found {:#04x}", + code[op_off], + ), + ))); + } + code[op_off] = 0x8B; + patch_lea_rip32(code, code_vmaddr, instr_offset, target_vmaddr, label) + } + } + } + /// x86_64 `call qword [rip + disp32]` patcher. disp32 is /// measured from the byte just past the call (i.e. from /// `instr_vmaddr + CALL_QWORD_RIP32_LEN`). diff --git a/src/c5/codegen/mod.rs b/src/c5/codegen/mod.rs index dd02e3704..5f65ebbcc 100644 --- a/src/c5/codegen/mod.rs +++ b/src/c5/codegen/mod.rs @@ -43,7 +43,7 @@ pub(crate) mod aarch64; #[allow(dead_code)] pub(crate) mod abi_classify; mod jit; -mod passes; +pub(crate) mod passes; pub(crate) mod ssa; pub(crate) mod x86_64; @@ -232,9 +232,7 @@ pub(super) fn pc_extent_for_lowering( // highest `end_pc`; the codegen's per-`Inst::Call` fixup // pass uses the same dense `pc_to_native` table to // recognise them as out-of-range, so the table has to - // cover the placeholder range too. `extern_function_imports` - // is empty for every build that didn't go through the - // relocatable -c path. + // cover the placeholder range too. let from_imports = program .extern_function_imports .iter() @@ -416,6 +414,55 @@ pub(super) fn plan_call_args_aggs( placements.push(placement); continue; } + // Windows aarch64 variadic convention: an anonymous composite + // is passed as if all SIMD/FP registers were unavailable -- a + // <= 16-byte composite (HFA or not) rides the integer bank + // x0-x7 then the stack, a larger one goes by reference. The + // callee's va_arg walks one 8-byte-stride region, so an FP + // bank placement would read garbage on both sides. + if i >= fixed_args && abi.variadic_int_only && matches!(abi.arch, Arch::Aarch64) { + let placement = if agg.size > 16 { + if int_idx < int_max { + let r = abi.int_arg_regs[int_idx]; + int_idx += 1; + ArgPlacement::StructByRefReg(r) + } else { + let off = stack_used; + stack_used += 8; + ArgPlacement::StructByRefStack(off) + } + } else { + let need = (aligned as usize / 8).max(1); + if int_idx + need <= int_max { + let mut regs = [ClassReg { + reg: 0, + is_fp: false, + }; 4]; + for (n, slot) in regs.iter_mut().enumerate().take(need) { + *slot = ClassReg { + reg: abi.int_arg_regs[int_idx], + is_fp: false, + }; + let _ = n; + int_idx += 1; + } + ArgPlacement::StructRegs { + regs, + n: need as u8, + } + } else { + int_idx = int_max; + let off = stack_used; + stack_used += aligned; + ArgPlacement::StructStack { + off, + size: agg.size, + } + } + }; + placements.push(placement); + continue; + } let placement = match &agg.class { AggClass::Regs(classes) => { let need_int = classes.iter().filter(|c| **c == RegClass::Integer).count(); @@ -504,7 +551,10 @@ pub(super) fn plan_call_args_aggs( placements.push(placement); continue; } - let is_fp = (fp_arg_mask & (1u32 << i)) != 0; + // The walker's mask covers the first 32 arguments; later + // positions read as integer-classed, matching the producer's + // bound (an unguarded shift by i >= 32 overflows). + let is_fp = i < 32 && (fp_arg_mask & (1u32 << i)) != 0; let is_variadic = i >= fixed_args; let force_stack = is_variadic && abi.variadic_on_stack; let allow_fp_reg = !is_variadic || !abi.variadic_int_only; @@ -1175,6 +1225,11 @@ pub(crate) struct Build { /// segment, so a `DataFixup { data_offset: K }` resolves to /// byte K of this `Vec`. pub data: Vec, + /// Base alignment `data` requires in the image, at least 8. + /// Raised past 8 only by linked foreign sections with a larger + /// sh_addralign (e.g. `.rodata.cst16`); the writers place the + /// data section at a multiple of it. + pub data_align: usize, /// Bytes of zero-initialised data placed past the file image, in the /// `[data.len(), data.len() + bss_size)` offset range. Carries no file /// storage: the loader zero-fills it (ELF `p_memsz > p_filesz`, PE @@ -1233,9 +1288,9 @@ pub(crate) struct Build { /// resolution. The `OutputKind::Relocatable` writer emits one /// undefined-extern symbol per unique name plus one /// `R_AARCH64_CALL26` / `R_X86_64_PLT32` reloc per call site - /// in `.rela.text`. Final-image writers leave the field - /// untouched because no `extern_function_imports` ever land - /// in a single-TU compile path. + /// in `.rela.text`. The JIT refuses a build with entries here + /// (`undefined reference`); final-image writers leave the + /// field untouched. #[allow(dead_code)] // consumed only by the std-only elf_reloc writer pub user_extern_call_sites: Vec, /// Cross-TU data references. Populated by the SSA emitters @@ -1386,7 +1441,9 @@ pub(crate) struct Build { /// trampoline. Indexed by `ResolvedImports::imports` slot -- /// `plt_trampoline_offsets[i]` is the local code address the /// per-format writer should expose as `imports[i].local_name` - /// in the static symbol table. + /// in the static symbol table. `None` for an import with no + /// trampoline (a data import bound through the GOT/IAT); the + /// writers must not synthesize a text symbol for those. /// /// Each trampoline is a tiny GOT/IAT-load + tail-jump (3 /// instructions on aarch64 / 1 instruction on x86_64) that @@ -1396,7 +1453,7 @@ pub(crate) struct Build { /// the GOT load -- so a debugger's `b malloc` resolves /// against this in-image local symbol rather than getting /// lost in the dynamic linker's macro-expansion sites. - pub plt_trampoline_offsets: Vec, + pub plt_trampoline_offsets: Vec>, /// Post-prologue native byte offset of each function, keyed by /// `ent_pc`. The SSA emit records `code.len()` right after the /// prologue; the DWARF CFI pass turns the value into the FDE's diff --git a/src/c5/codegen/passes/dedup_imm.rs b/src/c5/codegen/passes/dedup_imm.rs index a9ecdb8cd..c3edafacf 100644 --- a/src/c5/codegen/passes/dedup_imm.rs +++ b/src/c5/codegen/passes/dedup_imm.rs @@ -273,12 +273,14 @@ mod tests { addr: 0, disp: 0, kind: LoadKind::I64, + volatile: false, }, Inst::ImmData(7), Inst::Load { addr: 2, disp: 0, kind: LoadKind::I64, + volatile: false, }, ], alloc::vec![ diff --git a/src/c5/codegen/passes/drop_redundant_extend.rs b/src/c5/codegen/passes/drop_redundant_extend.rs index 11c052ba6..d50336a44 100644 --- a/src/c5/codegen/passes/drop_redundant_extend.rs +++ b/src/c5/codegen/passes/drop_redundant_extend.rs @@ -432,6 +432,7 @@ mod tests { addr: 0, disp: 0, kind: LoadKind::I32, + volatile: false, }, Inst::Extend { value: 1, @@ -465,6 +466,7 @@ mod tests { addr: 0, disp: 0, kind: LoadKind::I32, + volatile: false, }, Inst::Extend { value: 1, @@ -492,6 +494,7 @@ mod tests { addr: 0, disp: 0, kind: LoadKind::U32, + volatile: false, }, Inst::Extend { value: 1, @@ -536,6 +539,7 @@ mod tests { addr: 0, disp: 0, kind: LoadKind::I32, + volatile: false, }, Inst::Binop { op: BinOp::Add, @@ -551,6 +555,7 @@ mod tests { disp: 0, value: 3, kind: store_kind, + volatile: false, }, ], vec![Block { @@ -594,6 +599,7 @@ mod tests { addr: 0, disp: 0, kind: LoadKind::I32, + volatile: false, }, Inst::Binop { op: BinOp::Mul, diff --git a/src/c5/codegen/passes/index_fold.rs b/src/c5/codegen/passes/index_fold.rs index 2cb30b95e..358367735 100644 --- a/src/c5/codegen/passes/index_fold.rs +++ b/src/c5/codegen/passes/index_fold.rs @@ -26,6 +26,7 @@ //! The same pass folds a constant pointer offset (a struct field offset) //! into the load/store displacement: a `BinopI(Add, base, c)` address //! with an aligned, in-range `c` becomes `Load { addr=base, disp=c }`. +//! Unlike the scaled-index fold this covers the floating kinds too. //! As with the scaled-index case this fires for a shared address too -- //! the load and store of a read-modify-write of one field fold the //! offset into both accesses, provided every use is a same-width access. @@ -34,27 +35,43 @@ use alloc::vec::Vec; use crate::c5::ir::{BinOp, FunctionSsa, Inst, LoadKind, NO_VALUE, StoreKind, Terminator, ValueId}; -/// Access width in bytes for a load kind, or `None` for the floating -/// kinds (the indexed emit handles integers only). -fn load_width(kind: LoadKind) -> Option { +/// Access width in bytes for a load kind. Used by the displacement +/// fold, which applies to integer and floating accesses alike (the +/// immediate-offset emit honors `disp` for every kind on both targets). +fn load_width(kind: LoadKind) -> u8 { + match kind { + LoadKind::I64 | LoadKind::F64 => 8, + LoadKind::I32 | LoadKind::U32 | LoadKind::F32 => 4, + LoadKind::I16 | LoadKind::U16 => 2, + LoadKind::I8 | LoadKind::U8 => 1, + } +} + +/// Access width in bytes for a store kind. See [`load_width`]. +fn store_width(kind: StoreKind) -> u8 { + match kind { + StoreKind::I64 | StoreKind::F64 => 8, + StoreKind::I32 | StoreKind::F32 => 4, + StoreKind::I16 => 2, + StoreKind::I8 => 1, + } +} + +/// [`load_width`] restricted to the integer kinds, `None` for the +/// floating kinds (the indexed emit handles integers only). +fn int_load_width(kind: LoadKind) -> Option { match kind { - LoadKind::I64 => Some(8), - LoadKind::I32 | LoadKind::U32 => Some(4), - LoadKind::I16 | LoadKind::U16 => Some(2), - LoadKind::I8 | LoadKind::U8 => Some(1), LoadKind::F32 | LoadKind::F64 => None, + k => Some(load_width(k)), } } -/// Access width in bytes for a store kind, or `None` for the floating -/// kinds. -fn store_width(kind: StoreKind) -> Option { +/// [`store_width`] restricted to the integer kinds; the scaled-index +/// emit and the narrowing-store rewrite apply to integer values only. +fn int_store_width(kind: StoreKind) -> Option { match kind { - StoreKind::I64 => Some(8), - StoreKind::I32 => Some(4), - StoreKind::I16 => Some(2), - StoreKind::I8 => Some(1), StoreKind::F32 | StoreKind::F64 => None, + k => Some(store_width(k)), } } @@ -133,13 +150,15 @@ fn foldable_scaled_addresses( addr, disp: 0, kind, - } => (*addr, load_width(*kind)), + volatile: false, + } => (*addr, int_load_width(*kind)), Inst::Store { addr, disp: 0, kind, + volatile: false, .. - } => (*addr, store_width(*kind)), + } => (*addr, int_store_width(*kind)), _ => continue, }; if let Some(&(_, _, scale)) = cand.get(&addr) @@ -197,23 +216,25 @@ fn foldable_displaced_addresses( alloc::collections::BTreeMap::new(); let mut valid: alloc::collections::BTreeMap = alloc::collections::BTreeMap::new(); for inst in &func.insts { - let (addr, width) = match inst { + let (addr, w) = match inst { Inst::Load { addr, disp: 0, kind, + volatile: false, } => (*addr, load_width(*kind)), Inst::Store { addr, disp: 0, kind, + volatile: false, .. } => (*addr, store_width(*kind)), _ => continue, }; - let (Some(w), true) = (width, cand.contains_key(&addr)) else { + if !cand.contains_key(&addr) { continue; - }; + } let seen = width_seen.entry(addr).or_insert(0); *seen = if *seen == 0 || *seen == w { w } else { 0xff }; *valid.entry(addr).or_insert(0) += 1; @@ -288,7 +309,7 @@ fn narrow_store_values(func: &mut FunctionSsa) { let n = func.insts.len(); for idx in 0..n { let (value, width) = match &func.insts[idx] { - Inst::Store { value, kind, .. } => match store_width(*kind) { + Inst::Store { value, kind, .. } => match int_store_width(*kind) { Some(w) => (*value, w), None => continue, }, @@ -318,29 +339,31 @@ pub(crate) fn run(funcs: &mut [FunctionSsa]) { addr, disp: 0, kind, + volatile: false, } => { - if let Some(width) = load_width(*kind) { - if let Some(&(base, index, scale)) = scaled.get(addr) { - debug_assert_eq!(scale, width); - rewrites.push(( - idx, - Inst::LoadIndexed { - base, - index, - scale, - kind: *kind, - }, - )); - } else if let Some(&(base, disp)) = displaced.get(addr) { - rewrites.push(( - idx, - Inst::Load { - addr: base, - disp, - kind: *kind, - }, - )); - } + if let (Some(width), Some(&(base, index, scale))) = + (int_load_width(*kind), scaled.get(addr)) + { + debug_assert_eq!(scale, width); + rewrites.push(( + idx, + Inst::LoadIndexed { + base, + index, + scale, + kind: *kind, + }, + )); + } else if let Some(&(base, disp)) = displaced.get(addr) { + rewrites.push(( + idx, + Inst::Load { + addr: base, + disp, + kind: *kind, + volatile: false, + }, + )); } } Inst::Store { @@ -348,31 +371,33 @@ pub(crate) fn run(funcs: &mut [FunctionSsa]) { disp: 0, value, kind, + volatile: false, } => { - if let Some(width) = store_width(*kind) { - if let Some(&(base, index, scale)) = scaled.get(addr) { - debug_assert_eq!(scale, width); - rewrites.push(( - idx, - Inst::StoreIndexed { - base, - index, - scale, - value: *value, - kind: *kind, - }, - )); - } else if let Some(&(base, disp)) = displaced.get(addr) { - rewrites.push(( - idx, - Inst::Store { - addr: base, - disp, - value: *value, - kind: *kind, - }, - )); - } + if let (Some(width), Some(&(base, index, scale))) = + (int_store_width(*kind), scaled.get(addr)) + { + debug_assert_eq!(scale, width); + rewrites.push(( + idx, + Inst::StoreIndexed { + base, + index, + scale, + value: *value, + kind: *kind, + }, + )); + } else if let Some(&(base, disp)) = displaced.get(addr) { + rewrites.push(( + idx, + Inst::Store { + addr: base, + disp, + value: *value, + kind: *kind, + volatile: false, + }, + )); } } _ => {} diff --git a/src/c5/codegen/passes/inline.rs b/src/c5/codegen/passes/inline.rs index ee57b9d9a..440cadfe3 100644 --- a/src/c5/codegen/passes/inline.rs +++ b/src/c5/codegen/passes/inline.rs @@ -706,10 +706,49 @@ fn splice_multi_block( new_f32.push(f32); }; - // Step 1: caller blocks 0..splice_block_idx (unchanged). - for (b_idx, block) in original.blocks.iter().enumerate().take(splice_block_idx) { - let block_start = new_insts.len() as u32; - for pc in block.inst_range.start..block.inst_range.end { + // Neither block array is ordered definitions-before-uses, and the + // call result's mapping only materializes when the callee's Return + // is spliced (Step 6) -- after Step 4 already emitted the caller + // blocks that follow the splice point. Run the emission to a fixed + // point, as the flat single-block splice does: emission is + // structurally identical across passes, so every inst keeps its new + // id and the maps converge one forward-reference level per pass. + let mut guard = original.insts.len() + callee.insts.len() + 2; + loop { + new_insts.clear(); + new_inst_src.clear(); + new_f32.clear(); + new_blocks.clear(); + let remap_before = remap.clone(); + let callee_remap_before = callee_remap.clone(); + + // Step 1: caller blocks 0..splice_block_idx (unchanged). + for (b_idx, block) in original.blocks.iter().enumerate().take(splice_block_idx) { + let block_start = new_insts.len() as u32; + for pc in block.inst_range.start..block.inst_range.end { + emit_caller_inst( + pc, + &mut new_insts, + &mut new_inst_src, + &mut new_f32, + &mut remap, + &original, + ); + } + let term = map_terminator_caller(block.terminator, &remap); + let exit_acc = map_v(block.exit_acc, &remap); + new_blocks.push(Block { + start_pc: block.start_pc, + inst_range: block_start..new_insts.len() as u32, + terminator: term, + exit_acc, + }); + let _ = b_idx; + } + + // Step 2: prefix (caller's splice block, insts up to call). + let prefix_start = new_insts.len() as u32; + for pc in splice_block.inst_range.start..call_pc { emit_caller_inst( pc, &mut new_insts, @@ -719,59 +758,149 @@ fn splice_multi_block( &original, ); } - let term = map_terminator_caller(block.terminator, &remap); - let exit_acc = map_v(block.exit_acc, &remap); + let callee_entry_new_id = callee_block_base; new_blocks.push(Block { - start_pc: block.start_pc, - inst_range: block_start..new_insts.len() as u32, - terminator: term, - exit_acc, + start_pc: splice_block.start_pc, + inst_range: prefix_start..new_insts.len() as u32, + terminator: Terminator::Jmp(callee_entry_new_id), + exit_acc: NO_VALUE, }); - let _ = b_idx; - } + let _ = prefix_id; - // Step 2: prefix (caller's splice block, insts up to call). - let prefix_start = new_insts.len() as u32; - for pc in splice_block.inst_range.start..call_pc { - emit_caller_inst( - pc, - &mut new_insts, - &mut new_inst_src, - &mut new_f32, - &mut remap, - &original, - ); - } - let callee_entry_new_id = callee_block_base; - new_blocks.push(Block { - start_pc: splice_block.start_pc, - inst_range: prefix_start..new_insts.len() as u32, - terminator: Terminator::Jmp(callee_entry_new_id), - exit_acc: NO_VALUE, - }); - let _ = prefix_id; + // Step 3: postfix block placeholder (filled after callee splices). + // We need its ID stable now so the callee's Return -> Jmp(postfix) + // points to it; emit insts + terminator below after the callee. + let postfix_block_slot = new_blocks.len(); + new_blocks.push(Block { + start_pc: 0, + inst_range: 0..0, + terminator: Terminator::Jmp(0), + exit_acc: NO_VALUE, + }); + let _ = postfix_id; + + // Step 4: caller blocks splice_block_idx+1..n_caller (shifted +1). + for (b_idx, block) in original + .blocks + .iter() + .enumerate() + .skip(splice_block_idx + 1) + { + let block_start = new_insts.len() as u32; + for pc in block.inst_range.start..block.inst_range.end { + emit_caller_inst( + pc, + &mut new_insts, + &mut new_inst_src, + &mut new_f32, + &mut remap, + &original, + ); + } + let term = map_terminator_caller(block.terminator, &remap); + let exit_acc = map_v(block.exit_acc, &remap); + new_blocks.push(Block { + start_pc: block.start_pc, + inst_range: block_start..new_insts.len() as u32, + terminator: term, + exit_acc, + }); + let _ = b_idx; + } - // Step 3: postfix block placeholder (filled after callee splices). - // We need its ID stable now so the callee's Return -> Jmp(postfix) - // points to it; emit insts + terminator below after the callee. - let postfix_block_slot = new_blocks.len(); - new_blocks.push(Block { - start_pc: 0, - inst_range: 0..0, - terminator: Terminator::Jmp(0), - exit_acc: NO_VALUE, - }); - let _ = postfix_id; + // Step 5: remap the call's args through the caller's now-built remap. + let remapped_args: Vec = call_args.iter().map(|&a| map_v(a, &remap)).collect(); - // Step 4: caller blocks splice_block_idx+1..n_caller (shifted +1). - for (b_idx, block) in original - .blocks - .iter() - .enumerate() - .skip(splice_block_idx + 1) - { - let block_start = new_insts.len() as u32; - for pc in block.inst_range.start..block.inst_range.end { + // Step 6: splice every callee block. + for cblock in &callee.blocks { + let block_start = new_insts.len() as u32; + for ce_pc in cblock.inst_range.start..cblock.inst_range.end { + let cinst = &callee.insts[ce_pc as usize]; + match cinst { + Inst::ParamRef { idx, kind } => { + let i = *idx as usize; + let arg = if i < remapped_args.len() { + remapped_args[i] + } else { + NO_VALUE + }; + callee_remap[ce_pc as usize] = splice_param_ref( + *kind, + arg, + (0, 0), + &mut new_insts, + &mut new_inst_src, + &mut new_f32, + ); + continue; + } + Inst::LoadLocal { .. } | Inst::StoreLocal { .. } | Inst::AllocaInit(_) => { + callee_remap[ce_pc as usize] = NO_VALUE; + continue; + } + _ => {} + } + if let Some(translated) = rewrite_callee_inst(cinst, &remapped_args, &callee_remap) + { + let new_id = new_insts.len() as u32; + callee_remap[ce_pc as usize] = new_id; + new_insts.push(translated); + new_inst_src.push((0, 0)); + new_f32.push( + callee + .f32_values + .get(ce_pc as usize) + .copied() + .unwrap_or(false), + ); + } + } + let new_term = match cblock.terminator { + Terminator::Jmp(b) => Terminator::Jmp(shift_callee_bid(b)), + Terminator::FallThrough(b) => Terminator::Jmp(shift_callee_bid(b)), + Terminator::Bz { + cond, + target, + fall_through, + } => Terminator::Bz { + cond: map_v(cond, &callee_remap), + target: shift_callee_bid(target), + fall_through: shift_callee_bid(fall_through), + }, + Terminator::Bnz { + cond, + target, + fall_through, + } => Terminator::Bnz { + cond: map_v(cond, &callee_remap), + target: shift_callee_bid(target), + fall_through: shift_callee_bid(fall_through), + }, + Terminator::Return(v) => { + remap[call_pc as usize] = map_v(v, &callee_remap); + Terminator::Jmp(postfix_id) + } + Terminator::TailExt(_) => unreachable!("filter rejects TailExt"), + Terminator::GotoIndirect { .. } => { + unreachable!("filter rejects GotoIndirect") + } + }; + let exit_acc = if cblock.exit_acc != NO_VALUE { + map_v(cblock.exit_acc, &callee_remap) + } else { + NO_VALUE + }; + new_blocks.push(Block { + start_pc: 0, + inst_range: block_start..new_insts.len() as u32, + terminator: new_term, + exit_acc, + }); + } + + // Step 7: fill the postfix slot now that the call's remap is set. + let postfix_start = new_insts.len() as u32; + for pc in (call_pc + 1)..splice_block.inst_range.end { emit_caller_inst( pc, &mut new_insts, @@ -781,129 +910,26 @@ fn splice_multi_block( &original, ); } - let term = map_terminator_caller(block.terminator, &remap); - let exit_acc = map_v(block.exit_acc, &remap); - new_blocks.push(Block { - start_pc: block.start_pc, - inst_range: block_start..new_insts.len() as u32, - terminator: term, - exit_acc, - }); - let _ = b_idx; - } - - // Step 5: remap the call's args through the caller's now-built remap. - let remapped_args: Vec = call_args.iter().map(|&a| map_v(a, &remap)).collect(); - - // Step 6: splice every callee block. - for cblock in &callee.blocks { - let block_start = new_insts.len() as u32; - for ce_pc in cblock.inst_range.start..cblock.inst_range.end { - let cinst = &callee.insts[ce_pc as usize]; - match cinst { - Inst::ParamRef { idx, kind } => { - let i = *idx as usize; - let arg = if i < remapped_args.len() { - remapped_args[i] - } else { - NO_VALUE - }; - callee_remap[ce_pc as usize] = splice_param_ref( - *kind, - arg, - (0, 0), - &mut new_insts, - &mut new_inst_src, - &mut new_f32, - ); - continue; - } - Inst::LoadLocal { .. } | Inst::StoreLocal { .. } | Inst::AllocaInit(_) => { - callee_remap[ce_pc as usize] = NO_VALUE; - continue; - } - _ => {} - } - if let Some(translated) = rewrite_callee_inst(cinst, &remapped_args, &callee_remap) { - let new_id = new_insts.len() as u32; - callee_remap[ce_pc as usize] = new_id; - new_insts.push(translated); - new_inst_src.push((0, 0)); - new_f32.push( - callee - .f32_values - .get(ce_pc as usize) - .copied() - .unwrap_or(false), - ); - } - } - let new_term = match cblock.terminator { - Terminator::Jmp(b) => Terminator::Jmp(shift_callee_bid(b)), - Terminator::FallThrough(b) => Terminator::Jmp(shift_callee_bid(b)), - Terminator::Bz { - cond, - target, - fall_through, - } => Terminator::Bz { - cond: map_v(cond, &callee_remap), - target: shift_callee_bid(target), - fall_through: shift_callee_bid(fall_through), - }, - Terminator::Bnz { - cond, - target, - fall_through, - } => Terminator::Bnz { - cond: map_v(cond, &callee_remap), - target: shift_callee_bid(target), - fall_through: shift_callee_bid(fall_through), - }, - Terminator::Return(v) => { - remap[call_pc as usize] = map_v(v, &callee_remap); - Terminator::Jmp(postfix_id) - } - Terminator::TailExt(_) => unreachable!("filter rejects TailExt"), - Terminator::GotoIndirect { .. } => { - unreachable!("filter rejects GotoIndirect") - } + let postfix_term = match splice_block.terminator { + Terminator::FallThrough(b) => Terminator::Jmp(shift_caller_bid(b)), + other => map_terminator_caller(other, &remap), }; - let exit_acc = if cblock.exit_acc != NO_VALUE { - map_v(cblock.exit_acc, &callee_remap) - } else { - NO_VALUE - }; - new_blocks.push(Block { + let postfix_exit_acc = map_v(splice_block.exit_acc, &remap); + new_blocks[postfix_block_slot] = Block { start_pc: 0, - inst_range: block_start..new_insts.len() as u32, - terminator: new_term, - exit_acc, - }); - } + inst_range: postfix_start..new_insts.len() as u32, + terminator: postfix_term, + exit_acc: postfix_exit_acc, + }; - // Step 7: fill the postfix slot now that the call's remap is set. - let postfix_start = new_insts.len() as u32; - for pc in (call_pc + 1)..splice_block.inst_range.end { - emit_caller_inst( - pc, - &mut new_insts, - &mut new_inst_src, - &mut new_f32, - &mut remap, - &original, - ); + if remap == remap_before && callee_remap == callee_remap_before { + break; + } + guard -= 1; + if guard == 0 { + break; + } } - let postfix_term = match splice_block.terminator { - Terminator::FallThrough(b) => Terminator::Jmp(shift_caller_bid(b)), - other => map_terminator_caller(other, &remap), - }; - let postfix_exit_acc = map_v(splice_block.exit_acc, &remap); - new_blocks[postfix_block_slot] = Block { - start_pc: 0, - inst_range: postfix_start..new_insts.len() as u32, - terminator: postfix_term, - exit_acc: postfix_exit_acc, - }; // Carry both the caller's own and the spliced callee's cross-TU // symbol references onto their new value-ids. The symbol indices diff --git a/src/c5/codegen/passes/store_forward.rs b/src/c5/codegen/passes/store_forward.rs index 159e73d62..05865988f 100644 --- a/src/c5/codegen/passes/store_forward.rs +++ b/src/c5/codegen/passes/store_forward.rs @@ -133,7 +133,17 @@ fn run_one(func: &mut FunctionSsa) { break; } match &func.insts[i] { - Inst::Load { addr, disp, kind } => { + // A volatile load must perform its own memory access + // (C99 5.1.2.3p2 / 6.7.3p6): it neither reuses an + // available value nor seeds one. It reads only, so + // existing entries stay valid. + Inst::Load { volatile: true, .. } => {} + Inst::Load { + addr, + disp, + kind, + volatile: false, + } => { let addr = *addr; let disp = *disp; let kind = *kind; @@ -202,16 +212,21 @@ fn run_one(func: &mut FunctionSsa) { disp, value, kind, + volatile, } => { let addr = *addr; let disp = *disp; let value = *value; let kind = *kind; + let volatile = *volatile; let w = store_width(kind); // Drop every entry not provably disjoint from the // written range. table.retain(|e| e.addr == addr && !overlaps(e.disp, e.width, disp, w)); - if is_int_store(kind) { + // A volatile store invalidates like any store but + // seeds no forward: a later load of the location + // must read memory (C99 6.7.3p6). + if is_int_store(kind) && !volatile { table.push(Entry { addr, disp, @@ -443,12 +458,14 @@ mod tests { addr: 0, disp: 0, value: 1, - kind: StoreKind::I64 + kind: StoreKind::I64, + volatile: false, }, Inst::Load { addr: 0, disp: 0, - kind: LoadKind::I64 + kind: LoadKind::I64, + volatile: false, }, ], Terminator::Return(3), @@ -479,12 +496,14 @@ mod tests { addr: 0, disp: 0, value: 1, - kind: StoreKind::I32 + kind: StoreKind::I32, + volatile: false, }, Inst::Load { addr: 0, disp: 0, - kind: LoadKind::I32 + kind: LoadKind::I32, + volatile: false, }, ], Terminator::Return(3), @@ -522,12 +541,14 @@ mod tests { addr: 0, disp: 0, value: 1, - kind: StoreKind::I8 + kind: StoreKind::I8, + volatile: false, }, Inst::Load { addr: 0, disp: 0, - kind: LoadKind::U8 + kind: LoadKind::U8, + volatile: false, }, ], Terminator::Return(3), @@ -540,7 +561,8 @@ mod tests { Inst::Load { addr: 0, disp: 0, - kind: LoadKind::U8 + kind: LoadKind::U8, + volatile: false, } ), "an unsigned sub-width reload must not forward", @@ -567,7 +589,8 @@ mod tests { addr: 0, disp: 0, value: 1, - kind: StoreKind::I64 + kind: StoreKind::I64, + volatile: false, }, Inst::Mcpy { dst: 0, @@ -577,7 +600,8 @@ mod tests { Inst::Load { addr: 0, disp: 0, - kind: LoadKind::I64 + kind: LoadKind::I64, + volatile: false, }, ], Terminator::Return(4), @@ -591,6 +615,94 @@ mod tests { assert!(matches!(f.insts[4], Inst::Load { .. })); } + /// A volatile store seeds no forwarding entry: the reload after it + /// must read memory (C99 6.7.3p6). + #[test] + fn volatile_store_seeds_no_forward() { + let mut f = fresh( + alloc::vec![ + Inst::ParamRef { + idx: 0, + kind: LoadKind::I64 + }, + Inst::ParamRef { + idx: 1, + kind: LoadKind::I64 + }, + Inst::Store { + addr: 0, + disp: 0, + value: 1, + kind: StoreKind::I64, + volatile: true, + }, + Inst::Load { + addr: 0, + disp: 0, + kind: LoadKind::I64, + volatile: false, + }, + ], + Terminator::Return(3), + 3, + ); + run_one(&mut f); + assert!( + matches!(f.blocks[0].terminator, Terminator::Return(3)), + "a load after a volatile store must not forward", + ); + assert!(matches!(f.insts[3], Inst::Load { .. })); + } + + /// A volatile load neither reuses an available value nor seeds one: + /// each source-level read performs its own access (C99 5.1.2.3p2). + #[test] + fn volatile_load_neither_reuses_nor_seeds() { + let mut f = fresh( + alloc::vec![ + Inst::ParamRef { + idx: 0, + kind: LoadKind::I64 + }, + Inst::ParamRef { + idx: 1, + kind: LoadKind::I64 + }, + Inst::Store { + addr: 0, + disp: 0, + value: 1, + kind: StoreKind::I64, + volatile: false, + }, + Inst::Load { + addr: 0, + disp: 0, + kind: LoadKind::I64, + volatile: true, + }, + Inst::Load { + addr: 0, + disp: 0, + kind: LoadKind::I64, + volatile: true, + }, + Inst::Binop { + op: crate::c5::ir::BinOp::Add, + lhs: 3, + rhs: 4 + }, + ], + Terminator::Return(5), + 5, + ); + run_one(&mut f); + assert!( + matches!(f.insts[5], Inst::Binop { lhs: 3, rhs: 4, .. }), + "volatile loads must not forward from the store or each other", + ); + } + /// Two loads of the same location with no write between: the second /// forwards to the first. #[test] @@ -608,12 +720,14 @@ mod tests { Inst::Load { addr: 0, disp: 0, - kind: LoadKind::I64 + kind: LoadKind::I64, + volatile: false, }, Inst::Load { addr: 0, disp: 0, - kind: LoadKind::I64 + kind: LoadKind::I64, + volatile: false, }, Inst::Binop { op: crate::c5::ir::BinOp::Add, diff --git a/src/c5/codegen/passes/struct_return_reg.rs b/src/c5/codegen/passes/struct_return_reg.rs index 1542c6b56..435f9c6ff 100644 --- a/src/c5/codegen/passes/struct_return_reg.rs +++ b/src/c5/codegen/passes/struct_return_reg.rs @@ -214,12 +214,13 @@ fn promote_once(func: &mut FunctionSsa) -> bool { disp, value, kind, + volatile, } => { if let Some(&s) = la_slot.get(addr) { // A write into a tracked slot. Promotable only as a - // single full-width store at offset 0; any other - // store shape disqualifies the slot. - let full = *disp == 0 && store_width(*kind) == 8; + // single full-width non-volatile store at offset 0; + // any other store shape disqualifies the slot. + let full = *disp == 0 && store_width(*kind) == 8 && !*volatile; let u = slots.entry(s).or_insert_with(SlotUse::empty); if !u.disqualified && u.store_idx == 0 && full { u.store_idx = idx; @@ -234,9 +235,14 @@ fn promote_once(func: &mut FunctionSsa) -> bool { mark_disq(&mut slots, s); } } - Inst::Load { addr, disp, kind } => { + Inst::Load { + addr, + disp, + kind, + volatile, + } => { if let Some(&s) = la_slot.get(addr) { - if *disp == 0 { + if *disp == 0 && !*volatile { slots .entry(s) .or_insert_with(SlotUse::empty) @@ -383,6 +389,7 @@ fn promote_once(func: &mut FunctionSsa) -> bool { disp: 0, value: u.word, kind: u.kind, + volatile: false, }, )); // A reference to the copy's result reads the stored value. diff --git a/src/c5/codegen/ssa/build.rs b/src/c5/codegen/ssa/build.rs index 4b6d5c575..9884bd595 100644 --- a/src/c5/codegen/ssa/build.rs +++ b/src/c5/codegen/ssa/build.rs @@ -540,10 +540,16 @@ impl SsaBuilder { /// 6.3.1.8); tag it f32 so the codegen keeps it in the s-view of an /// FP register without a widening conversion. pub(crate) fn load(&mut self, addr: ValueId, kind: LoadKind) -> ValueId { + self.load_vol(addr, kind, false) + } + + /// [`Self::load`] with an explicit volatile mark (C99 6.7.3p6). + pub(crate) fn load_vol(&mut self, addr: ValueId, kind: LoadKind, volatile: bool) -> ValueId { let v = self.push(Inst::Load { addr, disp: 0, kind, + volatile, }); if matches!(kind, LoadKind::F32) { self.mark_f32(v); @@ -558,12 +564,24 @@ impl SsaBuilder { /// alias a local whose address escaped earlier; drop every /// CSE entry so a later `load_local` re-reads the slot. pub(crate) fn store(&mut self, addr: ValueId, value: ValueId, kind: StoreKind) -> ValueId { + self.store_vol(addr, value, kind, false) + } + + /// [`Self::store`] with an explicit volatile mark (C99 6.7.3p6). + pub(crate) fn store_vol( + &mut self, + addr: ValueId, + value: ValueId, + kind: StoreKind, + volatile: bool, + ) -> ValueId { self.local_cache.clear(); self.push(Inst::Store { addr, disp: 0, value, kind, + volatile, }) } @@ -575,23 +593,39 @@ impl SsaBuilder { /// instructions; the codegen drops one local-slot load per /// match. pub(crate) fn load_local(&mut self, off: i64, kind: LoadKind) -> ValueId { - for entry in &self.local_cache { - if entry.off == off && entry.kind == kind { - return entry.value; + self.load_local_vol(off, kind, false) + } + + /// [`Self::load_local`] with an explicit volatile mark. A volatile + /// load bypasses the CSE cache both ways: it never reuses a cached + /// value and never seeds one, so every source-level read performs + /// a memory access (C99 5.1.2.3p2). + pub(crate) fn load_local_vol(&mut self, off: i64, kind: LoadKind, volatile: bool) -> ValueId { + if !volatile { + for entry in &self.local_cache { + if entry.off == off && entry.kind == kind { + return entry.value; + } } } - let v = self.push(Inst::LoadLocal { off, kind }); + let v = self.push(Inst::LoadLocal { + off, + kind, + volatile, + }); // A `float`-typed local load is single precision (C99 6.3.1.8); // tag it f32 so the codegen keeps it in the s-view of an FP // register without a widening conversion. if matches!(kind, LoadKind::F32) { self.mark_f32(v); } - self.local_cache.push(LocalCacheEntry { - off, - kind, - value: v, - }); + if !volatile { + self.local_cache.push(LocalCacheEntry { + off, + kind, + value: v, + }); + } v } @@ -605,8 +639,24 @@ impl SsaBuilder { /// load would be safe, but special-casing it isn't worth the /// surface area; the next `load_local` simply re-emits. pub(crate) fn store_local(&mut self, off: i64, value: ValueId, kind: StoreKind) -> ValueId { + self.store_local_vol(off, value, kind, false) + } + + /// [`Self::store_local`] with an explicit volatile mark. + pub(crate) fn store_local_vol( + &mut self, + off: i64, + value: ValueId, + kind: StoreKind, + volatile: bool, + ) -> ValueId { self.local_cache.retain(|e| e.off != off); - self.push(Inst::StoreLocal { off, value, kind }) + self.push(Inst::StoreLocal { + off, + value, + kind, + volatile, + }) } /// `Inst::Binop`. In-block CSE: a prior `binop(op, lhs, rhs)` diff --git a/src/c5/codegen/ssa/dump.rs b/src/c5/codegen/ssa/dump.rs index 57683cc30..1d1bfcb57 100644 --- a/src/c5/codegen/ssa/dump.rs +++ b/src/c5/codegen/ssa/dump.rs @@ -89,25 +89,45 @@ fn fmt_inst(inst: &Inst) -> String { BlockAddr(b) => format!("BlockAddr(block={b})"), LocalAddr(n) => format!("LocalAddr({n})"), TlsAddr(o) => format!("TlsAddr({o})"), - Load { addr, disp, kind } => format!( - "Load {{ addr=v{addr}, disp={disp}, kind={} }}", - fmt_load_kind(*kind) + Load { + addr, + disp, + kind, + volatile, + } => format!( + "Load {{ addr=v{addr}, disp={disp}, kind={}{} }}", + fmt_load_kind(*kind), + fmt_volatile(*volatile), ), Store { addr, disp, value, kind, + volatile, } => format!( - "Store {{ addr=v{addr}, disp={disp}, value=v{value}, kind={} }}", + "Store {{ addr=v{addr}, disp={disp}, value=v{value}, kind={}{} }}", fmt_store_kind(*kind), + fmt_volatile(*volatile), ), - LoadLocal { off, kind } => { - format!("LoadLocal {{ off={off}, kind={} }}", fmt_load_kind(*kind),) - } - StoreLocal { off, value, kind } => format!( - "StoreLocal {{ off={off}, value=v{value}, kind={} }}", + LoadLocal { + off, + kind, + volatile, + } => format!( + "LoadLocal {{ off={off}, kind={}{} }}", + fmt_load_kind(*kind), + fmt_volatile(*volatile), + ), + StoreLocal { + off, + value, + kind, + volatile, + } => format!( + "StoreLocal {{ off={off}, value=v{value}, kind={}{} }}", fmt_store_kind(*kind), + fmt_volatile(*volatile), ), LoadIndexed { base, @@ -271,6 +291,11 @@ fn fmt_place(p: Place) -> String { } } +/// Rendered only when set so non-volatile dumps are unchanged. +fn fmt_volatile(v: bool) -> &'static str { + if v { ", volatile" } else { "" } +} + fn fmt_load_kind(k: LoadKind) -> &'static str { match k { LoadKind::I64 => "I64", diff --git a/src/c5/codegen/ssa/emit_common.rs b/src/c5/codegen/ssa/emit_common.rs index a179654b4..ab7375724 100644 --- a/src/c5/codegen/ssa/emit_common.rs +++ b/src/c5/codegen/ssa/emit_common.rs @@ -714,6 +714,9 @@ pub(crate) fn is_dead_pure( alloc: &super::reg_alloc::Allocation, ) -> bool { use super::super::ir::Inst::*; + // A volatile load is never pure: the access itself is the side + // effect (C99 5.1.2.3p2 / 6.7.3p6), so it is emitted even with no + // consumers, at every optimization level. let pure = matches!( inst, Imm(_) @@ -721,8 +724,14 @@ pub(crate) fn is_dead_pure( | ImmCode(_) | LocalAddr(_) | TlsAddr(_) - | Load { .. } - | LoadLocal { .. } + | Load { + volatile: false, + .. + } + | LoadLocal { + volatile: false, + .. + } | LoadIndexed { .. } | Binop { .. } | BinopI { .. } diff --git a/src/c5/codegen/ssa/liveness.rs b/src/c5/codegen/ssa/liveness.rs index d34e11516..efd0c1797 100644 --- a/src/c5/codegen/ssa/liveness.rs +++ b/src/c5/codegen/ssa/liveness.rs @@ -403,7 +403,8 @@ impl Liveness { let is_call = matches!( inst, Inst::Call { .. } | Inst::CallIndirect { .. } | Inst::CallExt { .. } - ) || (tls_addr_is_call && matches!(inst, Inst::TlsAddr(_))); + ) || (tls_addr_is_call && matches!(inst, Inst::TlsAddr(_))) + || super::reg_alloc::is_setjmp_barrier(inst); if super::reg_alloc::produces_value(inst) { live.remove(&idx); } diff --git a/src/c5/codegen/ssa/mem2reg.rs b/src/c5/codegen/ssa/mem2reg.rs index 645016e09..5754cac7b 100644 --- a/src/c5/codegen/ssa/mem2reg.rs +++ b/src/c5/codegen/ssa/mem2reg.rs @@ -32,6 +32,16 @@ pub(crate) fn promotable_slots(func: &FunctionSsa) -> BTreeSet { let mut address_taken: BTreeSet = BTreeSet::new(); for inst in &func.insts { match inst { + // A volatile access pins the slot to memory: every read and + // write must be performed as the abstract machine specifies + // (C99 6.7.3p6), and the object must retain its last store + // across control transfers the CFG does not model (7.13.2.1 + // longjmp), so the slot is never lifted into a register. + Inst::LoadLocal { off, volatile, .. } | Inst::StoreLocal { off, volatile, .. } + if *volatile => + { + address_taken.insert(*off); + } Inst::LoadLocal { off, .. } | Inst::StoreLocal { off, .. } => { touched.insert(*off); } @@ -539,7 +549,7 @@ fn for_each_operand_mut(inst: &mut Inst, mut f: impl FnMut(&mut ValueId)) { fn slot_is_full_width(func: &FunctionSsa, slot: i64) -> bool { for inst in &func.insts { match inst { - Inst::LoadLocal { off, kind } if *off == slot && *kind != LoadKind::I64 => { + Inst::LoadLocal { off, kind, .. } if *off == slot && *kind != LoadKind::I64 => { return false; } Inst::StoreLocal { off, kind, .. } if *off == slot && *kind != StoreKind::I64 => { @@ -571,7 +581,7 @@ fn slot_narrow_load_kind(func: &FunctionSsa, slot: i64) -> Option { let mut store_kind: Option = None; for inst in &func.insts { match inst { - Inst::LoadLocal { off, kind } if *off == slot => match load_kind { + Inst::LoadLocal { off, kind, .. } if *off == slot => match load_kind { None => load_kind = Some(*kind), Some(k) if k == *kind => {} Some(_) => return None, @@ -724,7 +734,7 @@ fn slot_class(func: &FunctionSsa, slot: i64) -> Option { saw_int_store = true; } } - Inst::LoadLocal { off, kind } if *off == slot => match kind { + Inst::LoadLocal { off, kind, .. } if *off == slot => match kind { LoadKind::F32 | LoadKind::F64 => { saw_fp_load = true; match fp_load_kind { @@ -1286,16 +1296,19 @@ mod tests { off: -1, value: 0, kind: StoreKind::I64, + volatile: false, }, Inst::LoadLocal { off: -1, kind: LoadKind::I64, + volatile: false, }, Inst::LocalAddr(-2), Inst::StoreLocal { off: -2, value: 0, kind: StoreKind::I64, + volatile: false, }, ]; let blocks = alloc::vec![empty_block(Terminator::Return(NO_VALUE))]; @@ -1308,6 +1321,33 @@ mod tests { ); } + #[test] + fn volatile_slot_is_not_promotable() { + // Slot -1 is accessed only through volatile LoadLocal / + // StoreLocal (C99 6.7.3p6): every access must reach memory, + // so the slot is excluded from promotion. + let insts = alloc::vec![ + Inst::Imm(1), + Inst::StoreLocal { + off: -1, + value: 0, + kind: StoreKind::I64, + volatile: true, + }, + Inst::LoadLocal { + off: -1, + kind: LoadKind::I64, + volatile: true, + }, + ]; + let blocks = alloc::vec![empty_block(Terminator::Return(2))]; + let f = func_with(insts, blocks); + assert!( + !promotable_slots(&f).contains(&-1), + "volatile-accessed slot -1 must stay memory-resident" + ); + } + #[test] fn run_neutralises_writes_to_write_only_slot() { // Address-free slot -1 is stored twice (two distinct int @@ -1320,12 +1360,14 @@ mod tests { off: -1, value: 0, kind: StoreKind::I32, + volatile: false, }, Inst::Imm(2), Inst::StoreLocal { off: -1, value: 2, kind: StoreKind::I32, + volatile: false, }, Inst::Imm(99), ]; @@ -1438,10 +1480,12 @@ mod tests { off: -1, value: 0, kind: StoreKind::I64, + volatile: false, }, Inst::LoadLocal { off: -1, kind: LoadKind::I64, + volatile: false, }, ]; let blocks = alloc::vec![ @@ -1476,11 +1520,13 @@ mod tests { off: -1, value: 0, kind: StoreKind::I64, + volatile: false, }, Inst::LocalAddr(-1), Inst::LoadLocal { off: -1, kind: LoadKind::I64, + volatile: false, }, ]; let blocks = alloc::vec![Block { @@ -1509,10 +1555,12 @@ mod tests { off: -1, value: 0, kind: StoreKind::I8, + volatile: false, }, Inst::LoadLocal { off: -1, kind: LoadKind::I8, + volatile: false, }, ]; let blocks = alloc::vec![Block { @@ -1548,10 +1596,12 @@ mod tests { off: -1, value: 0, kind: StoreKind::I8, + volatile: false, }, Inst::LoadLocal { off: -1, kind: LoadKind::U8, + volatile: false, }, ]; let blocks = alloc::vec![Block { @@ -1588,16 +1638,19 @@ mod tests { off: -1, value: 1, kind: StoreKind::I64, + volatile: false, }, Inst::Imm(2), // block 2 Inst::StoreLocal { off: -1, value: 3, kind: StoreKind::I64, + volatile: false, }, Inst::LoadLocal { off: -1, kind: LoadKind::I64, + volatile: false, }, // block 3 ]; let blocks = alloc::vec![ @@ -1655,6 +1708,7 @@ mod tests { off: -1, value: 1, kind: StoreKind::I64, + volatile: false, }, // block 2 Inst::Imm(2), @@ -1662,11 +1716,13 @@ mod tests { off: -1, value: 3, kind: StoreKind::I64, + volatile: false, }, // block 3 Inst::LoadLocal { off: -1, kind: LoadKind::I64, + volatile: false, }, ]; let blocks = alloc::vec![ @@ -1725,7 +1781,7 @@ mod tests { } // The LoadLocal slid forward by one phi. match &f.insts[6] { - Inst::LoadLocal { off, kind } => { + Inst::LoadLocal { off, kind, .. } => { assert_eq!(*off, -1); assert_eq!(*kind, LoadKind::I64); } @@ -1774,16 +1830,19 @@ mod tests { off: -1, value: 1, kind: StoreKind::I64, + volatile: false, }, Inst::Imm(2), Inst::StoreLocal { off: -1, value: 3, kind: StoreKind::I64, + volatile: false, }, Inst::LoadLocal { off: -1, kind: LoadKind::I64, + volatile: false, }, Inst::ImmData(0), ]; @@ -1857,6 +1916,7 @@ mod tests { off: -1, value: 1, kind: StoreKind::I64, + volatile: false, }, // block 2: ids 3..5 Inst::Imm(22), @@ -1864,11 +1924,13 @@ mod tests { off: -1, value: 3, kind: StoreKind::I64, + volatile: false, }, // block 3: id 5 Inst::LoadLocal { off: -1, kind: LoadKind::I64, + volatile: false, }, ]; let blocks = alloc::vec![ @@ -1987,10 +2049,12 @@ mod tests { off: -1, value: 1, kind: StoreKind::I64, + volatile: false, }, Inst::LoadLocal { off: -1, kind: LoadKind::I64, + volatile: false, }, // block 2 ]; let blocks = alloc::vec![ @@ -2087,7 +2151,8 @@ mod tests { Inst::StoreLocal { off: -1, value: 0, - kind: StoreKind::I64 + kind: StoreKind::I64, + volatile: false, }, // v1 // b1: condition operand (placeholder; the body emits a // constant so the branch is deterministic; not subject @@ -2098,18 +2163,21 @@ mod tests { Inst::StoreLocal { off: -1, value: 3, - kind: StoreKind::I64 + kind: StoreKind::I64, + volatile: false, }, // v4 Inst::Imm(9), // v5 Inst::StoreLocal { off: -1, value: 5, - kind: StoreKind::I64 + kind: StoreKind::I64, + volatile: false, }, // v6 // b3: load -1 Inst::LoadLocal { off: -1, - kind: LoadKind::I64 + kind: LoadKind::I64, + volatile: false, }, // v7 ]; let blocks = alloc::vec![ diff --git a/src/c5/codegen/ssa/reg_alloc.rs b/src/c5/codegen/ssa/reg_alloc.rs index 9e0702577..7378265df 100644 --- a/src/c5/codegen/ssa/reg_alloc.rs +++ b/src/c5/codegen/ssa/reg_alloc.rs @@ -104,12 +104,13 @@ pub(crate) struct Allocation { /// skip pure-with-no-uses insts (dead-code elimination). A value /// with zero uses and no side effects produces no machine code. pub use_counts: Vec, - /// Highest PC index that names each value as an operand. A - /// value defined at PC `i` is live throughout `[i, last_use[i]]` - /// and the emit pass queries this to compute the set of - /// registers carrying live SSA values at any given PC -- needed - /// when picking an intra-instruction scratch that must not - /// clobber a value the next instruction reads. + /// Highest PC index that names each value as an operand, raised + /// across back edges by `extend_last_use_across_blocks`. A value + /// defined at PC `i` is live throughout `[i, last_use[i]]`. The + /// allocator's interval tests read it: `class_last_use` feeds + /// `promote_calls_after_def_to_classes` so a value whose range + /// spans a call takes a callee-saved home, and the coalescing + /// hints avoid a caller-saved register such a call would clobber. pub last_use: Vec, /// For `BinopI(Shr, X, K)` insts the allocator recognised as /// the upper half of a sign-narrow `Shl K; Shr K` pair (K in @@ -529,6 +530,77 @@ pub(crate) fn allocate(func: &FunctionSsa, target: Target) -> Allocation { _ => None, } }; + // The fold reads `places[shl_src]` when the Shr is emitted, past the + // source's coloring-visible live range (its last use is the Shl). It + // is sound only when nothing between the pair can change that place: + // both insts in one block, every intervening inst free of fixed + // emit-level clobbers (calls, div/mod, register-count shifts, + // atomics, mcpy), and no intervening definition colored onto the + // same place. + let mut block_of: Vec = vec![0; func.insts.len()]; + for (b, blk) in func.blocks.iter().enumerate() { + for v in blk.inst_range.clone() { + block_of[v as usize] = b as u32; + } + } + let clobber_free = |inst: &Inst| -> bool { + match inst { + Inst::Imm(_) + | Inst::ImmData(_) + | Inst::ImmCode(_) + | Inst::ImmExtCode(_) + | Inst::BlockAddr(_) + | Inst::LocalAddr(_) + | Inst::Extend { .. } + | Inst::FpCast { .. } + | Inst::Fneg(_) + | Inst::Fma { .. } + | Inst::Load { .. } + | Inst::LoadLocal { .. } + | Inst::LoadIndexed { .. } + | Inst::Store { .. } + | Inst::StoreLocal { .. } + | Inst::StoreIndexed { .. } => true, + Inst::BinopI { op, .. } => { + !matches!(op, BinOp::Div | BinOp::Divu | BinOp::Mod | BinOp::Modu) + } + Inst::Binop { op, .. } => !matches!( + op, + BinOp::Div + | BinOp::Divu + | BinOp::Mod + | BinOp::Modu + | BinOp::Shl + | BinOp::Shr + | BinOp::Shru + ), + _ => false, + } + }; + let fold_preserves_source = |shl_pc: ValueId, shr_pc: ValueId| -> bool { + if block_of[shl_pc as usize] != block_of[shr_pc as usize] { + return false; + } + let src_place = match func.insts.get(shl_pc as usize) { + Some(inst) => match shift_shape(inst) { + Some((_, src, _, _)) => places.get(src as usize).copied().unwrap_or(Place::None), + None => return false, + }, + None => return false, + }; + for p in (shl_pc + 1)..shr_pc { + let inst_p = &func.insts[p as usize]; + if !clobber_free(inst_p) { + return false; + } + if produces_value(inst_p) + && places.get(p as usize).copied().unwrap_or(Place::None) == src_place + { + return false; + } + } + true + }; for (i, inst) in func.insts.iter().enumerate() { let Some((shr_op, shr_lhs, shr_k, shr_imm_v)) = shift_shape(inst) else { continue; @@ -548,6 +620,9 @@ pub(crate) fn allocate(func: &FunctionSsa, target: Target) -> Allocation { if use_counts.get(shr_lhs as usize).copied().unwrap_or(0) != 1 { continue; } + if !fold_preserves_source(shr_lhs, i as ValueId) { + continue; + } sxtw_source[i] = shl_src; sxtw_k[i] = shr_k; use_counts[shr_lhs as usize] = 0; @@ -1140,6 +1215,9 @@ fn compute_use_counts(func: &FunctionSsa) -> Vec { /// True when the inst has no side effects and can be DCE'd if its /// result is unread. Mirrors `is_dead_pure` in ssa_emit_common but /// kept here to drive the allocator's use-count fixed-point pass. +/// A volatile load is an access the abstract machine performs even +/// when the value is unused (C99 5.1.2.3p2 / 6.7.3p6), so it is +/// never pure. fn is_pure_inst(inst: &Inst) -> bool { matches!( inst, @@ -1149,8 +1227,14 @@ fn is_pure_inst(inst: &Inst) -> bool { | Inst::ImmExtCode(_) | Inst::LocalAddr(_) | Inst::TlsAddr(_) - | Inst::Load { .. } - | Inst::LoadLocal { .. } + | Inst::Load { + volatile: false, + .. + } + | Inst::LoadLocal { + volatile: false, + .. + } | Inst::LoadIndexed { .. } | Inst::Binop { .. } | Inst::BinopI { .. } @@ -1161,6 +1245,19 @@ fn is_pure_inst(inst: &Inst) -> bool { ) } +/// Whether `inst` is the inline setjmp intrinsic. A longjmp back to +/// the setjmp site restores only the jmp_buf register set (x19-x28, +/// x29, sp, d8-d15), so for allocation the site clobbers the +/// caller-saved banks exactly like a call (C99 7.13.2.1p3 requires +/// values unmodified since setjmp to survive the second return). +pub(crate) fn is_setjmp_barrier(inst: &Inst) -> bool { + matches!( + inst, + Inst::Intrinsic { kind, .. } + if *kind == crate::c5::op::Intrinsic::SetjmpAArch64 as i64 + ) +} + /// Invoke `f` for each operand `ValueId` referenced by `inst`. pub(crate) fn for_each_operand(inst: &Inst, mut f: impl FnMut(ValueId)) { match inst { @@ -1849,9 +1946,13 @@ fn compute_last_use(func: &FunctionSsa) -> Vec { } }; bump(b.exit_acc); + // A `GotoIndirect` sets `exit_acc` to its target, so the bump + // above already covers it; the explicit arm keeps this walk + // uniform with the liveness and use-count terminator walks. match &b.terminator { Terminator::Bz { cond, .. } | Terminator::Bnz { cond, .. } => bump(*cond), Terminator::Return(v) => bump(*v), + Terminator::GotoIndirect { target } => bump(*target), _ => {} } } @@ -1916,6 +2017,7 @@ fn extend_last_use_across_blocks(func: &FunctionSsa, last_use: &mut [u32]) { match &blk.terminator { Terminator::Bz { cond, .. } | Terminator::Bnz { cond, .. } => mark(*cond), Terminator::Return(v) if *v != NO_VALUE => mark(*v), + Terminator::GotoIndirect { target } if *target != NO_VALUE => mark(*target), _ => {} } } @@ -2016,7 +2118,8 @@ fn promote_calls_after_def_to_classes( let is_call = matches!( inst, Inst::Call { .. } | Inst::CallIndirect { .. } | Inst::CallExt { .. } - ) || (tls_addr_is_call && matches!(inst, Inst::TlsAddr(_))); + ) || (tls_addr_is_call && matches!(inst, Inst::TlsAddr(_))) + || is_setjmp_barrier(inst); if is_call { call_pcs.push(idx as u32); } @@ -2308,6 +2411,48 @@ int main(void) { return 0; } /// Allocate every function in quicksort.c on aarch64. The /// fixture has straight-line control flow and short /// expressions; the allocator should never spill. + #[test] + fn unused_volatile_reads_survive_dead_pure_skip() { + // C99 5.1.2.3p2: a volatile read is a side effect. The emit's + // dead-code skip must keep the unused loads and their address + // chains at every optimization level. + let funcs = lift("tests/fixtures/c/volatile_unused_read.c"); + let main = funcs.iter().find(|f| f.name == "main").expect("main"); + let alloc = allocate(main, Target::host()); + let mut volatile_loads = 0; + for (v, inst) in main.insts.iter().enumerate() { + match inst { + Inst::Load { + volatile: true, + addr, + .. + } => { + volatile_loads += 1; + assert!( + !super::super::emit_common::is_dead_pure(inst, v as ValueId, &alloc), + "volatile Load v{v} must not be skipped as dead" + ); + assert_ne!( + alloc.use_counts[*addr as usize], 0, + "the volatile load's address chain must stay live" + ); + } + Inst::LoadLocal { volatile: true, .. } => { + volatile_loads += 1; + assert!( + !super::super::emit_common::is_dead_pure(inst, v as ValueId, &alloc), + "volatile LoadLocal v{v} must not be skipped as dead" + ); + } + _ => {} + } + } + assert!( + volatile_loads >= 2, + "expected the global and the local volatile reads in SSA, saw {volatile_loads}" + ); + } + #[test] fn allocate_quicksort_no_spill() { let funcs = lift("tests/fixtures/c/quicksort.c"); diff --git a/src/c5/codegen/ssa/shadow.rs b/src/c5/codegen/ssa/shadow.rs index 28725d149..6a446cdba 100644 --- a/src/c5/codegen/ssa/shadow.rs +++ b/src/c5/codegen/ssa/shadow.rs @@ -365,14 +365,17 @@ fn live_data_intervals( live[interval_of(off)] = true; } } + // The target interval is resolved via the anchor: a one-past-the-end + // target coincides with the next object's start and would mark the + // wrong object live. let edges: Vec<(usize, usize)> = program .data_relocs .iter() - .filter(|r| (r.data_offset as i64) < data_len && (r.target_offset as i64) < data_len) + .filter(|r| (r.data_offset as i64) < data_len && (r.target_anchor as i64) < data_len) .map(|r| { ( interval_of(r.data_offset as i64), - interval_of(r.target_offset as i64), + interval_of(r.target_anchor as i64), ) }) .collect(); @@ -554,7 +557,23 @@ pub(crate) fn compact_program_data( } for r in &mut out.data_relocs { r.data_offset = map(r.data_offset as i64) as u64; - r.target_offset = map(r.target_offset as i64) as u64; + // Rebase the target against its own object, resolved via the + // anchor: a one-past-the-end target (C99 6.5.6p8) lies on the + // next object's start and the raw offset would follow that + // object instead. + let anchor = r.target_anchor as i64; + if (0..data_len).contains(&anchor) { + let i = interval_of(anchor); + if new_base[i] >= 0 { + r.target_offset = (new_base[i] + (r.target_offset as i64 - starts[i])) as u64; + } else { + r.target_offset = 0; + } + r.target_anchor = map(anchor) as u64; + } else { + r.target_offset = map(r.target_offset as i64) as u64; + r.target_anchor = r.target_offset; + } } for r in &mut out.code_relocs { r.data_offset = map(r.data_offset as i64) as u64; diff --git a/src/c5/codegen/ssa/slot_coalesce.rs b/src/c5/codegen/ssa/slot_coalesce.rs index 30ba6535c..990e4c35e 100644 --- a/src/c5/codegen/ssa/slot_coalesce.rs +++ b/src/c5/codegen/ssa/slot_coalesce.rs @@ -202,6 +202,16 @@ fn coalesce(f: &mut FunctionSsa) -> BTreeMap> { Inst::Call { ret_slot_local, .. } | Inst::CallIndirect { ret_slot_local, .. } | Inst::CallExt { ret_slot_local, .. } => *ret_slot_local, + // A volatile-accessed slot keeps its own storage: the + // object must hold its last store across control + // transfers the CFG does not model (C99 7.13.2.1 + // longjmp), so the liveness below cannot justify + // sharing or moving it. + Inst::LoadLocal { off, volatile, .. } | Inst::StoreLocal { off, volatile, .. } + if *volatile => + { + *off + } _ => continue, }; if movable(off) && !agg_cells.contains(&off) { diff --git a/src/c5/codegen/x86_64/emit.rs b/src/c5/codegen/x86_64/emit.rs index a8e59f142..6061c54ae 100644 --- a/src/c5/codegen/x86_64/emit.rs +++ b/src/c5/codegen/x86_64/emit.rs @@ -334,14 +334,13 @@ fn param_placements(func: &FunctionSsa, abi: super::Abi) -> alloc::vec::Vec (usize, usize) { let placements = param_placements(func, abi); // The count of register-passed (non-stack) placements and the count @@ -1224,18 +1223,20 @@ fn marshal_args( } } - // System V FP-eightbyte aggregate arguments: any aggregate containing - // an SSE eightbyte. regs[0] may be an xmm, so the regs[0]-as-base scheme - // below cannot apply -- materialize the source address into a scratch - // GPR and load each eightbyte into its register (movsd for SSE, mov for - // INTEGER). Runs after the scalar-FP moves (their xmm sources consumed) - // and before the integer marshal (the source address, in a GPR, not yet - // overwritten); the eightbytes are memory loads, joining no xmm cycle. + // System V aggregates whose eightbytes are all SSE: no integer + // eightbyte register can hold the base, so materialize the source + // address into a scratch GPR and load each eightbyte's xmm. Runs + // after the scalar-FP moves (their xmm sources consumed); the loads + // touch only SCRATCH_R10 and the aggregate's own xmm targets, so + // they cannot disturb the integer parallel move below. Mixed + // SSE/INTEGER aggregates are deferred: their integer eightbyte + // targets are argument GPRs that may still be another argument's + // pending source, so their base rides the parallel move instead. for (i, &placement) in plan.placements.iter().enumerate() { let super::ArgPlacement::StructRegs { regs, n } = placement else { continue; }; - if n == 0 || !regs.iter().take(n as usize).any(|c| c.is_fp) { + if n == 0 || !regs.iter().take(n as usize).all(|c| c.is_fp) { continue; } let base = match materialize_int_shifted( @@ -1253,30 +1254,29 @@ fn marshal_args( return false; } }; - // The source address must not share a register with an INTEGER - // eightbyte's destination (an argument GPR): loading that eightbyte - // would clobber the base before a later SSE eightbyte loads from it. - // materialize_int_shifted may return the value's existing register - // (an argument GPR), so stage it in SCRATCH_R10, never an argument - // or aggregate destination. if base.0 != SCRATCH_R10.0 { emit_mov_rr(code, SCRATCH_R10, base); } - let base = SCRATCH_R10; for (k, cr) in regs.iter().take(n as usize).enumerate() { - let off = (k as i32) * 8; - if cr.is_fp { - emit_movsd_xmm_mem(code, Reg(cr.reg), base, off); - } else { - emit_mov_r_mem(code, Reg(cr.reg), base, off); - } + emit_movsd_xmm_mem(code, Reg(cr.reg), SCRATCH_R10, (k as i32) * 8); } } + // First INTEGER eightbyte register of an aggregate, if any: the + // aggregate's base address is routed there by the parallel move and + // the eightbyte loads below read from it (that register's own + // eightbyte loads last). + let agg_base_reg = |regs: &[super::ClassReg; 4], n: u8| -> Option { + regs.iter() + .take(n as usize) + .find(|c| !c.is_fp) + .map(|c| c.reg) + }; + // Integer-register placements plus aggregate base addresses are one // parallel register move (System V AMD64 3.2.3). A scalar `IntReg` // arg moves src->target; a `StructRegs` arg positions its base - // address into its own first eightbyte register `regs[0]`, from + // address into its own first integer eightbyte register, from // which the eightbytes load below (the base register is overwritten // by its own eightbyte last). Routing the base through that per- // aggregate register -- never a shared scratch -- keeps one @@ -1291,12 +1291,10 @@ fn marshal_args( int_moves.push((s, r)); } } - // FP-eightbyte aggregates (an SSE unit) loaded above. - super::ArgPlacement::StructRegs { regs, n } - if n > 0 && !regs.iter().take(n as usize).any(|c| c.is_fp) => - { - let dst = regs[0].reg; - if let Place::IntReg(s) = arg_place(i) + // All-SSE aggregates loaded above. + super::ArgPlacement::StructRegs { regs, n } => { + if let Some(dst) = agg_base_reg(®s, n) + && let Place::IntReg(s) = arg_place(i) && s != dst { int_moves.push((s, dst)); @@ -1343,16 +1341,14 @@ fn marshal_args( } // Aggregate bases not already register-resident (spill / computed) - // materialise into the aggregate's first eightbyte register, the - // same destination the move loop used for the register-resident - // case. + // materialise into the aggregate's first integer eightbyte + // register, the same destination the move loop used for the + // register-resident case. for (i, &placement) in plan.placements.iter().enumerate() { if let super::ArgPlacement::StructRegs { regs, n } = placement - && n > 0 - && !regs.iter().take(n as usize).any(|c| c.is_fp) + && let Some(dst) = agg_base_reg(®s, n) && !matches!(arg_place(i), Place::IntReg(_)) { - let dst = regs[0].reg; let src = match materialize_int_shifted( code, arg_place(i), @@ -1374,21 +1370,31 @@ fn marshal_args( } } - // Load each aggregate's eightbytes from the base now in `regs[0]`. - // High eightbytes first; `regs[0]` (the base) is read last, - // overwritten by its own eightbyte. Integer-only (homogeneous - // floating-point aggregates excluded upstream). + // Load each aggregate's eightbytes from the base now in its first + // integer eightbyte register: SSE eightbytes first (they leave the + // base intact), then the remaining integer eightbytes high-first, + // the base register's own eightbyte last since the load overwrites + // it. All-SSE aggregates were loaded above. for &placement in plan.placements.iter() { - // Integer-class aggregate: load eightbytes from the base in regs[0]. - // FP-eightbyte aggregates (an SSE unit) were loaded above. if let super::ArgPlacement::StructRegs { regs, n } = placement - && !regs.iter().take(n as usize).any(|c| c.is_fp) + && let Some(base) = agg_base_reg(®s, n) { - let base = regs[0].reg; - for k in (1..n as usize).rev() { - emit_mov_r_mem(code, Reg(regs[k].reg), Reg(base), (k as i32) * 8); + for (k, cr) in regs.iter().take(n as usize).enumerate() { + if cr.is_fp { + emit_movsd_xmm_mem(code, Reg(cr.reg), Reg(base), (k as i32) * 8); + } + } + for (k, cr) in regs.iter().take(n as usize).enumerate().rev() { + if !cr.is_fp && cr.reg != base { + emit_mov_r_mem(code, Reg(cr.reg), Reg(base), (k as i32) * 8); + } } - emit_mov_r_mem(code, Reg(base), Reg(base), 0); + let base_off = regs + .iter() + .take(n as usize) + .position(|c| !c.is_fp && c.reg == base) + .unwrap_or(0); + emit_mov_r_mem(code, Reg(base), Reg(base), (base_off as i32) * 8); } } @@ -2863,7 +2869,9 @@ fn emit_inst( spill_dst_to_slot(code, dst, rd, frame); true } - Inst::Load { addr, disp, kind } => emit_load( + Inst::Load { + addr, disp, kind, .. + } => emit_load( code, dst, *addr, @@ -2878,13 +2886,14 @@ fn emit_inst( disp, value, kind, + .. } => emit_store(code, dst, v, *addr, *disp, *value, *kind, alloc, frame), - Inst::LoadLocal { off, kind } => { + Inst::LoadLocal { off, kind, .. } => { emit_load_local(code, dst, *off, *kind, alloc.is_f32(v), frame, func, abi) } - Inst::StoreLocal { off, value, kind } => { - emit_store_local(code, dst, v, *off, *value, *kind, alloc, frame, func, abi) - } + Inst::StoreLocal { + off, value, kind, .. + } => emit_store_local(code, dst, v, *off, *value, *kind, alloc, frame, func, abi), Inst::LoadIndexed { base, index, @@ -5010,12 +5019,17 @@ fn emit_shift_by_count_reg( spill_dst_to_slot(code, dst, rd, frame); return true; } + // Save rcx whenever any value is allocated there (unless the count + // already sits in rcx, in which case nothing below writes it). A + // `def < v < last_use` pc-interval test is not a liveness test: a + // value carried around a loop back edge is live at the shift while + // the shift's pc lies outside the interval. + let _ = v; let rcx_holds_live = count_reg.map(|r| r.0).unwrap_or(u8::MAX) != Reg::RCX.0 - && alloc.places.iter().enumerate().any(|(idx, p)| { - let i = idx as u32; - let last = alloc.last_use.get(idx).copied().unwrap_or(0); - matches!(p, Place::IntReg(r) if *r == Reg::RCX.0) && i < v && v < last - }); + && alloc + .places + .iter() + .any(|p| matches!(p, Place::IntReg(r) if *r == Reg::RCX.0)); if rcx_holds_live { emit_push_r(code, Reg::RCX); } @@ -5405,6 +5419,43 @@ fn emit_binop_imm( } #[allow(clippy::too_many_arguments)] +/// Store a register-classed <= 16-byte aggregate return into the +/// caller's result temp at `[rbp + base]`. Eightbytes are classified +/// (System V AMD64 3.2.3): INTEGER arrive in rax:rdx, SSE in +/// xmm0:xmm1; Win64 register returns classify as one INTEGER +/// eightbyte in rax. Variadic and non-variadic callees return +/// identically, so every call shape shares this store. +fn store_agg_return( + code: &mut Vec, + desc: &super::super::ir::AggDesc, + base: i64, + abi: super::Abi, +) { + let eb_classes = match super::abi_classify::classify_aggregate( + desc.size, + desc.align, + &desc.fields, + abi, + true, + ) { + super::abi_classify::AggClass::Regs(c) => c, + _ => alloc::vec::Vec::new(), + }; + let int_ret = [Reg::RAX, Reg::RDX]; + let mut int_i = 0usize; + let mut sse_i = 0u8; + for (k, class) in eb_classes.iter().enumerate() { + let disp = (base + (k as i64) * 8) as i32; + if matches!(class, super::abi_classify::RegClass::Sse) { + emit_movsd_mem_xmm(code, Reg::RBP, disp, Reg(Reg::XMM0.0 + sse_i)); + sse_i += 1; + } else { + emit_mov_mem_r(code, Reg::RBP, disp, int_ret[int_i]); + int_i += 1; + } + } +} + fn emit_call( code: &mut Vec, dst: Place, @@ -5461,17 +5512,12 @@ fn emit_call( if plan.scratch_bytes > 0 { emit_add_rsp_imm32(code, plan.scratch_bytes); } - // A variadic callee may still return a <=16-byte aggregate by - // value in rax:rdx; store it into the caller's result temp, as - // the non-variadic path below does. Without this the struct - // result is dropped (the scalar bridge leaves the slot unwritten). + // A variadic callee returns a <=16-byte aggregate exactly like a + // non-variadic one; classify the eightbytes (SSE ones arrive in + // xmm0/xmm1, not rax:rdx). if let Some(ai) = ret_agg { - let size = agg_descs[ai as usize].size; let base = local_slot_off(ret_slot_local, func, frame, abi); - emit_mov_mem_r(code, Reg::RBP, base as i32, Reg::RAX); - if size > 8 { - emit_mov_mem_r(code, Reg::RBP, (base + 8) as i32, Reg::RDX); - } + store_agg_return(code, &agg_descs[ai as usize], base, abi); return true; } // c5 internal call return convention: an integer / pointer @@ -5532,17 +5578,12 @@ fn emit_call( if plan.scratch_bytes > 0 { emit_add_rsp_imm32(code, plan.scratch_bytes); } - // A variadic callee may still return a <=16-byte aggregate by - // value in rax:rdx; store it into the caller's result temp, as - // the non-variadic path below does. Without this the struct - // result is dropped (the scalar bridge leaves the slot unwritten). + // A variadic callee returns a <=16-byte aggregate exactly like a + // non-variadic one; classify the eightbytes (SSE ones arrive in + // xmm0/xmm1, not rax:rdx). if let Some(ai) = ret_agg { - let size = agg_descs[ai as usize].size; let base = local_slot_off(ret_slot_local, func, frame, abi); - emit_mov_mem_r(code, Reg::RBP, base as i32, Reg::RAX); - if size > 8 { - emit_mov_mem_r(code, Reg::RBP, (base + 8) as i32, Reg::RDX); - } + store_agg_return(code, &agg_descs[ai as usize], base, abi); return true; } // c5 internal call return convention: an integer / pointer @@ -5613,31 +5654,7 @@ fn emit_call( if let Some(ai) = ret_agg { let desc = &agg_descs[ai as usize]; let base = local_slot_off(ret_slot_local, func, frame, abi); - let eb_classes = match super::abi_classify::classify_aggregate( - desc.size, - desc.align, - &desc.fields, - abi, - true, - ) { - super::abi_classify::AggClass::Regs(c) => c, - _ => alloc::vec::Vec::new(), - }; - // SSE eightbytes arrive in xmm0/xmm1, INTEGER in rax/rdx; store each - // into the caller's result temp at its eightbyte offset. - let int_ret = [Reg::RAX, Reg::RDX]; - let mut int_i = 0usize; - let mut sse_i = 0u8; - for (k, class) in eb_classes.iter().enumerate() { - let disp = (base + (k as i64) * 8) as i32; - if matches!(class, super::abi_classify::RegClass::Sse) { - emit_movsd_mem_xmm(code, Reg::RBP, disp, Reg(Reg::XMM0.0 + sse_i)); - sse_i += 1; - } else { - emit_mov_mem_r(code, Reg::RBP, disp, int_ret[int_i]); - int_i += 1; - } - } + store_agg_return(code, desc, base, abi); return true; } // c5 internal call return convention: an integer / pointer @@ -5749,29 +5766,7 @@ fn emit_call_ext( if let Some(ai) = ret_agg { let desc = &agg_descs[ai as usize]; let base = local_slot_off(ret_slot_local, func, frame, abi); - let eb_classes = match super::abi_classify::classify_aggregate( - desc.size, - desc.align, - &desc.fields, - abi, - true, - ) { - super::abi_classify::AggClass::Regs(c) => c, - _ => alloc::vec::Vec::new(), - }; - let int_ret = [Reg::RAX, Reg::RDX]; - let mut int_i = 0usize; - let mut sse_i = 0u8; - for (k, class) in eb_classes.iter().enumerate() { - let disp = (base + (k as i64) * 8) as i32; - if matches!(class, super::abi_classify::RegClass::Sse) { - emit_movsd_mem_xmm(code, Reg::RBP, disp, Reg(Reg::XMM0.0 + sse_i)); - sse_i += 1; - } else { - emit_mov_mem_r(code, Reg::RBP, disp, int_ret[int_i]); - int_i += 1; - } - } + store_agg_return(code, desc, base, abi); return true; } // Sub-word integer returns get the standard sign / zero @@ -6045,31 +6040,7 @@ fn emit_call_indirect( if let Some(ai) = ret_agg { let desc = &agg_descs[ai as usize]; let base = local_slot_off(ret_slot_local, func, frame, abi); - let eb_classes = match super::abi_classify::classify_aggregate( - desc.size, - desc.align, - &desc.fields, - abi, - true, - ) { - super::abi_classify::AggClass::Regs(c) => c, - _ => alloc::vec::Vec::new(), - }; - // SSE eightbytes arrive in xmm0/xmm1, INTEGER in rax/rdx; store each - // into the caller's result temp at its eightbyte offset. - let int_ret = [Reg::RAX, Reg::RDX]; - let mut int_i = 0usize; - let mut sse_i = 0u8; - for (k, class) in eb_classes.iter().enumerate() { - let disp = (base + (k as i64) * 8) as i32; - if matches!(class, super::abi_classify::RegClass::Sse) { - emit_movsd_mem_xmm(code, Reg::RBP, disp, Reg(Reg::XMM0.0 + sse_i)); - sse_i += 1; - } else { - emit_mov_mem_r(code, Reg::RBP, disp, int_ret[int_i]); - int_i += 1; - } - } + store_agg_return(code, desc, base, abi); return true; } // A floating-point return rides xmm0 (C99 6.2.5p10); an integer @@ -6357,19 +6328,32 @@ fn emit_intrinsic( return false; } }; - // Three distinct registers: src pointer in r11, dst pointer - // in rcx, the copied word in r10 (all outside the allocator's - // live values for this instruction). Copy the three 8-byte - // words -- gp_offset + fp_offset packed in the first, then - // overflow_arg_area and reg_save_area. - let Some(dst_p) = materialize_int(code, dst_place, SCRATCH_RCX, frame) else { + // Both pointers ride the reserved r10 / r11 scratches (rcx + // is in the allocator's caller pool and may hold a live + // value across the intrinsic). The copied word borrows a + // pool register around a push/pop pair, mirroring + // emit_mcpy; the spill loads above run before the push so + // rsp-relative offsets stay valid. + let Some(dst_p) = materialize_int(code, dst_place, SCRATCH_R10, frame) else { bail_msg("VaCopy: &dst not in int reg / spill"); return false; }; + let temp = if dst_p.0 != Reg::RAX.0 && src_p.0 != Reg::RAX.0 { + Reg::RAX + } else if dst_p.0 != Reg::RCX.0 && src_p.0 != Reg::RCX.0 { + Reg::RCX + } else { + Reg::RDX + }; + emit_push_r(code, temp); + // Copy the three 8-byte `__va_list_tag` words (ABI 3.5.7): + // gp_offset + fp_offset packed in the first, then + // overflow_arg_area and reg_save_area. for off in [0i32, 8, 16] { - emit_mov_r_mem(code, SCRATCH_R10, src_p, off); - emit_mov_mem_r(code, dst_p, off, SCRATCH_R10); + emit_mov_r_mem(code, temp, src_p, off); + emit_mov_mem_r(code, dst_p, off, temp); } + emit_pop_r(code, temp); true } I::VaStart => { @@ -6649,6 +6633,50 @@ fn emit_intrinsic( spill_dst_to_slot(code, dst, rd_phys, frame); true } + I::AllocaSave => { + // Read the arena top for a VLA block snapshot (C99 6.7.6.2). + if current_alloca_top == 0 { + bail_msg("AllocaSave: AllocaInit didn't run for this function"); + return false; + } + let Some(rd) = int_or_spill_dst(dst) else { + bail_msg("AllocaSave: dst not int reg / spill"); + return false; + }; + let rd_phys = if matches!(dst, Place::Spill(_)) { + SCRATCH_R10 + } else { + rd + }; + emit_mov_r_mem(code, rd_phys, Reg::RBP, -(current_alloca_top as i32)); + spill_dst_to_slot(code, dst, rd_phys, frame); + true + } + I::AllocaRestore => { + // Restore the arena top on VLA block exit. + if current_alloca_top == 0 { + bail_msg("AllocaRestore: AllocaInit didn't run for this function"); + return false; + } + if args.len() != 1 { + bail_msg("AllocaRestore: expected 1 arg"); + return false; + } + let v_place = alloc + .places + .get(args[0] as usize) + .copied() + .unwrap_or(Place::None); + let v = match materialize_int(code, v_place, SCRATCH_R10, frame) { + Some(r) => r, + None => { + bail_msg("AllocaRestore: arg not int reg / spill / fp"); + return false; + } + }; + emit_mov_mem_r(code, Reg::RBP, -(current_alloca_top as i32), v); + true + } I::SetjmpAArch64 | I::LongjmpAArch64 => { bail_msg("intrinsic: AArch64 setjmp / longjmp on non-AArch64 target"); false @@ -7237,19 +7265,17 @@ fn emit_atomic_cas( /// own prologue, but the tail call site can't tell from here, so /// keep the tail conversion off when *this* function is variadic /// (its arg slots stay on the c5 stack rather than reg cells). -/// * The function has no `LocalAddr` to a negative slot: any such -/// address could have been passed to the callee in an earlier -/// call's argument, and tearing down our frame before the jmp -/// would invalidate it. -/// * The function records no callee-saved register use -/// (`alloc.gpr_used.is_empty()`): the epilogue would emit per-reg -/// restores between the arg marshal and the jmp, all of which -/// are callee-saved (rbx / r12 / r14 / r15 / rsi / rdi on Win64) -/// and so don't alias the caller-saved arg-register window the -/// tail call has just populated. Restricted on this first pass -/// for tractability; the more general path can drop this gate -/// once it is shown to be safe via an explicit save-before-marshal -/// sequence. +/// * The function takes no `LocalAddr`, whether to a user local +/// (negative `off`) or a c5 cdecl param cell (`off >= 2`): such an +/// address could have been passed to an earlier callee, and the +/// param cells are overwritten by the tail-callee's own prologue, +/// so tearing down the frame before the jmp would make it dangle. +/// +/// Callee-saved register use is allowed: the marshalled arguments ride +/// the caller-saved arg-register window, which is disjoint from +/// `alloc.gpr_used` (only callee-saved regs land there), so the +/// epilogue's per-reg restores cannot clobber them (see +/// `emit_tail_call`). fn detect_tail_call<'a>( func: &'a FunctionSsa, block: &super::super::ir::Block, diff --git a/src/c5/codegen/x86_64/encode.rs b/src/c5/codegen/x86_64/encode.rs index fb1d44a6d..70f8ca8de 100644 --- a/src/c5/codegen/x86_64/encode.rs +++ b/src/c5/codegen/x86_64/encode.rs @@ -2146,8 +2146,7 @@ pub(crate) fn lower( // `apply_fixups` and re-emit them as // `Build::user_extern_call_sites` entries that the writer // surfaces as `R_X86_64_PLT32` relocs against the - // callee's symbol. Empty for builds without - // `CompileOptions::no_entry_point`. + // callee's symbol. let extern_pc_lookup: alloc::collections::BTreeMap = program .extern_function_imports .iter() @@ -2303,6 +2302,7 @@ pub(crate) fn lower( copy_relocs: Vec::new(), text: code, data: program.data.clone(), + data_align: program.data_align, bss_size: 0, entry_offset, got_fixups, @@ -2342,7 +2342,9 @@ pub(crate) fn lower( // Overwritten by `lower_for` from `NativeOptions::debug_info`. debug_info: true, merged_dwarf: None, - plt_trampoline_offsets, + // Every import on this single-TU path gets a trampoline (data + // imports ride `ResolvedImports::data_bindings`, not `imports`). + plt_trampoline_offsets: plt_trampoline_offsets.into_iter().map(Some).collect(), }) } diff --git a/src/c5/compiler/aggregate.rs b/src/c5/compiler/aggregate.rs index dbce15ded..53619dce0 100644 --- a/src/c5/compiler/aggregate.rs +++ b/src/c5/compiler/aggregate.rs @@ -47,6 +47,22 @@ impl Compiler { name: &str, is_union: bool, packed: bool, + ) -> Result { + // An alignment request preceding the tag + // (`__declspec(align(16)) struct S { ... }`) belongs to the + // declaration, not to the first member; park it across the + // body parse so the member checks see only member attributes. + let decl_attr_align = core::mem::take(&mut self.pending.attr_align); + let r = self.parse_aggregate_body_inner(name, is_union, packed); + self.pending.attr_align = self.pending.attr_align.max(decl_attr_align); + r + } + + fn parse_aggregate_body_inner( + &mut self, + name: &str, + is_union: bool, + packed: bool, ) -> Result { // Pre-register or recycle a forward declaration so // self-referential pointer fields can find this aggregate @@ -149,6 +165,15 @@ impl Compiler { while is_decl_modifier(self.lex.tk) { if self.lex.tk == Token::Attribute { self.skip_attribute_specifiers()?; + // Member layout uses 8-byte alignment at most; a + // larger request would change the struct layout + // silently, so it is a diagnostic. + let m_align = core::mem::take(&mut self.pending.attr_align); + if m_align > 8 { + return Err(self.compile_err(format!( + "member alignment {m_align} is not supported (at most 8)" + ))); + } continue; } if self.lex.tk == Token::Atomic && self.lex.peek_after_whitespace(b'(') { @@ -168,7 +193,8 @@ impl Compiler { // unsigned, so a value with the field's high bit set // zero-extends rather than sign-extends. let mut field_base_is_enum = false; - let field_base = if let Some(inner) = atomic_field_base { + let field_base_tok = self.lex.tk; + let mut field_base = if let Some(inner) = atomic_field_base { inner } else if self.lex.tk == Token::Typeof { // `typeof ( ... ) member;` (C23 6.7.2.5): the operand's @@ -310,14 +336,18 @@ impl Compiler { return Err(self.compile_err("type expected in struct field")); }; - // Trailing modifiers: `int long`, `unsigned long long`, etc. - while is_decl_modifier(self.lex.tk) { - if self.lex.tk == Token::Attribute { - self.skip_attribute_specifiers()?; - continue; + // Trailing specifiers: C99 6.7.2p2 admits any order, so + // `int long` / `char unsigned` fields re-derive the base + // tag from the folded modifiers. + let (saw_int_mod, trailing_quals) = self.consume_trailing_decl_modifiers(&mut mods)?; + if saw_int_mod { + if field_base_tok == Token::Int { + field_base = mods.int_base(); + } else if field_base_tok == Token::Char { + field_base = mods.char_tag(self.target.plain_char_signed()); } - self.next()?; } + field_base |= trailing_quals; // Anonymous struct/union member (C11 6.7.2.1p13). The // type-prefix parse just registered an anon-tagged @@ -497,6 +527,12 @@ impl Compiler { // A member may carry a trailing attribute // (`int x __attribute__((deprecated));`). self.skip_attribute_specifiers()?; + let m_align = core::mem::take(&mut self.pending.attr_align); + if m_align > 8 { + return Err(self.compile_err(format!( + "member alignment {m_align} is not supported (at most 8)" + ))); + } // A typedef whose alias is an array contributes // its dimension when the declarator stayed at the // typedef's element type (`jmp_buf b;` -> @@ -742,24 +778,35 @@ impl Compiler { /// semantics: no inter-member padding and an alignment of 1. Used /// when the attribute marker follows the body, after the fields were /// placed at their natural alignment. A union only loses its tail - /// padding (members already sit at offset 0). Bitfield members are - /// left at their computed offsets; the packed bit-layout rules are - /// not modeled here. + /// padding (members already sit at offset 0). Bitfields pack at the + /// bit level with no storage-unit padding (the GCC/clang packed + /// layout; C99 6.7.2.1p11 leaves the unit implementation-defined); + /// a non-bitfield member starts at the next byte boundary. pub(super) fn repack_struct(&mut self, struct_id: usize) { self.structs[struct_id].align = 1; if self.structs[struct_id].is_union { return; } let n = self.structs[struct_id].fields.len(); - let mut offset = 0usize; + let mut bit_cursor = 0usize; + let mut bitfields: Vec<(usize, usize)> = Vec::new(); for i in 0..n { let (ty, array_size, bit_width) = { let f = &self.structs[struct_id].fields[i]; (f.ty, f.array_size, f.bit_width) }; if bit_width > 0 { + // TODO: a field whose bits would span more than an + // 8-byte load window (start % 8 + width > 64) is bumped + // to the next byte; gcc packs it contiguously. + if bit_cursor % 8 + bit_width as usize > 64 { + bit_cursor = round_up(bit_cursor, 8); + } + bitfields.push((i, bit_cursor)); + bit_cursor += bit_width as usize; continue; } + let offset = bit_cursor.div_ceil(8); self.structs[struct_id].fields[i].offset = offset; let storage = if array_size > 0 { self.size_of_type(ty) * array_size as usize @@ -768,9 +815,26 @@ impl Compiler { } else { self.size_of_type(ty) }; - offset += storage; + bit_cursor = (offset + storage) * 8; + } + let size = bit_cursor.div_ceil(8).max(1); + // Each bitfield's addressable unit is the smallest 1/2/4/8-byte + // window covering its bits, slid back when it would extend past + // the struct's tail (a packed struct has no tail padding to + // absorb the read-modify-write span). + for (i, bit_start) in bitfields { + let width = self.structs[struct_id].fields[i].bit_width as usize; + let unit = (bit_start % 8 + width).div_ceil(8).next_power_of_two(); + let mut off = bit_start / 8; + if off + unit > size && unit <= size { + off = size - unit; + } + let f = &mut self.structs[struct_id].fields[i]; + f.offset = off; + f.bit_offset = (bit_start - off * 8) as u32; + f.bit_unit_size = unit as u8; } - self.structs[struct_id].size = offset.max(1); + self.structs[struct_id].size = size; } } diff --git a/src/c5/compiler/call_fixups.rs b/src/c5/compiler/call_fixups.rs index 597c36497..b161bf373 100644 --- a/src/c5/compiler/call_fixups.rs +++ b/src/c5/compiler/call_fixups.rs @@ -163,12 +163,12 @@ impl Compiler { /// Lev /// ``` /// - /// Variadic libc fns lose anything beyond their declared - /// fixed prefix -- a trampoline can only forward what its - /// signature tells it to push. The known callers (e.g. - /// dispatch-table slots for `fcntl` and `ioctl`) work - /// because the cast at the use site lines up with the fixed - /// prefix the trampoline does forward. + /// Variadic bindings take the frameless tail-jump shape + /// instead: the caller marshalled the tail per the variadic + /// convention (stack region and, on System V, `al`), which a + /// forwarding body of fixed arity cannot repack; a `jmp` + /// passes every register class and the stack through + /// unchanged. pub(super) fn emit_sys_trampolines(&mut self) { use crate::c5::codegen::ssa::build::SsaBuilder; use crate::c5::ir::{LoadKind, NO_VALUE}; @@ -208,12 +208,14 @@ impl Compiler { // return that runs a widening `fcvt d0,s0`, and since `s0` // and `d0` alias `v0`, the widened double's zero low half // overwrites the `s0` the caller reads (C99 6.2.5p10 / - // AAPCS64 6.4.2: a `float` result occupies `s0`). The - // `double` case happened to survive because no widening - // was emitted, but the tail jump is the correct path for - // both. Variadic bindings keep the forwarding body so the - // dispatch-table arg repacking stays in scope; no bound - // variadic libc routine returns a floating-point scalar. + // AAPCS64 6.4.2: a `float` result occupies `s0`). + // + // A variadic binding takes the same tail jump: the caller + // marshalled the tail per the variadic convention (the + // stack region on AAPCS64-Darwin, `al` on System V), and + // only a frameless jump carries that through -- a + // forwarding body of fixed arity would drop everything + // past its declared prefix. let ret_ty = self.symbols[sys_idx].type_; let touches_fp = is_float_ty(ret_ty) || is_double_ty(ret_ty) @@ -221,7 +223,7 @@ impl Compiler { .params .iter() .any(|&p| is_float_ty(p) || is_double_ty(p)); - if !is_variadic && touches_fp { + if is_variadic || touches_fp { let mut sb = SsaBuilder::new(ent_pc, 0, false); sb.set_locals(0); sb.set_name(alloc::format!("__c5_sys_{}", self.symbols[sys_idx].name)); @@ -236,16 +238,9 @@ impl Compiler { continue; } - // Forwarded arg count. Variadic prefix forwards one - // extra so dispatch tables (open / fcntl / ioctl) - // line up. - let nargs_ssa = if fixed_nargs == 0 && !is_variadic { - 0 - } else if is_variadic { - fixed_nargs + 1 - } else { - fixed_nargs - }; + // Forwarded arg count (variadic bindings took the tail + // jump above). + let nargs_ssa = fixed_nargs; // The synthesised trampoline's own signature is a // fixed-arg host-ABI function: callers reach it via // function pointer through `(sys_ptr)open`, which the @@ -292,68 +287,10 @@ impl Compiler { self.synthetic_ssa_funcs.push(func); let synth_idx = self.synthetic_ssa_funcs.len() - 1; - // Two trampoline shapes coexist: - // - // * Prototype-bearing bindings (`int fopen(char *, - // char *);`, ..., or any `int foo(...);`) get the - // classic `Ent + Lea/Li/Psh + JsrExt + Adj + Lev` - // body. The forwarded arg count matches the - // prototype, and the JsrExt lowering's per-arg - // FP-mask + post-call sub-word extension (#48) both - // stay in scope. - // - // * Bindings with *no* declared params (just - // `int Name();`) -- e.g. kernel32 entries that - // real-world dispatch tables cast back to the - // right arity at the call site -- get a tail-call - // body. The trampoline is `jmp [rip+iat]` and the - // caller's indirect-call lowering owns the host-ABI - // arg setup, return-register copy, and stack - // adjustment. Sub-word extension is left to the - // caller (the call site casts the result to the - // right type explicitly), which matches what - // real-world dispatch-table consumers already do. - if fixed_nargs == 0 && !is_variadic { - // The SSA-tier trampoline body is fully built by - // SsaBuilder above; bump the parser PC counter by - // one so the synthesised function's `end_pc` - // stays strictly greater than its `ent_pc`, which - // is what the linker and DWARF range builder - // require. - self.next_ent_pc += 1; - self.synthetic_ssa_funcs[synth_idx].end_pc = self.next_ent_pc; - continue; - } - - // For variadic libc fns the binding-declared param - // count is only the fixed prefix; common dispatch - // tables (open/fcntl/ioctl) want the trampoline to - // forward *one* of the variadic args so the caller's - // 3-argument cast lines up with what `JsrExt` packs - // onto the macOS arm64 variadic-args stack region. - // Callers that pass strictly the fixed prefix end up - // reading one junk slot from above their own pushes, - // but no in-the-wild caller does -- they all add at - // least one extra arg precisely to feed the variadic. - // The general case (forward N variadic args where N - // is unknown at compile time) needs a real va_args - // bridge -- tracked separately with the `c5 va_list` - // work. - let nargs = if is_variadic { - fixed_nargs + 1 - } else { - fixed_nargs - }; - // SSA body fully built by SsaBuilder above. Reserve a // single PC unit so the trampoline's `end_pc` is // strictly greater than `ent_pc`, satisfying the - // linker / DWARF range invariant. The cdecl - // right-to-left arg push, JsrExt + binding, Adj - // cleanup and Lev epilogue used to be tape ops here; - // the matching SSA insts live on - // `synthetic_ssa_funcs[synth_idx]` and drive the codegen. - let _ = (nargs, binding_idx); + // linker / DWARF range invariant. self.next_ent_pc += 1; self.synthetic_ssa_funcs[synth_idx].end_pc = self.next_ent_pc; } diff --git a/src/c5/compiler/const_expr.rs b/src/c5/compiler/const_expr.rs index cf4b111fb..29881569b 100644 --- a/src/c5/compiler/const_expr.rs +++ b/src/c5/compiler/const_expr.rs @@ -33,8 +33,8 @@ use super::super::error::C5Error; use super::super::token::{Token, Ty}; use super::Compiler; use super::types::{ - is_floating_ty, is_struct_ty, is_unsigned_ty, narrow_const_int, strip_unsigned, struct_id_of, - struct_ptr_depth, + UNSIGNED_BIT, integer_promote, is_floating_ty, is_pointer_ty, is_struct_ty, is_unsigned_ty, + narrow_const_int, strip_unsigned, struct_id_of, struct_ptr_depth, usual_arith_common_ty, }; /// Compile-time arithmetic value of a constant expression. Integer @@ -45,29 +45,78 @@ use super::types::{ /// conversions"). The integer-typed callers (array sizes, enums, /// bitfield widths, integer global inits) truncate via /// [`ConstVal::as_int`] at the boundary. +/// +/// An integer value carries its C type tag so every operator can +/// apply the 6.3.1.8 conversions at the right width and signedness +/// (`0xFFFFFFFFFFFFFFFFULL / 3` divides unsigned; `-1 < 1u` +/// compares at `unsigned int`). Invariant: `val` holds the value +/// in `ty`'s representation -- sign-extended for a signed type, +/// zero-extended for an unsigned type narrower than 8 bytes, raw +/// bits for an unsigned 8-byte type. #[derive(Copy, Clone, Debug)] pub(super) enum ConstVal { - Int(i64), + Int { val: i64, ty: i64 }, Float(f64), } +/// Operator selector for [`Compiler::const_int_binop`], the single +/// integer fold shared by every binary operator in the +/// constant-expression grammar. +#[derive(Copy, Clone, PartialEq)] +enum ConstBinOp { + Or, + Xor, + And, + Add, + Sub, + Mul, + Div, + Rem, + Shl, + Shr, + Lt, + Le, + Gt, + Ge, + Eq, + Ne, +} + impl ConstVal { + /// An `int`-typed value: comparison and logical results, and + /// the other places C99 mandates `int`. + fn int(v: i64) -> ConstVal { + ConstVal::Int { + val: v, + ty: Ty::Int as i64, + } + } + /// Coerce to an `i64`. Float values truncate toward zero, matching /// C's "cast to integer" semantics for the destination integer /// constant expression. pub(super) fn as_int(self) -> i64 { match self { - ConstVal::Int(v) => v, + ConstVal::Int { val, .. } => val, ConstVal::Float(v) => v as i64, } } + /// The C type tag of an integer value (`int` for a float a + /// caller coerces through [`Self::as_int`]). + fn int_ty(self) -> i64 { + match self { + ConstVal::Int { ty, .. } => ty, + ConstVal::Float(_) => Ty::Int as i64, + } + } + /// Coerce to an `f64`. Integer values widen exactly for any value /// within `f64`'s 53-bit mantissa range (which is every integer /// constant c5 currently lexes). pub(super) fn as_float(self) -> f64 { match self { - ConstVal::Int(v) => v as f64, + ConstVal::Int { val, .. } => val as f64, ConstVal::Float(v) => v, } } @@ -79,13 +128,114 @@ impl ConstVal { /// True if the value is non-zero. Used by `&&`, `||`, `?:`, `!`. fn is_truthy(self) -> bool { match self { - ConstVal::Int(v) => v != 0, + ConstVal::Int { val, .. } => val != 0, ConstVal::Float(v) => v != 0.0, } } } impl Compiler { + /// Fold one integer binary operator per C99 6.3.1.8: both + /// operands convert to their common type and the operation runs + /// in that type's signedness, renormalized to its width. Shifts + /// take the promoted left-operand type instead (6.5.7p3). + /// Pointer-typed operands (string addresses, offsetof chains) + /// fold at full 64-bit width with no conversion. A zero divisor + /// in an evaluated operand is a compile error (6.6p4); signed + /// overflow wraps, matching the runtime lowering. + fn const_int_binop( + &self, + op: ConstBinOp, + l: ConstVal, + r: ConstVal, + ) -> Result { + use ConstBinOp as B; + let (a_ty, b_ty) = (l.int_ty(), r.int_ty()); + let ptr = is_pointer_ty(a_ty) || is_pointer_ty(b_ty); + if matches!(op, B::Shl | B::Shr) { + let pty = if ptr { + Ty::LongLong as i64 + } else { + integer_promote(a_ty) + }; + let bytes = self.size_of_type(pty); + let uns = is_unsigned_ty(pty); + let lv = narrow_const_int(bytes, uns, false, l.as_int()); + let sh = (r.as_int() & 63) as u32; + let v = if op == B::Shl { + (lv as u64).wrapping_shl(sh) as i64 + } else if uns { + ((lv as u64) >> sh) as i64 + } else { + lv.wrapping_shr(sh) + }; + return Ok(ConstVal::Int { + val: narrow_const_int(bytes, uns, false, v), + ty: pty, + }); + } + let common = if ptr { + Ty::LongLong as i64 + } else { + usual_arith_common_ty(a_ty, b_ty, self.target) + }; + let bytes = self.size_of_type(common); + let uns = is_unsigned_ty(common); + let lv = narrow_const_int(bytes, uns, false, l.as_int()); + let rv = narrow_const_int(bytes, uns, false, r.as_int()); + let val = match op { + B::Or => lv | rv, + B::Xor => lv ^ rv, + B::And => lv & rv, + B::Add => lv.wrapping_add(rv), + B::Sub => lv.wrapping_sub(rv), + B::Mul => lv.wrapping_mul(rv), + B::Div | B::Rem => { + if rv == 0 { + if self.const_unevaluated == 0 { + return Err(self.compile_err("division by zero in a constant expression")); + } + 0 + } else if uns { + let (a, b) = (lv as u64, rv as u64); + (if op == B::Rem { a % b } else { a / b }) as i64 + } else if op == B::Rem { + lv.wrapping_rem(rv) + } else { + lv.wrapping_div(rv) + } + } + B::Lt | B::Le | B::Gt | B::Ge | B::Eq | B::Ne => { + let hold = if uns { + let (a, b) = (lv as u64, rv as u64); + match op { + B::Lt => a < b, + B::Le => a <= b, + B::Gt => a > b, + B::Ge => a >= b, + B::Eq => a == b, + _ => a != b, + } + } else { + match op { + B::Lt => lv < rv, + B::Le => lv <= rv, + B::Gt => lv > rv, + B::Ge => lv >= rv, + B::Eq => lv == rv, + _ => lv != rv, + } + }; + return Ok(ConstVal::int(hold as i64)); + } + B::Shl | B::Shr => unreachable!(), + }; + Ok(ConstVal::Int { + val: narrow_const_int(bytes, uns, false, val), + ty: common, + }) + } + /// Parse a constant integer expression at parse time. Used /// during declarator parsing where the value has to be known /// before any IR-building emit (array dimensions, bitfield @@ -102,6 +252,51 @@ impl Compiler { Ok(self.parse_const_expr_cond_val()?.as_int()) } + /// Try to fold an array-declarator dimension to an integer + /// constant. Returns `Some(value)` for a constant dimension, or + /// `None` when the dimension is a non-constant expression (a C99 + /// 6.7.6.2 variable-length array) -- in which case the lexer is + /// restored so the caller can re-parse the dimension as a runtime + /// expression. + pub(super) fn try_parse_constant_dim(&mut self) -> Result, C5Error> { + let snap = self.lex.snapshot(); + self.pending.const_expr_nonconst = false; + match self.parse_const_expr_cond_val() { + // Folded to a constant; the caller validates the trailing `]`. + Ok(v) => Ok(Some(v.as_int())), + // Non-constant operand -> a VLA dimension: rewind for the + // caller's runtime-expression parse. + Err(_) if self.pending.const_expr_nonconst => { + self.lex.restore(snap); + Ok(None) + } + // A genuine constant-expression error (division by zero, an + // overflowing shift, ...) is diagnosed, not treated as a VLA. + Err(e) => Err(e), + } + } + + /// Consume an array-declarator dimension up to (not including) the + /// matching `]`. Used for a variable-length array parameter, whose + /// size is discarded when the array is adjusted to a pointer (C99 + /// 6.7.6.3p7); also absorbs the `[*]` unspecified-size form. + pub(super) fn skip_array_dimension_expr(&mut self) -> Result<(), C5Error> { + let mut depth: i64 = 0; + loop { + if self.lex.tk == Token::Brak { + depth += 1; + } else if self.lex.tk == ']' { + if depth == 0 { + return Ok(()); + } + depth -= 1; + } else if self.lex.tk == 0 { + return Err(self.compile_err("close bracket expected in array declarator")); + } + self.next()?; + } + } + /// Parse a C11 6.7.10 `_Static_assert(, /// "");` (or its C23 `static_assert` alias). /// On entry the current token is `Token::StaticAssert`. The @@ -183,33 +378,54 @@ impl Compiler { let cond = self.parse_const_expr_or_val()?; if self.lex.tk == Token::Cond { self.next()?; - let then_val = self.parse_const_expr_or_val()?; + // Both arms are parsed (their tokens must be consumed) + // but the not-taken arm is unevaluated per C99 6.5.15, + // so a zero divisor there must not diagnose. + let taken = cond.is_truthy(); + let then_val = self.parse_const_unevaluated(!taken, Self::parse_const_expr_or_val)?; if self.lex.tk != ':' { return Err(self.compile_err("`:` expected in conditional constant expression")); } self.next()?; - let else_val = self.parse_const_expr_cond_val()?; - Ok(if cond.is_truthy() { then_val } else { else_val }) + let else_val = self.parse_const_unevaluated(taken, Self::parse_const_expr_cond_val)?; + Ok(if taken { then_val } else { else_val }) } else { Ok(cond) } } + /// Run `rule` with the unevaluated-operand depth raised when + /// `unevaluated` holds, so C99 6.6p4 zero-divisor diagnostics + /// stay scoped to evaluated operands. + fn parse_const_unevaluated( + &mut self, + unevaluated: bool, + rule: fn(&mut Self) -> Result, + ) -> Result { + if unevaluated { + self.const_unevaluated += 1; + } + let r = rule(self); + if unevaluated { + self.const_unevaluated -= 1; + } + r + } + pub(super) fn parse_const_expr_or_val(&mut self) -> Result { let mut left = self.parse_const_expr_and_val()?; while self.lex.tk == Token::Lor { self.next()?; - let right = self.parse_const_expr_and_val()?; - // Short-circuit semantics aren't observable at parse - // time -- the right operand was already consumed by - // the recursive call -- but the result still has C99's - // `int 0 | 1` shape. + // The right operand's tokens are always consumed, but a + // short-circuited operand is unevaluated (C99 6.5.14). + let right = + self.parse_const_unevaluated(left.is_truthy(), Self::parse_const_expr_and_val)?; let r = if left.is_truthy() || right.is_truthy() { 1 } else { 0 }; - left = ConstVal::Int(r); + left = ConstVal::int(r); } Ok(left) } @@ -218,13 +434,14 @@ impl Compiler { let mut left = self.parse_const_expr_bitor_val()?; while self.lex.tk == Token::Lan { self.next()?; - let right = self.parse_const_expr_bitor_val()?; + let right = + self.parse_const_unevaluated(!left.is_truthy(), Self::parse_const_expr_bitor_val)?; let r = if left.is_truthy() && right.is_truthy() { 1 } else { 0 }; - left = ConstVal::Int(r); + left = ConstVal::int(r); } Ok(left) } @@ -234,7 +451,7 @@ impl Compiler { while self.lex.tk == Token::OrOp { self.next()?; let right = self.parse_const_expr_xor_val()?; - left = ConstVal::Int(left.as_int() | right.as_int()); + left = self.const_int_binop(ConstBinOp::Or, left, right)?; } Ok(left) } @@ -244,7 +461,7 @@ impl Compiler { while self.lex.tk == Token::XorOp { self.next()?; let right = self.parse_const_expr_bitand_val()?; - left = ConstVal::Int(left.as_int() ^ right.as_int()); + left = self.const_int_binop(ConstBinOp::Xor, left, right)?; } Ok(left) } @@ -254,7 +471,7 @@ impl Compiler { while self.lex.tk == Token::AndOp { self.next()?; let right = self.parse_const_expr_eq_val()?; - left = ConstVal::Int(left.as_int() & right.as_int()); + left = self.const_int_binop(ConstBinOp::And, left, right)?; } Ok(left) } @@ -262,27 +479,21 @@ impl Compiler { fn parse_const_expr_eq_val(&mut self) -> Result { let mut left = self.parse_const_expr_rel_val()?; loop { - if self.lex.tk == Token::EqOp { - self.next()?; - let r = self.parse_const_expr_rel_val()?; - let eq = if left.is_float() || r.is_float() { - left.as_float() == r.as_float() - } else { - left.as_int() == r.as_int() - }; - left = ConstVal::Int(eq as i64); + let op = if self.lex.tk == Token::EqOp { + ConstBinOp::Eq } else if self.lex.tk == Token::NeOp { - self.next()?; - let r = self.parse_const_expr_rel_val()?; - let ne = if left.is_float() || r.is_float() { - left.as_float() != r.as_float() - } else { - left.as_int() != r.as_int() - }; - left = ConstVal::Int(ne as i64); + ConstBinOp::Ne } else { break; - } + }; + self.next()?; + let r = self.parse_const_expr_rel_val()?; + left = if left.is_float() || r.is_float() { + let eq = left.as_float() == r.as_float(); + ConstVal::int((if op == ConstBinOp::Eq { eq } else { !eq }) as i64) + } else { + self.const_int_binop(op, left, r)? + }; } Ok(left) } @@ -291,39 +502,31 @@ impl Compiler { let mut left = self.parse_const_expr_shift_val()?; loop { let op = if self.lex.tk == Token::LtOp { - Some('<') + ConstBinOp::Lt } else if self.lex.tk == Token::LeOp { - Some('l') + ConstBinOp::Le } else if self.lex.tk == Token::GtOp { - Some('>') + ConstBinOp::Gt } else if self.lex.tk == Token::GeOp { - Some('g') + ConstBinOp::Ge } else { - None + break; }; - let Some(op) = op else { break }; self.next()?; let r = self.parse_const_expr_shift_val()?; - let b = if left.is_float() || r.is_float() { + left = if left.is_float() || r.is_float() { let lf = left.as_float(); let rf = r.as_float(); - match op { - '<' => lf < rf, - 'l' => lf <= rf, - '>' => lf > rf, + let b = match op { + ConstBinOp::Lt => lf < rf, + ConstBinOp::Le => lf <= rf, + ConstBinOp::Gt => lf > rf, _ => lf >= rf, - } + }; + ConstVal::int(b as i64) } else { - let li = left.as_int(); - let ri = r.as_int(); - match op { - '<' => li < ri, - 'l' => li <= ri, - '>' => li > ri, - _ => li >= ri, - } + self.const_int_binop(op, left, r)? }; - left = ConstVal::Int(b as i64); } Ok(left) } @@ -331,17 +534,16 @@ impl Compiler { fn parse_const_expr_shift_val(&mut self) -> Result { let mut left = self.parse_const_expr_add_val()?; loop { - if self.lex.tk == Token::ShlOp { - self.next()?; - let r = self.parse_const_expr_add_val()?; - left = ConstVal::Int(left.as_int() << r.as_int()); + let op = if self.lex.tk == Token::ShlOp { + ConstBinOp::Shl } else if self.lex.tk == Token::ShrOp { - self.next()?; - let r = self.parse_const_expr_add_val()?; - left = ConstVal::Int(left.as_int() >> r.as_int()); + ConstBinOp::Shr } else { break; - } + }; + self.next()?; + let r = self.parse_const_expr_add_val()?; + left = self.const_int_binop(op, left, r)?; } Ok(left) } @@ -367,7 +569,7 @@ impl Compiler { left = if left.is_float() || r.is_float() { ConstVal::Float(left.as_float() + r.as_float()) } else { - ConstVal::Int(left.as_int().wrapping_add(r.as_int())) + self.const_int_binop(ConstBinOp::Add, left, r)? }; } else if self.lex.tk == Token::SubOp { self.next()?; @@ -375,7 +577,7 @@ impl Compiler { left = if left.is_float() || r.is_float() { ConstVal::Float(left.as_float() - r.as_float()) } else { - ConstVal::Int(left.as_int().wrapping_sub(r.as_int())) + self.const_int_binop(ConstBinOp::Sub, left, r)? }; } else { break; @@ -397,7 +599,7 @@ impl Compiler { left = if left.is_float() || r.is_float() { ConstVal::Float(left.as_float() * r.as_float()) } else { - ConstVal::Int(left.as_int().wrapping_mul(r.as_int())) + self.const_int_binop(ConstBinOp::Mul, left, r)? }; } else if self.lex.tk == Token::DivOp { self.next()?; @@ -408,18 +610,14 @@ impl Compiler { // for 0.0/0.0, not a fold to zero. ConstVal::Float(left.as_float() / r.as_float()) } else { - let ri = r.as_int(); - let v = if ri == 0 { 0 } else { left.as_int() / ri }; - ConstVal::Int(v) + self.const_int_binop(ConstBinOp::Div, left, r)? }; } else if self.lex.tk == Token::ModOp { // C99 6.5.5: `%` requires integer operands. Coerce - // both sides through `as_int` and operate on i64. + // both sides through `as_int` and fold as integers. self.next()?; let r = self.parse_const_expr_unary_val()?; - let ri = r.as_int(); - let v = if ri == 0 { 0 } else { left.as_int() % ri }; - left = ConstVal::Int(v); + left = self.const_int_binop(ConstBinOp::Rem, left, r)?; } else { break; } @@ -427,11 +625,36 @@ impl Compiler { Ok(left) } + /// Renormalize a unary integer result to the operand's promoted + /// type (C99 6.5.3.3: `-` and `~` apply the integer promotions + /// and yield the promoted type). Pointer-typed operands keep + /// their full-width value. + fn const_unary_promoted(&self, v: i64, operand_ty: i64) -> ConstVal { + if is_pointer_ty(operand_ty) { + return ConstVal::Int { + val: v, + ty: operand_ty, + }; + } + let pty = integer_promote(operand_ty); + ConstVal::Int { + val: narrow_const_int(self.size_of_type(pty), is_unsigned_ty(pty), false, v), + ty: pty, + } + } + pub(super) fn parse_const_expr_unary_val(&mut self) -> Result { + // Every recursive cycle in the constant-expression grammar + // (parentheses, ternary arms, unary chains) passes through + // here, so this one guard bounds the whole cascade. + self.with_nesting("expression", |c| c.parse_const_expr_unary_val_inner()) + } + + fn parse_const_expr_unary_val_inner(&mut self) -> Result { if self.lex.tk == Token::SubOp { self.next()?; return Ok(match self.parse_const_expr_unary_val()? { - ConstVal::Int(v) => ConstVal::Int(v.wrapping_neg()), + ConstVal::Int { val, ty } => self.const_unary_promoted(val.wrapping_neg(), ty), ConstVal::Float(v) => ConstVal::Float(-v), }); } @@ -442,33 +665,56 @@ impl Compiler { if self.lex.tk == '!' { self.next()?; let v = self.parse_const_expr_unary_val()?; - return Ok(ConstVal::Int(if v.is_truthy() { 0 } else { 1 })); + return Ok(ConstVal::int(if v.is_truthy() { 0 } else { 1 })); } if self.lex.tk == '~' { self.next()?; - let v = self.parse_const_expr_unary_val()?.as_int(); - return Ok(ConstVal::Int(!v)); + let v = self.parse_const_expr_unary_val()?; + return Ok(self.const_unary_promoted(!v.as_int(), v.int_ty())); } if self.lex.tk == Token::AndOp { - return Ok(ConstVal::Int(self.parse_const_offsetof()?)); + // Address constant: full-width, no arithmetic conversion. + let v = self.parse_const_offsetof()?; + return Ok(ConstVal::Int { + val: v, + ty: Ty::Ptr as i64, + }); } if self.lex.tk == Token::Sizeof { // Shared sizeof operand parser handles all three // shapes (type-name, bare identifier, general // expression). Constant-expression context just - // returns the byte count directly. + // returns the byte count, typed `size_t` (C99 6.5.3.4p4). self.next()?; - return Ok(ConstVal::Int(self.sizeof_operand_bytes()?)); + let v = self.sizeof_operand_bytes()?; + return Ok(ConstVal::Int { + val: v, + ty: self.size_t_ty(), + }); } if self.lex.tk == Token::Alignof { // C11 6.5.3.4: `_Alignof ( type-name )` is a constant - // expression; return the alignment directly. + // expression; the result is `size_t`. self.next()?; - return Ok(ConstVal::Int(self.alignof_operand_bytes()?)); + let v = self.alignof_operand_bytes()?; + return Ok(ConstVal::Int { + val: v, + ty: self.size_t_ty(), + }); } self.parse_const_expr_primary_val() } + /// The `size_t` type tag: `unsigned long` on LP64, + /// `unsigned long long` on LLP64. + fn size_t_ty(&self) -> i64 { + if self.target.is_windows() { + Ty::LongLong as i64 | UNSIGNED_BIT + } else { + Ty::Long as i64 | UNSIGNED_BIT + } + } + /// Recognise the GCC-style `offsetof` expansion in a constant /// expression -- `&((T*))->field[.field]*[[N]]`. The /// macro typically expands to @@ -668,12 +914,15 @@ impl Compiler { // targets are 8 bytes and keep the full value. let bytes = self.size_of_type(target_ty); let is_bool = strip_unsigned(target_ty) == Ty::Bool as i64; - ConstVal::Int(narrow_const_int( - bytes, - is_unsigned_ty(target_ty), - is_bool, - v.as_int(), - )) + ConstVal::Int { + val: narrow_const_int( + bytes, + is_unsigned_ty(target_ty), + is_bool, + v.as_int(), + ), + ty: target_ty, + } }); } let v = self.parse_const_expr_cond_val()?; @@ -684,9 +933,12 @@ impl Compiler { return Ok(v); } if self.lex.tk == Token::Num { + // Type the literal per C99 6.4.4.1p5 (suffix + magnitude) + // before `next()` resets the lexer's suffix fields. let v = self.lex.ival; + let ty = self.literal_auto_promoted_type(v); self.next()?; - return Ok(ConstVal::Int(v)); + return Ok(ConstVal::Int { val: v, ty }); } if self.lex.tk == '"' { // String literal in a constant expression -- evaluates @@ -701,7 +953,10 @@ impl Compiler { self.next()?; } self.data.push(0); - return Ok(ConstVal::Int(addr)); + return Ok(ConstVal::Int { + val: addr, + ty: Ty::Ptr as i64, + }); } if self.lex.tk == Token::FloatNum { // Floating literal -- the lexer staged the f64 bit @@ -718,15 +973,27 @@ impl Compiler { } if self.lex.tk == Token::Id && self.symbols[self.lex.curr_id_idx].class == Token::Num as i64 { + // Enumeration constants have type `int` (C99 6.7.2.2p3); + // a value past `int`'s range (accepted as an extension) + // keeps 64-bit rank so arithmetic doesn't truncate it. let v = self.symbols[self.lex.curr_id_idx].val; self.next()?; - return Ok(ConstVal::Int(v)); + let ty = if v as i32 as i64 == v { + Ty::Int as i64 + } else { + Ty::LongLong as i64 + }; + return Ok(ConstVal::Int { val: v, ty }); } let id_suffix = if self.lex.tk == Token::Id { format!(" `{}`", self.symbols[self.lex.curr_id_idx].name) } else { alloc::string::String::new() }; + // Reached a non-constant operand rather than a malformed + // constant: the array-declarator reads this to tell a C99 + // 6.7.6.2 VLA dimension apart from a constant-expression error. + self.pending.const_expr_nonconst = true; Err(self.compile_err(format!( "constant integer expected (got {}{id_suffix})", super::super::token::describe(self.lex.tk), diff --git a/src/c5/compiler/decl_base.rs b/src/c5/compiler/decl_base.rs index 13f033028..c5cd16ed2 100644 --- a/src/c5/compiler/decl_base.rs +++ b/src/c5/compiler/decl_base.rs @@ -31,7 +31,7 @@ use alloc::format; use super::super::error::C5Error; use super::super::token::{Token, Ty}; use super::Compiler; -use super::types::{UNSIGNED_BIT, is_decl_modifier, struct_ty_for}; +use super::types::{UNSIGNED_BIT, VOLATILE_BIT, is_decl_modifier, struct_ty_for}; /// Accumulator for the int-modifier soup that prefixes a C base /// type. `signed` / `unsigned` / `short` / `long` (any count) / @@ -291,6 +291,7 @@ impl Compiler { thread_local: &mut bool, noreturn: &mut bool, dllexport: &mut bool, + aligned: &mut bool, ) { if self.lex.tk == Token::Id { let n = self.symbols[self.lex.curr_id_idx].name.as_str(); @@ -309,6 +310,9 @@ impl Compiler { // MSVC `__declspec(dllexport)`: export the symbol, the // equivalent of `#pragma export(name)`. *dllexport = true; + } else if n == "aligned" || n == "__aligned__" || n == "align" { + // GNU `aligned(N)` / MSVC `__declspec(align(N))`. + *aligned = true; } } } @@ -328,15 +332,44 @@ impl Compiler { let mut thread_local = false; let mut noreturn = false; let mut dllexport = false; + let mut align: i64 = 0; loop { if self.lex.tk == Token::Attribute { // `__attribute__((...))`, `__declspec(...)`, // `_Alignas(...)`. Consume the balanced parenthesised // payload, recording the `packed` attribute. + let is_alignas = self.symbols[self.lex.curr_id_idx].name == "_Alignas"; self.next()?; if self.lex.tk != '(' { return Err(self.compile_err("`(` expected after attribute specifier")); } + // C11 6.7.5 `_Alignas(constant-expression)`. The + // type-name form's alignment never exceeds 8 in this + // dialect and stays advisory. + if is_alignas { + self.next()?; // ( + if self.lex.tk == Token::Num { + let n = self.parse_constant_int()?; + align = align.max(n); + if self.lex.tk != ')' { + return Err(self.compile_err("`)` expected after `_Alignas` operand")); + } + self.next()?; + } else { + let mut depth = 1i32; + while depth > 0 { + if self.lex.tk == '(' { + depth += 1; + } else if self.lex.tk == ')' { + depth -= 1; + } else if self.lex.tk == 0 { + return Err(self.compile_err("unterminated `_Alignas`")); + } + self.next()?; + } + } + continue; + } let mut depth = 0i32; loop { if self.lex.tk == '(' { @@ -351,14 +384,34 @@ impl Compiler { } else if self.lex.tk == 0 { return Err(self.compile_err("unterminated attribute specifier")); } else { + let mut saw_aligned = false; self.note_attribute_name( &mut packed, &mut maybe_unused, &mut thread_local, &mut noreturn, &mut dllexport, + &mut saw_aligned, ); self.next()?; + if saw_aligned { + if self.lex.tk == '(' { + self.next()?; + let n = self.parse_constant_int()?; + align = align.max(n); + if self.lex.tk != ')' { + return Err( + self.compile_err("`)` expected after `aligned` operand") + ); + } + self.next()?; + } else { + // Bare `aligned`: the target's largest + // fundamental alignment (16 on the + // supported targets). + align = align.max(16); + } + } } } } else if self.lex.tk == Token::Brak && self.lex.peek_after_whitespace(b'[') { @@ -389,14 +442,27 @@ impl Compiler { } else if self.lex.tk == 0 { return Err(self.compile_err("unterminated `[[` attribute")); } else { + let mut saw_aligned = false; self.note_attribute_name( &mut packed, &mut maybe_unused, &mut thread_local, &mut noreturn, &mut dllexport, + &mut saw_aligned, ); self.next()?; + if saw_aligned && self.lex.tk == '(' { + self.next()?; + let n = self.parse_constant_int()?; + align = align.max(n); + if self.lex.tk != ')' { + return Err( + self.compile_err("`)` expected after `aligned` operand") + ); + } + self.next()?; + } } } } else { @@ -415,6 +481,9 @@ impl Compiler { if dllexport { self.pending.attr_dllexport = true; } + if align > 0 { + self.pending.attr_align = self.pending.attr_align.max(align); + } Ok(packed) } @@ -461,6 +530,21 @@ impl Compiler { Ok(Some(bt)) } + /// `VOLATILE_BIT` when the current token is the `volatile` type + /// qualifier (C99 6.7.3), 0 for any other spelling mapped to + /// `Token::TypeQual` (`const`, `restrict`, calling-convention + /// decorations). Qualifier identity lives on the interned keyword + /// symbol; the caller consumes the token. + pub(super) fn lex_volatile_bit(&self) -> i64 { + if self.lex.tk != Token::TypeQual { + return 0; + } + match self.symbols[self.lex.curr_id_idx].name.as_str() { + "volatile" | "__volatile" | "__volatile__" => VOLATILE_BIT, + _ => 0, + } + } + pub(super) fn parse_decl_base_type(&mut self) -> Result { // Reset the void side channel up front so a previous // declaration's bare-void base doesn't leak into this one. @@ -486,6 +570,7 @@ impl Compiler { // collect everything we see, then look at the next token // for the type keyword. let mut m = IntModifiers::default(); + let mut qual_bits: i64 = 0; loop { // C23 6.7.13 `[[...]]` and GNU `__attribute__`/`__declspec` // may lead the declaration specifiers. @@ -514,8 +599,9 @@ impl Compiler { self.pending_noreturn = true; } if !self.try_consume_int_modifier(&mut m)? { - // const / volatile / restrict / _Atomic / etc. -- - // all no-ops in c5, just consume. + // `volatile` sets the tag's qualifier bit (C99 6.7.3); + // const / restrict / _Atomic / etc. are no-ops. + qual_bits |= self.lex_volatile_bit(); self.next()?; } } @@ -528,7 +614,8 @@ impl Compiler { return self.parse_typeof_specifier(); } - let bt = if let Some(scalar) = self.parse_scalar_base_specifier(&m)? { + let base_tok = self.lex.tk; + let mut bt = if let Some(scalar) = self.parse_scalar_base_specifier(&m)? { scalar } else if self.lex.tk == Token::Enum { // `enum [Tag] [{ ... }]` collapses to `int`; the shared @@ -590,17 +677,57 @@ impl Compiler { return Err(self.compile_err("type expected")); }; - // Trailing qualifiers / modifiers: `int const`, `int long`, - // `unsigned int long long`, etc. all collapse to the base type - // already chosen. + // Trailing specifiers: C99 6.7.2p2 admits the specifier + // multiset in any order, so `int long`, `int unsigned`, + // `char unsigned`, `double long` re-derive the base tag from + // the folded modifiers; trailing qualifiers fold into the + // qualifier bits. A non-scalar base (typedef, struct, enum) + // has no valid int-modifier combination; the tokens are + // consumed as before. + let (saw_int_mod, trailing_quals) = self.consume_trailing_decl_modifiers(&mut m)?; + qual_bits |= trailing_quals; + if saw_int_mod { + if base_tok == Token::Int { + bt = m.int_base(); + } else if base_tok == Token::Char { + bt = m.char_tag(self.target.plain_char_signed()); + } else if base_tok == Token::Double && m.saw_long() { + self.pending.base_was_long_double = true; + } + } + + Ok(bt | qual_bits) + } + + /// Consume the specifiers that may trail the base-type keyword: + /// int modifiers fold into `m` (the caller re-derives the base + /// tag), qualifier bits are returned for the caller to fold into + /// the type, and `inline` / `_Noreturn` set the same pending + /// flags as in leading position. + pub(super) fn consume_trailing_decl_modifiers( + &mut self, + m: &mut IntModifiers, + ) -> Result<(bool, i64), C5Error> { + let mut saw_int_mod = false; + let mut qual_bits = 0i64; while is_decl_modifier(self.lex.tk) { if self.lex.tk == Token::Attribute { self.skip_attribute_specifiers()?; continue; } + if self.lex.tk == Token::Inline { + self.pending_is_inline = true; + } + if self.lex.tk == Token::Noreturn { + self.pending_noreturn = true; + } + if self.try_consume_int_modifier(m)? { + saw_int_mod = true; + continue; + } + qual_bits |= self.lex_volatile_bit(); self.next()?; } - - Ok(bt) + Ok((saw_int_mod, qual_bits)) } } diff --git a/src/c5/compiler/declarator.rs b/src/c5/compiler/declarator.rs index 5b072b011..423be2f6a 100644 --- a/src/c5/compiler/declarator.rs +++ b/src/c5/compiler/declarator.rs @@ -108,13 +108,31 @@ impl Compiler { /// (0 when the parentheses enclose no `*`). Used by both the cast /// operand parser and the `sizeof` type-name parser. pub(super) fn parse_abstract_ptr_declarator_levels(&mut self) -> Result { + self.parse_abstract_ptr_declarator(false) + .map(|(levels, _)| levels) + } + + /// As [`Self::parse_abstract_ptr_declarator_levels`], but with + /// `capture_proto` the plain fn-pointer shape's `(args)` list is + /// parsed and returned so a cast expression can record the pointee + /// prototype (parameter types, variadic split) for a following + /// call. Nested declarator shapes keep the skip behaviour. + pub(super) fn parse_abstract_ptr_declarator( + &mut self, + capture_proto: bool, + ) -> Result<(i64, Option), C5Error> { debug_assert!(self.lex.tk == '('); let mut depth: i64 = 1; self.next()?; let mut nested_ptrs: i64 = 0; + // The plain fn-pointer shape holds only `*`s (and qualifiers) + // inside one paren level; anything else is a nested declarator + // whose trailing `(args)` is not the pointee prototype. + let mut plain = true; while depth > 0 && self.lex.tk != 0 { if self.lex.tk == '(' { depth += 1; + plain = false; } else if self.lex.tk == ')' { depth -= 1; if depth == 0 { @@ -123,6 +141,8 @@ impl Compiler { } } else if self.lex.tk == Token::MulOp && depth == 1 { nested_ptrs += 1; + } else if self.lex.tk != Token::TypeQual { + plain = false; } self.next()?; } @@ -130,9 +150,18 @@ impl Compiler { // function-pointer / function-returning-fn shape, or one or more // `[N]` / `[]` suffixes for the pointer-to-array shape // (`T (*)[N][M]`). Both are no-ops at c5's type-tag granularity. + let mut proto = None; if self.lex.tk == '(' { self.next()?; - self.skip_balanced_parens_after_open()?; + if capture_proto && plain && nested_ptrs > 0 { + let pp = self.parse_function_params()?; + for &p in &pp.indices { + Self::restore_shadowed_symbol(&mut self.symbols[p]); + } + proto = Some(pp); + } else { + self.skip_balanced_parens_after_open()?; + } } while self.lex.tk == Token::Brak { self.next()?; @@ -143,7 +172,7 @@ impl Compiler { self.accept(']')?; } } - Ok(nested_ptrs) + Ok((nested_ptrs, proto)) } /// Parse a single declarator: zero-or-more `*` (pointer levels) @@ -160,6 +189,10 @@ impl Compiler { /// the decay happened, but for c5 today the equivalence is /// sufficient. pub(super) fn parse_declarator(&mut self, base: i64) -> Result<(usize, i64, i64), C5Error> { + self.with_nesting("declarator", |c| c.parse_declarator_inner(base)) + } + + fn parse_declarator_inner(&mut self, base: i64) -> Result<(usize, i64, i64), C5Error> { // Taken once so it scopes to this parameter's own declarator, not // any nested one (a function-pointer parameter's prototype). let param_ctx = core::mem::take(&mut self.pending.param_decl_context); @@ -170,6 +203,7 @@ impl Compiler { // it lexes as a no-op type qualifier. Consume any here so it does // not stand in for the declarator name. while self.lex.tk == Token::TypeQual { + ty |= self.lex_volatile_bit(); self.next()?; } let mut leading_ptr_count: i64 = 0; @@ -178,11 +212,13 @@ impl Compiler { ty += Ty::Ptr as i64; leading_ptr_count += 1; // Pointer-level qualifiers: `int *const p`, `int *volatile p`, - // `char *restrict s`. Consumed; no semantic effect. An - // attribute may sit here too (`void * __attribute__((malloc)) - // p`). + // `char *restrict s`. A pointer-level `volatile` sets the + // tag's qualifier bit (C99 6.7.3; the single bit does not + // record the level). An attribute may sit here too + // (`void * __attribute__((malloc)) p`). loop { if self.lex.tk == Token::TypeQual { + ty |= self.lex_volatile_bit(); self.next()?; } else if self.lex.tk == Token::Attribute { self.skip_attribute_specifiers()?; @@ -473,15 +509,13 @@ impl Compiler { // decide how to interpret it. self.next()?; array_size = -1; - } else { - // `int xs[N]` -- N must fold to a positive integer - // constant. The constant-expression evaluator - // accepts integer literals (with optional unary - // minus) and identifiers bound to compile-time - // integer constants (Token::Num via enum or via - // `#define`s the preprocessor folded into the - // source token stream). - let n = self.parse_constant_int()?; + } else if let Some(n) = self.try_parse_constant_dim()? { + // `int xs[N]` -- N folded to an integer constant. The + // constant-expression evaluator accepts integer literals + // (with optional unary minus) and identifiers bound to + // compile-time integer constants (Token::Num via enum or + // via `#define`s the preprocessor folded into the source + // token stream). if n < 0 { return Err( self.compile_err(format!("array dimension must be positive (got {n})")) @@ -497,6 +531,39 @@ impl Compiler { // allocated past the fixed part. Route it through the same // `array_size = -1` sentinel. array_size = if n == 0 { -1 } else { n }; + } else { + // Non-constant dimension (C99 6.7.6.2). In a parameter it + // is adjusted to a pointer, so the size is parsed and + // discarded (6.7.6.3p7). At block scope it declares a + // variable-length array. Everywhere else it is a + // constraint violation. + if param_ctx { + self.skip_array_dimension_expr()?; + // `skip_array_dimension_expr` stops at the `]`; consume + // it so the declarator resumes past the dimension. + self.next()?; + array_size = -1; + } else if self.pending.vla_allowed { + self.expr(Token::Assign as i64)?; + self.pending.vla_dim_expr = self.ast_acc.take(); + if self.lex.tk != ']' { + return Err(self.compile_err("close bracket expected in array declarator")); + } + self.next()?; + if self.lex.tk == Token::Brak { + return Err(self.compile_err( + "multidimensional variable-length arrays are not supported", + )); + } + array_size = super::VLA_ARRAY_SIZE; + if idx != usize::MAX { + return Ok((idx, ty, array_size)); + } + } else { + return Err( + self.compile_err("variable-length array is only allowed at block scope") + ); + } } // Trailing dimensions for N-dim arrays. c5 stores // `array_size = product(dims)` (total element count), @@ -520,7 +587,18 @@ impl Compiler { self.next()?; continue; } - let m = self.parse_constant_int()?; + let Some(m) = self.try_parse_constant_dim()? else { + // A non-constant inner dimension makes the whole + // object a variably-modified type (C99 6.7.6.2); c5's + // stride model is compile-time only, so reject it + // cleanly rather than miscompile the row stride. + if self.pending.vla_allowed || param_ctx { + return Err(self.compile_err( + "multidimensional variable-length arrays are not supported", + )); + } + return Err(self.compile_err("constant integer expected in array declarator")); + }; if m <= 0 { return Err( self.compile_err(format!("array dimension must be positive (got {m})")) diff --git a/src/c5/compiler/diag.rs b/src/c5/compiler/diag.rs index 5b934a3e0..475107d0a 100644 --- a/src/c5/compiler/diag.rs +++ b/src/c5/compiler/diag.rs @@ -13,7 +13,7 @@ use super::super::error::C5Error; use super::super::token::Ty; use super::Compiler; use super::types::{ - UNSIGNED_BIT, is_floating_scalar, is_pointer_ty, is_struct_ty, struct_ptr_depth, + UNSIGNED_BIT, VOLATILE_BIT, is_floating_scalar, is_pointer_ty, is_struct_ty, struct_ptr_depth, }; impl Compiler { @@ -294,6 +294,28 @@ impl Compiler { } } + /// Bound one level of parser recursion. Every recursive cycle in + /// the grammar (expressions, constant expressions, declarators, + /// initializer lists, statements) passes through an entry wrapped + /// in this helper, so one counter bounds them all and + /// pathological nesting gets a diagnostic instead of exhausting + /// the native stack. C99 5.2.4.1 requires 63 nesting levels; the + /// bound stays well above any real source. + pub(super) fn with_nesting( + &mut self, + construct: &'static str, + f: impl FnOnce(&mut Self) -> Result, + ) -> Result { + const MAX_NEST_DEPTH: usize = 1024; + if self.nest_depth >= MAX_NEST_DEPTH { + return Err(self.compile_err(alloc::format!("{construct} nesting too deep"))); + } + self.nest_depth += 1; + let r = f(self); + self.nest_depth -= 1; + r + } + /// Build a `C5Error::Compile` whose message follows the /// gcc / clang-shape convention everything else in this codebase /// uses for diagnostics: @@ -341,6 +363,10 @@ impl Compiler { actual_is_zero_literal: bool, actual_is_untyped_call: bool, ) -> Option<&'static str> { + // C99 6.5.16.1p1: the target may add qualifiers; volatility + // never affects assignment compatibility. + let declared = declared & !VOLATILE_BIT; + let actual = actual & !VOLATILE_BIT; if declared == actual { return None; } @@ -378,8 +404,9 @@ impl Compiler { // are all interchangeable here -- the compatibility rule // is "is this any kind of byte pointer?", not "do the // signedness tags line up". - let decl_is_char_ptr = decl_is_ptr && (declared & !UNSIGNED_BIT) == char_ptr; - let act_is_char_ptr = act_is_ptr && (actual & !UNSIGNED_BIT) == char_ptr; + let decl_is_char_ptr = + decl_is_ptr && (declared & !(UNSIGNED_BIT | VOLATILE_BIT)) == char_ptr; + let act_is_char_ptr = act_is_ptr && (actual & !(UNSIGNED_BIT | VOLATILE_BIT)) == char_ptr; if decl_is_char_ptr && act_is_ptr { return None; } diff --git a/src/c5/compiler/emit.rs b/src/c5/compiler/emit.rs index 2fd1ccb68..f79c8b314 100644 --- a/src/c5/compiler/emit.rs +++ b/src/c5/compiler/emit.rs @@ -227,6 +227,14 @@ impl Compiler { } } + /// Pad `self.data` to `align` bytes -- the `_Alignas(16)` / + /// `aligned(16)` placement for a file-scope object. + pub(super) fn align_data_to(&mut self, align: usize) { + while !self.data.len().is_multiple_of(align.max(8)) { + self.data.push(0); + } + } + /// True when the most recently emitted instruction is `Imm 0` -- /// i.e. the expression that just finished compiling was the literal /// `0`. Used by [`Compiler::type_warning`] to suppress the NULL @@ -553,6 +561,9 @@ impl Compiler { // `array_dims` for the duration of its scope. Restore // copies the shadow back on scope exit. s.h_array_dims = s.array_dims.clone(); + s.h_is_vla = s.is_vla; + s.h_vla_ptr_slot = s.vla_ptr_slot; + s.h_vla_size_slot = s.vla_size_slot; } /// Inverse of [`Self::shadow_symbol`]: restore the saved outer @@ -568,6 +579,9 @@ impl Compiler { sym.array_size = sym.h_array_size; sym.inner_array_size = sym.h_inner_array_size; sym.array_dims = core::mem::take(&mut sym.h_array_dims); + sym.is_vla = sym.h_is_vla; + sym.vla_ptr_slot = sym.h_vla_ptr_slot; + sym.vla_size_slot = sym.h_vla_size_slot; sym.is_scope_static = false; sym.is_scope_typedef = false; } @@ -940,6 +954,62 @@ impl Compiler { .push_stmt(super::super::ast::Stmt::Decl(decl_id), pos) } + /// Push a `Decl::Vla` (C99 6.7.6.2) wrapped in a `Stmt::Decl` so + /// the block's item collection picks it up in source order. The + /// walker allocates the runtime-sized storage at this point. + pub(super) fn ast_emit_vla_decl( + &mut self, + sym: u32, + elem_ty: i64, + elem_size: i64, + ptr_slot: i64, + size_slot: i64, + dim: super::super::ast::ExprId, + ) -> super::super::ast::StmtId { + let pos = self.ast_src_pos(); + let decl_id = self.ast.push_decl( + super::super::ast::Decl::Vla { + sym, + elem_ty, + elem_size, + ptr_slot, + size_slot, + dim, + }, + pos, + ); + self.ast + .push_stmt(super::super::ast::Stmt::Decl(decl_id), pos) + } + + /// Push an `Expr::VlaBase` (a VLA identifier decayed to its + /// runtime base pointer, C99 6.3.2.1p3) and set it as the new + /// accumulator so the wrapping index / call-arg / assignment site + /// finds the pointer on `ast_acc`. + pub(super) fn ast_emit_vla_base( + &mut self, + ptr_slot: i64, + ty: i64, + ) -> super::super::ast::ExprId { + let pos = self.ast_src_pos(); + let id = self + .ast + .push_expr(super::super::ast::Expr::VlaBase { ptr_slot, ty }, pos); + self.ast_acc = Some(id); + id + } + + /// Push an `Expr::VlaSizeof` (the runtime byte count of a VLA, + /// C99 6.5.3.4p2) and set it as the new accumulator. + pub(super) fn ast_emit_vla_sizeof(&mut self, size_slot: i64) -> super::super::ast::ExprId { + let pos = self.ast_src_pos(); + let id = self + .ast + .push_expr(super::super::ast::Expr::VlaSizeof { size_slot }, pos); + self.ast_acc = Some(id); + id + } + /// Push an `Expr::Call` and set it as the new accumulator. /// Called by the function-call parser site after the per-arg /// temp store + reverse push + call dispatch lands. `callee` diff --git a/src/c5/compiler/expr.rs b/src/c5/compiler/expr.rs index 3cfa7dfd1..dc32bba42 100644 --- a/src/c5/compiler/expr.rs +++ b/src/c5/compiler/expr.rs @@ -109,7 +109,7 @@ impl Compiler { /// With `u`/`U`: same hierarchy in the unsigned variants. /// With `l`/`L` / `ll`/`LL`: floor at the named width and let /// the magnitude bump further as needed. - fn literal_auto_promoted_type(&self, ival: i64) -> i64 { + pub(super) fn literal_auto_promoted_type(&self, ival: i64) -> i64 { let suffix_long = self.lex.int_suffix_long; let mut is_unsigned = self.lex.int_suffix_unsigned; // C99 6.4.4.1: a hexadecimal, octal, or binary constant may take @@ -133,7 +133,9 @@ impl Compiler { if bits >= 128 { true } else { - mag <= (1u128 << (bits - 1)) + // Signed max is 2^(bits-1) - 1; 2^31 / 2^63 exactly + // must move to the next rank (or unsigned type). + mag < (1u128 << (bits - 1)) } } else if bits >= 128 { true @@ -431,6 +433,10 @@ impl Compiler { } pub(super) fn expr(&mut self, lev: i64) -> Result<(), C5Error> { + self.with_nesting("expression", |c| c.expr_inner(lev)) + } + + fn expr_inner(&mut self, lev: i64) -> Result<(), C5Error> { let mut t: i64; if self.lex.tk == 0 { @@ -500,12 +506,15 @@ impl Compiler { let total_bytes = self.sizeof_operand_bytes()?; self.emit_imm(total_bytes); self.ty = Ty::Int as i64; - // Dual-emit: sizeof is a compile-time constant per - // 6.5.3.4p2. Seed the accumulator with the matching - // IntLit so a wrapping expression (call argument, - // binary op, assignment) finds the value on - // `ast_acc`. - self.ast_emit_int_lit(total_bytes, self.ty); + // C99 6.5.3.4p2: `sizeof` of a variable-length array is a + // runtime value -- emit a load of the VLA's byte-count + // slot. Every other operand folds to a compile-time + // constant; seed the accumulator with the matching IntLit. + if let Some(size_slot) = self.pending.sizeof_vla_size_slot.take() { + self.ast_emit_vla_sizeof(size_slot); + } else { + self.ast_emit_int_lit(total_bytes, self.ty); + } } else if self.lex.tk == Token::Alignof { // C11 6.5.3.4: `_Alignof ( type-name )`, a compile-time // constant. Emit the alignment as a runtime immediate and @@ -540,6 +549,23 @@ impl Compiler { self.next()?; if self.lex.tk == '(' { self.next()?; + // C89 6.3.2.2 implicit declaration, restricted to the + // names the driver listed: the link set defines them, + // so the call binds `extern int name();` and resolves + // against the user's definition rather than through a + // header's library binding. + if self.symbols[id_idx].class == 0 + && !self.implicit_extern_fns.is_empty() + && self + .implicit_extern_fns + .iter() + .any(|n| n == &self.symbols[id_idx].name) + { + self.symbols[id_idx].class = Token::Fun as i64; + self.symbols[id_idx].type_ = Ty::Int as i64; + self.symbols[id_idx].linkage = crate::c5::symbol::Linkage::External; + self.symbols[id_idx].defined_here = false; + } // C11 7.17 atomic operations and the other compiler // builtins share the `#pragma intrinsic` registry // (`` declares the atomics). An atomic op is @@ -1294,6 +1320,7 @@ impl Compiler { self.ty = self.symbols[id_idx].type_; let is_struct_value = is_struct_ty(self.ty) && struct_ptr_depth(self.ty) == 0; let is_array_var = self.symbols[id_idx].array_size != 0; + let is_vla_var = self.symbols[id_idx].is_vla; // A function-pointer variable carries its callee parameter // types so the dereferenced-call shape `(*fp)(args)` (which // reaches the postfix path rather than the direct-identifier @@ -1312,7 +1339,14 @@ impl Compiler { // "address-as-value" rule but keep their type // because the `.field` operator needs the struct's // value type to look up offsets. - if is_array_var { + if is_vla_var { + // C99 6.3.2.1p3: a VLA decays to a pointer to its + // first element -- the runtime base pointer, loaded + // from the hidden slot, not a fixed frame address. + let ptr_slot = self.symbols[id_idx].vla_ptr_slot; + self.ty += Ty::Ptr as i64; + self.ast_emit_vla_base(ptr_slot, self.ty); + } else if is_array_var { if identifier_is_local { // Array decay produces the array's // address rather than a scalar value, so @@ -1502,6 +1536,7 @@ impl Compiler { } } while self.lex.tk == Token::TypeQual { + t |= self.lex_volatile_bit(); self.next()?; } } @@ -1536,8 +1571,9 @@ impl Compiler { // as a no-op pointer level. Counted-parens scan // until the cast's outer `)` so even nested fp // shapes consume cleanly. + let mut cast_fn_proto = None; if self.lex.tk == '(' { - let nested_ptrs = self.parse_abstract_ptr_declarator_levels()?; + let (nested_ptrs, proto) = self.parse_abstract_ptr_declarator(true)?; t += nested_ptrs * (Ty::Ptr as i64); // Abstract fn-ptr declarator: the inner `*` // count IS the indirection from the cast's @@ -1546,6 +1582,7 @@ impl Compiler { if nested_ptrs > 0 { cast_fpi = Some(nested_ptrs); } + cast_fn_proto = proto; } if self.lex.tk == ')' { self.next()?; @@ -1647,6 +1684,20 @@ impl Compiler { { self.pending.fn_ptr_chain_depth = fpi - 1; } + // C99 6.5.2.2p7: a call through the cast pointer + // uses the cast's prototype. Override the operand's + // recorded callee channel so a following call + // narrows each argument and splits the variadic + // tail per the cast, whatever the operand's own + // declared type said. + if let Some(pp) = cast_fn_proto { + self.pending.indirect_callee_is_variadic = pp.is_variadic; + self.pending.indirect_callee_params = if pp.types.is_empty() { + None + } else { + Some(pp.types) + }; + } } } else { self.expr(Token::Assign as i64)?; @@ -2450,7 +2501,8 @@ impl Compiler { // below when the lvalue is integer but the rhs is // floating (C99 6.5.16.2 performs the operation in the // common type). - let rhs_is_fp = is_floating_scalar(self.ty); + let rhs_ty = self.ty; + let rhs_is_fp = is_floating_scalar(rhs_ty); if (binop == Token::AddOp as i64 || binop == Token::SubOp as i64) && is_pointer_ty(lhs_ty) && !is_floating_scalar(lhs_ty) @@ -2503,6 +2555,16 @@ impl Compiler { // converts the result back to the lvalue's integer // type (C99 6.5.16.2). let op_is_fp = lhs_is_fp || rhs_is_fp; + // C99 6.5.16.2p3: `E1 op= E2` computes `E1 op E2`, so + // divide / modulo signedness follows the 6.3.1.8 common + // type of both operands, not the lvalue alone (`int x; + // x /= 2u` divides unsigned). Pointer operands keep the + // lvalue's signedness (no arithmetic common type). + let div_unsigned = if op_is_fp || is_pointer_ty(lhs_ty) || is_pointer_ty(rhs_ty) { + is_unsigned_ty(lhs_ty) + } else { + is_unsigned_ty(usual_arith_common_ty(lhs_ty, rhs_ty, self.target)) + }; use super::super::ir::BinOp as B; let bop = match binop { x if x == Token::AddOp as i64 => { @@ -2529,14 +2591,14 @@ impl Compiler { x if x == Token::DivOp as i64 => { if op_is_fp { B::Fdiv - } else if is_unsigned_ty(lhs_ty) { + } else if div_unsigned { B::Divu } else { B::Div } } x if x == Token::ModOp as i64 => { - if is_unsigned_ty(lhs_ty) { + if div_unsigned { B::Modu } else { B::Mod @@ -2615,18 +2677,21 @@ impl Compiler { let else_ty = self.ty; // C99 6.5.15p5: when both arms have arithmetic type the // conditional's type is their usual-arithmetic-conversions - // common type and each arm converts to it. Without the cast a - // mixed int / floating ternary stores one arm through the - // other arm's store kind (integer bits read as a double). Pure - // integer arms already lower correctly on the I64 path, so - // only the floating-involved case needs the conversion here. + // common type and each arm converts to it. Without the cast + // a mixed int / floating ternary stores one arm through the + // other arm's store kind, and mixed-signedness integer arms + // take the wrong signedness (`c ? 1u : -1` must be the + // zero-extended unsigned value, not sign-extended int). + // Same-typed integer arms need no conversion. let mut result_ty = self.ty; let arith = |t: i64| !is_pointer_ty(t) && !is_struct_ty(t); - if (is_floating_scalar(then_ty) || is_floating_scalar(else_ty)) - && arith(then_ty) - && arith(else_ty) - { - let common = fp_result_ty(then_ty, else_ty); + let arms_fp = is_floating_scalar(then_ty) || is_floating_scalar(else_ty); + if (arms_fp || then_ty != else_ty) && arith(then_ty) && arith(else_ty) { + let common = if arms_fp { + fp_result_ty(then_ty, else_ty) + } else { + usual_arith_common_ty(then_ty, else_ty, self.target) + }; result_ty = common; if then_ty != common && then_ast.is_some() { let pos = self.ast_src_pos(); @@ -2798,16 +2863,18 @@ impl Compiler { self.next()?; self.ast_psh(); self.expr(Token::AddOp as i64)?; - // Pick logical (Shru) for unsigned LHS, arithmetic (Shr) otherwise. - // The RHS is the shift count; only the LHS sign matters. - + // Pick logical (Shru) for unsigned LHS, arithmetic (Shr) + // otherwise; the RHS is the shift count and does not + // participate. C99 6.5.7p3: the result has the promoted + // LHS type, so a 64-bit LHS keeps its width. Set the + // type before building the AST node so the node carries + // the result type, mirroring the `<<` path. + let lhs_size = self.size_of_type(t); + self.ty = if lhs_size <= 2 { Ty::Int as i64 } else { t }; if is_unsigned_ty(t) { self.ast_binop(crate::c5::ir::BinOp::Shru); - // Preserve LHS unsigned-ness so chained shifts/compares stay unsigned. - self.ty = t; } else { self.ast_binop(crate::c5::ir::BinOp::Shr); - self.ty = Ty::Int as i64; } } else if self.lex.tk == Token::AddOp { self.next()?; diff --git a/src/c5/compiler/function.rs b/src/c5/compiler/function.rs index e31e4a0a2..8fe143f85 100644 --- a/src/c5/compiler/function.rs +++ b/src/c5/compiler/function.rs @@ -109,6 +109,7 @@ impl Compiler { ty += Ty::Ptr as i64; leading_ptr_count += 1; while self.lex.tk == Token::TypeQual { + ty |= self.lex_volatile_bit(); self.next()?; } } diff --git a/src/c5/compiler/global_init.rs b/src/c5/compiler/global_init.rs index 05f0256be..d01a61ef1 100644 --- a/src/c5/compiler/global_init.rs +++ b/src/c5/compiler/global_init.rs @@ -21,7 +21,9 @@ use alloc::format; use super::super::error::C5Error; use super::super::token::{Token, Ty}; use super::Compiler; -use super::types::{UNSIGNED_BIT, is_pointer_ty, is_struct_ty, struct_id_of, struct_ptr_depth}; +use super::types::{ + UNSIGNED_BIT, VOLATILE_BIT, is_pointer_ty, is_struct_ty, struct_id_of, struct_ptr_depth, +}; impl Compiler { /// After a leading `(TYPE)` cast in a global initializer, returns @@ -74,6 +76,17 @@ impl Compiler { var_ty: i64, var_offset: i64, is_thread_local: bool, + ) -> Result<(), C5Error> { + self.with_nesting("initializer", |c| { + c.parse_global_initializer_inner(var_ty, var_offset, is_thread_local) + }) + } + + fn parse_global_initializer_inner( + &mut self, + var_ty: i64, + var_offset: i64, + is_thread_local: bool, ) -> Result<(), C5Error> { let line = self.lex.line; // C99 6.7.8p11 allows a scalar initializer to be enclosed @@ -248,6 +261,7 @@ impl Compiler { self.data_relocs.push(crate::c5::program::DataReloc { data_offset: var_offset as u64, target_offset: target_offset as u64, + target_anchor: target_offset as u64, }); self.data_reloc_sym_idx.push(target_idx); return Ok(()); @@ -271,6 +285,7 @@ impl Compiler { self.data_relocs.push(crate::c5::program::DataReloc { data_offset: var_offset as u64, target_offset: addr as u64, + target_anchor: addr as u64, }); // String-literal target -- no originating // symbol; sentinel marks the entry as @@ -341,6 +356,7 @@ impl Compiler { self.data_relocs.push(crate::c5::program::DataReloc { data_offset: var_offset as u64, target_offset: off as u64, + target_anchor: off as u64, }); self.data_reloc_sym_idx.push(new_idx); return Ok(()); @@ -516,6 +532,7 @@ impl Compiler { self.data_relocs.push(crate::c5::program::DataReloc { data_offset: var_offset as u64, target_offset: target_offset as u64, + target_anchor: self.symbols[target_idx].val as u64, }); self.data_reloc_sym_idx.push(target_idx); return Ok(()); @@ -529,7 +546,7 @@ impl Compiler { // full 8 bytes the slot was sized for; a future // f32-narrow-storage path would shrink it for `float`. let var_is_float = { - let stripped = var_ty & !UNSIGNED_BIT; + let stripped = var_ty & !(UNSIGNED_BIT | VOLATILE_BIT); stripped == Ty::Float as i64 || stripped == Ty::Double as i64 }; // Constant expression, evaluated at compile time. Handles diff --git a/src/c5/compiler/initializer.rs b/src/c5/compiler/initializer.rs index 6cb9e3b80..46ee6fd82 100644 --- a/src/c5/compiler/initializer.rs +++ b/src/c5/compiler/initializer.rs @@ -38,7 +38,7 @@ use super::super::error::C5Error; use super::super::token::{Token, Ty}; use super::Compiler; use super::const_expr::ConstVal; -use super::types::{UNSIGNED_BIT, is_struct_ty, struct_id_of, struct_ptr_depth}; +use super::types::{UNSIGNED_BIT, VOLATILE_BIT, is_struct_ty, struct_id_of, struct_ptr_depth}; /// Relocation kind for one initializer-element value. Tracks /// whether the bytes need to be patched at link / load time so @@ -113,9 +113,14 @@ impl Compiler { return; } } + let anchor = match src_sym { + Some(sym_idx) => self.symbols[sym_idx].val, + None => value, + }; self.data_relocs.push(crate::c5::program::DataReloc { data_offset: here as u64, target_offset: value as u64, + target_anchor: anchor as u64, }); self.data_reloc_sym_idx.push(src_sym.unwrap_or(usize::MAX)); } @@ -168,7 +173,7 @@ impl Compiler { /// slots (Data / Code relocs) pass through unchanged. Callers /// write `size_of_type(elem_ty)` low bytes of the result. pub(super) fn to_storage_bits(&self, value: i64, reloc: InitElemReloc, elem_ty: i64) -> i64 { - let stripped = elem_ty & !UNSIGNED_BIT; + let stripped = elem_ty & !(UNSIGNED_BIT | VOLATILE_BIT); let is_float = stripped == Ty::Float as i64; let is_double = stripped == Ty::Double as i64; if !is_float && !is_double { @@ -208,12 +213,10 @@ impl Compiler { /// `self.data` at byte offset `here`. Caller has already /// grown `self.data` to at least `here + n_bytes`. fn write_init_bytes(&mut self, here: usize, value: i64, n_bytes: usize) { - if n_bytes == 1 { - self.data[here] = value as u8; - } else { - for i in 0..n_bytes { - self.data[here + i] = ((value >> (i * 8)) & 0xFF) as u8; - } + // `value` carries at most 8 significant bytes; zero a wider + // destination's tail rather than wrapping the shift count. + for i in 0..n_bytes { + self.data[here + i] = if i < 8 { (value >> (i * 8)) as u8 } else { 0 }; } } @@ -256,6 +259,15 @@ impl Compiler { pub(super) fn collect_array_initializer( &mut self, elem_ty: i64, + ) -> Result, C5Error> { + self.with_nesting("initializer", |c| { + c.collect_array_initializer_inner(elem_ty) + }) + } + + fn collect_array_initializer_inner( + &mut self, + elem_ty: i64, ) -> Result, C5Error> { // 2D inner-dim hint -- callers set this when the declarator // shape is `T xs[N][M]` so a nested `{ row }` that lists @@ -291,7 +303,7 @@ impl Compiler { // a multi-dimensional char array (`char c[2][6] = {"a", // "b"}`, one string per row) has a string as its first // element and must stay a brace list. - let is_char_array = (elem_ty & !UNSIGNED_BIT) == Ty::Char as i64; + let is_char_array = (elem_ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64; if inner_dims.is_empty() && self.lex.tk == '"' && (self.lex.str_is_wide || is_char_array) @@ -315,7 +327,7 @@ impl Compiler { depth += 1; self.next()?; } - let is_char_array = (elem_ty & !UNSIGNED_BIT) == Ty::Char as i64; + let is_char_array = (elem_ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64; if self.lex.tk == '"' && (self.lex.str_is_wide || is_char_array) { paren_depth = depth; } else { @@ -359,7 +371,7 @@ impl Compiler { self.expect_close_parens(paren_depth)?; return Ok(elems); } - if self.lex.tk == '"' && (elem_ty & !UNSIGNED_BIT) == Ty::Char as i64 { + if self.lex.tk == '"' && (elem_ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64 { let start_addr = self.take_concat_string_literal()?; let char_count = self.data.len() - start_addr; // C99 6.7.8p14: a string-literal initializer for a @@ -485,7 +497,7 @@ impl Compiler { if self.lex.tk == '"' && !self.lex.str_is_wide && inner_dims.len() == 1 - && (elem_ty & !UNSIGNED_BIT) == Ty::Char as i64 + && (elem_ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64 { let row = inner_dims[0] as usize; let start_addr = self.take_concat_string_literal()?; @@ -1405,17 +1417,19 @@ impl Compiler { } /// Walk a C99 6.7.8p7 designator-chain tail (the part after the - /// first `.field` has already been consumed) and resolve it - /// down to a concrete `(byte_offset, type)` pair for the value - /// site. Accepts further `.member` steps; `[index]` sub-array - /// designators surface as a parse error until they are wired - /// up. The current type must be a value-typed struct or union - /// for any `.` step. + /// first `.field` has already been consumed) and resolve it down + /// to the final member: its absolute byte offset and its + /// `StructField` record (so the caller sees array / bitfield + /// shape, not just the element type). Accepts further `.member` + /// steps; `[index]` sub-array designators surface as a parse + /// error until they are wired up. The current type must be a + /// value-typed struct or union for any `.` step. pub(super) fn resolve_nested_designator_chain( &mut self, mut cur_offset: i64, mut cur_ty: i64, - ) -> Result<(i64, i64), C5Error> { + ) -> Result<(i64, super::StructField), C5Error> { + let mut last: Option = None; while self.lex.tk == Token::Dot || self.lex.tk == Token::Brak { if self.lex.tk == Token::Dot { if !is_struct_ty(cur_ty) || struct_ptr_depth(cur_ty) != 0 { @@ -1443,13 +1457,16 @@ impl Compiler { let sub = self.structs[sid].fields[sub_idx].clone(); cur_offset += sub.offset as i64; cur_ty = sub.ty; + last = Some(sub); } else { return Err(self.compile_err( "`[N]` sub-designator inside a struct chain is not yet supported", )); } } - Ok((cur_offset, cur_ty)) + let field = + last.ok_or_else(|| self.compile_err("empty designator chain after `.field`"))?; + Ok((cur_offset, field)) } /// Collect a `{ ... }` struct initializer. Each entry can be @@ -1460,14 +1477,15 @@ impl Compiler { /// Number of scalar initializer positions a struct consumes in a /// brace-elided (flat) list (C99 6.7.8p20). A scalar / pointer / /// bitfield field is one; an array of N elements is N times the - /// element type's count; a nested struct recurses; an anonymous - /// union contributes its first member's count only (its - /// alternatives share one positional slot). + /// element type's count; a nested struct recurses; a union -- + /// named or anonymous -- contributes its first member's count + /// only (6.7.8p17: one initializer, for the first named member). pub(super) fn struct_flat_init_slots(&self, struct_id: usize) -> usize { let fields = self.structs[struct_id].fields.clone(); + let is_union = self.structs[struct_id].is_union; let mut total = 0usize; let mut i = 0; - while i < fields.len() { + while i < fields.len() && (!is_union || i == 0) { let f = &fields[i]; let elem = if is_struct_ty(f.ty) && struct_ptr_depth(f.ty) == 0 { self.struct_flat_init_slots(struct_id_of(f.ty)) @@ -1494,6 +1512,16 @@ impl Compiler { &mut self, struct_id: usize, var_offset: i64, + ) -> Result<(), C5Error> { + self.with_nesting("initializer", |c| { + c.collect_struct_initializer_inner(struct_id, var_offset) + }) + } + + fn collect_struct_initializer_inner( + &mut self, + struct_id: usize, + var_offset: i64, ) -> Result<(), C5Error> { if self.lex.tk != '{' { return Err(self.compile_err("struct initializer must start with `{{`")); @@ -1616,7 +1644,7 @@ impl Compiler { data.resize(end, 0); } }; - if self.lex.tk == '"' && (elem_ty & !UNSIGNED_BIT) == Ty::Char as i64 { + if self.lex.tk == '"' && (elem_ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64 { let start_addr = self.take_concat_string_literal()?; self.data.push(0); // ensure NUL terminator in the literal's bytes let mut idx = 0usize; @@ -1695,22 +1723,27 @@ impl Compiler { // C99 6.7.8p7: a designator list may be a chain of // `.member` and `[index]` steps. `.outer.inner = v` // is equivalent to `.outer = { .inner = v }`. Walk - // the chain to compute the cumulative byte offset - // and the final field's type, then store the value - // there directly. Falls through to the existing + // the chain to the final member, then initialize it + // through the shared member dispatch so a char-array + // member takes a string literal (6.7.8p14) and a + // bitfield merges into its unit, exactly as when the + // member is named directly. Falls through to the // single-level path when no extra steps follow. if self.lex.tk == Token::Dot || self.lex.tk == Token::Brak { let outer = self.structs[struct_id].fields[outer_idx].clone(); let chain_base = (var_offset as usize) + outer.offset; - let (final_offset, final_ty) = + let (final_offset, final_field) = self.resolve_nested_designator_chain(chain_base as i64, outer.ty)?; if self.lex.tk != Token::Assign { return Err(self.compile_err("`=` expected after nested-designator chain")); } self.next()?; - let (value, reloc) = self.parse_constant_init_value()?; - let size = self.size_of_type(final_ty); - self.write_init_value(final_offset as usize, size, value, reloc, final_ty); + self.skip_opt_compound_literal_cast()?; + let chain_parens = core::mem::take(&mut self.pending.compound_lit_close_parens); + self.fill_member_value(struct_id, &final_field, final_offset as usize)?; + for _ in 0..chain_parens { + self.accept(')')?; + } pos = outer_idx + 1; self.accept(',')?; continue; @@ -1856,303 +1889,315 @@ impl Compiler { self.accept(',')?; continue; } - // Three field shapes get nested `{ ... }` initializers: - // * array field (`T xs[N]`) - // * value-typed nested struct - // * value-typed nested union - // Pointer / scalar / bitfield fields read a single - // constant-expression value via parse_constant_init_value. - // C99 6.7.9p14: a char-array member may be initialized by a - // string literal optionally enclosed in braces - // (`struct S { char a[N]; } x = { {"..."} };`). Unwrap a - // single `{ "..." }` so the string-copy path handles it; a - // multi-dimensional char array (`char c[2][6] = {"a","b"}`, - // one string per row) keeps the brace as a per-row list. - let mut char_array_brace_string = false; - if field.array_size > 0 - && field.inner_array_size == 0 - && (field.ty & !UNSIGNED_BIT) == Ty::Char as i64 - && self.lex.tk == '{' - { - let snap = self.lex.snapshot(); - // Peeking the inner string token appends its bytes to the - // data segment; restore the length too if it is not a - // brace-wrapped string after all. - let data_snap = self.data.len(); - self.next()?; - if self.lex.tk == '"' { - char_array_brace_string = true; - } else { - self.lex.restore(snap); - self.data.truncate(data_snap); - } + self.fill_member_value(struct_id, &field, field_base)?; + // Consume the grouping `)` that wrapped a parenthesized + // compound literal element (`((T){...})`), counted while the + // cast was stripped above. + for _ in 0..close_parens { + self.accept(')')?; } - // A string literal initializing a char array may be enclosed - // in parentheses (C99 6.5.1 -- a parenthesized expression has - // the same value; `._data = ("str")` is the form a macro - // produces). Skip the leading `(` so the string-copy path - // below sees the literal; the matching `)`s are consumed after - // the copy. Without this the parenthesized leaf falls into the - // single-value path and stores the string's pointer. - let mut char_array_paren_depth = 0usize; - if field.array_size > 0 - && field.inner_array_size == 0 - && (field.ty & !UNSIGNED_BIT) == Ty::Char as i64 - && self.lex.tk == '(' - { - let snap = self.lex.snapshot(); - let data_snap = self.data.len(); - let mut depth = 0usize; - while self.lex.tk == '(' { - depth += 1; - self.next()?; + // A positional initializer fills the first member of an + // anonymous union (C99 6.7.8); the remaining members share + // its storage, so advance past the whole group rather than + // landing on the next alternative. + pos = field_idx + 1; + let group = field.anon_union_group; + if group != 0 { + let fields = &self.structs[struct_id].fields; + while pos < fields.len() && fields[pos].anon_union_group == group { + pos += 1; } - if self.lex.tk == '"' { - char_array_paren_depth = depth; + } + self.accept(',')?; + // C99 6.7.8p17: without designators a union takes a single + // initializer, for its first named member; in a brace-elided + // context stop there rather than consuming values meant for + // the surrounding aggregate's next members. + if !braced && self.structs[struct_id].is_union { + break; + } + } + Ok(()) + } + + /// Initialize one member at `field_base` from the current token + /// position, dispatching on the member's shape: + /// * char-array member from a string literal (C99 6.7.8p14), + /// optionally brace- or paren-wrapped + /// * array member from a brace list or a brace-elided flat list + /// (6.7.8p20) + /// * nested struct / union member, braced or brace-elided + /// * bitfield member (read-modify-write of its storage unit) + /// * scalar / pointer member from a single constant expression + /// Shared by the positional walk in `fill_struct_fields` and the + /// nested-designator path, so `.outer.inner = value` takes the + /// same shapes as a directly named member. `struct_id` is the + /// containing aggregate (error text only). + fn fill_member_value( + &mut self, + struct_id: usize, + field: &super::StructField, + field_base: usize, + ) -> Result<(), C5Error> { + let mut char_array_brace_string = false; + if field.array_size > 0 + && field.inner_array_size == 0 + && (field.ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64 + && self.lex.tk == '{' + { + let snap = self.lex.snapshot(); + // Peeking the inner string token appends its bytes to the + // data segment; restore the length too if it is not a + // brace-wrapped string after all. + let data_snap = self.data.len(); + self.next()?; + if self.lex.tk == '"' { + char_array_brace_string = true; + } else { + self.lex.restore(snap); + self.data.truncate(data_snap); + } + } + // A string literal initializing a char array may be enclosed + // in parentheses (C99 6.5.1 -- a parenthesized expression has + // the same value; `._data = ("str")` is the form a macro + // produces). Skip the leading `(` so the string-copy path + // below sees the literal; the matching `)`s are consumed after + // the copy. Without this the parenthesized leaf falls into the + // single-value path and stores the string's pointer. + let mut char_array_paren_depth = 0usize; + if field.array_size > 0 + && field.inner_array_size == 0 + && (field.ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64 + && self.lex.tk == '(' + { + let snap = self.lex.snapshot(); + let data_snap = self.data.len(); + let mut depth = 0usize; + while self.lex.tk == '(' { + depth += 1; + self.next()?; + } + if self.lex.tk == '"' { + char_array_paren_depth = depth; + } else { + self.lex.restore(snap); + self.data.truncate(data_snap); + } + } + if field.array_size > 0 + && self.lex.tk == '"' + && (field.ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64 + { + // `struct S { char a[N]; } x = { "..." };` -- copy the + // string bytes (including the trailing NUL) into the + // char-array field, padding the remainder with zeroes. + // Without this branch the parser falls into the + // single-value path and writes the *pointer* to the + // string's data-segment slot into the field's first + // 8 bytes, which produces garbage at read time. + let start_addr = self.take_concat_string_literal()?; + self.data.push(0); // ensure NUL terminator + let max = field.array_size as usize; + let mut idx = 0usize; + while idx < max { + let b = if start_addr + idx < self.data.len() { + self.data[start_addr + idx] } else { - self.lex.restore(snap); - self.data.truncate(data_snap); + 0 + }; + self.write_init_value( + field_base + idx, + 1, + b as i64, + super::initializer::InitElemReloc::None, + field.ty, + ); + idx += 1; + if start_addr + idx >= self.data.len() { + // Past the string; remainder stays zero. + // Still walk the loop so all `max` bytes are + // explicitly written (zeroed above by + // write_init_value when source byte is 0). } } - if field.array_size > 0 - && self.lex.tk == '"' - && (field.ty & !UNSIGNED_BIT) == Ty::Char as i64 - { - // `struct S { char a[N]; } x = { "..." };` -- copy the - // string bytes (including the trailing NUL) into the - // char-array field, padding the remainder with zeroes. - // Without this branch the parser falls into the - // single-value path and writes the *pointer* to the - // string's data-segment slot into the field's first - // 8 bytes, which produces garbage at read time. - let start_addr = self.take_concat_string_literal()?; - self.data.push(0); // ensure NUL terminator - let max = field.array_size as usize; - let mut idx = 0usize; - while idx < max { - let b = if start_addr + idx < self.data.len() { - self.data[start_addr + idx] - } else { - 0 - }; - self.write_init_value( - field_base + idx, - 1, - b as i64, - super::initializer::InitElemReloc::None, - field.ty, - ); - idx += 1; - if start_addr + idx >= self.data.len() { - // Past the string; remainder stays zero. - // Still walk the loop so all `max` bytes are - // explicitly written (zeroed above by - // write_init_value when source byte is 0). - } - } - if char_array_brace_string { - self.expect_close_brace_after_wrapped_string()?; - } - for _ in 0..char_array_paren_depth { - if self.lex.tk != ')' { - return Err(self.compile_err( - "`)` expected to close a parenthesized string initializer", - )); - } - self.next()?; + if char_array_brace_string { + self.expect_close_brace_after_wrapped_string()?; + } + for _ in 0..char_array_paren_depth { + if self.lex.tk != ')' { + return Err(self + .compile_err("`)` expected to close a parenthesized string initializer")); } - } else if field.array_size > 0 && self.lex.tk == '{' { self.next()?; - let elem_size = self.size_of_type(field.ty); - // C99 6.7.8p21: a brace-enclosed initializer for the - // array member initializes every element; positions not - // named by a designator -- and any value left by an - // overridden duplicate initializer (6.7.8p19) -- are set - // to zero. Clear the member's region before applying the - // listed values. - let region = elem_size * field.array_size as usize; - for b in &mut self.data[field_base..field_base + region] { - *b = 0; - } - let elem_is_struct = is_struct_ty(field.ty) && struct_ptr_depth(field.ty) == 0; - let elem_sid = if elem_is_struct { - Some(struct_id_of(field.ty)) - } else { - None - }; - let mut idx: usize = 0; - while self.lex.tk != '}' { - // C99 6.7.8p7 array designator inside an array - // field's nested initializer. `[N] = value` - // jumps the write cursor to N; subsequent - // positional entries (or further `[K] = ...` - // clauses) continue from there. Mirrors the - // top-level array-init path in - // `collect_array_initializer`. - if self.lex.tk == Token::Brak { - self.next()?; - let n = self.parse_constant_int()?; - if n < 0 { - return Err(self.compile_err(format!( - "array designator index must be non-negative (got {n})" - ))); - } - if self.lex.tk != ']' { - return Err( - self.compile_err("`]` expected after array designator index") - ); - } - self.next()?; - if self.lex.tk != Token::Assign { - return Err(self.compile_err("`=` expected after `[N]` designator")); - } - self.next()?; - idx = n as usize; - } - if idx as i64 >= field.array_size { + } + } else if field.array_size > 0 && self.lex.tk == '{' { + self.next()?; + let elem_size = self.size_of_type(field.ty); + // C99 6.7.8p21: a brace-enclosed initializer for the + // array member initializes every element; positions not + // named by a designator -- and any value left by an + // overridden duplicate initializer (6.7.8p19) -- are set + // to zero. Clear the member's region before applying the + // listed values. + let region = elem_size * field.array_size as usize; + for b in &mut self.data[field_base..field_base + region] { + *b = 0; + } + let elem_is_struct = is_struct_ty(field.ty) && struct_ptr_depth(field.ty) == 0; + let elem_sid = if elem_is_struct { + Some(struct_id_of(field.ty)) + } else { + None + }; + let mut idx: usize = 0; + while self.lex.tk != '}' { + // C99 6.7.8p7 array designator inside an array + // field's nested initializer. `[N] = value` + // jumps the write cursor to N; subsequent + // positional entries (or further `[K] = ...` + // clauses) continue from there. Mirrors the + // top-level array-init path in + // `collect_array_initializer`. + if self.lex.tk == Token::Brak { + self.next()?; + let n = self.parse_constant_int()?; + if n < 0 { return Err(self.compile_err(format!( - "too many initializers for `{}.{}`", - self.structs[struct_id].name, field.name + "array designator index must be non-negative (got {n})" ))); } - let here = field_base + idx * elem_size; - // C99 6.7.8p20: an array-of-struct field accepts a - // nested brace-enclosed initializer for each element, - // and the element's braces may be elided. A `{ ... }` - // element routes through the struct collector; a - // brace-elided element consumes exactly that element's - // fields from the flat list via `fill_struct_fields`. - // Scalar element types fall through to the constant- - // value path. (Without the elided-element branch a - // flat list wrote a single scalar with the struct's - // byte width, overflowing `write_init_bytes`.) - if let Some(sid) = elem_sid { - if self.lex.tk == '{' { - self.collect_struct_initializer(sid, here as i64)?; - } else { - self.fill_struct_fields(sid, here as i64, false)?; - } - } else { - let (value, reloc) = self.parse_constant_init_value()?; - self.write_init_value(here, elem_size, value, reloc, field.ty); + if self.lex.tk != ']' { + return Err(self.compile_err("`]` expected after array designator index")); } - idx += 1; - self.accept(',')?; - } - self.next()?; // consume `}` - } else if field.array_size > 0 { - // C99 6.7.8p20 "implicit braces removed": a flat - // value list inside a struct initializer can fill - // an array field directly, without nested braces. - // Absorb up to `array_size` values from the - // surrounding brace list; the outer struct loop - // then advances to the next field on the - // following `,`. A canonical instance is - // struct { unsigned char c[4]; } v = { 1,2,3,4 }; - // where the inner array's brace pair is elided. - let elem_size = self.size_of_type(field.ty); - let mut idx: usize = 0; - while (idx as i64) < field.array_size && self.lex.tk != '}' { - let (value, reloc) = self.parse_constant_init_value()?; - let here = field_base + idx * elem_size; - self.write_init_value(here, elem_size, value, reloc, field.ty); - idx += 1; - if idx as i64 >= field.array_size { - break; + self.next()?; + if self.lex.tk != Token::Assign { + return Err(self.compile_err("`=` expected after `[N]` designator")); } - if self.lex.tk == ',' { - self.next()?; + self.next()?; + idx = n as usize; + } + if idx as i64 >= field.array_size { + return Err(self.compile_err(format!( + "too many initializers for `{}.{}`", + self.structs[struct_id].name, field.name + ))); + } + let here = field_base + idx * elem_size; + // C99 6.7.8p20: an array-of-struct field accepts a + // nested brace-enclosed initializer for each element, + // and the element's braces may be elided. A `{ ... }` + // element routes through the struct collector; a + // brace-elided element consumes exactly that element's + // fields from the flat list via `fill_struct_fields`. + // Scalar element types fall through to the constant- + // value path. (Without the elided-element branch a + // flat list wrote a single scalar with the struct's + // byte width, overflowing `write_init_bytes`.) + if let Some(sid) = elem_sid { + if self.lex.tk == '{' { + self.collect_struct_initializer(sid, here as i64)?; } else { - break; + self.fill_struct_fields(sid, here as i64, false)?; } - } - } else if is_struct_ty(field.ty) - && struct_ptr_depth(field.ty) == 0 - && (self.lex.tk == '{' || !self.structs[struct_id_of(field.ty)].is_union) - { - let nested_sid = struct_id_of(field.ty); - if self.lex.tk == '{' { - self.collect_struct_initializer(nested_sid, field_base as i64)?; } else { - // C99 6.7.8p20: a nested struct field's braces may be - // elided, filling its members from the surrounding flat - // list. Mirrors the array-of-struct element path. An - // unbraced union takes only its first member, handled by - // the single-value path below. - self.fill_struct_fields(nested_sid, field_base as i64, false)?; + let (value, reloc) = self.parse_constant_init_value()?; + self.write_init_value(here, elem_size, value, reloc, field.ty); } - } else if field.bit_width > 0 { - // Bitfield brace-initializer entry. C99 6.7.8 says - // the initializer's value is converted to the - // bitfield's type as if assigned. A naive - // `write_init_value(field_base, sizeof(base), value)` - // would clobber every other bitfield sharing the - // same storage unit -- adjacent fields in the same - // brace list each rewrite the entire unit. Merge - // the bitfield's bits into the existing storage - // unit instead. - let (value, _reloc) = self.parse_constant_init_value()?; - // C99 6.7.2.1p11: the bitfield's addressable storage - // unit width is determined by the declared base type; - // the RMW span must match `bit_unit_size` so it does - // not read or write outside the unit. - let unit_bytes = field.bit_unit_size as usize; - let mut unit_value: i64 = 0; - for i in 0..unit_bytes { - unit_value |= (self.data[field_base + i] as i64) << (i * 8); + idx += 1; + self.accept(',')?; + } + self.next()?; // consume `}` + } else if field.array_size > 0 { + // C99 6.7.8p20 "implicit braces removed": a flat + // value list inside a struct initializer can fill + // an array field directly, without nested braces. + // Absorb up to `array_size` values from the + // surrounding brace list; the outer struct loop + // then advances to the next field on the + // following `,`. A canonical instance is + // struct { unsigned char c[4]; } v = { 1,2,3,4 }; + // where the inner array's brace pair is elided. + let elem_size = self.size_of_type(field.ty); + let mut idx: usize = 0; + while (idx as i64) < field.array_size && self.lex.tk != '}' { + let (value, reloc) = self.parse_constant_init_value()?; + let here = field_base + idx * elem_size; + self.write_init_value(here, elem_size, value, reloc, field.ty); + idx += 1; + if idx as i64 >= field.array_size { + break; } - let bit_width = field.bit_width; - let bit_offset = field.bit_offset; - let mask: i64 = if bit_width >= 64 { - -1 + if self.lex.tk == ',' { + self.next()?; } else { - (1i64 << bit_width) - 1 - }; - let cleared = unit_value & !(mask << bit_offset); - let merged = cleared | ((value & mask) << bit_offset); - for i in 0..unit_bytes { - self.data[field_base + i] = ((merged >> (i * 8)) & 0xFF) as u8; + break; } + } + } else if is_struct_ty(field.ty) && struct_ptr_depth(field.ty) == 0 { + let nested_sid = struct_id_of(field.ty); + if self.lex.tk == '{' { + self.collect_struct_initializer(nested_sid, field_base as i64)?; } else { - // C99 6.7.9p11: a scalar member's initializer may be - // enclosed in braces (`{ .field = { expr } }`); strip a - // single wrapper, matching the runtime scalar path. - let braced_scalar = self.lex.tk == '{'; - if braced_scalar { - self.next()?; - } - let (value, reloc) = self.parse_constant_init_value()?; - let field_size = self.size_of_type(field.ty); - self.write_init_value(field_base, field_size, value, reloc, field.ty); - if braced_scalar { - self.accept(',')?; - if self.lex.tk != '}' { - return Err(self.compile_err( - "scalar initializer wrapped in `{ ... }` must hold a single value", - )); - } - self.next()?; // consume `}` - } + // C99 6.7.8p20: a nested aggregate field's braces may be + // elided, filling its members from the surrounding flat + // list. Mirrors the array-of-struct element path. For a + // union the recursion converts and stores one value into + // the first named member (6.7.8p17) and returns. + self.fill_struct_fields(nested_sid, field_base as i64, false)?; + } + } else if field.bit_width > 0 { + // Bitfield brace-initializer entry. C99 6.7.8 says + // the initializer's value is converted to the + // bitfield's type as if assigned. A naive + // `write_init_value(field_base, sizeof(base), value)` + // would clobber every other bitfield sharing the + // same storage unit -- adjacent fields in the same + // brace list each rewrite the entire unit. Merge + // the bitfield's bits into the existing storage + // unit instead. + let (value, _reloc) = self.parse_constant_init_value()?; + // C99 6.7.2.1p11: the bitfield's addressable storage + // unit width is determined by the declared base type; + // the RMW span must match `bit_unit_size` so it does + // not read or write outside the unit. + let unit_bytes = field.bit_unit_size as usize; + let mut unit_value: i64 = 0; + for i in 0..unit_bytes { + unit_value |= (self.data[field_base + i] as i64) << (i * 8); + } + let bit_width = field.bit_width; + let bit_offset = field.bit_offset; + let mask: i64 = if bit_width >= 64 { + -1 + } else { + (1i64 << bit_width) - 1 + }; + let cleared = unit_value & !(mask << bit_offset); + let merged = cleared | ((value & mask) << bit_offset); + for i in 0..unit_bytes { + self.data[field_base + i] = ((merged >> (i * 8)) & 0xFF) as u8; } - // Consume the grouping `)` that wrapped a parenthesized - // compound literal element (`((T){...})`), counted while the - // cast was stripped above. - for _ in 0..close_parens { - self.accept(')')?; + } else { + // C99 6.7.9p11: a scalar member's initializer may be + // enclosed in braces (`{ .field = { expr } }`); strip a + // single wrapper, matching the runtime scalar path. + let braced_scalar = self.lex.tk == '{'; + if braced_scalar { + self.next()?; } - // A positional initializer fills the first member of an - // anonymous union (C99 6.7.8); the remaining members share - // its storage, so advance past the whole group rather than - // landing on the next alternative. - pos = field_idx + 1; - let group = field.anon_union_group; - if group != 0 { - let fields = &self.structs[struct_id].fields; - while pos < fields.len() && fields[pos].anon_union_group == group { - pos += 1; + let (value, reloc) = self.parse_constant_init_value()?; + let field_size = self.size_of_type(field.ty); + self.write_init_value(field_base, field_size, value, reloc, field.ty); + if braced_scalar { + self.accept(',')?; + if self.lex.tk != '}' { + return Err(self.compile_err( + "scalar initializer wrapped in `{ ... }` must hold a single value", + )); } + self.next()?; // consume `}` } - self.accept(',')?; } Ok(()) } @@ -2281,9 +2326,9 @@ impl Compiler { self.pending_local_init_ast = self.ast_acc; if is_struct_ty(ty) && struct_ptr_depth(ty) == 0 { self.mark_emit_other(); - } else if (ty & !UNSIGNED_BIT) == Ty::Char as i64 { + } else if (ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64 { self.ast_assign(); - } else if (ty & !UNSIGNED_BIT) == Ty::Float as i64 { + } else if (ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Float as i64 { // `float`-typed local: narrow the accumulator (an f64 // bit pattern from the RHS) to single-precision and // store 4 bytes. The slot reserved by diff --git a/src/c5/compiler/locals.rs b/src/c5/compiler/locals.rs index 48993a1bc..4d775f630 100644 --- a/src/c5/compiler/locals.rs +++ b/src/c5/compiler/locals.rs @@ -31,7 +31,9 @@ use alloc::format; use super::super::error::C5Error; use super::super::token::{Token, Ty}; use super::Compiler; -use super::types::{UNSIGNED_BIT, is_pointer_ty, is_struct_ty, struct_id_of, struct_ptr_depth}; +use super::types::{ + UNSIGNED_BIT, VOLATILE_BIT, is_pointer_ty, is_struct_ty, struct_id_of, struct_ptr_depth, +}; impl Compiler { /// Drain the three pending local-initializer carriers into a single @@ -63,6 +65,10 @@ impl Compiler { /// emit its local declaration. A non-`Loc` binding (a redeclaration /// that resolved elsewhere) discards the carriers without emitting. pub(super) fn finalize_local_init(&mut self, loc_idx: usize) { + // A VLA already emitted its `Decl::Vla` in `allocate_vla_local`. + if self.symbols[loc_idx].is_vla { + return; + } if self.symbols[loc_idx].class == Token::Loc as i64 { let slot_off = self.symbols[loc_idx].val; let init = self.drain_pending_local_init(); @@ -81,6 +87,7 @@ impl Compiler { let mut is_static = false; let mut is_extern = false; let mut saw_specifier = false; + let mut qual_bits: i64 = 0; while self.lex.tk == Token::Extern || self.lex.tk == Token::Static || self.lex.tk == Token::FuncSpec @@ -92,6 +99,8 @@ impl Compiler { if self.lex.tk == Token::Extern { is_extern = true; } + // `volatile` qualifies the declared type (C99 6.7.3). + qual_bits |= self.lex_volatile_bit(); saw_specifier = true; self.next()?; } @@ -103,7 +112,7 @@ impl Compiler { Ty::Int as i64 } else { self.parse_decl_base_type()? - }; + } | qual_bits; // A function-pointer typedef base type contributes its lineage to // every declarator in the list (`fn_t a, b;` makes both a and b // function pointers). The per-declarator symbol creation consumes @@ -127,7 +136,11 @@ impl Compiler { self.pending.base_is_function_type = base_is_function_type; self.pending.typedef_fn_proto = base_typedef_fn_proto; self.pending.fn_ptr_param_types = base_fn_ptr_param_types.clone(); + // C99 6.7.6.2: a non-constant array dimension at block scope + // is a variable-length array. + self.pending.vla_allowed = true; let (loc_idx, ty, mut array_size) = self.parse_declarator(lbt)?; + self.pending.vla_allowed = false; // C23 6.7.13.5 `[[maybe_unused]]` / GNU // `__attribute__((unused))` on the declaration suppresses // the unused-variable diagnostic for the names it declares. @@ -199,6 +212,18 @@ impl Compiler { self.shadow_symbol(loc_idx); + // C11 6.7.5 on block-scope objects: a static local's + // `.data` slot honors up to 16 like a file-scope object; + // an automatic object lives in 8-byte frame slots, so a + // larger request is a diagnostic, never a silent drop. + let req_align = core::mem::take(&mut self.pending.attr_align); + if req_align > 16 || (req_align > 8 && !is_static) { + return Err(self.compile_err(format!( + "requested alignment {req_align} is not supported here \ + (automatic objects align to 8, static objects to at most 16)" + ))); + } + if is_static { self.symbols[loc_idx].class = Token::Glo as i64; self.symbols[loc_idx].type_ = ty; @@ -208,6 +233,10 @@ impl Compiler { // object of the same name reappears. The `Loc`-gated // cleanup would skip it, so mark it for restore. self.symbols[loc_idx].is_scope_static = true; + if req_align > 8 { + self.align_data_to(req_align as usize); + self.data_align = 16; + } self.allocate_static_local(loc_idx, ty, array_size)?; self.ast_emit_static_local_decl(loc_idx as u32); } else { @@ -591,12 +620,49 @@ impl Compiler { /// * deferred-size array (`int xs[] = {...};`): the /// initializer determines the dimension first, then storage /// is reserved. + /// C99 6.7.6.2 variable-length array local. Reserves two hidden + /// frame slots -- the runtime base pointer and the runtime byte + /// count -- and records a `Decl::Vla`; the walker allocates the + /// storage from the per-frame alloca arena. The array is not + /// promotable and its storage is reclaimed on block exit by the + /// scope bracket `parse_block_stmt` emits. + fn allocate_vla_local(&mut self, loc_idx: usize, elem_ty: i64) -> Result<(), C5Error> { + // C99 6.7.8p3: a VLA declaration may not carry an initializer. + if self.lex.tk == Token::Assign { + return Err(self.compile_err("a variable-length array may not have an initializer")); + } + let dim = match self.pending.vla_dim_expr.take() { + Some(d) => d, + None => return Err(self.compile_err("variable-length array has no dimension")), + }; + let ptr_slot = self.reserve_slots(1); + let size_slot = self.reserve_slots(1); + let elem_size = self.size_of_type(elem_ty) as i64; + let s = &mut self.symbols[loc_idx]; + s.is_vla = true; + s.type_ = elem_ty; + s.array_size = 0; + s.vla_ptr_slot = ptr_slot; + s.vla_size_slot = size_slot; + s.was_written = true; + s.address_escaped = true; + self.func_vla_decls += 1; + // The VLA storage comes from the per-frame alloca arena, so the + // function reserves the arena and its bookkeeping slot. + self.uses_alloca_in_current_fn = true; + self.ast_emit_vla_decl(loc_idx as u32, elem_ty, elem_size, ptr_slot, size_slot, dim); + Ok(()) + } + pub(super) fn allocate_local_with_init( &mut self, loc_idx: usize, ty: i64, declared_array_size: i64, ) -> Result<(), C5Error> { + if declared_array_size == super::VLA_ARRAY_SIZE { + return self.allocate_vla_local(loc_idx, ty); + } // C99 6.7.9: an initializer at the declaration site counts // as a store from the perspective of the dead-store // analysis. Mark before parsing the initializer so @@ -1468,17 +1534,58 @@ impl Compiler { // C99 6.7.8p7 nested designator chain. See the // matching branch in `collect_struct_initializer` // for the constant-staging variant. Computes the - // cumulative offset / final type, then emits one + // cumulative offset / final member, then emits one // store at `&local + extra_offset + final_offset`. if self.lex.tk == Token::Dot || self.lex.tk == Token::Brak { let outer = self.structs[sid].fields[outer_idx].clone(); let chain_base = extra_offset + outer.offset as i64; - let (final_offset, final_ty) = + let (final_offset, final_field) = self.resolve_nested_designator_chain(chain_base, outer.ty)?; if self.lex.tk != Token::Assign { return Err(self.compile_err("`=` expected after nested-designator chain")); } self.next()?; + // A char-array final member takes a string literal + // (C99 6.7.8p14): per-byte constant stores, zero + // fill; mirrors the positional branch below. Other + // array or bitfield finals are rejected the same + // way the positional walk rejects them. + if final_field.array_size > 0 { + if self.lex.tk == '"' + && !self.lex.str_is_wide + && (final_field.ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64 + { + let start_addr = self.take_concat_string_literal()?; + self.data.push(0); // ensure NUL terminator + for k in 0..final_field.array_size as usize { + let b = if start_addr + k < self.data.len() { + self.data[start_addr + k] as i64 + } else { + 0 + }; + let value = self.ast_emit_int_lit(b, Ty::Char as i64); + self.pending_local_runtime_elements.push( + super::super::ast::RuntimeInitElement { + offset: final_offset + k as i64, + value, + ty: Ty::Char as i64, + }, + ); + } + pos = outer_idx + 1; + self.accept(',')?; + continue; + } + return Err(self.compile_err( + "non-constant array-field initializer not yet supported", + )); + } + if final_field.bit_width > 0 { + return Err( + self.compile_err("non-constant bitfield initializer not yet supported") + ); + } + let final_ty = final_field.ty; self.emit_lea(local_val); if final_offset > 0 { self.ast_psh(); @@ -1534,7 +1641,7 @@ impl Compiler { // it composes with non-constant sibling fields. if self.lex.tk == '"' && !self.lex.str_is_wide - && (field.ty & !UNSIGNED_BIT) == Ty::Char as i64 + && (field.ty & !(UNSIGNED_BIT | VOLATILE_BIT)) == Ty::Char as i64 { let start_addr = self.take_concat_string_literal()?; self.data.push(0); // ensure NUL terminator diff --git a/src/c5/compiler/mod.rs b/src/c5/compiler/mod.rs index 165a98c1b..df0952b57 100644 --- a/src/c5/compiler/mod.rs +++ b/src/c5/compiler/mod.rs @@ -214,6 +214,12 @@ pub struct CompileOptions { /// most but not all of the GNU C surface, so it claims `__GNUC__` /// only when the caller opts in. pub gnu: bool, + /// Function names an undeclared call may bind as a C89 6.3.2.2 + /// implicit `extern int name();` instead of triggering the + /// auto-include retry. The driver fills this in a multi-TU build + /// for auto-included names another input defines, so the user's + /// definition wins over the header's library binding. + pub implicit_extern_fns: Vec, } impl CompileOptions { @@ -273,6 +279,12 @@ impl CompileOptions { self.no_entry_point = on; self } + /// Replace the implicit-extern function-name list. See + /// [`Self::implicit_extern_fns`]. + pub fn with_implicit_extern_fns(mut self, names: Vec) -> Self { + self.implicit_extern_fns = names; + self + } } /// Ephemeral side-channel state passed between parser layers -- @@ -283,6 +295,12 @@ impl CompileOptions { /// function-pointer chain-depth tracker into one carrier so the /// `Compiler` field list reads as "lexer + symbols + codegen /// output + transient state" instead of eleven loose fields. +/// Sentinel `array_size` for a C99 6.7.6.2 variable-length array +/// declarator: distinct from `0` (scalar), `> 0` (constant array), +/// and `-1` (deferred / flexible `T x[]`). The dimension expression +/// rides on `Pending::vla_dim_expr`. +pub(in crate::c5::compiler) const VLA_ARRAY_SIZE: i64 = -2; + #[derive(Debug)] pub(in crate::c5::compiler) struct Pending { /// Side channel from the base-type parsers @@ -416,6 +434,26 @@ pub(in crate::c5::compiler) struct Pending { /// the array length. Cleared by every base-type parse /// (`0` means "not from an array typedef"). pub typedef_base_array_size: i64, + /// Set true while parsing a block-scope object declarator, where + /// a non-constant array dimension is a C99 6.7.6.2 variable-length + /// array. Elsewhere (file scope, struct member, typedef, cast, + /// sizeof) a non-constant dimension is a constraint violation. + pub vla_allowed: bool, + /// The declarator's parsed VLA dimension expression, set when the + /// leading `[expr]` was non-constant and `vla_allowed`. `None` for + /// a constant-dimension array. Consumed by the local-decl site. + pub vla_dim_expr: Option, + /// Set by `sizeof_operand_bytes` to the VLA's runtime-byte-count + /// slot when the operand is a variable-length array (C99 + /// 6.5.3.4p2); the `sizeof` site then emits a runtime load instead + /// of a constant. `None` for a constant-size operand. + pub sizeof_vla_size_slot: Option, + /// Set by the constant-expression evaluator when it fails because it + /// reached a non-constant operand (a runtime identifier, call, ...), + /// as opposed to a malformed constant (division by zero, ...). Lets + /// the array-declarator distinguish a C99 6.7.6.2 VLA dimension from + /// a genuine constant-expression error that must be diagnosed. + pub const_expr_nonconst: bool, /// Binding-site carrier for a function-pointer typedef's /// prototype: `Some((fixed_param_count, is_variadic))` when the /// base type was a typedef whose alias is a function-pointer @@ -580,6 +618,12 @@ pub(in crate::c5::compiler) struct Pending { /// skip to mark the declared locals so their unused-variable /// diagnostics are suppressed. pub attr_maybe_unused: bool, + /// Requested object alignment from `_Alignas(N)` / + /// `__attribute__((aligned(N)))` / `__declspec(align(N))`, 0 when + /// absent. The declaration parse takes it: file-scope objects + /// honor up to 16, anything larger (or an automatic object above + /// the 8-byte slot alignment) is a diagnostic, never silent. + pub attr_align: i64, /// A consumed `__declspec(thread)`. Read by the declaration parse to mark /// the declared object thread-local (the storage class `_Thread_local` /// reaches the same flag through the keyword path). @@ -605,6 +649,10 @@ impl Default for Pending { init_inner_dims: alloc::vec::Vec::new(), init_target_array_size: 0, typedef_base_array_size: 0, + vla_allowed: false, + vla_dim_expr: None, + sizeof_vla_size_slot: None, + const_expr_nonconst: false, typedef_fn_proto: None, fn_ptr_param_types: None, indirect_callee_params: None, @@ -625,6 +673,7 @@ impl Default for Pending { last_imm_was_zero: false, compound_lit_close_parens: 0, attr_maybe_unused: false, + attr_align: 0, attr_thread_local: false, attr_dllexport: false, } @@ -682,6 +731,13 @@ pub struct Compiler { /// definition. uses_alloca_in_current_fn: bool, + /// Count of C99 6.7.6.2 variable-length arrays declared so far in + /// the current function. Snapshotted around a block's declarations + /// so `parse_block_stmt` knows whether to bracket the block with + /// the alloca-arena save / restore that reclaims VLA storage on + /// exit. Reset on each new function definition. + func_vla_decls: usize, + /// True when the most recent decl-spec parse consumed an /// `inline` / `__inline` / `__inline__` keyword. Captured at /// function-symbol commit time onto `FinishedFunction::is_inline` @@ -695,6 +751,13 @@ pub struct Compiler { /// scopes to the immediately following declarator only. pending_noreturn: bool, + /// Nesting depth of unevaluated constant-expression operands + /// (short-circuited `&&` / `||` right sides and not-taken `?:` + /// arms). C99 6.6p4 forbids a zero divisor in a constant + /// expression, but an unevaluated operand must not trigger the + /// diagnostic (`1 ? 2 : 1/0` is accepted by gcc / clang). + const_unevaluated: u32, + /// Per-function AST. The arena is reset at every function /// entry; the SSA walker reads from these snapshots at codegen /// entry. @@ -775,6 +838,12 @@ pub struct Compiler { /// Number of currently-open `continue`-eligible scopes /// (loops only; `switch` doesn't open one). loop_continue_depth: usize, + /// Recursion depth shared by the recursive-descent entry points + /// (statements, expressions, constant expressions, declarators, + /// initializer lists). Bounded by `MAX_NEST_DEPTH` via + /// `with_nesting` so pathological nesting is diagnosed instead + /// of exhausting the native stack. + nest_depth: usize, /// Linear table of `(label_name, text_pc)`. Per-function (cleared /// at every function start), so it stays small -- typically 0-2 /// entries even in code that uses `goto`. Linear scan beats @@ -848,10 +917,9 @@ pub struct Compiler { /// the .tls$ callback chain on Win64). Each `_Thread_local` /// global gets `slots_of_type(ty) * 8` bytes here, with /// `Symbol::val` holding the byte offset within `tls_data`. - /// Today we don't parse TLS initialisers, so the segment is - /// always zero-filled and goes entirely into .tbss; the layout - /// leaves room for a future "initialised TLS image -> .tdata" - /// path. + /// A `_Thread_local int x = 5;` initialiser fills its slice and + /// raises `tls_init_size` so its bytes go into .tdata; an + /// uninitialised variable stays zero-filled in .tbss. tls_data: Vec, /// Number of bytes at the start of [`Self::tls_data`] that /// are statically initialised by an explicit @@ -959,6 +1027,15 @@ pub struct Compiler { /// `entry_name = None` if no entry symbol exists. no_entry_point: bool, + /// Base alignment the `.data` image requires, at least 8. Raised + /// to 16 when a file-scope object requests `_Alignas(16)`. + data_align: usize, + + /// Mirror of [`CompileOptions::implicit_extern_fns`]. An + /// undeclared call to a listed name binds as a C89 6.3.2.2 + /// implicit `extern int name();` resolved at link time. + implicit_extern_fns: Vec, + /// Mirror of [`CompileOptions::export_all_functions`]. When set, /// `resolve_exports` adds every non-static defined function to the /// export list so a `--shared` consumer can `dlsym` it. @@ -1154,7 +1231,7 @@ impl Compiler { /// Reserve `n_slots` eight-byte frame cells and return the /// negative base offset, bumping the high-water mark. Callers /// own any `multi_cell_temps` push and any `loc_offs` recycle. - fn reserve_slots(&mut self, n_slots: i64) -> i64 { + pub(super) fn reserve_slots(&mut self, n_slots: i64) -> i64 { self.loc_offs += n_slots; if self.loc_offs > self.max_loc_offs { self.max_loc_offs = self.loc_offs; @@ -1272,8 +1349,10 @@ impl Compiler { max_loc_offs: 0, multi_cell_temps: alloc::vec::Vec::new(), uses_alloca_in_current_fn: false, + func_vla_decls: 0, pending_is_inline: false, pending_noreturn: false, + const_unevaluated: 0, ast: super::ast::Ast::new(), ast_acc: None, ast_vstack: Vec::new(), @@ -1285,6 +1364,7 @@ impl Compiler { pending_local_runtime_elements: Vec::new(), loop_break_depth: 0, loop_continue_depth: 0, + nest_depth: 0, labels: Vec::new(), unresolved_gotos: Vec::new(), switch_cases: Vec::new(), @@ -1309,6 +1389,8 @@ impl Compiler { pending_store_symbols: Vec::new(), warn_dead_store: opts.warn_dead_store, no_entry_point: opts.no_entry_point, + data_align: 8, + implicit_extern_fns: opts.implicit_extern_fns.clone(), export_all_functions: opts.export_all_functions, source_files: Vec::new(), source_label: opts.source_label.clone(), @@ -1500,6 +1582,7 @@ impl Compiler { // missing headers. The force-include set only grows, and a // header already in it ends the loop, so progress is monotone. let mut infos: Vec = Vec::new(); + let mut auto_names: Vec = Vec::new(); loop { let e = match result { Ok(mut prog) => { @@ -1510,6 +1593,7 @@ impl Compiler { for info in infos.into_iter().rev() { prog.warnings.insert(0, info); } + prog.auto_includes = auto_names; return Ok(prog); } Err(e) => e, @@ -1528,6 +1612,7 @@ impl Compiler { infos.push(format!( "info: auto-including <{header}> for undeclared `{name}`" )); + auto_names.push(name); result = Compiler::with_options_inner(source.clone(), target, opts.clone(), false) .compile_one_pass(); } @@ -1559,48 +1644,21 @@ impl Compiler { // `target_ent_pc`. self.emit_sys_trampolines(); self.resolve_code_relocs()?; - // macOS resolves a `#pragma binding(data ...)` import (e.g. - // environ) through the GOT -- a flat-namespace bind to the host - // data symbol -- not through a COPY-relocated local slot, so the - // symbol must stay undefined even in a self-contained image. The - // no_entry_point clear below does this for relocatable objects; - // do the same for a data binding's local here regardless of - // no_entry_point so `live_glo_addr` returns `GloAddr::Extern` and - // routes the reference through `imm_data_extern` to the GOT - // rather than an uninitialized `.data` slot. - if self.target == Target::MacOSAarch64 { - let data_locals: alloc::collections::BTreeSet = self - .dylibs - .iter() - .flat_map(|d| d.bindings.iter()) - .filter(|b| b.is_data) - .map(|b| b.local_name.clone()) - .collect(); - for sym in self.symbols.iter_mut() { - if sym.class == Token::Glo as i64 - && sym.is_extern_decl - && !sym.has_initializer - && data_locals.contains(&sym.name) - { - sym.defined_here = false; - sym.val = 0; - } - } - } - // Cross-TU function imports. Every extern-declared - // `Token::Fun` symbol with no body in this TU gets a - // unique placeholder ent_pc (past `text.len()`), then has - // `Symbol::val` rewritten to that PC. The walker reads - // `Symbol::val` through `live_fun_val` when lowering an - // `Inst::Call`, so the matching call site carries the - // placeholder as its `target_pc`. The native codegen - // detects the placeholder (outside `[0, text.len())`) - // and emits a `RelocCallSite` against the symbol's name - // instead of resolving in place. Single-TU compiles - // without `no_entry_point` never reach this branch with - // an unresolved call: `resolve_entry_and_dllmain_pcs` - // errors out first. - let extern_imports = if self.no_entry_point { + // Cross-TU / undefined extern linkage. One model for every + // consumer: the linker resolves the references, the VM and + // the JIT refuse the unresolved ones, and no mode falls + // back to phantom storage or a colliding pc. + // + // Every extern-declared `Token::Fun` symbol with no body in + // this TU gets a unique placeholder ent_pc (past + // `text.len()`), then has `Symbol::val` rewritten to that + // PC. The walker reads `Symbol::val` through `live_fun_val` + // when lowering an `Inst::Call`, so the matching call site + // carries the placeholder as its `target_pc`. The native + // codegen detects the placeholder (outside `[0, + // text.len())`) and emits a `RelocCallSite` against the + // symbol's name instead of resolving in place. + let extern_imports = { use crate::c5::symbol::Linkage; let mut imports: alloc::vec::Vec<(usize, String)> = alloc::vec::Vec::new(); let mut next_pc = self.next_ent_pc + 1; @@ -1626,7 +1684,10 @@ impl Compiler { // walker emits `Inst::ImmData(stale_offset)` and the // ET_REL writer lowers it as a `.data section symbol + // 0` reloc, losing the symbol identity needed for - // cross-TU resolution. + // cross-TU resolution. The same clear keeps a `#pragma + // binding(data ...)` local (e.g. environ) undefined so + // its references route through the GOT / loader import + // instead of an uninitialized local slot. for sym in self.symbols.iter_mut() { if sym.class == Token::Glo as i64 && sym.linkage == Linkage::External @@ -1663,13 +1724,12 @@ impl Compiler { } } imports - } else { - alloc::vec::Vec::new() }; let (entry_pc, dllmain_pc, resolved_entry_name) = self.resolve_entry_and_dllmain_pcs()?; let exports = self.resolve_exports()?; Ok(Program { data: self.data, + data_align: self.data_align, data_object_starts: self.data_object_starts, entry_pc, warnings: self.warnings, @@ -1702,6 +1762,8 @@ impl Compiler { // CRT-recognised fallbacks (`wmain`, `WinMain`, // `wWinMain`) chosen when `main` is absent. entry_name: resolved_entry_name, + entry_pragma: self.pp_entrypoint.clone(), + auto_includes: Vec::new(), subsystem: self.pp_subsystem, // Compile output is pre-optimizer; only the explicit // `optimize()` step flips this on. diff --git a/src/c5/compiler/run_compile.rs b/src/c5/compiler/run_compile.rs index c492bc3d6..ab2a98408 100644 --- a/src/c5/compiler/run_compile.rs +++ b/src/c5/compiler/run_compile.rs @@ -25,8 +25,8 @@ use super::super::token::{Token, Ty}; use super::Compiler; use super::decl_base; use super::types::{ - UNSIGNED_BIT, format_signature, is_decl_modifier, is_pointer_ty, is_struct_ty, struct_id_of, - struct_ptr_depth, + UNSIGNED_BIT, VOLATILE_BIT, format_signature, is_decl_modifier, is_pointer_ty, is_struct_ty, + struct_id_of, struct_ptr_depth, }; impl Compiler { @@ -79,6 +79,7 @@ impl Compiler { let mut static_seen = false; let mut extern_seen = false; let mut atomic_base: Option = None; + let mut qual_bits: i64 = 0; let mut m = decl_base::IntModifiers::default(); // `_Noreturn`, `__declspec(thread)`, `__declspec(dllexport)`, and // `inline` scope to this declaration; clear the carriers so they @@ -88,6 +89,7 @@ impl Compiler { self.pending_noreturn = false; self.pending.attr_thread_local = false; self.pending.attr_dllexport = false; + self.pending.attr_align = 0; self.pending_is_inline = false; loop { if self.lex.tk == Token::ThreadLocal { @@ -126,6 +128,8 @@ impl Compiler { if self.lex.tk == Token::Noreturn { self.pending_noreturn = true; } + // `volatile` qualifies the declared type (C99 6.7.3). + qual_bits |= self.lex_volatile_bit(); self.next()?; } else { break; @@ -214,15 +218,17 @@ impl Compiler { } // Trailing qualifiers / int modifiers between the base // type and the declarators -- `Foo const *p`, `int long - // x`, etc. The base type is already chosen; these are - // pure no-ops in c5 but appear in real C source. + // x`, etc. The base type is already chosen; a trailing + // `volatile` still qualifies it (C99 6.7.3). while is_decl_modifier(self.lex.tk) { if self.lex.tk == Token::Attribute { self.skip_attribute_specifiers()?; continue; } + qual_bits |= self.lex_volatile_bit(); self.next()?; } + bt |= qual_bits; // A function-pointer typedef base type contributes its lineage // to every declarator in the list (`fn_t a, b;`). The @@ -292,6 +298,7 @@ impl Compiler { array_size = typedef_dim; } self.ty = ty; + let prior_array_size = self.symbols[id_idx].array_size; self.symbols[id_idx].array_size = array_size; if fn_ptr_indirection > 0 { self.symbols[id_idx].fn_ptr_indirection = fn_ptr_indirection; @@ -781,11 +788,13 @@ impl Compiler { // neither a specifier nor a type nor a parameter // name -- that is the function body. let mut saw_specifier = false; + let mut qual_bits: i64 = 0; while self.lex.tk == Token::FuncSpec || self.lex.tk == Token::Static || self.lex.tk == Token::Extern || self.lex.tk == Token::TypeQual { + qual_bits |= self.lex_volatile_bit(); self.next()?; saw_specifier = true; } @@ -795,7 +804,7 @@ impl Compiler { Ty::Int as i64 } else { break; - }; + } | qual_bits; while self.lex.tk != ';' && self.lex.tk != 0 { let (decl_idx, mut decl_ty, decl_arr) = self.parse_declarator(base)?; if decl_idx != usize::MAX { @@ -869,6 +878,7 @@ impl Compiler { self.labels.clear(); self.unresolved_gotos.clear(); self.uses_alloca_in_current_fn = false; + self.func_vla_decls = 0; self.ast_reset(); let ent_pc = self.next_ent_pc; @@ -957,7 +967,7 @@ impl Compiler { // float-typed code expects, and the load/store // semantics stay consistent. for &idx in params.indices.iter() { - let pty = self.symbols[idx].type_ & !UNSIGNED_BIT; + let pty = self.symbols[idx].type_ & !(UNSIGNED_BIT | VOLATILE_BIT); if pty != Ty::Float as i64 { continue; } @@ -1323,6 +1333,27 @@ impl Compiler { } else if self.symbols[id_idx].linkage != crate::c5::symbol::Linkage::Internal { self.symbols[id_idx].linkage = crate::c5::symbol::Linkage::External; } + // C11 6.7.5: a requested alignment up to 16 is + // honored on file-scope objects (the writers place + // `.data` at `Program::data_align`); anything + // larger is a diagnostic, never a silent drop. + let req_align = core::mem::take(&mut self.pending.attr_align); + if req_align > 16 { + return Err(self.compile_err(format!( + "requested alignment {req_align} exceeds the supported maximum of 16" + ))); + } + let decl_align: usize = if req_align > 8 { + if thread_local { + return Err(self.compile_err( + "alignment above 8 is not supported for `_Thread_local` objects", + )); + } + self.data_align = 16; + 16 + } else { + 8 + }; let was_extern_only_decl = extern_seen && self.lex.tk != Token::Assign && array_size != -1; // `extern struct S s;` while `struct S` is still @@ -1345,7 +1376,13 @@ impl Compiler { continue; } if was_extern_only_decl { - self.symbols[id_idx].is_extern_decl = true; + // C99 6.2.2p4 + 6.9.2p2: `extern T x;` after a + // prior file-scope definition (tentative or + // initialized) redeclares the same object; the + // definition stands. + if !self.symbols[id_idx].defined_here { + self.symbols[id_idx].is_extern_decl = true; + } } else { self.symbols[id_idx].is_extern_decl = false; // Default: a file-scope global declaration @@ -1371,8 +1408,16 @@ impl Compiler { // address against the defining TU's // storage. if extern_seen { - self.symbols[id_idx].is_extern_decl = true; - self.symbols[id_idx].defined_here = false; + // C99 6.2.2p4: after a prior definition, + // `extern T x[];` is a redeclaration of + // the same object -- the definition and + // its dimension stand. + if self.symbols[id_idx].defined_here { + self.symbols[id_idx].array_size = prior_array_size; + } else { + self.symbols[id_idx].is_extern_decl = true; + self.symbols[id_idx].defined_here = false; + } self.accept(',')?; continue; } @@ -1388,7 +1433,9 @@ impl Compiler { } let elem = self.size_of_type(ty) as i64; let aligned = ((elem + 7) / 8) * 8; - if self.size_of_type(ty) > 1 { + if decl_align > 8 { + self.align_data_to(decl_align); + } else if self.size_of_type(ty) > 1 { self.align_data_to_8(); } let off = self.data.len() as i64; @@ -1450,7 +1497,7 @@ impl Compiler { { self.symbols[id_idx].val } else { - self.align_data_to_8(); + self.align_data_to(decl_align); let fresh = self.data.len() as i64; self.symbols[id_idx].reserved_data_bytes = needed; for _ in 0..needed { @@ -1548,7 +1595,9 @@ impl Compiler { { self.symbols[id_idx].val } else { - if self.size_of_type(ty) > 1 { + if decl_align > 8 { + self.align_data_to(decl_align); + } else if self.size_of_type(ty) > 1 { self.align_data_to_8(); } let fresh = self.data.len() as i64; @@ -1622,7 +1671,9 @@ impl Compiler { } off } else { - if self.size_of_type(ty) > 1 { + if decl_align > 8 { + self.align_data_to(decl_align); + } else if self.size_of_type(ty) > 1 { self.align_data_to_8(); } let off = self.data.len() as i64; diff --git a/src/c5/compiler/sizeof_expr.rs b/src/c5/compiler/sizeof_expr.rs index 6c824d7dd..5698e5b10 100644 --- a/src/c5/compiler/sizeof_expr.rs +++ b/src/c5/compiler/sizeof_expr.rs @@ -50,6 +50,9 @@ impl Compiler { } pub(super) fn sizeof_operand_bytes(&mut self) -> Result { + // Cleared each call; set only when the operand is a VLA whose + // size the `sizeof` site must read at runtime (C99 6.5.3.4p2). + self.pending.sizeof_vla_size_slot = None; // Snapshot the lex state before any speculative paren // consumption so the operand-shape dispatch below can // restore when `sizeof (expr)->m` turns out to wrap the @@ -155,6 +158,12 @@ impl Compiler { let idx = self.lex.curr_id_idx; let var_ty = self.symbols[idx].type_; let arr = self.symbols[idx].array_size; + // C99 6.5.3.4p2: `sizeof` of a VLA is the runtime byte + // count. Signal the caller to load it from the VLA's + // size slot; the returned constant is unused in that case. + if self.symbols[idx].is_vla { + self.pending.sizeof_vla_size_slot = Some(self.symbols[idx].vla_size_slot); + } self.next()?; if arr > 0 { arr * self.size_of_type(var_ty) as i64 diff --git a/src/c5/compiler/stmt.rs b/src/c5/compiler/stmt.rs index 84bd14389..3096ca935 100644 --- a/src/c5/compiler/stmt.rs +++ b/src/c5/compiler/stmt.rs @@ -282,6 +282,19 @@ impl Compiler { if let Some(pp) = typedef_params { self.symbols[id_idx].params = pp.types; self.symbols[id_idx].is_variadic = pp.is_variadic; + } else if let Some((proto_fixed, proto_variadic)) = self.pending.typedef_fn_proto.take() + { + // `typedef RET (*NAME)(args)` at block scope: the + // declarator captured the pointee prototype. Record it + // as the file-scope branch does, so an indirect call + // through a variable of this typedef narrows arguments + // and routes a variadic tail per the host ABI. + self.symbols[id_idx].params = self + .pending + .fn_ptr_param_types + .take() + .unwrap_or_else(|| alloc::vec![0i64; proto_fixed]); + self.symbols[id_idx].is_variadic = proto_variadic; } self.accept(',')?; } @@ -333,7 +346,11 @@ impl Compiler { self.pending.base_is_function_type = base_is_function_type; self.pending.typedef_fn_proto = base_typedef_fn_proto; self.pending.fn_ptr_param_types = base_fn_ptr_param_types.clone(); + // C99 6.7.6.2: a non-constant array dimension at block scope + // is a variable-length array. + self.pending.vla_allowed = true; let (loc_idx, ty, mut array_size) = self.parse_declarator(lbt)?; + self.pending.vla_allowed = false; // C99 6.3.2.1p4: a function-pointer rvalue auto-decays // through any unary `*` chain. The `Symbol::fn_ptr_indirection` // side-channel records how many indirection levels sit between @@ -477,6 +494,10 @@ impl Compiler { let mut block_symbols = Vec::new(); let mut top_level_ids: alloc::vec::Vec = alloc::vec::Vec::new(); + // C99 6.2.4p2: a VLA declared directly in this block has its + // storage reclaimed on block exit. Track whether any appears so + // the block is bracketed with the alloca-arena save / restore. + let mut block_has_vla = false; while self.lex.tk != '}' { // C23 6.7.13 / 6.8: an attribute-specifier-sequence may // lead either a declaration or a statement at block scope. @@ -501,7 +522,11 @@ impl Compiler { } else if self.lex_is_type_start() { let item_before = self.ast_stmts_snapshot(); let sym_before = block_symbols.len(); + let vla_before = self.func_vla_decls; self.parse_block_local_decl(&mut block_symbols)?; + if self.func_vla_decls > vla_before { + block_has_vla = true; + } if leading_maybe_unused { // C23 6.7.13.5: `[[maybe_unused]]` on a declaration // suppresses the unused diagnostics for the names it @@ -534,6 +559,24 @@ impl Compiler { top_level_ids.push(item_id); } } + // C99 6.2.4p2: bracket a VLA-declaring block so the arena top + // is snapshotted on entry and restored on exit, reclaiming the + // VLA storage (per iteration when the block is a loop body). + if block_has_vla { + let save_slot = self.reserve_slots(1); + let pos = self.ast_src_pos(); + let enter = self + .ast + .push_stmt(super::super::ast::Stmt::VlaScopeEnter { save_slot }, pos); + let exit = self + .ast + .push_stmt(super::super::ast::Stmt::VlaScopeExit { save_slot }, pos); + let mut bracketed = alloc::vec::Vec::with_capacity(top_level_ids.len() + 2); + bracketed.push(enter); + bracketed.extend_from_slice(&top_level_ids); + bracketed.push(exit); + top_level_ids = bracketed; + } // Wrap the collected top-level stmt ids into a // `Stmt::Compound`. Only this Compound references the // top-level stmts -- inner wrappers are dead AST entries @@ -919,6 +962,10 @@ impl Compiler { } pub(super) fn stmt(&mut self) -> Result<(), C5Error> { + self.with_nesting("statement", |c| c.stmt_inner()) + } + + fn stmt_inner(&mut self) -> Result<(), C5Error> { // Function-pointer callee parameters captured for a postfix // indirect call never span a statement: drop any left set by a // producer whose call did not consume them so they cannot reach an diff --git a/src/c5/compiler/type_layout.rs b/src/c5/compiler/type_layout.rs index 07a3c0f01..8b6c079d0 100644 --- a/src/c5/compiler/type_layout.rs +++ b/src/c5/compiler/type_layout.rs @@ -17,8 +17,8 @@ use super::super::token::{Token, Ty}; use super::Compiler; use super::StructDef; use super::types::{ - UNSIGNED_BIT, is_pointer_ty, is_struct_ty, is_type_start_token, pointee_size_no_struct, - struct_id_of, struct_ptr_depth, + UNSIGNED_BIT, VOLATILE_BIT, is_pointer_ty, is_struct_ty, is_type_start_token, + pointee_size_no_struct, struct_id_of, struct_ptr_depth, }; impl Compiler { @@ -34,7 +34,7 @@ impl Compiler { // struct value, whose size lives in the struct table. return self.structs[struct_id_of(ptr_ty)].size as i64; } - let stripped = ptr_ty & !UNSIGNED_BIT; + let stripped = ptr_ty & !(UNSIGNED_BIT | VOLATILE_BIT); if stripped == (Ty::Long as i64) + (Ty::Ptr as i64) && self.target.is_windows() { return 4; } @@ -173,7 +173,7 @@ impl Compiler { // Unsigned bit is orthogonal to width: `unsigned char` is // still 1 byte, `unsigned int` is still 4 bytes. Strip it // before consulting the band identity. - let ty = ty & !UNSIGNED_BIT; + let ty = ty & !(UNSIGNED_BIT | VOLATILE_BIT); if is_struct_ty(ty) { if struct_ptr_depth(ty) > 0 { 8 @@ -215,7 +215,7 @@ impl Compiler { /// alignment of their fields, but c5 currently caps struct /// alignment at 8 to match the rest of the IR's slot model. pub(super) fn align_of_type(&self, ty: i64) -> usize { - let ty = ty & !UNSIGNED_BIT; + let ty = ty & !(UNSIGNED_BIT | VOLATILE_BIT); if ty == Ty::Float as i64 { // `float` is 4 bytes; its natural alignment matches. // Same rule the rest of the integer / pointer family @@ -270,7 +270,7 @@ fn flat_scalar_size(ty: i64, target: Target) -> u32 { if is_pointer_ty(ty) { return 8; } - let bare = ty & !UNSIGNED_BIT; + let bare = ty & !(UNSIGNED_BIT | VOLATILE_BIT); if bare == Ty::Bool as i64 || bare == Ty::Char as i64 { 1 } else if bare == Ty::Short as i64 { @@ -319,7 +319,7 @@ pub(crate) fn flatten_struct_fields( if is_struct_value { flatten_struct_fields(structs, target, struct_id_of(elem_ty), off, out); } else { - let bare = elem_ty & !UNSIGNED_BIT; + let bare = elem_ty & !(UNSIGNED_BIT | VOLATILE_BIT); let kind = if is_pointer_ty(elem_ty) { ScalarKind::Int } else if bare == Ty::Float as i64 { diff --git a/src/c5/compiler/types.rs b/src/c5/compiler/types.rs index 6dc052a80..688c63f40 100644 --- a/src/c5/compiler/types.rs +++ b/src/c5/compiler/types.rs @@ -66,6 +66,22 @@ pub(crate) fn is_unsigned_ty(ty: i64) -> bool { (ty & UNSIGNED_BIT) != 0 } +/// High-bit flag marking a type tag `volatile`-qualified (C99 6.7.3). +/// Orthogonal to the band scheme like [`UNSIGNED_BIT`]: stripped by +/// [`strip_unsigned`] before any band classifier consults the tag. The +/// single bit does not record which indirection level carries the +/// qualifier, so `volatile T *`, `T * volatile`, and `volatile T` +/// all set it; every access through such a tag is treated as a +/// volatile access (a conservative over-approximation -- extra +/// volatility only inhibits optimization, per 5.1.2.3p2 an access to +/// a volatile object may not be elided or coalesced). +pub(crate) const VOLATILE_BIT: i64 = 1 << 29; + +/// `true` if `ty` carries the volatile qualifier at any level. +pub(crate) fn is_volatile_ty(ty: i64) -> bool { + (ty & VOLATILE_BIT) != 0 +} + /// Apply a C99 6.3.1.3 integer conversion to a constant value: /// narrow to `bytes` width and re-interpret by the target's /// signedness. `_Bool` maps any nonzero value to 1 (6.3.1.2). An @@ -91,14 +107,14 @@ pub(crate) fn narrow_const_int(bytes: usize, unsigned: bool, is_bool: bool, v: i } } -/// Drop the unsigned bit. Use to recover the bare band-encoded type -/// before consulting a helper that classifies by band. Most of the -/// helpers in this module call this at their entry; outside callers -/// only need it when storing a type tag where a non-bit-flagged tag -/// is expected (e.g., switch-table comparisons against `Ty::Int as -/// i64`). +/// Drop the qualifier bits (`UNSIGNED_BIT`, `VOLATILE_BIT`). Use to +/// recover the bare band-encoded type before consulting a helper that +/// classifies by band. Most of the helpers in this module call this at +/// their entry; outside callers only need it when storing a type tag +/// where a non-bit-flagged tag is expected (e.g., switch-table +/// comparisons against `Ty::Int as i64`). pub(crate) fn strip_unsigned(ty: i64) -> i64 { - ty & !UNSIGNED_BIT + ty & !(UNSIGNED_BIT | VOLATILE_BIT) } /// Round `x` up to the nearest multiple of `alignment` (which must @@ -649,7 +665,7 @@ mod ty_tag { // `is_pointer_ty`. The base band ([0, 100): char / int) admits any // offset >= Ty::Ptr; every other band reserves even offsets. fn pointer_by_even_stride(ty: i64) -> bool { - let stripped = ty & !UNSIGNED_BIT; + let stripped = ty & !(UNSIGNED_BIT | VOLATILE_BIT); let base = stripped - (stripped % 100); let off = stripped - base; if base == 0 { diff --git a/src/c5/error.rs b/src/c5/error.rs index 7f3e3f915..1df4f4572 100644 --- a/src/c5/error.rs +++ b/src/c5/error.rs @@ -63,11 +63,11 @@ pub(crate) fn fmt_internal_err(message: &str) -> String { /// malformed archives). These describe a problem with the user's /// command line or sources -- not a c5 bug -- so they MUST NOT /// carry the `internal compiler error:` marker. Mirrors ld / -/// gold's "error:" prefix. Gated to the `full` feature -- the -/// only caller lives in the linker module, so under +/// gold's "error:" prefix. Gated to `native-emit` -- the callers +/// live in the linker module and the final-image writers, so under /// `--no-default-features --lib` this helper would otherwise /// trip the dead-code lint. -#[cfg(feature = "full")] +#[cfg(any(feature = "native-emit", feature = "std"))] pub(crate) fn fmt_link_err(message: &str) -> String { use alloc::format; format!("error: {message}") diff --git a/src/c5/headers.rs b/src/c5/headers.rs index c9067dd88..85b113b7f 100644 --- a/src/c5/headers.rs +++ b/src/c5/headers.rs @@ -90,6 +90,10 @@ pub(super) const EMBEDDED_HEADERS: &[(&str, &str)] = &[ ("assert.h", include_str!("../../headers/include/assert.h")), ("time.h", include_str!("../../headers/include/time.h")), ("utime.h", include_str!("../../headers/include/utime.h")), + ( + "sys/utime.h", + include_str!("../../headers/include/sys/utime.h"), + ), ("netdb.h", include_str!("../../headers/include/netdb.h")), ( "sys/utsname.h", @@ -130,6 +134,26 @@ pub(super) const EMBEDDED_HEADERS: &[(&str, &str)] = &[ ("sys/uio.h", include_str!("../../headers/include/sys/uio.h")), ("sys/un.h", include_str!("../../headers/include/sys/un.h")), ("net/if.h", include_str!("../../headers/include/net/if.h")), + ( + "net/ethernet.h", + include_str!("../../headers/include/net/ethernet.h"), + ), + ( + "sys/file.h", + include_str!("../../headers/include/sys/file.h"), + ), + ( + "sys/cdefs.h", + include_str!("../../headers/include/sys/cdefs.h"), + ), + ( + "CoreFoundation/CoreFoundation.h", + include_str!("../../headers/include/CoreFoundation/CoreFoundation.h"), + ), + ( + "SystemConfiguration/SCDynamicStoreCopySpecific.h", + include_str!("../../headers/include/SystemConfiguration/SCDynamicStoreCopySpecific.h"), + ), ( "sys/attr.h", include_str!("../../headers/include/sys/attr.h"), @@ -162,10 +186,30 @@ pub(super) const EMBEDDED_HEADERS: &[(&str, &str)] = &[ "mach/mach.h", include_str!("../../headers/include/mach/mach.h"), ), + ( + "mach/task.h", + include_str!("../../headers/include/mach/task.h"), + ), + ( + "sysexits.h", + include_str!("../../headers/include/sysexits.h"), + ), + ( + "sys/sys_domain.h", + include_str!("../../headers/include/sys/sys_domain.h"), + ), + ( + "sys/sysctl.h", + include_str!("../../headers/include/sys/sysctl.h"), + ), ( "mach-o/dyld.h", include_str!("../../headers/include/mach-o/dyld.h"), ), + ( + "mach-o/loader.h", + include_str!("../../headers/include/mach-o/loader.h"), + ), ( "sys/stat.h", include_str!("../../headers/include/sys/stat.h"), @@ -189,6 +233,38 @@ pub(super) const EMBEDDED_HEADERS: &[(&str, &str)] = &[ "linux/random.h", include_str!("../../headers/include/linux/random.h"), ), + ( + "linux/auxvec.h", + include_str!("../../headers/include/linux/auxvec.h"), + ), + ( + "linux/fs.h", + include_str!("../../headers/include/linux/fs.h"), + ), + ( + "linux/sched.h", + include_str!("../../headers/include/linux/sched.h"), + ), + ( + "linux/wait.h", + include_str!("../../headers/include/linux/wait.h"), + ), + ( + "linux/memfd.h", + include_str!("../../headers/include/linux/memfd.h"), + ), + ( + "linux/limits.h", + include_str!("../../headers/include/linux/limits.h"), + ), + ( + "sys/auxv.h", + include_str!("../../headers/include/sys/auxv.h"), + ), + ( + "sys/pidfd.h", + include_str!("../../headers/include/sys/pidfd.h"), + ), ("pty.h", include_str!("../../headers/include/pty.h")), ("utmp.h", include_str!("../../headers/include/utmp.h")), ( @@ -264,7 +340,46 @@ pub(super) const EMBEDDED_HEADERS: &[(&str, &str)] = &[ include_str!("../../headers/include/semaphore.h"), ), ("dlfcn.h", include_str!("../../headers/include/dlfcn.h")), + ("fenv.h", include_str!("../../headers/include/fenv.h")), + ("io.h", include_str!("../../headers/include/io.h")), + ("direct.h", include_str!("../../headers/include/direct.h")), + ("intrin.h", include_str!("../../headers/include/intrin.h")), + ("bcrypt.h", include_str!("../../headers/include/bcrypt.h")), + ( + "TargetConditionals.h", + include_str!("../../headers/include/TargetConditionals.h"), + ), + ( + "AvailabilityMacros.h", + include_str!("../../headers/include/AvailabilityMacros.h"), + ), + ("os/log.h", include_str!("../../headers/include/os/log.h")), + ("os/lock.h", include_str!("../../headers/include/os/lock.h")), + ( + "crt_externs.h", + include_str!("../../headers/include/crt_externs.h"), + ), ("windows.h", include_str!("../../headers/include/windows.h")), + ("winbase.h", include_str!("../../headers/include/winbase.h")), + ( + "winioctl.h", + include_str!("../../headers/include/winioctl.h"), + ), + ("pathcch.h", include_str!("../../headers/include/pathcch.h")), + ("psapi.h", include_str!("../../headers/include/psapi.h")), + ( + "versionhelpers.h", + include_str!("../../headers/include/versionhelpers.h"), + ), + ("crtdbg.h", include_str!("../../headers/include/crtdbg.h")), + ("aclapi.h", include_str!("../../headers/include/aclapi.h")), + ("lmcons.h", include_str!("../../headers/include/lmcons.h")), + ("sddl.h", include_str!("../../headers/include/sddl.h")), + ("shlwapi.h", include_str!("../../headers/include/shlwapi.h")), + ( + "sys/locking.h", + include_str!("../../headers/include/sys/locking.h"), + ), ( "wincrypt.h", include_str!("../../headers/include/wincrypt.h"), diff --git a/src/c5/ir.rs b/src/c5/ir.rs index 682661fdf..956127439 100644 --- a/src/c5/ir.rs +++ b/src/c5/ir.rs @@ -79,29 +79,41 @@ pub(crate) enum Inst { /// Load from `addr + disp`. Width / signedness driven by the /// source load op. `disp` is a byte offset folded from a constant /// pointer addition (a struct field offset) into the addressing - /// mode; it is zero for a plain dereference. + /// mode; it is zero for a plain dereference. `volatile` marks an + /// access to a volatile-qualified object (C99 6.7.3p6): the load + /// must be performed strictly per the abstract machine, so no pass + /// may delete, duplicate, or forward it (5.1.2.3p2). Load { addr: ValueId, disp: i32, kind: LoadKind, + volatile: bool, }, /// Store to `addr + disp`. The c5 semantics leave the stored value /// in the accumulator afterward; downstream uses of this /// instruction's id read that value. `disp` is a byte offset folded /// from a constant pointer addition, zero for a plain dereference. + /// `volatile` as for [`Self::Load`]. Store { addr: ValueId, disp: i32, value: ValueId, kind: StoreKind, + volatile: bool, }, /// Load from a local / parameter slot. Equivalent to a /// `LocalAddr(off)` followed by `Load { kind }`, but /// represented as a single instruction so the per-arch emit /// folds the address into the load's addressing mode and /// the allocator does not need to assign a register to the - /// intermediate address. - LoadLocal { off: i64, kind: LoadKind }, + /// intermediate address. `volatile` as for [`Self::Load`]; a + /// slot with any volatile access also stays out of mem2reg + /// promotion and slot coalescing. + LoadLocal { + off: i64, + kind: LoadKind, + volatile: bool, + }, /// Store to a local / parameter slot. Same shape as /// [`Self::Store`] but with the address represented as a /// constant slot offset, so the emit folds it into the @@ -110,6 +122,7 @@ pub(crate) enum Inst { off: i64, value: ValueId, kind: StoreKind, + volatile: bool, }, /// Load from `base + index * scale`. Folded form of /// `Add(base, Mul/Shl(index, scale))` followed by a `Load`, @@ -117,7 +130,8 @@ pub(crate) enum Inst { /// (`ldr Wt, [Xn, Xm, lsl #log2(scale)]` on aarch64, scaled /// SIB on x86_64). `scale` is in bytes and matches the /// natural width of `kind` (1 for I8/U8, 2 for I16/U16, 4 for - /// I32/U32, 8 for I64). + /// I32/U32, 8 for I64). Carries no volatile flag: `index_fold` + /// leaves volatile accesses on the plain `Load` / `Store` forms. LoadIndexed { base: ValueId, index: ValueId, @@ -281,6 +295,9 @@ pub(crate) enum Inst { /// (control transfers out). TailExt(i64), /// Whole-struct memory copy. + /// TODO: carries no volatile flag; a copy of a volatile-qualified + /// aggregate (C99 6.7.3p6) is not marked. Scalar volatile + /// accesses ride `Load` / `Store`, which cover the defined uses. Mcpy { dst: ValueId, src: ValueId, diff --git a/src/c5/lexer.rs b/src/c5/lexer.rs index 47f97a6d2..37c9ee851 100644 --- a/src/c5/lexer.rs +++ b/src/c5/lexer.rs @@ -943,6 +943,24 @@ impl Lexer { items } + /// Consume the C99 6.4.4.1 integer suffix (`u`/`U` and one or two + /// `l`/`L` in any combination) and record it in the suffix fields + /// the expression parser types the literal from. Shared by every + /// integer base so no base drops the suffix. + fn lex_int_suffix(&mut self) { + let mut l_count: u8 = 0; + let mut u_seen = false; + while self.pos < self.src.len() && matches!(self.src[self.pos], b'u' | b'U' | b'l' | b'L') { + match self.src[self.pos] { + b'l' | b'L' => l_count = l_count.saturating_add(1), + _ => u_seen = true, + } + self.pos += 1; + } + self.int_suffix_long = l_count.min(2); + self.int_suffix_unsigned = u_seen; + } + /// Finalise a numeric constant: a digit/suffix run must not be /// immediately followed by an identifier character. `1_000`, /// `0x1_0000`, `1.0q` are invalid preprocessing numbers (C99 6.4.8) @@ -1071,15 +1089,17 @@ impl Lexer { && self.pos < self.src.len() && (b'0'..=b'7').contains(&self.src[self.pos]) { + // Accumulate via wrapping_mul / wrapping_add so a + // full 64-bit octal pattern (the spelling of + // ULLONG_MAX) does not trip debug-build overflow + // detection; the type picker types it per C99 + // 6.4.4.1 from the wrapped bit pattern. while self.pos < self.src.len() && (b'0'..=b'7').contains(&self.src[self.pos]) { - val = val * 8 + (self.src[self.pos] - b'0') as i64; - self.pos += 1; - } - while self.pos < self.src.len() - && matches!(self.src[self.pos], b'u' | b'U' | b'l' | b'L') - { + let digit = (self.src[self.pos] - b'0') as i64; + val = val.wrapping_mul(8).wrapping_add(digit); self.pos += 1; } + self.lex_int_suffix(); self.ival = val; self.tk = Tok(Token::Num as i64); self.int_is_decimal = false; @@ -1116,11 +1136,7 @@ impl Lexer { ), ))); } - while self.pos < self.src.len() - && matches!(self.src[self.pos], b'u' | b'U' | b'l' | b'L') - { - self.pos += 1; - } + self.lex_int_suffix(); self.ival = val; self.tk = Tok(Token::Num as i64); self.int_is_decimal = false; @@ -1176,30 +1192,9 @@ impl Lexer { &format!("{}: hex literal `0x` has no digits", self.line), ))); } - // Hex literals can carry the standard integer suffix - // letters (u/U/l/L plus ll/LL combinations such as - // 0xFFFFULL). Per C99 6.4.4.1 record the longness - // (one or two `l`/`L`) and the unsigned modifier - // so the expression parser can type the literal - // accordingly; without that the literal would - // default to `int` and any arithmetic that - // assumes 64-bit width truncates to 32. - let mut l_count: u8 = 0; - let mut u_seen = false; - while self.pos < self.src.len() - && matches!(self.src[self.pos], b'u' | b'U' | b'l' | b'L') - { - match self.src[self.pos] { - b'l' | b'L' => l_count = l_count.saturating_add(1), - b'u' | b'U' => u_seen = true, - _ => {} - } - self.pos += 1; - } + self.lex_int_suffix(); self.ival = val; self.tk = Tok(Token::Num as i64); - self.int_suffix_long = l_count.min(2); - self.int_suffix_unsigned = u_seen; self.int_is_decimal = false; return self.end_number(); } @@ -1225,29 +1220,13 @@ impl Lexer { // (1u, 1L, 1ULL, 1lu, ...). When any suffix letter is // present, the literal is unambiguously an integer -- // no float-suffix `f`/`F` can follow because the - // standard doesn't allow it on integer literals. Per - // C99 6.4.4.1, count consecutive `l`/`L` characters - // (one => long, two => long long) and note any - // `u`/`U` for the unsigned modifier. + // standard doesn't allow it on integer literals. if self.pos < self.src.len() && matches!(self.src[self.pos], b'u' | b'U' | b'l' | b'L') { - let mut l_count: u8 = 0; - let mut u_seen = false; - while self.pos < self.src.len() - && matches!(self.src[self.pos], b'u' | b'U' | b'l' | b'L') - { - match self.src[self.pos] { - b'l' | b'L' => l_count = l_count.saturating_add(1), - b'u' | b'U' => u_seen = true, - _ => {} - } - self.pos += 1; - } + self.lex_int_suffix(); self.ival = val; self.tk = Tok(Token::Num as i64); - self.int_suffix_long = l_count.min(2); - self.int_suffix_unsigned = u_seen; return self.end_number(); } @@ -1684,8 +1663,34 @@ impl Lexer { _ => { if "!~;{}()],:".contains(c) { self.tk = Tok(c as i64); - } else { + } else if matches!(c, ' ' | '\t' | '\r' | '\x0B' | '\x0C' | '\0') { + // C99 6.4p3 white-space characters separate + // tokens and are otherwise ignored. A NUL is + // ignored too, following gcc. continue; + } else if c as u32 == 0xEF + && self.src.get(self.pos) == Some(&0xBB) + && self.src.get(self.pos + 1) == Some(&0xBF) + { + // UTF-8 byte-order mark; accepted and + // skipped, following gcc and clang. + self.pos += 2; + continue; + } else { + // Any other byte cannot start a + // preprocessing token (C99 6.4); dropping + // it would let the parse re-synchronize + // into a different program. + let shown = if c.is_ascii_graphic() { + format!("`{c}`") + } else { + format!("byte 0x{:02X}", c as u32) + }; + return Err(C5Error::Compile(crate::c5::error::fmt_compile_err( + &self.file, + self.line, + &format!("unrecognized character {shown} in source"), + ))); } } } @@ -2097,6 +2102,40 @@ mod tests { lex.ival } + /// Drive the lexer over `src` until EOF or the first error. + fn lex_all(src: &str) -> Result<(), C5Error> { + let mut lex = Lexer::new(src.to_string()); + let mut symbols: Vec = Vec::new(); + let mut index = SymbolIndex::new(); + let mut data: Vec = Vec::new(); + loop { + lex.next(&mut symbols, &mut index, &mut data)?; + if lex.tk == Tok::EOF { + return Ok(()); + } + } + } + + #[test] + fn unrecognized_bytes_are_lex_errors() { + // A byte that cannot start a preprocessing token (C99 6.4) must + // be diagnosed, not dropped -- `*$p` re-synchronizing as `*p` + // compiles a different program. + for (src, shown) in [ + ("int b = *$p;", "`$`"), + ("int a = `3`;", "``"), + ("int a @ b;", "`@`"), + ("int caf\u{e9};", "byte 0xC3"), + ] { + let err = lex_all(src).expect_err(src); + assert!(format!("{err}").contains(shown), "{src}: {err}"); + } + // White-space characters and a leading UTF-8 BOM are not errors, + // and literals keep their bytes. + lex_all("\u{feff}int x;\x0C int \x0B y;").unwrap(); + lex_all("const char *s = \"caf\u{e9} $ @\";").unwrap(); + } + #[test] fn simple_escapes_decode_to_their_byte() { assert_eq!(lex_string_literal(r#""\n""#), vec![b'\n']); diff --git a/src/c5/linker/image.rs b/src/c5/linker/image.rs index 580eb39d6..eed2d7912 100644 --- a/src/c5/linker/image.rs +++ b/src/c5/linker/image.rs @@ -1033,6 +1033,7 @@ mod tests { // x86_64: `mov eax, 42; ret` -- minimal main body. text: alloc::vec![0xb8, 0x2a, 0x00, 0x00, 0x00, 0xc3], data: alloc::vec![], + data_align: 8, bss_size: 0, defined, imports: alloc::vec![], diff --git a/src/c5/linker/link.rs b/src/c5/linker/link.rs index 62e015c36..b512f1d0e 100644 --- a/src/c5/linker/link.rs +++ b/src/c5/linker/link.rs @@ -49,6 +49,10 @@ pub struct MergedNative { pub text: Vec, /// Concatenated `.data` bytes. pub data: Vec, + /// Base alignment the merged `.data` requires: the largest input + /// section alignment, at least 8. The image writers place the + /// data stream at a multiple of this. + pub data_align: usize, /// Sum of every unit's `.bss` size. The final-image writer /// emits a single `.bss` of this size; no file bytes. pub bss_size: usize, @@ -157,8 +161,10 @@ pub struct MergedNative { /// the result in little-endian over `width` bytes. pub debug_info_text_relocs: Vec, pub debug_line_text_relocs: Vec, - /// Per-function post-prologue byte offset in [`Self::text`]. - /// Sourced from the writer's synthetic + /// Post-prologue byte offset in [`Self::text`], keyed by the + /// function's merged entry offset (name-keying would collapse + /// same-named statics across units onto one anchor). Sourced + /// from the writer's synthetic /// `.Lc5_prologue_end_` STB_LOCAL STT_NOTYPE symbols /// (see `elf_reloc::PROLOGUE_END_PREFIX`), rebased by the /// per-unit text base. The synth path consults this to @@ -166,7 +172,7 @@ pub struct MergedNative { /// `dwarf::build_debug_frame` emits /// `DW_CFA_advance_loc ` ahead of the /// post-prologue CFA rule. - pub prologue_ends: BTreeMap, + pub prologue_ends: BTreeMap, /// Defined `STT_FUNC STB_LOCAL` (static) functions as /// `(name, merged_text_offset)`, rebased by the per-unit text base. /// Kept as a flat list separate from `defined` -- which is @@ -296,9 +302,10 @@ pub fn link_native_objects_with_options( // the same through `NT_BADC_ELF_TPOFF` fixups resolved in Pass 4.1 // below (x86_64 variant-2 `sub imm32`, Linux/aarch64 variant-1 `add // imm12`, Windows/aarch64 TEB-indexed `add imm12`), so a multi-unit - // link rebases each access against the merged layout. A same-unit - // access on the Windows TEB path with no cross-unit reference carries - // no fixup and keeps its baked single-unit offset. + // link rebases each access against the merged layout. On the + // Windows/aarch64 TEB path both a unit-local and an extern access + // record a fixup, so a unit-local offset is rebased by its unit's + // base in the merged block rather than kept as a baked offset. let uses_tlv = objs.iter().any(|o| { !o.macho_tlv_descriptors.is_empty() || !o.macho_tlv_fixups.is_empty() @@ -357,24 +364,36 @@ pub fn link_native_objects_with_options( // Pass 1 -- layout. Compute each unit's `.text` / `.data` / // `.bss` base in the merged image. 16-byte alignment for // `.text` (matches the writer's section header) and 8-byte - // for `.data` / `.bss`. + // for `.data` / `.bss`, raised to a unit's own data alignment + // (a foreign object's high-align sections, e.g. `.rodata.cst16`). let mut text_bases: Vec = Vec::with_capacity(objs.len()); let mut data_bases: Vec = Vec::with_capacity(objs.len()); let mut bss_bases: Vec = Vec::with_capacity(objs.len()); let mut text: Vec = Vec::new(); let mut data: Vec = Vec::new(); let mut bss_size: usize = 0; + let mut data_align: usize = 8; for obj in objs { align_up(&mut text, 16); text_bases.push(text.len()); text.extend_from_slice(&obj.text); - align_up(&mut data, 8); + align_up(&mut data, obj.data_align.max(8)); + data_align = data_align.max(obj.data_align); data_bases.push(data.len()); data.extend_from_slice(&obj.data); - bss_size = align_usize(bss_size, 8); + // Each unit's bss offsets carry an alignment residue modulo 16 + // (the `.bss` sh_addralign the per-unit writer claims); a + // 16-aligned unit base preserves it. + bss_size = align_usize(bss_size, 16); bss_bases.push(bss_size); bss_size += obj.bss_size; } + // The merged bss region begins at `data.len()` in the unified + // data-offset space; pad the file image so bss offsets keep their + // per-unit alignment residues in the final image. + if bss_size > 0 { + align_up(&mut data, data_align.max(16)); + } // Pass 2 -- defined symbols. Every `STB_GLOBAL` symbol that // lives in a `.text` / `.data` / `.bss` section in some @@ -440,10 +459,12 @@ pub fn link_native_objects_with_options( // STB_LOCAL STT_NOTYPE symbol per function at the post- // prologue native byte offset, named with the // `PROLOGUE_END_PREFIX` prefix; rebase its value by the - // unit's text base and key it on the source function name - // (the suffix). Duplicate names lose to the first writer - // (matches the `defined` rule for STB_GLOBAL above). - let mut prologue_ends: BTreeMap = BTreeMap::new(); + // unit's text base and key it on the *same unit's* function + // entry offset. Name-keying would hand a later unit's + // same-named static the first unit's anchor, describing a + // framed function as frameless in the Win-x64 .pdata / DWARF + // CFA output. + let mut prologue_ends: BTreeMap = BTreeMap::new(); for (i, obj) in objs.iter().enumerate() { for sym in &obj.symbols { if !matches!(sym.section, NativeSymSection::Text) { @@ -455,10 +476,16 @@ pub fn link_native_objects_with_options( if fn_name.is_empty() { continue; } - let merged_offset = text_bases[i] as u64 + sym.value; - prologue_ends - .entry(fn_name.to_string()) - .or_insert(merged_offset); + // STT_FUNC = 2. + let Some(fsym) = obj.symbols.iter().find(|s| { + s.kind == 2 && matches!(s.section, NativeSymSection::Text) && s.name == fn_name + }) else { + continue; + }; + prologue_ends.insert( + text_bases[i] as u64 + fsym.value, + text_bases[i] as u64 + sym.value, + ); } } @@ -544,6 +571,15 @@ pub fn link_native_objects_with_options( // (Mach-O). The PLT pass consults this to skip stub creation. let mut data_import_indices: alloc::collections::BTreeSet = alloc::collections::BTreeSet::new(); + // Names with dylib routing from any unit's binding map. The c5 `.o` + // writer emits its libc imports as STB_WEAK UNDEF paired with a map + // entry; a weak UNDEF *without* routing is a genuine unresolved weak + // reference (typically from a foreign object) and resolves to + // address 0 per ELF practice rather than becoming a required import. + let routed_import_names: alloc::collections::BTreeSet<&str> = objs + .iter() + .flat_map(|o| o.import_dylib_map.iter().map(|(n, _)| n.as_str())) + .collect(); let record_import = |name: &str, imports: &mut Vec, idx_for_name: &mut BTreeMap| @@ -690,6 +726,23 @@ pub fn link_native_objects_with_options( // so the writer binds the host symbol through the GOT, // rather than rejecting it as unresolved. let is_data_binding = data_binding_locals.contains(&sym.name); + // STB_WEAK = 2. An unresolved weak reference with + // no dylib routing resolves to address 0 (C + // practice; ELF leaves the symbol 0 so the + // `if (fn) fn();` guard idiom skips the call). + if sym.binding == 2 + && !is_data_binding + && !routed_import_names.contains(sym.name.as_str()) + { + resolve_weak_undef_to_zero( + machine, + &mut text, + patch_offset, + reloc, + &sym.name, + )?; + continue; + } if sym.binding == 1 && !allow_undefined && !is_data_binding { return Err(link_err(&format!( "undefined reference to `{}`", @@ -891,12 +944,33 @@ pub fn link_native_objects_with_options( // Pass 2.5 and join `defined` with section // == Bss; the lookup is the same as for an // Undef cross-unit reference. - defined.get(&sym.name).map(|d| d.section).ok_or_else(|| { - link_err(&format!( - "undefined reference to `{}` (data initializer)", - sym.name, - )) - })? + match defined.get(&sym.name) { + Some(d) => d.section, + // An unresolved weak reference in a data + // initializer takes the absolute value + // 0 + addend (ELF behavior); patch the + // slot now, no reloc survives. + None if sym.binding == 2 + && !routed_import_names.contains(sym.name.as_str()) => + { + let slot = slot_offset as usize; + if slot + 8 > data.len() { + return Err(err(&format!( + "weak data reloc slot 0x{slot:x} past end of data (len {})", + data.len(), + ))); + } + data[slot..slot + 8] + .copy_from_slice(&(reloc.addend as u64).to_le_bytes()); + continue; + } + None => { + return Err(link_err(&format!( + "undefined reference to `{}` (data initializer)", + sym.name, + ))); + } + } } NativeSymSection::Tls => { return Err(link_err(&format!( @@ -978,23 +1052,43 @@ pub fn link_native_objects_with_options( } // Build the merged import->dylib map. Each unit's per-import // dylib_index is local to that unit's `dylibs` list; translate - // through `merged_idx_for[unit_idx][per_unit_idx]` so the value - // refers to the merged `dylibs` order. First entry per import - // name wins -- a sibling unit redeclaring the same name picks - // up the same dylib through cross-TU resolution anyway. + // through `local_to_merged` so the value refers to the merged + // `dylibs` order. Two units routing the same import to different + // dylibs is a conflict: whichever entry won, the loser's calls + // would bind against the wrong library, so reject it. let mut import_dylib_map: BTreeMap = BTreeMap::new(); - for obj in objs { + for (i, obj) in objs.iter().enumerate() { let mut local_to_merged: Vec = Vec::with_capacity(obj.dylibs.len()); for d in &obj.dylibs { - let merged_idx = dylibs.iter().position(|m| m == d).unwrap_or(0) as u32; + // The merged list was built from these same entries above, + // so the position lookup cannot miss. + let merged_idx = dylibs + .iter() + .position(|m| m == d) + .expect("merged dylib list contains every per-unit path") + as u32; local_to_merged.push(merged_idx); } for (name, idx) in &obj.import_dylib_map { - if import_dylib_map.contains_key(name) { - continue; + let merged_idx = local_to_merged.get(*idx as usize).copied().ok_or_else(|| { + link_err(&format!( + "object {i}: import `{name}` routes to dylib index {idx} \ + out of range ({} dylibs declared)", + obj.dylibs.len(), + )) + })?; + match import_dylib_map.get(name) { + None => { + import_dylib_map.insert(name.clone(), merged_idx); + } + Some(&prev) if prev == merged_idx => {} + Some(&prev) => { + return Err(link_err(&format!( + "import `{name}` routed to `{}` by one object and `{}` by another", + dylibs[prev as usize], dylibs[merged_idx as usize], + ))); + } } - let merged_idx = local_to_merged.get(*idx as usize).copied().unwrap_or(0); - import_dylib_map.insert(name.clone(), merged_idx); } } @@ -1172,6 +1266,7 @@ pub fn link_native_objects_with_options( Ok(MergedNative { text, data, + data_align, bss_size, defined, imports, @@ -1567,6 +1662,96 @@ pub fn emit_aarch64_plt(merged: &mut MergedNative) -> Result, // ---- Reloc application ---- +/// Resolve a reference to an unresolved STB_WEAK UNDEF symbol to +/// address 0 (ELF behavior for a weak reference nothing on the link +/// line satisfies). A branch becomes a no-op, matching the GNU +/// linkers' AArch64 handling of branches to undefined weak symbols; +/// an address-materializing instruction is rewritten to produce the +/// constant 0 so the `if (fn) fn();` guard idiom reads a null +/// pointer. Instruction shapes outside the supported set are a +/// diagnostic, never a silent import. +fn resolve_weak_undef_to_zero( + machine: NativeMachine, + text: &mut [u8], + patch_offset: usize, + reloc: &NativeReloc, + name: &str, +) -> Result<(), C5Error> { + let unsupported = |what: &str| { + err(&format!( + "unresolved weak reference to `{name}`: cannot resolve {what} to address 0", + )) + }; + if patch_offset + .checked_add(4) + .is_none_or(|end| end > text.len()) + { + return Err(err(&format!( + "relocation patch offset 0x{patch_offset:x} past end of text (len {})", + text.len(), + ))); + } + const AARCH64_NOP: u32 = 0xd503_201f; + match (machine, reloc.rtype) { + (NativeMachine::Aarch64, R_AARCH64_CALL26) => { + text[patch_offset..patch_offset + 4].copy_from_slice(&AARCH64_NOP.to_le_bytes()); + Ok(()) + } + (NativeMachine::Aarch64, R_AARCH64_ADR_PREL_PG_HI21) => { + // `adrp xd, ` -> `movz xd, #0`. + let instr = + u32::from_le_bytes(text[patch_offset..patch_offset + 4].try_into().unwrap()); + let rd = instr & 0x1f; + let movz = 0xd280_0000 | rd; + text[patch_offset..patch_offset + 4].copy_from_slice(&movz.to_le_bytes()); + Ok(()) + } + (NativeMachine::Aarch64, R_AARCH64_ADD_ABS_LO12_NC) => { + // The pair's ADRP already produced 0 in `xn`; keep the + // destination 0 whether or not it aliases the source. + let instr = + u32::from_le_bytes(text[patch_offset..patch_offset + 4].try_into().unwrap()); + let rd = instr & 0x1f; + let rn = (instr >> 5) & 0x1f; + let repl = if rd == rn { + AARCH64_NOP + } else { + 0xd280_0000 | rd + }; + text[patch_offset..patch_offset + 4].copy_from_slice(&repl.to_le_bytes()); + Ok(()) + } + (NativeMachine::X86_64, R_X86_64_PLT32) | (NativeMachine::X86_64, R_X86_64_PC32) => { + // `r_offset` names the disp32 field; classify by the + // instruction bytes ahead of it. + if patch_offset >= 1 && text[patch_offset - 1] == 0xE8 { + // `call rel32` -> 5-byte NOP (0F 1F 44 00 00). + text[patch_offset - 1..patch_offset + 4] + .copy_from_slice(&[0x0F, 0x1F, 0x44, 0x00, 0x00]); + return Ok(()); + } + if patch_offset >= 3 + && (0x40..=0x4f).contains(&text[patch_offset - 3]) + && text[patch_offset - 2] == 0x8D + && text[patch_offset - 1] & 0xC7 == 0x05 + { + // `lea reg, [rip+disp32]` -> `mov reg, 0` (C7 /0 + // imm32). The modrm reg field moves to rm, so the + // REX.R bit becomes REX.B; REX.W carries over. + let rex = text[patch_offset - 3]; + let reg = (text[patch_offset - 1] >> 3) & 0x7; + text[patch_offset - 3] = 0x40 | (rex & 0x08) | ((rex & 0x04) >> 2); + text[patch_offset - 2] = 0xC7; + text[patch_offset - 1] = 0xC0 | reg; + text[patch_offset..patch_offset + 4].copy_from_slice(&[0, 0, 0, 0]); + return Ok(()); + } + Err(unsupported("the referencing instruction")) + } + _ => Err(unsupported(&format!("reloc type {}", reloc.rtype))), + } +} + fn apply_reloc( machine: NativeMachine, text: &mut [u8], @@ -2099,6 +2284,7 @@ mod tests { machine: NativeMachine::X86_64, text: alloc::vec::Vec::new(), data: alloc::vec::Vec::new(), + data_align: 1, bss_size: 0, tls_data: alloc::vec::Vec::new(), tls_bss_size: 0, @@ -2168,6 +2354,7 @@ mod tests { machine: NativeMachine::X86_64, text: alloc::vec::Vec::new(), data: alloc::vec::Vec::new(), + data_align: 1, bss_size: 0, tls_data: alloc::vec::Vec::new(), tls_bss_size: 0, @@ -2212,6 +2399,7 @@ mod tests { machine: NativeMachine::X86_64, text: alloc::vec::Vec::new(), data: alloc::vec![0u8; 4], + data_align: 1, bss_size: 0, tls_data: alloc::vec::Vec::new(), tls_bss_size: 0, @@ -2286,6 +2474,7 @@ mod tests { machine: NativeMachine::X86_64, text, data, + data_align: 1, bss_size: 0, tls_data: alloc::vec::Vec::new(), tls_bss_size: 0, @@ -2434,6 +2623,58 @@ mod tests { ); } + /// Two objects routing the same import name to different dylibs is a + /// conflict; first-writer-wins previously bound the loser's calls + /// against the wrong library with no diagnostic. + #[test] + fn conflicting_import_dylib_routing_errors() { + let mk = |dylib: &str| NativeObject { + machine: NativeMachine::X86_64, + text: alloc::vec::Vec::new(), + data: alloc::vec::Vec::new(), + data_align: 1, + bss_size: 0, + tls_data: alloc::vec::Vec::new(), + tls_bss_size: 0, + symbols: alloc::vec::Vec::new(), + text_relocs: alloc::vec::Vec::new(), + data_relocs: alloc::vec::Vec::new(), + dylibs: alloc::vec![dylib.to_string()], + import_dylib_map: alloc::vec![("f".to_string(), 0u32)], + exports: alloc::vec::Vec::new(), + tls_index_fixups: alloc::vec::Vec::new(), + macho_tlv_descriptors: alloc::vec::Vec::new(), + macho_tlv_fixups: alloc::vec::Vec::new(), + tls_symbols: alloc::vec::Vec::new(), + macho_tlv_descriptor_syms: alloc::vec::Vec::new(), + elf_tpoff_fixups: alloc::vec::Vec::new(), + copy_relocs: alloc::vec::Vec::new(), + debug_info: alloc::vec::Vec::new(), + debug_abbrev: alloc::vec::Vec::new(), + debug_line: alloc::vec::Vec::new(), + debug_str: alloc::vec::Vec::new(), + debug_info_relocs: alloc::vec::Vec::new(), + debug_line_relocs: alloc::vec::Vec::new(), + }; + // Same routing across units links fine. + let merged = link_native_objects(&[mk("libA.so"), mk("libA.so")]).expect("consistent"); + assert_eq!(merged.import_dylib_map.get("f"), Some(&0)); + // Divergent routing errors and names both libraries. + let err = link_native_objects(&[mk("libA.so"), mk("libB.so")]).unwrap_err(); + assert!( + err.to_string().contains("libA.so") && err.to_string().contains("libB.so"), + "error must name both dylibs: {err}" + ); + // A per-unit dylib index past the unit's dylib list errors. + let mut bad = mk("libA.so"); + bad.import_dylib_map = alloc::vec![("f".to_string(), 5u32)]; + let err = link_native_objects(&[bad]).unwrap_err(); + assert!( + err.to_string().contains("out of range"), + "expected an index diagnostic, got: {err}" + ); + } + fn compile_native(src: &str, target: Target, opts: NativeOptions) -> NativeObject { let program = Compiler::new(src.to_string()).compile().expect("compile"); let bytes = emit_native_with_options(&program, target, opts).expect("emit"); diff --git a/src/c5/linker/object.rs b/src/c5/linker/object.rs index 7ab488c9d..eb5eb531c 100644 --- a/src/c5/linker/object.rs +++ b/src/c5/linker/object.rs @@ -340,6 +340,10 @@ pub struct NativeObject { pub machine: NativeMachine, pub text: Vec, pub data: Vec, + /// Largest sh_addralign among the data-family sections. The linker + /// aligns this object's base in the merged `.data` to it and the + /// image writers keep the merged stream's base alignment. + pub data_align: usize, /// Size of the `.bss` section in bytes. The reader doesn't /// allocate bytes for it (the writer doesn't either -- /// `SHT_NOBITS` records size but no file content). @@ -620,6 +624,7 @@ pub fn parse_native_elf(bytes: &[u8]) -> Result { text_bytes.extend_from_slice(section_slice(bytes, sh)?); } let mut data_bytes: Vec = Vec::new(); + let mut data_align: usize = 1; let mut data_base_per_shndx: Vec<(usize, u64)> = Vec::with_capacity(data_section_indices.len()); for &sh_i in &data_section_indices { let sh = &shdrs[sh_i]; @@ -628,6 +633,17 @@ pub fn parse_native_elf(bytes: &[u8]) -> Result { "data-family section at index {sh_i} has sh_type SHT_NOBITS (must hold file bytes)", ))); } + // Honor the section's sh_addralign (e.g. `.rodata.cst16` carries + // 16 for SSE constants): pad the merged blob before appending and + // carry the maximum outward so the image placement keeps it. + let align = sh.sh_addralign.max(1) as usize; + if !align.is_power_of_two() { + return Err(err(&format!( + "data-family section at index {sh_i} has non-power-of-two sh_addralign {align}", + ))); + } + data_align = data_align.max(align); + data_bytes.resize(data_bytes.len().next_multiple_of(align), 0); let base = data_bytes.len() as u64; data_base_per_shndx.push((sh_i, base)); data_bytes.extend_from_slice(section_slice(bytes, sh)?); @@ -1025,6 +1041,7 @@ pub fn parse_native_elf(bytes: &[u8]) -> Result { machine, text: text_bytes, data: data_bytes, + data_align, bss_size, tls_data: tls_data_bytes, tls_bss_size, diff --git a/src/c5/linker/synth_build.rs b/src/c5/linker/synth_build.rs index 5a98dab1d..06935bc1f 100644 --- a/src/c5/linker/synth_build.rs +++ b/src/c5/linker/synth_build.rs @@ -16,13 +16,6 @@ //! `is_variadic` / `fixed_args` / `param_types` across the ELF //! ET_REL roundtrip. The C99-motivated fix is a per-binding //! metadata note section. TODO. -//! * Multi-object `_Thread_local` storage. A single TLS-bearing -//! input is fully threaded: ELF PT_TLS via -//! [`MergedNative::tls_data`], the Win64 `_tls_index` fixups and -//! macOS TLV descriptors via the matching `.note.badc` records. -//! Merging two or more TLS objects still needs per-unit TPOFF / -//! descriptor-index relocations, so `link_native_objects` rejects -//! the multi-object case. TODO. //! * DWARF debug info. The merged image has no AST / function //! metadata to drive DWARF emit; debug sections are skipped, //! matching `write_executable_elf64`'s policy. TODO. @@ -30,6 +23,12 @@ //! Shared-library output is handled: the caller passes //! [`OutputKind::SharedLibrary`] and the `#pragma export` names ride //! the ET_REL `NT_BADC_EXPORTS` note into [`MergedNative::exports`]. +//! +//! `_Thread_local` storage is threaded for single- and multi-object +//! links: ELF PT_TLS via [`MergedNative::tls_data`], the Win64 +//! `_tls_index` fixups and macOS TLV descriptors via the matching +//! `.note.badc` records, with per-unit TPOFF / descriptor rebasing +//! resolved in `link_native_objects`. #![cfg(feature = "std")] @@ -125,19 +124,20 @@ fn synth_program_and_build( } else { resolve_entry_offset(merged, entry_name)? }; - let imports = synth_imports(merged, target); + let imports = synth_imports(merged, target)?; let SynthFixups { got: got_fixups, data: data_fixups, func: func_fixups, } = synth_fixups(merged, plt)?; let (data_relocs, code_relocs) = synth_relocs(merged); - let plt_trampoline_offsets = synth_plt_offsets(merged, plt); + let plt_trampoline_offsets = synth_plt_offsets(merged, plt)?; let exports = synth_exports(merged, export_all, output_kind); let pc_to_native = synth_pc_to_native(&merged.text, &code_relocs, &exports); let program = Program { data: Vec::new(), + data_align: 8, data_object_starts: Vec::new(), entry_pc: 0, warnings: Vec::new(), @@ -155,6 +155,8 @@ fn synth_program_and_build( structs: Vec::new(), enums: Vec::new(), entry_name: Some(entry_name.to_string()), + entry_pragma: None, + auto_includes: Vec::new(), subsystem, finished_functions: Vec::new(), symbols: Vec::new(), @@ -198,7 +200,7 @@ fn synth_program_and_build( pc_to_native.resize(pc + 1, usize::MAX); } pc_to_native[pc] = pc; - if let Some(&post_native) = merged.prologue_ends.get(name) { + if let Some(&post_native) = merged.prologue_ends.get(&(pc as u64)) { func_prologue_native.insert(pc, post_native as usize); } } @@ -213,7 +215,7 @@ fn synth_program_and_build( pc_to_native.resize(pc + 1, usize::MAX); } pc_to_native[pc] = pc; - if let Some(&post_native) = merged.prologue_ends.get(name) { + if let Some(&post_native) = merged.prologue_ends.get(&(pc as u64)) { func_prologue_native.insert(pc, post_native as usize); } } @@ -293,17 +295,20 @@ fn synth_program_and_build( // dynamically loaded module resolves them (a Python C extension // binding `PyFloat_Type` and the rest of the C-API against the // interpreter executable). macOS publishes every global of every - // executable through the Mach-O symtab. ELF splits the same coverage - // across two flags matching the system toolchain's `-rdynamic`: - // `--export-all` adds functions (STT_FUNC), `--export-data` adds data - // globals (STT_OBJECT). Both gate the export because it widens the - // global symbol scope. Resolved from `merged.defined` at link time; - // shared libraries use `exports`, and the PE writer ignores the field. + // executable through the Mach-O symtab. ELF and PE split the same + // coverage across two flags matching the toolchain's `-rdynamic`: + // `--export-all` adds functions (STT_FUNC / .edata name), + // `--export-data` adds data globals (STT_OBJECT / .edata name). Both + // gate the export because it widens the global symbol scope. Resolved + // from `merged.defined` at link time; shared libraries use `exports`. let is_exec = output_kind == OutputKind::Executable; let macos_exec = target == Target::MacOSAarch64 && is_exec; - let elf_exec = matches!(target, Target::LinuxX64 | Target::LinuxAarch64) && is_exec; - let export_funcs = macos_exec || (elf_exec && export_all); - let export_data_globals = macos_exec || (elf_exec && export_data); + let flagged_exec = matches!( + target, + Target::LinuxX64 | Target::LinuxAarch64 | Target::WindowsX64 | Target::WindowsAarch64 + ) && is_exec; + let export_funcs = macos_exec || (flagged_exec && export_all); + let export_data_globals = macos_exec || (flagged_exec && export_data); let dynamic_exports: Vec = if export_funcs || export_data_globals { merged .defined @@ -339,6 +344,7 @@ fn synth_program_and_build( dynamic_exports, text: merged.text.clone(), data: merged.data.clone(), + data_align: merged.data_align, bss_size: merged.bss_size as i64, entry_offset, got_fixups, @@ -473,7 +479,7 @@ fn resolve_entry_offset(merged: &MergedNative, entry_name: &str) -> Result ResolvedImports { +fn synth_imports(merged: &MergedNative, target: Target) -> Result { // `merged.dylibs` holds each `#pragma dylib` path the input // units recorded (in declaration order, deduped). When a // unit was produced before the `.badc.dylibs` section landed @@ -503,11 +509,27 @@ fn synth_imports(merged: &MergedNative, target: Target) -> ResolvedImports { .iter() .map(|(local, host)| (local.as_str(), host.as_str())) .collect(); - let imports: Vec = merged - .imports - .iter() - .enumerate() - .map(|(i, name)| ResolvedImport { + let mut imports: Vec = Vec::with_capacity(merged.imports.len()); + for (i, name) in merged.imports.iter().enumerate() { + let flat_lookup = merged.flat_imports.contains(name); + // `import_dylib_map` carries the per-import dylib assignment the + // .o writer recorded. A miss is defaulted to dylib 0 only when + // nothing hangs on the choice: a flat-lookup import binds through + // the loader's global scope (the ordinal is unread), and a + // single-dylib image (including the legacy-`.o` default fallback + // above) leaves one library to route to. With several dylibs a + // miss would silently bind the call to the wrong library, so fail. + let dylib_index = match merged.import_dylib_map.get(name) { + Some(&idx) => idx as usize, + None if flat_lookup || dylibs.len() <= 1 => 0, + None => { + return Err(synth_err(&alloc::format!( + "import `{name}` carries no dylib routing ({} dylibs in the image)", + dylibs.len(), + ))); + } + }; + imports.push(ResolvedImport { binding_idx: i as i64, // The .o writer stores each libc import under its // per-target `real_symbol` (the name the dynamic @@ -524,33 +546,27 @@ fn synth_imports(merged: &MergedNative, target: Target) -> ResolvedImports { // the host's exported `_name`; ELF uses the name verbatim. real_symbol: if let Some(host) = data_binding_hosts.get(name.as_str()) { (*host).to_string() - } else if merged.flat_imports.contains(name) && target == Target::MacOSAarch64 { + } else if flat_lookup && target == Target::MacOSAarch64 { alloc::format!("_{name}") } else { name.clone() }, - // `import_dylib_map` carries the per-import dylib - // assignment the .o writer recorded. An import - // missing from the map falls back to dylib 0 (the - // first dylib in the merge) so legacy `.o` files - // produced before NT_BADC_BINDING_MAP landed still - // round-trip. - dylib_index: merged.import_dylib_map.get(name).copied().unwrap_or(0) as usize, - flat_lookup: merged.flat_imports.contains(name), + dylib_index, + flat_lookup, is_variadic: false, fixed_args: 0, return_type_tag: 0, returns_long_double: false, param_types: Vec::new(), - }) - .collect(); + }); + } // Data bindings are surfaced separately, from the merged // `.note.badc` copy-reloc records (see `synth_data_copy_relocs`). - ResolvedImports { + Ok(ResolvedImports { imports, dylibs, data_bindings: Vec::new(), - } + }) } fn default_dylib(target: Target) -> ResolvedDylib { @@ -804,6 +820,7 @@ fn synth_relocs(merged: &MergedNative) -> (Vec, Vec) { data_relocs.push(DataReloc { data_offset: r.slot_offset, target_offset: r.target_offset, + target_anchor: r.target_offset, }); } NativeSymSection::Bss => { @@ -814,6 +831,7 @@ fn synth_relocs(merged: &MergedNative) -> (Vec, Vec) { data_relocs.push(DataReloc { data_offset: r.slot_offset, target_offset: merged.data.len() as u64 + r.target_offset, + target_anchor: merged.data.len() as u64 + r.target_offset, }); } NativeSymSection::Text => { @@ -920,14 +938,26 @@ fn synth_exports( exports } -fn synth_plt_offsets(merged: &MergedNative, plt: &[PltTrampoline]) -> Vec { - let mut offsets = alloc::vec![0usize; merged.imports.len()]; +/// Per-import trampoline offsets aligned with `merged.imports`. +/// `None` for an import no trampoline was emitted for (a data import +/// bound through the GOT/IAT), so a writer never fabricates a text +/// symbol at the slot's default offset for it. +fn synth_plt_offsets( + merged: &MergedNative, + plt: &[PltTrampoline], +) -> Result>, C5Error> { + let mut offsets = alloc::vec![None; merged.imports.len()]; for t in plt { - if t.import_index < offsets.len() { - offsets[t.import_index] = t.text_offset; + if t.import_index >= offsets.len() { + return Err(synth_err(&alloc::format!( + "PLT trampoline references import index {} out of range ({} imports)", + t.import_index, + offsets.len(), + ))); } + offsets[t.import_index] = Some(t.text_offset); } - offsets + Ok(offsets) } fn synth_err(msg: &str) -> C5Error { @@ -953,6 +983,7 @@ mod tests { // aarch64: `mov w0, #42; ret`. text: alloc::vec![0x40, 0x05, 0x80, 0x52, 0xc0, 0x03, 0x5f, 0xd6], data: alloc::vec![], + data_align: 8, bss_size: 0, defined, imports: alloc::vec![], @@ -1021,7 +1052,7 @@ mod tests { // target's `real_symbol` from `#pragma binding`; the // synthesizer passes the name through verbatim. merged.imports = alloc::vec!["_malloc".to_string()]; - let imports = synth_imports(&merged, Target::MacOSAarch64); + let imports = synth_imports(&merged, Target::MacOSAarch64).expect("synth"); assert_eq!(imports.dylibs.len(), 1); assert!( imports.dylibs[0].path.contains("libSystem"), @@ -1036,7 +1067,7 @@ mod tests { fn synth_imports_no_underscore_for_linux() { let mut merged = tiny_aarch64_main(); merged.imports = alloc::vec!["malloc".to_string()]; - let imports = synth_imports(&merged, Target::LinuxAarch64); + let imports = synth_imports(&merged, Target::LinuxAarch64).expect("synth"); assert_eq!(imports.imports[0].real_symbol, "malloc"); } @@ -1049,14 +1080,66 @@ mod tests { let mut merged = tiny_aarch64_main(); merged.imports = alloc::vec!["JS_ToIndex".to_string()]; merged.flat_imports.insert("JS_ToIndex".to_string()); - let mac = synth_imports(&merged, Target::MacOSAarch64); + let mac = synth_imports(&merged, Target::MacOSAarch64).expect("synth"); assert!(mac.imports[0].flat_lookup, "must be flat-lookup on macOS"); assert_eq!(mac.imports[0].real_symbol, "_JS_ToIndex"); - let elf = synth_imports(&merged, Target::LinuxAarch64); + let elf = synth_imports(&merged, Target::LinuxAarch64).expect("synth"); assert!(elf.imports[0].flat_lookup, "must be flat-lookup on ELF"); assert_eq!(elf.imports[0].real_symbol, "JS_ToIndex"); } + /// A non-flat import missing from the routing map is defaulted to + /// dylib 0 only when a single dylib leaves no choice; with several + /// dylibs the old `unwrap_or(0)` silently misrouted the binding. + #[test] + fn synth_imports_unmapped_routing() { + let mut merged = tiny_aarch64_main(); + merged.imports = alloc::vec!["puts".to_string()]; + merged.dylibs = alloc::vec!["/usr/lib/libSystem.B.dylib".to_string()]; + let single = synth_imports(&merged, Target::MacOSAarch64).expect("single dylib routes"); + assert_eq!(single.imports[0].dylib_index, 0); + + merged.dylibs.push("/usr/lib/libother.dylib".to_string()); + let err = synth_imports(&merged, Target::MacOSAarch64).expect_err("ambiguous miss"); + assert!( + alloc::format!("{err}").contains("puts"), + "error must name the import: {err}" + ); + + // A flat-lookup import binds through the loader's global scope; + // the ordinal is unread, so the miss is fine. + merged.flat_imports.insert("puts".to_string()); + let flat = synth_imports(&merged, Target::MacOSAarch64).expect("flat import routes"); + assert!(flat.imports[0].flat_lookup); + + // A mapped import routes as recorded. + merged.flat_imports.clear(); + merged.import_dylib_map.insert("puts".to_string(), 1); + let mapped = synth_imports(&merged, Target::MacOSAarch64).expect("mapped"); + assert_eq!(mapped.imports[0].dylib_index, 1); + } + + /// `synth_plt_offsets` keeps a `None` slot for an import without a + /// trampoline (a data import) so no writer fabricates a text symbol + /// at the slot's default offset for it. + #[test] + fn synth_plt_offsets_leaves_untrampolined_imports_none() { + let mut merged = tiny_aarch64_main(); + merged.imports = alloc::vec!["environ".to_string(), "malloc".to_string()]; + let plt = alloc::vec![PltTrampoline { + text_offset: 0x40, + import_index: 1, + }]; + let offsets = synth_plt_offsets(&merged, &plt).expect("offsets"); + assert_eq!(offsets, alloc::vec![None, Some(0x40)]); + + let bad = alloc::vec![PltTrampoline { + text_offset: 0x40, + import_index: 7, + }]; + assert!(synth_plt_offsets(&merged, &bad).is_err()); + } + #[test] fn synth_exports_resolves_pragma_export_names_only() { // synth_exports promotes the `#pragma export` union diff --git a/src/c5/object/dwarf.rs b/src/c5/object/dwarf.rs index b24cb18dc..9b23d024d 100644 --- a/src/c5/object/dwarf.rs +++ b/src/c5/object/dwarf.rs @@ -534,8 +534,10 @@ fn prologue_size_for(ent_pc: usize, low_pc: usize, build: &Build) -> u32 { fn end_of_user_text(build: &Build) -> usize { build .plt_trampoline_offsets - .first() + .iter() .copied() + .flatten() + .min() .unwrap_or(build.text.len()) } @@ -564,7 +566,13 @@ fn collect_plt_subprograms( build.plt_trampoline_offsets.len(), "trampoline-offset count must match import count" ); - let n = imports.len(); + // A data import (bound through the GOT) has no trampoline + // (`None` slot) and gets no stub DIE. + let stubbed: Vec<(&super::ResolvedImport, usize)> = imports + .iter() + .zip(build.plt_trampoline_offsets.iter()) + .filter_map(|(imp, off)| off.map(|o| (imp, o))) + .collect(); // Per-stub size. Trampolines are emitted contiguously and // are uniform-sized per arch, so the delta between two // consecutive offsets is exact. The last-stub-to-text-end @@ -574,10 +582,10 @@ fn collect_plt_subprograms( // `build.text.len() - offsets.last()` overshoots by the // marker bytes (the overshoot was visible as DW_AT_high_pc // = 0x1f instead of 0xc on the linked_list fixture). - let stub_size = if n >= 2 { - (build.plt_trampoline_offsets[1] - build.plt_trampoline_offsets[0]) as u64 + let stub_size = if stubbed.len() >= 2 { + (stubbed[1].1 - stubbed[0].1) as u64 } else { - // Single import: fall back to the per-arch constant. Has + // Single stub: fall back to the per-arch constant. Has // to match `super::aarch64::emit_plt_trampolines` // (3 instructions = 12 bytes) / // `super::x86_64::emit_plt_trampolines` (1 jmp = 6 @@ -588,11 +596,9 @@ fn collect_plt_subprograms( } }; - imports + stubbed .iter() - .enumerate() - .map(|(i, imp)| { - let off = build.plt_trampoline_offsets[i]; + .map(|&(imp, off)| { // Synthetic per-param names: `arg0`, `arg1`, ... The // c5 binding doesn't track parameter names, but // gdb's `info args` and `bt` skip name-less entries @@ -2229,7 +2235,12 @@ impl DebugFrameFdeHeader { /// `build.text` by `emit_plt_trampolines`, so the range is /// `[code_vmaddr + offsets[0], code_vmaddr + build.text.len())`. fn plt_pool_range(build: &Build, code_vmaddr: u64) -> Option<(u64, u64)> { - let first = build.plt_trampoline_offsets.first().copied()?; + let first = build + .plt_trampoline_offsets + .iter() + .copied() + .flatten() + .min()?; let start = code_vmaddr + first as u64; let end = code_vmaddr + build.text.len() as u64; if end > start { @@ -2921,7 +2932,7 @@ mod tests { assert_eq!(plt_pool_range(&build, 0x1000), None); // Once a trampoline is recorded, the range covers from the // first stub byte to the end of `build.text`. - build.plt_trampoline_offsets = alloc::vec![0xc0, 0xcc]; + build.plt_trampoline_offsets = alloc::vec![Some(0xc0), Some(0xcc)]; build.text.extend(alloc::vec![0u8; 0x40]); // pretend trampolines are appended assert_eq!(plt_pool_range(&build, 0x1000), Some((0x10c0, 0x1140))); } @@ -3003,7 +3014,7 @@ mod tests { let build = Build { copy_relocs: Default::default(), text, - plt_trampoline_offsets: alloc::vec![0xc0, 0xcc], + plt_trampoline_offsets: alloc::vec![Some(0xc0), Some(0xcc)], imports, ..Build::default() }; @@ -3090,7 +3101,7 @@ mod tests { let mut build = Build { copy_relocs: Default::default(), text: alloc::vec![0u8; 0x200], - plt_trampoline_offsets: alloc::vec![0x180, 0x18c, 0x198], + plt_trampoline_offsets: alloc::vec![Some(0x180), Some(0x18c), Some(0x198)], ..Build::default() }; assert_eq!(end_of_user_text(&build), 0x180); diff --git a/src/c5/object/dwarf_reloc.rs b/src/c5/object/dwarf_reloc.rs index 9a8c7442a..5f4beb3d5 100644 --- a/src/c5/object/dwarf_reloc.rs +++ b/src/c5/object/dwarf_reloc.rs @@ -1357,7 +1357,7 @@ fn decompose_pointer_chain(type_tag: i64) -> Option { const STRUCT_BASE: i64 = 1000; const STRUCT_STRIDE: i64 = 1000; let unsigned = (type_tag & UNSIGNED_BIT) != 0; - let bare = type_tag & !UNSIGNED_BIT; + let bare = crate::c5::compiler::types::strip_unsigned(type_tag); if bare < 0 { return None; } @@ -1417,7 +1417,7 @@ fn base_type_for_leaf( ) -> Option { const UNSIGNED_BIT: i64 = 1 << 30; let unsigned = (leaf & UNSIGNED_BIT) != 0; - let bare = leaf & !UNSIGNED_BIT; + let bare = crate::c5::compiler::types::strip_unsigned(leaf); let desc = if bare == Ty::Bool as i64 { BaseTypeDesc { name: "_Bool", diff --git a/src/c5/object/elf.rs b/src/c5/object/elf.rs index 909cc500f..f9c8c35c2 100644 --- a/src/c5/object/elf.rs +++ b/src/c5/object/elf.rs @@ -656,14 +656,22 @@ fn build_plt_symtab( build.plt_trampoline_offsets.len(), "trampoline-offset count must match import count" ); + // A data import (bound through the GOT) has no trampoline + // (`None` slot); a text symbol for it would mislabel whatever + // code sits at the fabricated address. + let plt_locals: Vec<(&str, usize)> = imports + .iter() + .zip(build.plt_trampoline_offsets.iter()) + .filter_map(|(imp, off)| off.map(|o| (imp.local_name.as_str(), o))) + .collect(); // .strtab: leading NUL (st_name=0 -> empty string sentinel) // followed by NUL-separated import names. let mut strtab = alloc::vec![0u8]; - let mut name_offsets: Vec = Vec::with_capacity(imports.len()); - for imp in imports { + let mut name_offsets: Vec = Vec::with_capacity(plt_locals.len()); + for &(name, _) in &plt_locals { name_offsets.push(strtab.len() as u32); - strtab.extend_from_slice(imp.local_name.as_bytes()); + strtab.extend_from_slice(name.as_bytes()); strtab.push(0); } @@ -671,7 +679,7 @@ fn build_plt_symtab( // STT_FUNC per trampoline. Local symbols come first by spec // (the .symtab section header's `sh_info` field points one // past the last local entry). - let mut symtab: Vec = Vec::with_capacity((1 + imports.len()) * ELF64_SYM_SIZE as usize); + let mut symtab: Vec = Vec::with_capacity((1 + plt_locals.len()) * ELF64_SYM_SIZE as usize); write_struct( &mut symtab, &Elf64Sym { @@ -683,9 +691,8 @@ fn build_plt_symtab( st_size: 0, }, ); - for (i, imp) in imports.iter().enumerate() { - let _ = imp; - let st_value = text_vmaddr + build.plt_trampoline_offsets[i] as u64; + for (i, &(_, tramp_offset)) in plt_locals.iter().enumerate() { + let st_value = text_vmaddr + tramp_offset as u64; write_struct( &mut symtab, &Elf64Sym { @@ -719,7 +726,13 @@ fn build_plt_symtab( .iter() .map(|&pc| build.pc_to_native[pc] as u64) .collect(); - boundaries.extend(build.plt_trampoline_offsets.iter().map(|&o| o as u64)); + boundaries.extend( + build + .plt_trampoline_offsets + .iter() + .flatten() + .map(|&o| o as u64), + ); boundaries.push(text_len); boundaries.sort_unstable(); for (i, name) in build.func_names.iter().enumerate() { @@ -1311,6 +1324,17 @@ pub(super) fn write( machine: Machine, ) -> Result, C5Error> { let is_shared = build.output_kind == super::OutputKind::SharedLibrary; + // Both backends lower `_Thread_local` access with the local-exec + // model, whose TP-relative offsets are valid only in the + // executable's static TLS block; baked into ET_DYN they address + // another module's TLS. TODO: implement the general-dynamic TLS + // model for ELF shared-library output. + if is_shared && !build.tls_data.is_empty() { + return Err(C5Error::Compile(crate::c5::error::fmt_link_err( + "_Thread_local data is not supported in ELF shared-library output: \ + only the executable-model (local-exec) TLS sequence is implemented", + ))); + } let n_imports = build.imports.imports.len(); // Pick the libc-exit tail when the user has any // libc `exit` import (typically through ``), @@ -1350,13 +1374,25 @@ pub(super) fn write( // executable has no exports, so the tables are unchanged. let mut elf_exports: Vec = Vec::new(); for exp in &build.exports { - if let Some(&native_off) = build.pc_to_native.get(exp.ent_pc) { - elf_exports.push(ElfExport { - name: exp.name.clone(), - section: super::DynamicExportSection::Text, - offset: native_off as u64, - }); + let native_off = build + .pc_to_native + .get(exp.ent_pc) + .copied() + .unwrap_or(usize::MAX); + if native_off == usize::MAX { + return Err(C5Error::Compile(crate::c5::error::fmt_internal_err( + &format!( + "ELF: exported function `{}` (bc PC {}) doesn't \ + align with any native instruction", + exp.name, exp.ent_pc + ), + ))); } + elf_exports.push(ElfExport { + name: exp.name.clone(), + section: super::DynamicExportSection::Text, + offset: native_off as u64, + }); } for d in &build.dynamic_exports { if !elf_exports.iter().any(|e| e.name == d.name) { @@ -1473,6 +1509,12 @@ pub(super) fn write( }; import_versym[i] = idx; } + // Version names extend `.dynstr` past `build_dynstr`'s pad; re-pad + // so the sections laid out from `dynstr.len()` (`.hash`, + // `.gnu.version`) stay congruent with their claimed sh_addralign. + while !dynstr.len().is_multiple_of(8) { + dynstr.push(0); + } let has_versions = !verneed_groups.is_empty(); // Two extra allocated sections (.gnu.version / .gnu.version_r) precede // .rela.dyn when has_versions, shifting .text onward by two. Symbols @@ -1616,7 +1658,10 @@ pub(super) fn write( let dynamic_size = (build.imports.dylibs.len() as u64 + 11 + version_dyn_tags) * ELF64_DYN_SIZE; let got_off = dynamic_off + dynamic_size; let got_size = (n_imports as u64) * 8; - let data_off = got_off + got_size; + // `.data`'s base alignment: p_vaddr == p_offset within the RW + // segment, so aligning the file offset aligns the vaddr. + let data_align = build.data_align.max(8) as u64; + let data_off = round_up(got_off + got_size, data_align); let data_size = build.data.len() as u64; // PT_TLS requires `p_vaddr % p_align == 0` (ELF gABI), and glibc // computes a `_Thread_local`'s address as `tp - roundup(p_memsz, @@ -2205,6 +2250,11 @@ pub(super) fn write( // .got -- one zero-filled u64 per import. Loader fills these in // via .rela.dyn / R_AARCH64_GLOB_DAT before _start runs. out.extend(vec![0u8; got_size as usize]); + // Pad to the aligned `data_off` (see the layout). + while (out.len() as u64) < data_off { + out.push(0); + } + debug_assert_eq!(out.len() as u64, data_off); // build.data -- the program's static data segment, with // pointer-to-global initializers resolved to absolute VAs. @@ -2557,7 +2607,7 @@ pub(super) fn write( sh_size: data_size, sh_link: 0, sh_info: 0, - sh_addralign: 8, + sh_addralign: data_align, sh_entsize: 0, }, ); @@ -2879,6 +2929,9 @@ mod tests { structs: Vec::new(), enums: Vec::new(), entry_name: None, + entry_pragma: None, + auto_includes: Vec::new(), + data_align: 8, subsystem: None, finished_functions: alloc::vec::Vec::new(), symbols: alloc::vec::Vec::new(), @@ -2895,6 +2948,7 @@ mod tests { copy_relocs: Default::default(), text: vec![0x40, 0x05, 0x80, 0xD2, 0xC0, 0x03, 0x5F, 0xD6], data: Vec::new(), + data_align: 8, bss_size: 0, entry_offset: 0, got_fixups: Vec::new(), @@ -2988,6 +3042,24 @@ mod tests { assert_eq!(e_machine, EM_AARCH64); } + /// An export whose ent_pc misses `pc_to_native` must fail the write + /// with a diagnostic; it was previously dropped from `.dynsym` + /// silently, shipping a shared library without the symbol. + #[test] + fn export_with_unmapped_ent_pc_errors() { + let mut build = tiny_build(); + build.output_kind = super::super::OutputKind::SharedLibrary; + build.exports = vec![crate::c5::program::ExportedFunction { + name: "ghost".into(), + ent_pc: 999, + }]; + let err = write(&tiny_program(), &build, Machine::Aarch64).unwrap_err(); + assert!( + err.to_string().contains("ghost"), + "error must name the export: {err}" + ); + } + #[test] fn program_header_table_self_describes() { let bytes = write(&tiny_program(), &tiny_build(), Machine::Aarch64).unwrap(); diff --git a/src/c5/object/elf_reloc.rs b/src/c5/object/elf_reloc.rs index d0c40872a..48068bde9 100644 --- a/src/c5/object/elf_reloc.rs +++ b/src/c5/object/elf_reloc.rs @@ -257,14 +257,13 @@ fn e_machine_for(machine: Machine) -> u16 { /// COPY-relocated data import (`environ`), whose `st_size` the loader /// compares against the host symbol's. fn data_global_byte_size(sym: &crate::c5::symbol::Symbol) -> u64 { - use crate::c5::compiler::types::is_pointer_ty; + use crate::c5::compiler::types::{is_pointer_ty, strip_unsigned}; use crate::c5::token::Ty; - const UNSIGNED_BIT: i64 = 1 << 30; let ty = sym.type_; let elem: u64 = if is_pointer_ty(ty) { 8 } else { - let stripped = ty & !UNSIGNED_BIT; + let stripped = strip_unsigned(ty); if stripped == Ty::Char as i64 || stripped == Ty::Bool as i64 { 1 } else if stripped == Ty::Short as i64 { @@ -290,9 +289,9 @@ fn data_global_byte_size(sym: &crate::c5::symbol::Symbol) -> u64 { /// Emit a relocatable ELF64 object holding the contents of /// `build`. The result is a standard `.o` that `ld` / `lld` can -/// link (modulo missing relocations -- the writer doesn't yet -/// emit `.rela.text`, so a TU with cross-TU calls produces a -/// link error today). +/// link: the writer emits `.rela.text` (SHT_RELA, `sh_info` = the +/// `.text` section index) with one entry per call site, so a TU with +/// cross-TU calls resolves at link time. pub(super) fn write_relocatable( program: &Program, build: &Build, @@ -1033,8 +1032,10 @@ pub(super) fn write_relocatable( ..Default::default() }); - // .data - let data_off = round_up(out.len() as u64, 8); + // .data -- `sh_addralign` carries the unit's base data alignment + // so the linker places this unit's data at a multiple of it. + let data_align = build.data_align.max(8) as u64; + let data_off = round_up(out.len() as u64, data_align); out.resize(data_off as usize, 0); out.extend_from_slice(&build.data); sh.push(Elf64Shdr { @@ -1043,7 +1044,7 @@ pub(super) fn write_relocatable( sh_flags: SHF_ALLOC | SHF_WRITE, sh_offset: data_off, sh_size: build.data.len() as u64, - sh_addralign: 8, + sh_addralign: data_align, ..Default::default() }); @@ -1761,6 +1762,9 @@ mod tests { structs: Vec::new(), enums: Vec::new(), entry_name: None, + entry_pragma: None, + auto_includes: Vec::new(), + data_align: 8, subsystem: None, finished_functions: Vec::new(), symbols: Vec::new(), @@ -1776,6 +1780,7 @@ mod tests { copy_relocs: Default::default(), text: Vec::new(), data: Vec::new(), + data_align: 8, bss_size: 0, entry_offset: 0, got_fixups: Vec::new(), diff --git a/src/c5/object/mach_o.rs b/src/c5/object/mach_o.rs index d823b1a54..f76017d53 100644 --- a/src/c5/object/mach_o.rs +++ b/src/c5/object/mach_o.rs @@ -238,12 +238,11 @@ const SEG_INDEX_DATA: u8 = 2; const S_ATTR_DEBUG: u32 = 0x0200_0000; /// Mach-O section type bits used by the TLV layout. See -/// `` for the full set; we only need -/// `__thread_bss` (zero-fill, the only flavour the c5 frontend -/// generates today since `_Thread_local` initialisers aren't -/// supported) and `__thread_vars` (descriptors). The matching -/// `__thread_data` (S_THREAD_LOCAL_REGULAR = 0x11) would be -/// emitted alongside if we ever support TLS initialisers. +/// `` for the full set. `__thread_vars` holds the +/// descriptors; the per-thread storage is `__thread_bss` (zero-fill) +/// when every `_Thread_local` starts zero, or `__thread_data` +/// (S_THREAD_LOCAL_REGULAR = 0x11, file-backed init template) once any +/// initialiser makes `build.tls_init_size` non-zero. #[allow(dead_code)] const S_ZEROFILL: u32 = 0x1; // __bss (zero-fill, no file backing) const S_THREAD_LOCAL_REGULAR: u32 = 0x11; // __thread_data (init data) @@ -753,6 +752,7 @@ fn segment_data_with_tlv( data_addr: u64, data_size: u64, data_offset: u32, + data_align_log2: u32, thread_vars_addr: u64, thread_vars_size: u64, thread_vars_offset: u32, @@ -809,7 +809,7 @@ fn segment_data_with_tlv( addr: data_addr, size: data_size, offset: data_offset, - align: 3, + align: data_align_log2, reloff: 0, nreloc: 0, flags: 0, @@ -924,6 +924,7 @@ fn segment_data( data_addr: u64, data_size: u64, data_offset: u32, + data_align_log2: u32, bss_addr: u64, bss_size: u64, ) -> Vec { @@ -979,7 +980,7 @@ fn segment_data( addr: data_addr, size: data_size, offset: data_offset, - align: 3, // log2 -- 8 bytes + align: data_align_log2, reloff: 0, nreloc: 0, flags: 0, // S_REGULAR @@ -1606,6 +1607,27 @@ struct TlvBindContext { segment_offset: u64, /// Number of TLV descriptors that need binding. tlv_count: usize, + /// 1-based LC_LOAD_DYLIB ordinal of libSystem, which defines + /// `__tlv_bootstrap` (see [`tlv_bootstrap_ordinal`]). + bootstrap_ordinal: u64, +} + +/// 1-based LC_LOAD_DYLIB ordinal of libSystem, the dylib that defines +/// `__tlv_bootstrap`. The bind stream and the matching nlist entry both +/// resolve the ordinal through here so they cannot diverge. An image +/// using TLV without linking libSystem cannot bind the descriptors, so +/// that is an error rather than a guessed ordinal. +fn tlv_bootstrap_ordinal(dylibs: &[crate::c5::codegen::ResolvedDylib]) -> Result { + dylibs + .iter() + .position(|d| d.path.contains("libSystem")) + .map(|i| (i + 1) as u64) + .ok_or_else(|| { + C5Error::Compile(crate::c5::error::fmt_internal_err( + "Mach-O: `_Thread_local` requires libSystem for `__tlv_bootstrap`, \ + but no linked dylib matches libSystem", + )) + }) } /// Bind opcode stream that resolves the program's imports plus, @@ -1718,20 +1740,7 @@ fn build_bind_opcodes( out.push(BIND_OPCODE_DO_BIND); } if let Some(ctx) = tlv_ctx { - // `__tlv_bootstrap` always lives in libSystem; its - // dylib ordinal is the position of libSystem in the - // per-image dylib list, +1. We reuse the first dylib - // (libSystem is always present on macOS targets) for - // simplicity; if the order ever changes, the - // matching nlist entry's ordinal is computed the same - // way. - let bootstrap_ordinal = imports - .dylibs - .iter() - .position(|d| d.path.contains("libSystem")) - .map(|i| (i + 1) as u64) - .unwrap_or(1); - let bootstrap_source = BindSource::Dylib(bootstrap_ordinal); + let bootstrap_source = BindSource::Dylib(ctx.bootstrap_ordinal); if current_source != Some(bootstrap_source) { push_bind_source(&mut out, bootstrap_source); } @@ -1994,7 +2003,10 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error let data_vmaddr = TEXT_VMADDR_BASE + text_vmsize; let got_size = (build.imports.imports.len() * 8) as u64; let got_section_offset_in_segment: u64 = 0; - let data_section_offset_in_segment: u64 = round_up(got_size, 8); + // __data's base alignment: the segment base is page-aligned, so + // aligning the in-segment offset aligns both fileoff and vmaddr. + let data_align = build.data_align.max(8) as u64; + let data_section_offset_in_segment: u64 = round_up(got_size, data_align); let program_data_size = build.data.len() as u64; let post_data_offset_in_segment: u64 = round_up(data_section_offset_in_segment + program_data_size, 8); @@ -2087,6 +2099,7 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error Some(TlvBindContext { segment_offset: thread_vars_offset_in_segment, tlv_count: n_tlv, + bootstrap_ordinal: tlv_bootstrap_ordinal(&build.imports.dylibs)?, }) } else { None @@ -2126,25 +2139,20 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error // `real_symbol` ("_malloc") so `nm`/`lldb` show the name // the C source uses. // - // Test fixtures sometimes hand us a `Build` with imports but - // no trampoline offsets (no per-arch lower() ran); in that - // case we skip the local section. - let emit_plt_locals = !build.plt_trampoline_offsets.is_empty(); - // One local symbol per PLT trampoline. Function imports carry a - // trampoline; data imports (bound through the GOT) do not, and the - // routing appends them after the function imports, so the first - // `plt_trampoline_offsets.len()` imports are exactly the trampolined - // ones. The remaining imports still get an undefined symtab entry + - // bind below. - let n_trampolines = build.plt_trampoline_offsets.len(); - let mut symbol_names: Vec<&str> = if emit_plt_locals { - build.imports.imports[..n_trampolines] - .iter() - .map(|imp| imp.local_name.as_str()) - .collect() - } else { - Vec::new() - }; + // One local symbol per PLT trampoline. A data import (bound through + // the GOT) carries no trampoline (`None` slot) and gets only the + // undefined symtab entry + bind below -- a local text symbol for it + // would sit at the slot's default address (the first function's + // bytes) and mislabel backtraces and breakpoints. Keyed by import + // index, not by ordering, so the two never diverge. + let plt_locals: Vec<(&str, usize)> = build + .imports + .imports + .iter() + .zip(build.plt_trampoline_offsets.iter()) + .filter_map(|(imp, off)| off.map(|o| (imp.local_name.as_str(), o))) + .collect(); + let mut symbol_names: Vec<&str> = plt_locals.iter().map(|&(name, _)| name).collect(); // Executable dynamic exports: every defined global symbol, so a // dlopen'd module binds the program's symbols. `#pragma export` // populates `build.exports` for shared libraries instead, so the @@ -2182,16 +2190,10 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error // [Locals] one entry per PLT trampoline. Data imports have no // trampoline; they appear only as undefined import symbols below. - if emit_plt_locals { - debug_assert!( - n_trampolines <= build.imports.imports.len(), - "more trampolines than imports" - ); - for (i, &tramp_offset) in build.plt_trampoline_offsets.iter().enumerate() { - let n_strx = str_indices[i]; - let n_value = code_vmaddr_base + tramp_offset as u64; - symtab.extend_from_slice(&nlist_local(n_strx, n_value, SECT_INDEX_TEXT)); - } + for (i, &(_, tramp_offset)) in plt_locals.iter().enumerate() { + let n_strx = str_indices[i]; + let n_value = code_vmaddr_base + tramp_offset as u64; + symtab.extend_from_slice(&nlist_local(n_strx, n_value, SECT_INDEX_TEXT)); } // [Defined exports] (N_EXT | N_SECT). Each one's `n_value` @@ -2226,7 +2228,9 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error // global symbols, so a dlopen'd module binds against them. A text // symbol's value is the code base plus its byte offset within // `build.text`; a data symbol's value is the `__data` section - // vmaddr plus its byte offset within `build.data`. + // vmaddr plus its byte offset within `build.data`. dyld resolves + // an image carrying LC_DYLD_INFO through the export trie only, so + // each dynamic export joins the trie alongside its symtab entry. let dyn_export_str_base = n_locals + export_disk_names.len(); for (i, d) in dyn_exports_emit.iter().enumerate() { let n_strx = str_indices[dyn_export_str_base + i]; @@ -2243,6 +2247,7 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error } }; symtab.extend_from_slice(&nlist_defined(n_strx, n_value, n_sect)); + export_trie_entries.push((dyn_export_disk_names[i].clone(), n_value - TEXT_VMADDR_BASE)); } // [Undefined imports] (N_EXT | N_UNDF). Indices in // `str_indices` are shifted past the locals + exports. @@ -2252,16 +2257,7 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error symtab.extend_from_slice(&nlist_undef(n_strx, ordinal)); } if tls_present { - // `__tlv_bootstrap` comes from libSystem.B.dylib (which is - // already in the dylib list because every macOS Mach-O - // we emit links libSystem). Find its ordinal. - let bootstrap_dylib_ordinal = build - .imports - .dylibs - .iter() - .position(|d| d.path.contains("libSystem")) - .map(|i| (i + 1) as u8) - .unwrap_or(1); + let bootstrap_dylib_ordinal = tlv_bootstrap_ordinal(&build.imports.dylibs)? as u8; let bootstrap_strx = str_indices[symbol_names.len() - 1]; symtab.extend_from_slice(&nlist_undef(bootstrap_strx, bootstrap_dylib_ordinal)); } @@ -2435,6 +2431,7 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error data_section_vmaddr, program_data_size, data_section_fileoff as u32, + data_align.trailing_zeros(), thread_vars_vmaddr, thread_vars_size, thread_vars_fileoff as u32, @@ -2457,6 +2454,7 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error data_section_vmaddr, program_data_size, data_section_fileoff as u32, + data_align.trailing_zeros(), bss_base_vmaddr, build.bss_size as u64, ) @@ -2562,9 +2560,9 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error // then dyld_info family, then symbol tables, then dylinker / // dylib / build_version / main (or LC_ID_DYLIB for shared libs). // Segment LC order: __PAGEZERO, __TEXT, __DATA, __DWARF - // (executables only), __LINKEDIT -- the layout - // `go build` produces for executables. __DWARF reuses - // __LINKEDIT's vmaddr with vmsize=0, so the loaded image's + // (present when debug info is emitted, for both executables and + // dylibs), __LINKEDIT. __DWARF occupies its own page-aligned + // vmaddr slot between __DATA and __LINKEDIT, so the loaded image's // address space stays monotonic non-decreasing. // File-resident order matches LC order. out.extend_from_slice(&pagezero); @@ -2736,9 +2734,9 @@ pub(super) fn write(program: &Program, build: &Build) -> Result, C5Error } out.resize((data_fileoff + data_filesize) as usize, 0); - // __DWARF contents (executables only -- dylibs skip phase - // 1 DWARF, see `emit_dwarf`). Order matches what - // `segment_dwarf` pointed each section at: info, abbrev, + // __DWARF contents, emitted whenever debug info is requested + // (executables and dylibs, gated by `emit_dwarf`). Order matches + // what `segment_dwarf` pointed each section at: info, abbrev, // line, str. Sits ahead of __LINKEDIT so codesign can grow // __LINKEDIT at the file tail without trampling debug // bytes. @@ -2811,6 +2809,9 @@ mod tests { structs: Vec::new(), enums: Vec::new(), entry_name: None, + entry_pragma: None, + auto_includes: Vec::new(), + data_align: 8, subsystem: None, finished_functions: alloc::vec::Vec::new(), symbols: alloc::vec::Vec::new(), @@ -2828,6 +2829,7 @@ mod tests { // movz x0, #42 ; ret text: vec![0x40, 0x05, 0x80, 0xD2, 0xC0, 0x03, 0x5F, 0xD6], data: Vec::new(), + data_align: 8, bss_size: 0, entry_offset: 0, got_fixups: Vec::new(), @@ -2972,6 +2974,26 @@ mod tests { ); } + /// `__tlv_bootstrap` binds against libSystem's real ordinal; an + /// image whose dylib list lacks libSystem cannot bind the TLV + /// descriptors and must fail rather than guess ordinal 1. + #[test] + fn tlv_bootstrap_ordinal_requires_libsystem() { + use crate::c5::codegen::ResolvedDylib; + let dylibs = vec![ + ResolvedDylib { + name: "libfoo".into(), + path: "/usr/lib/libfoo.dylib".into(), + }, + ResolvedDylib { + name: "libSystem".into(), + path: "/usr/lib/libSystem.B.dylib".into(), + }, + ]; + assert_eq!(tlv_bootstrap_ordinal(&dylibs).unwrap(), 2); + assert!(tlv_bootstrap_ordinal(&dylibs[..1]).is_err()); + } + #[test] fn uleb128_round_trips() { // Spot-check the encoder against a few known values from diff --git a/src/c5/object/pe.rs b/src/c5/object/pe.rs index 6d2842791..c1725c3f8 100644 --- a/src/c5/object/pe.rs +++ b/src/c5/object/pe.rs @@ -177,11 +177,12 @@ const NUM_DATA_DIRS: u32 = 16; /// appears when the c5 program has initialized data -- string /// literals, globals, or `_Thread_local` storage -- because /// real Windows kernels reject images that list a zero-sized -/// section. The optional `.reloc` only appears when the -/// program declares any `_Thread_local` global; that's the -/// only path that puts absolute VAs into the image (the three -/// pointer fields of `IMAGE_TLS_DIRECTORY64`), which the -/// ASLR-aware loader needs to fix up after sliding. +/// section. The optional `.reloc` appears when the image holds +/// any absolute VA the ASLR-aware loader must fix up after +/// sliding: the three `IMAGE_TLS_DIRECTORY64` pointer fields +/// (when the program declares a `_Thread_local` global) and any +/// absolute pointer baked by an address-of-static data or code +/// relocation. /// /// `.pdata` is the Exception Directory, mandatory under the /// 64-bit Windows ABI: the loader looks up `RUNTIME_FUNCTION` @@ -191,13 +192,13 @@ const NUM_DATA_DIRS: u32 = 16; /// hosts can reject a missing entry, so we emit it on both /// arches. /// -/// `.reloc` is omitted for TLS-free images because every -/// cross-section reference the codegen emits is RIP-relative -/// (x86_64) or PC-relative (aarch64 ADRP+ADD), so the -/// DYNAMIC_BASE-flagged image can be slid to any address -/// without touching any absolute pointer in the file. The -/// only absolute pointers we ever emit live inside the TLS -/// directory, which is why `.reloc` follows TLS presence. +/// `.reloc` is omitted only when the image holds no absolute +/// pointer: most cross-section references are RIP-relative +/// (x86_64) or PC-relative (aarch64 ADRP+ADD), and a +/// DYNAMIC_BASE-flagged image slides freely without touching +/// them. Absolute VAs live in the TLS directory and in +/// address-of-static initializers, so `.reloc` follows their +/// presence. fn num_sections( data_section_present: bool, reloc_section_present: bool, @@ -391,7 +392,13 @@ pub(super) fn write( let reloc_section_present = !build.tls_data.is_empty() || !build.data_relocs.is_empty() || !build.code_relocs.is_empty(); - let edata_section_present = is_dll && !build.exports.is_empty(); + // `.edata` is present whenever the image exports anything: a + // `#pragma export` set (shared library or executable, matching the + // ELF `.dynsym` behaviour) or an executable's `--export-all` / + // `--export-data` dynamic exports. A PE executable may legally carry + // an export directory; GetProcAddress resolves against it, which is + // what a plugin host loading modules relies on. + let edata_section_present = !build.exports.is_empty() || !build.dynamic_exports.is_empty(); // Emit DWARF debug sections in PE images so lldb / // gdb can resolve user-function names + types in PE // backtraces. Suppressed when the user passed `--no-debug` / @@ -602,11 +609,10 @@ pub(super) fn write( // `.edata` holds the IMAGE_EXPORT_DIRECTORY plus the // arrays it references -- function RVAs, name RVAs, - // ordinals, plus the DLL name and each export name. - // Only present in shared-library output with at least one - // `#pragma export` symbol. (`edata_section_present` was - // already computed above so the headers-size pass knew - // about it.) + // ordinals, plus the image name and each export name. + // Present when the image exports anything (see + // `edata_section_present` above, computed early so the + // headers-size pass knew about it). let edata_rva: u32 = if edata_section_present { round_up( if reloc_section_present { @@ -633,13 +639,51 @@ pub(super) fn write( 0 }; let edata_bytes: Vec = if edata_section_present { - build_export_directory( - edata_rva, - text_rva + text_prologue_len, - &build.exports, - &build.pc_to_native, - build.shared_lib_name.as_deref(), - )? + // Resolve every export to its runtime RVA. `#pragma export` + // entries carry a bc PC that maps through `pc_to_native`; + // dynamic exports already carry a byte offset within + // `build.text` / `build.data`. Names may overlap when + // `--export-all` re-covers a `#pragma export` symbol; the + // pragma entry wins (both resolve to the same address). + let mut entries: Vec<(String, u32)> = Vec::new(); + for exp in &build.exports { + let native_off = build + .pc_to_native + .get(exp.ent_pc) + .copied() + .unwrap_or(usize::MAX); + if native_off == usize::MAX { + return Err(C5Error::Compile(crate::c5::error::fmt_internal_err( + &format!( + "PE: exported function `{}` (bc PC {}) doesn't \ + align with any native instruction", + exp.name, exp.ent_pc + ), + ))); + } + entries.push(( + exp.name.clone(), + text_rva + text_prologue_len + native_off as u32, + )); + } + for d in &build.dynamic_exports { + if entries.iter().any(|(n, _)| n == &d.name) { + continue; + } + let rva = match d.section { + super::DynamicExportSection::Text => text_rva + text_prologue_len + d.offset as u32, + super::DynamicExportSection::Data => { + if !data_section_present { + return Err(C5Error::Compile(crate::c5::error::fmt_internal_err( + &format!("PE: data export `{}` without a .data section", d.name), + ))); + } + data_rva + d.offset as u32 + } + }; + entries.push((d.name.clone(), rva)); + } + build_export_directory(edata_rva, entries, build.shared_lib_name.as_deref())? } else { Vec::new() }; @@ -779,9 +823,19 @@ pub(super) fn write( // of `b malloc` resolution by some tool versions. let mut coff_symbols: Vec = Vec::new(); if emit_plt_coff_symbols { - for (i, imp) in build.imports.imports.iter().enumerate() { - let trampoline_rva = - text_rva + text_prologue_len + build.plt_trampoline_offsets[i] as u32; + for (imp, off) in build + .imports + .imports + .iter() + .zip(build.plt_trampoline_offsets.iter()) + { + // A data import (bound through the IAT) has no trampoline; + // a text symbol for it would mislabel the code at the + // fabricated RVA. + let Some(tramp_offset) = *off else { + continue; + }; + let trampoline_rva = text_rva + text_prologue_len + tramp_offset as u32; let mut name_field = [0u8; 8]; let name_bytes = imp.local_name.as_bytes(); if name_bytes.len() <= 8 { @@ -1090,13 +1144,13 @@ pub(super) fn write( }); } write_section_headers(&mut out, §ions); - pad_to(&mut out, text_file_off as usize); + pad_to(&mut out, text_file_off as usize)?; out.extend_from_slice(&text_bytes); - pad_to(&mut out, (text_file_off + text_raw_size) as usize); + pad_to(&mut out, (text_file_off + text_raw_size) as usize)?; out.extend_from_slice(&pdata_bytes); - pad_to(&mut out, (pdata_file_off + pdata_raw_size) as usize); + pad_to(&mut out, (pdata_file_off + pdata_raw_size) as usize)?; out.extend_from_slice(&idata_bytes); - pad_to(&mut out, (idata_file_off + idata_raw_size) as usize); + pad_to(&mut out, (idata_file_off + idata_raw_size) as usize)?; if data_section_present { // Apply pointer-to-global initializers in `.data`: // each `int *p = &x;` slot holds the preferred VA @@ -1156,7 +1210,7 @@ pub(super) fn write( pad_to( &mut out, (data_file_off + tls_layout.tls_index_offset_in_data) as usize, - ); + )?; // `_tls_index` -- 4-byte slot, zero-initialised; the // Windows loader writes the chosen slot index here at // module-init time. @@ -1166,7 +1220,7 @@ pub(super) fn write( pad_to( &mut out, (data_file_off + tls_layout.directory_offset_in_data) as usize, - ); + )?; // IMAGE_TLS_DIRECTORY64. Layout: // StartAddressOfRawData : u64 -- VA of init data start // EndAddressOfRawData : u64 -- VA of init data end @@ -1189,13 +1243,13 @@ pub(super) fn write( // subsequent `tls_array[0] + offset` then lands // inside another module's per-thread storage and // reads non-zero data, which trips - // `thread_local_basic.c`'s "counter != 0" check. - // The c5 frontend never produces non-zero TLS init - // bytes today (no `_Thread_local int x = 5;` - // syntax), so emitting the whole block as zero - // template bytes is byte-for-byte identical to the - // SizeOfZeroFill scheme but sidesteps the loader - // edge case. + // the "counter != 0" check in a per-thread test. + // The frontend may produce non-zero TLS init bytes + // (`_Thread_local int x = 5;`); `build.tls_data` + // already holds the init template followed by the + // zero-init tail, so emitting the whole block as + // template bytes carries both correctly and sidesteps + // the empty-template edge case. let tls_init_start_va = IMAGE_BASE + (data_rva + tls_layout.tls_init_offset_in_data) as u64; let tls_init_end_va = tls_init_start_va + build.tls_data.len() as u64; @@ -1207,40 +1261,46 @@ pub(super) fn write( out.extend_from_slice(&0u64.to_le_bytes()); // AddressOfCallBacks out.extend_from_slice(&zero_fill.to_le_bytes()); out.extend_from_slice(&0u32.to_le_bytes()); // Characteristics - // TLS template -- copied verbatim into each - // thread's per-thread region by the loader. The c5 - // frontend zero-initialises every TLS variable - // today, so this is effectively N bytes of zeros. + // TLS template -- copied verbatim into each thread's + // per-thread region by the loader. `tls_data` holds the + // initialised bytes followed by the zero-init tail. out.extend_from_slice(&build.tls_data); } } if reloc_section_present { - pad_to(&mut out, reloc_file_off as usize); + pad_to(&mut out, reloc_file_off as usize)?; out.extend_from_slice(&reloc_bytes); } if edata_section_present { - pad_to(&mut out, edata_file_off as usize); + pad_to(&mut out, edata_file_off as usize)?; out.extend_from_slice(&edata_bytes); } // DWARF debug sections come last in the file image // (before the COFF string table that names them). for slot in &dwarf_pe_sections { - pad_to(&mut out, slot.file_off as usize); + pad_to(&mut out, slot.file_off as usize)?; out.extend_from_slice(&slot.bytes); } // COFF symbol table immediately before its string // table. Both live at the file tail (post-DWARF). Emitted // when there are PLT trampolines; absent otherwise. if !coff_symbols.is_empty() { - pad_to(&mut out, coff_symtab_file_off as usize); + pad_to(&mut out, coff_symtab_file_off as usize)?; out.extend_from_slice(&coff_symbols); } if !coff_strtab.is_empty() { - pad_to(&mut out, coff_strtab_file_off as usize); + pad_to(&mut out, coff_strtab_file_off as usize)?; out.extend_from_slice(&coff_strtab); } - pad_to(&mut out, total_file_size); - debug_assert_eq!(out.len(), total_file_size, "file size mismatch"); + pad_to(&mut out, total_file_size)?; + if out.len() != total_file_size { + return Err(C5Error::Compile(crate::c5::error::fmt_internal_err( + &format!( + "PE layout drift: emitted {:#x} bytes, layout computed {total_file_size:#x}", + out.len(), + ), + ))); + } Ok(out) } @@ -1303,21 +1363,20 @@ struct ImageExportDirectory { const IMAGE_EXPORT_DIRECTORY_SIZE: usize = 40; const _: () = assert!(core::mem::size_of::() == IMAGE_EXPORT_DIRECTORY_SIZE); -/// Build the `.edata` section bytes for a DLL with exports. +/// Build the `.edata` section bytes for an image with exports. /// Layout: `IMAGE_EXPORT_DIRECTORY` followed by /// AddressOfFunctions / AddressOfNames / -/// AddressOfNameOrdinals arrays, then the DLL-name and +/// AddressOfNameOrdinals arrays, then the image-name and /// per-export-name strings (NUL-terminated). /// -/// All RVAs in the directory are image-relative; the -/// `text_prologue_rva` is `text_rva + stub_len`, the byte -/// where `build.text` starts. Each export's runtime RVA is -/// `text_prologue_rva + pc_to_native[ent_pc]`. +/// `exports` pairs each export name with its resolved image-relative +/// RVA (functions and data alike). The name pointer table is lexically +/// ordered, as the loader and GetProcAddress binary-search it; the +/// parallel ordinal table maps each name back to its +/// AddressOfFunctions slot. fn build_export_directory( edata_rva: u32, - text_prologue_rva: u32, - exports: &[crate::c5::program::ExportedFunction], - pc_to_native: &[usize], + exports: Vec<(String, u32)>, image_name: Option<&str>, ) -> Result, C5Error> { let n = exports.len() as u32; @@ -1328,7 +1387,7 @@ fn build_export_directory( let ordinals_off = names_off + 4 * n; let strings_off = ordinals_off + 2 * n; - // The DLL-name string heads the string blob; per-export + // The image-name string heads the string blob; per-export // names follow, each NUL-terminated. We compute their // RVAs as we go so the AddressOfNames entries match. let dll_name = image_name.unwrap_or("c5-output.dll"); @@ -1355,39 +1414,34 @@ fn build_export_directory( }, ); - // AddressOfFunctions -- RVA of each function. - for exp in exports { - let native_off = pc_to_native.get(exp.ent_pc).copied().unwrap_or(usize::MAX); - if native_off == usize::MAX { - return Err(C5Error::Compile(crate::c5::error::fmt_internal_err( - &format!( - "PE: exported function `{}` (bc PC {}) doesn't \ - align with any native instruction", - exp.name, exp.ent_pc - ), - ))); - } - let rva = text_prologue_rva + native_off as u32; + // AddressOfFunctions -- resolved RVA of each export. + for (_, rva) in &exports { out.extend_from_slice(&rva.to_le_bytes()); } + // The name pointer table must be lexically ordered; the parallel + // ordinal table maps each name back to its AddressOfFunctions slot. + let mut by_name: Vec = (0..exports.len()).collect(); + by_name.sort_by(|&a, &b| exports[a].0.as_bytes().cmp(exports[b].0.as_bytes())); + // AddressOfNames -- RVA of each export's name string. let mut cur = strings_rva + dll_name.len() as u32 + 1; - for exp in exports { + for &i in &by_name { out.extend_from_slice(&cur.to_le_bytes()); - cur += exp.name.len() as u32 + 1; + cur += exports[i].0.len() as u32 + 1; } - // AddressOfNameOrdinals -- u16 ordinal per export. - for i in 0..n { + // AddressOfNameOrdinals -- u16 unbiased ordinal per name. + for &i in &by_name { out.extend_from_slice(&(i as u16).to_le_bytes()); } - // String blob: DLL name first, then each export name. + // String blob: image name first, then each export name in + // name-pointer-table order. out.extend_from_slice(dll_name.as_bytes()); out.push(0); - for exp in exports { - out.extend_from_slice(exp.name.as_bytes()); + for &i in &by_name { + out.extend_from_slice(exports[i].0.as_bytes()); out.push(0); } @@ -2853,10 +2907,11 @@ fn patch_aarch64_adrp_ldr( Ok(()) } -/// Patch an aarch64 `adrp xd, _; add xd, xd, #_` pair so the final -/// xd holds the absolute-address-mod-image-base equivalent of -/// `target_rva` (resolved by the loader at fixed image base since -/// we don't ship base relocations). +/// Patch an aarch64 `adrp xd, _; add xd, xd, #_` pair to point at +/// `target_rva`. The encoding is PC-relative: `adrp` takes the signed +/// 4 KiB page delta from its own page and `add` the 12-bit in-page +/// offset, so an ASLR slide moves the instruction and its target by +/// the same delta and the pair needs no base relocation. fn patch_aarch64_adrp_add( text: &mut [u8], adrp_offset_in_text: u32, @@ -2898,10 +2953,21 @@ fn round_up_usize(value: usize, align: usize) -> usize { (value + align - 1) & !(align - 1) } -fn pad_to(out: &mut Vec, target_len: usize) { - if out.len() < target_len { - out.resize(target_len, 0); +/// Zero-pad `out` to the precomputed file offset of the next section. +/// A write cursor already past the target means the layout pass and +/// the emission pass disagree; every later `pointer_to_raw_data` would +/// then be wrong, so that is a hard error rather than a silent overlap. +fn pad_to(out: &mut Vec, target_len: usize) -> Result<(), C5Error> { + if out.len() > target_len { + return Err(C5Error::Compile(crate::c5::error::fmt_internal_err( + &format!( + "PE layout drift: write cursor {:#x} past computed file offset {target_len:#x}", + out.len(), + ), + ))); } + out.resize(target_len, 0); + Ok(()) } #[cfg(test)] @@ -2942,6 +3008,56 @@ mod tests { assert_eq!(round_up(0x201, 0x200), 0x400); } + /// `pad_to` rejects a write cursor already past the layout's + /// computed file offset instead of silently overlapping sections. + #[test] + fn pad_to_rejects_cursor_past_target() { + let mut out = alloc::vec![0u8; 16]; + assert!(pad_to(&mut out, 8).is_err()); + assert!(pad_to(&mut out, 16).is_ok()); + pad_to(&mut out, 32).expect("grow"); + assert_eq!(out.len(), 32); + } + + /// The export name pointer table is binary-searched by + /// GetProcAddress, so `build_export_directory` orders the entries + /// lexically with the ordinal table pointing back at each name's + /// AddressOfFunctions slot. + #[test] + fn export_directory_sorts_names_lexically() { + let bytes = build_export_directory( + 0x5000, + alloc::vec![ + ("zeta".to_string(), 0x1000u32), + ("alpha".to_string(), 0x2000u32), + ], + Some("t.dll"), + ) + .expect("build export directory"); + let name_pos = |needle: &[u8]| { + bytes + .windows(needle.len()) + .position(|w| w == needle) + .expect("name present") + }; + assert!(name_pos(b"alpha\0") < name_pos(b"zeta\0")); + // AddressOfFunctions stays in declaration order. + let funcs_off = IMAGE_EXPORT_DIRECTORY_SIZE; + let rva0 = u32::from_le_bytes(bytes[funcs_off..funcs_off + 4].try_into().unwrap()); + let rva1 = u32::from_le_bytes(bytes[funcs_off + 4..funcs_off + 8].try_into().unwrap()); + assert_eq!((rva0, rva1), (0x1000, 0x2000)); + // Ordinal table (after funcs + names arrays) maps sorted names + // back to their slots: alpha -> slot 1, zeta -> slot 0. + let ordinals_off = funcs_off + 4 * 2 + 4 * 2; + let ord0 = u16::from_le_bytes(bytes[ordinals_off..ordinals_off + 2].try_into().unwrap()); + let ord1 = u16::from_le_bytes( + bytes[ordinals_off + 2..ordinals_off + 4] + .try_into() + .unwrap(), + ); + assert_eq!((ord0, ord1), (1, 0)); + } + /// The packed AArch64 RUNTIME_FUNCTION encodes `FunctionLength` /// in 11 bits (units = 4-byte instructions). The maximum /// representable value is `0x7FF == 2047` instructions; a @@ -3042,6 +3158,62 @@ mod tests { assert_eq!(size, 0, "TLS size must be 0 when no TLS present"); } + /// A PE executable may legally carry an export directory (a plugin + /// host publishing its API for GetProcAddress). `--export-all` / + /// `--export-data` reach PE executables through `dynamic_exports`; + /// the flags previously no-op'd for PE, leaving the directory empty. + #[test] + fn executable_dynamic_exports_emit_export_directory() { + use crate::Compiler; + let program = Compiler::new("int main() { return 0; }".to_string()) + .compile() + .expect("compile"); + let mut build = lower_for( + &program, + super::super::Target::WindowsX64, + super::super::NativeOptions::default(), + ) + .expect("lower"); + build.dynamic_exports = alloc::vec![crate::c5::codegen::DynamicExport { + name: "bump".to_string(), + section: super::super::DynamicExportSection::Text, + offset: 0, + }]; + let bytes = write( + &program, + &build, + Machine::X86_64, + super::super::Target::WindowsX64, + ) + .expect("write PE"); + let (rva, size) = read_data_directory(&bytes, DATA_DIRECTORY_EXPORT); + assert_ne!(rva, 0, "export directory RVA must be set"); + assert_ne!(size, 0, "export directory size must be set"); + assert!( + bytes.windows(5).any(|w| w == b"bump\0"), + "the export name must appear in the image" + ); + + // Without dynamic exports the executable carries no directory. + let plain = write( + &program, + &lower_for( + &program, + super::super::Target::WindowsX64, + super::super::NativeOptions::default(), + ) + .expect("lower"), + Machine::X86_64, + super::super::Target::WindowsX64, + ) + .expect("write PE"); + assert_eq!( + read_data_directory(&plain, DATA_DIRECTORY_EXPORT), + (0, 0), + "a plain executable must carry no export directory" + ); + } + /// PE with `_Thread_local`: TLS directory entry must point /// at a non-empty IMAGE_TLS_DIRECTORY64 of size 40, and the /// directory's contents must reference plausible RVAs (well diff --git a/src/c5/op.rs b/src/c5/op.rs index afe7dcfc4..3a32ffd24 100644 --- a/src/c5/op.rs +++ b/src/c5/op.rs @@ -186,6 +186,16 @@ pub enum Intrinsic { /// (eax/edx destinations) then the input value (ecx = register index). /// x86_64 only. The interpreter zeroes the outputs. Xgetbv = 45, + /// Read the current per-frame alloca-arena top pointer (the + /// bookkeeping slot the matching `AllocaInit` set up). Takes no + /// argument, returns the top. Used to snapshot the arena on entry + /// to a block that declares a variable-length array (C99 6.7.6.2) + /// so the storage is reclaimed on block exit. + AllocaSave = 46, + /// Write the per-frame alloca-arena top pointer back to a value a + /// prior `AllocaSave` captured. One argument (the saved top); + /// returns nothing. Reclaims a VLA block's storage on exit. + AllocaRestore = 47, } impl Intrinsic { @@ -236,6 +246,8 @@ impl Intrinsic { 43 => Some(Intrinsic::AtomicThreadFence), 44 => Some(Intrinsic::Cpuid), 45 => Some(Intrinsic::Xgetbv), + 46 => Some(Intrinsic::AllocaSave), + 47 => Some(Intrinsic::AllocaRestore), _ => None, } } diff --git a/src/c5/preprocessor.rs b/src/c5/preprocessor.rs index 38ffbe594..9c800b5eb 100644 --- a/src/c5/preprocessor.rs +++ b/src/c5/preprocessor.rs @@ -177,6 +177,9 @@ pub(crate) struct Preprocessor { // string-prefix compares were the leftover frontend hot spot // after the symbol-table fix went in. macros: HashMap, + /// Compilation target; Windows include resolution is + /// case-insensitive, matching its filesystems. + target: Target, fn_macros: HashMap, /// One entry per `#pragma dylib(name, "path")`, in the order /// declared. Each entry collects the bindings whose @@ -487,7 +490,8 @@ impl Preprocessor { // thread-local storage. GCC and clang made the same choice while // they lacked ``. `` is provided, so // `__STDC_NO_ATOMICS__` also stays undefined. - macros.insert("__STDC_NO_VLA__".to_string(), "1".to_string()); + // `__STDC_NO_VLA__` stays undefined: c5 supports C99 6.7.6.2 + // variable-length arrays (single dimension, block scope). macros.insert("__STDC_NO_COMPLEX__".to_string(), "1".to_string()); macros.insert( "__DATE__".to_string(), @@ -532,6 +536,13 @@ impl Preprocessor { Target::MacOSAarch64 => { macros.insert("__APPLE__".to_string(), "1".to_string()); macros.insert("__MACH__".to_string(), "1".to_string()); + // Deployment target, decimal MMmmpp. Matches the 11.0 + // minimum OS version stamped into LC_BUILD_VERSION; + // derives its version gates from it. + macros.insert( + "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__".to_string(), + "110000".to_string(), + ); } Target::LinuxAarch64 | Target::LinuxX64 => { macros.insert("__linux__".to_string(), "1".to_string()); @@ -558,6 +569,7 @@ impl Preprocessor { } Self { macros, + target, fn_macros, dylibs: Vec::new(), exports: Vec::new(), @@ -714,6 +726,9 @@ impl Preprocessor { /// about; the top-level call uses `""`, `#include`'d /// files use the header name (`"stdio.h"`). fn process_named(&mut self, source: &str, filename: &str) -> Result { + // A UTF-8 byte-order mark opening the file is accepted and + // skipped, following gcc and clang. + let source = source.strip_prefix('\u{feff}').unwrap_or(source); // c99 sec 5.1.1.2 phase 2: every `\\\n` joins lines. We do this // up-front so the line-by-line preprocessor never sees a // continuation. Line counts are preserved by emitting blank @@ -868,7 +883,7 @@ impl Preprocessor { active = taken; } Directive::If(expr) => { - let taken = active && self.eval_condition(expr, source_line)?; + let taken = active && self.eval_condition(expr, source_line, filename)?; cond_stack.push(CondFrame { parent_active: active, this_branch_taken: taken, @@ -878,73 +893,18 @@ impl Preprocessor { active = taken; } Directive::Else => { - let frame = cond_stack.last_mut().ok_or_else(|| { - C5Error::Compile(super::error::fmt_compile_err( - filename, - line_no, - "`#else` with no matching `#if`", - )) - })?; - if frame.saw_else { - return Err(C5Error::Compile(super::error::fmt_compile_err( - filename, - line_no, - "duplicate `#else` for the same `#if`", - ))); - } - frame.saw_else = true; - let taken = frame.parent_active && !frame.any_branch_taken; - frame.this_branch_taken = taken; - frame.any_branch_taken |= taken; - active = taken; + active = apply_else(&mut cond_stack, filename, line_no)?; } Directive::Elif(expr) => { - // The directive eval needs a `&Self`, but - // `cond_stack.last_mut()` borrows `self` for - // the frame -- evaluate the expression first - // and only then mutate the frame. - let parent_active = - cond_stack.last().map(|f| f.parent_active).ok_or_else(|| { - C5Error::Compile(super::error::fmt_compile_err( - filename, - line_no, - "`#elif` with no matching `#if`", - )) - })?; - let any_taken_so_far = cond_stack - .last() - .map(|f| f.any_branch_taken) - .unwrap_or(false); - let eligible = parent_active && !any_taken_so_far; - let cond = if eligible { - self.eval_condition(expr, source_line)? - } else { - false - }; - // Non-empty by the `parent_active` ok_or_else above. - let frame = cond_stack - .last_mut() - .expect("cond_stack non-empty after parent_active check"); - if frame.saw_else { - return Err(C5Error::Compile(super::error::fmt_compile_err( - filename, - line_no, - "`#elif` after `#else` for the same `#if`", - ))); - } - frame.this_branch_taken = cond; - frame.any_branch_taken |= cond; - active = cond; + // The directive eval needs a `&Self`, but the + // frame update borrows `cond_stack` -- check + // eligibility first, evaluate, then mutate. + let eligible = elif_eligible(&cond_stack, filename, line_no)?; + let cond = eligible && self.eval_condition(expr, source_line, filename)?; + active = apply_elif(&mut cond_stack, cond, filename, line_no)?; } Directive::Endif => { - let frame = cond_stack.pop().ok_or_else(|| { - C5Error::Compile(super::error::fmt_compile_err( - filename, - line_no, - "`#endif` with no matching `#if`", - )) - })?; - active = frame.parent_active; + active = apply_endif(&mut cond_stack, filename, line_no)?; } Directive::Pragma(args) => { if active { @@ -1234,8 +1194,8 @@ impl Preprocessor { join_active = taken; } Directive::If(expr) => { - let taken = - join_active && self.eval_condition(expr, source_line)?; + let taken = join_active + && self.eval_condition(expr, source_line, filename)?; join_stack.push(CondFrame { parent_active: join_active, this_branch_taken: taken, @@ -1244,37 +1204,45 @@ impl Preprocessor { }); join_active = taken; } + // An `#elif` / `#else` / `#endif` with no + // frame opened inside the argument list + // belongs to the conditional enclosing the + // macro call; apply it to the outer stack so + // argument gathering resumes in the right + // branch and the outer frame still closes. Directive::Elif(expr) => { - let parent_active = - join_stack.last().map(|f| f.parent_active).unwrap_or(false); - let any_taken = join_stack - .last() - .map(|f| f.any_branch_taken) - .unwrap_or(true); - let eligible = parent_active && !any_taken; - let cond = if eligible { - self.eval_condition(expr, source_line)? + let stack = if join_stack.is_empty() { + &mut cond_stack } else { - false + &mut join_stack }; - if let Some(frame) = join_stack.last_mut() { - frame.this_branch_taken = cond; - frame.any_branch_taken |= cond; + let eligible = elif_eligible(stack, filename, source_line)?; + let cond = + eligible && self.eval_condition(expr, source_line, filename)?; + let taken = apply_elif(stack, cond, filename, source_line)?; + if join_stack.is_empty() { + active = taken; } - join_active = cond; + join_active = taken; } Directive::Else => { - if let Some(frame) = join_stack.last_mut() { - let taken = frame.parent_active && !frame.any_branch_taken; - frame.saw_else = true; - frame.this_branch_taken = taken; - frame.any_branch_taken |= taken; - join_active = taken; + let stack = if join_stack.is_empty() { + &mut cond_stack + } else { + &mut join_stack + }; + let taken = apply_else(stack, filename, source_line)?; + if join_stack.is_empty() { + active = taken; } + join_active = taken; } Directive::Endif => { if let Some(frame) = join_stack.pop() { join_active = frame.parent_active; + } else { + active = apply_endif(&mut cond_stack, filename, source_line)?; + join_active = active; } } // Other directives inside a macro argument are @@ -1770,10 +1738,19 @@ impl Preprocessor { // INC(...) calls expanded too. Hot path is the // not-a-macro case -- the early `None` saves an // allocation per source identifier. - match self.expand(ident) { + match self.expand_chain(ident) { None => out.push_str(ident), - Some(expanded) => { - let nested = Blocklist::Cons(ident, blocklist); + Some((expanded, chain)) => { + // Paint the name and every chain intermediate + // (C99 6.10.3.4p2) so the rescan cannot re-fire + // a macro the walk already went through. + let mut painted: Vec<&str> = alloc::vec![ident]; + for c in &chain { + if !painted.contains(&c.as_str()) { + painted.push(c); + } + } + let nested = Blocklist::Many(&painted, blocklist); // Token-stream rescan (C99 6.10.3.4): if the // expansion is a single identifier and the // *source* token immediately after the @@ -1880,18 +1857,31 @@ impl Preprocessor { /// non-macro identifiers than macro hits) and lets callers skip /// allocating a String just to compare it back against the input. fn expand(&self, name: &str) -> Option { + self.expand_chain(name).map(|(body, _)| body) + } + + /// `expand` plus the chain of intermediate macro names the walk + /// passed through. C99 6.10.3.4p2 paints every name replaced + /// during the rescan, so the caller must add the chain to the + /// blocklist -- otherwise a terminal body that re-mentions an + /// intermediate (`#define B C` / `#define C B x`) re-fires it and + /// duplicates tokens. A revisited name ends the walk. + fn expand_chain(&self, name: &str) -> Option<(String, Vec)> { let first = self.macros.get(name)?; - // We've got at least one substitution. Follow the - // `#define A B` -> `#define B 5` chain up to a fixed depth so - // a `#define A A` self-loop doesn't spin forever. + let mut chain: Vec = Vec::new(); let mut current = first.clone(); - for _ in 0..32 { + while chain.len() < 32 { + if current == name || chain.iter().any(|c| c == ¤t) { + break; + } match self.macros.get(¤t) { - Some(next) if next != ¤t => current = next.clone(), - _ => break, + Some(next) => { + chain.push(core::mem::replace(&mut current, next.clone())); + } + None => break, } } - Some(current) + Some((current, chain)) } /// `expand` but with the original name returned (allocated as a @@ -1919,21 +1909,8 @@ impl Preprocessor { i += 1; continue; } - // Strip `/* ... */` block comments and `// ...` line - // comments. They show up routinely on `#if` lines. - if bytes[i] == b'/' && bytes.get(i + 1) == Some(&b'*') { - i += 2; - while i + 1 < bytes.len() && !(bytes[i] == b'*' && bytes[i + 1] == b'/') { - i += 1; - } - i = (i + 2).min(bytes.len()); - out.push(' '); - continue; - } - if bytes[i] == b'/' && bytes.get(i + 1) == Some(&b'/') { - i = bytes.len(); - continue; - } + // Comments were removed in phase 3; the literal-aware + // strip after substitution covers macro-introduced ones. // Match `defined` keyword (must be a complete word). if bytes[i..].starts_with(b"defined") { let after = i + b"defined".len(); @@ -1987,14 +1964,15 @@ impl Preprocessor { } // Now expand all remaining identifiers (object + function- // like) via the standard substitute pass. Then strip block - // and line comments from the result -- macro bodies can - // carry inline `/* ... */` comments that survive expansion - // and would otherwise confuse the expression tokenizer. + // and line comments from the result -- driver-predefined + // macro bodies never went through phase 3 and can carry + // comments that would confuse the expression tokenizer. + // `strip_c_comments` keeps string and char literals intact. let substituted = self.substitute(&out, "<#if>", line_no); - strip_comments(&substituted) + strip_c_comments(&substituted) } - fn eval_condition(&self, expr: &str, line_no: usize) -> Result { + fn eval_condition(&self, expr: &str, line_no: usize, filename: &str) -> Result { // Full c99 `#if` expression evaluator: integer constants, // identifiers (treated as 0 if undefined), `defined(X)`, // unary `!`, comparisons, and boolean operators with @@ -2011,7 +1989,7 @@ impl Preprocessor { // substitute would otherwise expand X away. let prepared = self.expand_for_if(expr, line_no); self.take_pending_error()?; - let mut p = IfExprParser::new(&prepared, self); + let mut p = IfExprParser::new(&prepared, self, filename); let v = p.parse_ternary()?; p.skip_ws(); if !p.at_end() { @@ -2710,8 +2688,8 @@ impl Preprocessor { self.finish_include(resolved, name, line_no, filename) } - /// Shared tail of `process_include` / `process_include_next`: warn on a - /// miss, honour `#pragma once`, bound the include depth, and process + /// Shared tail of `process_include` / `process_include_next`: error on + /// a miss, honour `#pragma once`, bound the include depth, and process /// the resolved body. fn finish_include( &mut self, @@ -2721,19 +2699,22 @@ impl Preprocessor { filename: &str, ) -> Result { let Some((content, resolved_path)) = resolved else { - // Missing header. Push a warning into the same list - // the parser uses; the caller drains it through to - // `Program::warnings` after the compile finishes. - self.warnings.push(format!( - "{filename}:{line_no}: warning: include `{name}` not found, \ - dropping (no header search path or embedded header matched)" - )); + // Missing header is a hard error, as in gcc/clang: the + // directive cannot perform the replacement C99 6.10.2 + // requires, and continuing with an empty body miscompiles. if self.show_includes { let depth = self.include_stack.len() + 1; self.include_trace .push(format!("{} {} (missing)", "!".repeat(depth), name)); } - return Ok(String::new()); + return Err(C5Error::Compile(super::error::fmt_compile_err( + filename, + line_no, + &format!( + "include `{name}` not found \ + (no header search path or embedded header matched)" + ), + ))); }; // `#pragma once` dedups by the resolved path (file identity), // not the include spelling, so two different spellings that @@ -2809,7 +2790,19 @@ impl Preprocessor { } } let _ = source_dir; - embedded_header(name).map(|s| (s.to_string(), name.to_string())) + if let Some(body) = embedded_header(name) { + return Some((body.to_string(), name.to_string())); + } + // Windows resolves includes case-insensitively (its filesystems + // are); match the embedded registry the same way there. + if matches!(self.target, Target::WindowsX64 | Target::WindowsAarch64) { + let lower = name.to_ascii_lowercase(); + return super::headers::embedded_headers() + .iter() + .find(|(n, _)| n.eq_ignore_ascii_case(&lower)) + .map(|(n, body)| (body.to_string(), n.to_string())); + } + None } /// Resolve `name` for `#include_next`: skip search-path entries up to @@ -2985,33 +2978,6 @@ impl Blocklist<'_> { } } -/// Strip C-style `/* ... */` block comments and `// ...` line -/// comments from a single-line buffer. Used on the post-macro- -/// expansion `#if` expression where inlined comments would -/// otherwise confuse the expression tokenizer. -fn strip_comments(s: &str) -> String { - let mut out = String::with_capacity(s.len()); - let bytes = s.as_bytes(); - let mut i = 0; - while i < bytes.len() { - if bytes[i] == b'/' && bytes.get(i + 1) == Some(&b'*') { - i += 2; - while i + 1 < bytes.len() && !(bytes[i] == b'*' && bytes[i + 1] == b'/') { - i += 1; - } - i = (i + 2).min(bytes.len()); - out.push(' '); - continue; - } - if bytes[i] == b'/' && bytes.get(i + 1) == Some(&b'/') { - break; - } - out.push(bytes[i] as char); - i += 1; - } - out -} - /// Phase-3 comment removal: strip `/* ... */` block comments and /// `// ...` line comments from the entire source. Each comment is /// replaced by a single space so token boundaries are preserved @@ -3430,6 +3396,89 @@ impl CondFrame { } } +/// `#else` state transition on the innermost frame; returns the new +/// active state. Shared by the main directive loop and the +/// macro-argument line joiner so both agree on the semantics. +fn apply_else(stack: &mut [CondFrame], filename: &str, line_no: usize) -> Result { + let frame = stack.last_mut().ok_or_else(|| { + C5Error::Compile(super::error::fmt_compile_err( + filename, + line_no, + "`#else` with no matching `#if`", + )) + })?; + if frame.saw_else { + return Err(C5Error::Compile(super::error::fmt_compile_err( + filename, + line_no, + "duplicate `#else` for the same `#if`", + ))); + } + frame.saw_else = true; + let taken = frame.parent_active && !frame.any_branch_taken; + frame.this_branch_taken = taken; + frame.any_branch_taken |= taken; + Ok(taken) +} + +/// Whether an `#elif` on the innermost frame is eligible to take +/// (parent branch active, no earlier arm taken). C99 6.10.1p3: the +/// controlling expression of an ineligible group is not evaluated, +/// so the caller evaluates only when this returns true. +fn elif_eligible(stack: &[CondFrame], filename: &str, line_no: usize) -> Result { + let frame = stack.last().ok_or_else(|| { + C5Error::Compile(super::error::fmt_compile_err( + filename, + line_no, + "`#elif` with no matching `#if`", + )) + })?; + Ok(frame.parent_active && !frame.any_branch_taken) +} + +/// `#elif` state transition with the already-evaluated condition; +/// returns the new active state. +fn apply_elif( + stack: &mut [CondFrame], + cond: bool, + filename: &str, + line_no: usize, +) -> Result { + let frame = stack.last_mut().ok_or_else(|| { + C5Error::Compile(super::error::fmt_compile_err( + filename, + line_no, + "`#elif` with no matching `#if`", + )) + })?; + if frame.saw_else { + return Err(C5Error::Compile(super::error::fmt_compile_err( + filename, + line_no, + "`#elif` after `#else` for the same `#if`", + ))); + } + frame.this_branch_taken = cond; + frame.any_branch_taken |= cond; + Ok(cond) +} + +/// `#endif` pops the innermost frame; returns the restored active state. +fn apply_endif( + stack: &mut Vec, + filename: &str, + line_no: usize, +) -> Result { + let frame = stack.pop().ok_or_else(|| { + C5Error::Compile(super::error::fmt_compile_err( + filename, + line_no, + "`#endif` with no matching `#if`", + )) + })?; + Ok(frame.parent_active) +} + enum Directive<'a> { /// Object-like macro: `#define NAME body`. Define(&'a str, &'a str), @@ -3549,18 +3598,9 @@ fn parse_directive(rest: &str) -> Directive<'_> { if let Some(after) = rest.strip_prefix("define") { let after = after.trim_start(); let (name, rest_after_name) = split_ident(after); - // Strip `//` line comments from the macro body. Otherwise - // `#define X 42 // a constant` would expand to "42 // a - // constant", and the comment text would either swallow the - // rest of the substitution line (lexer treats `//` as - // line-comment) or land in the token stream and break - // parsing. C `/* ... */` comments inside macro bodies - // aren't supported elsewhere in this dialect, so we don't - // try to strip those. - let stripped = match rest_after_name.find("//") { - Some(i) => &rest_after_name[..i], - None => rest_after_name, - }; + // Comments were removed in translation phase 3 (C99 5.1.1.2) + // before directives execute, so `//` or `/*` remaining here + // can only be string- or char-literal content and must stay. // Function-like form: name immediately followed by `(`. The // C standard requires no whitespace between the name and the // open paren -- a space turns it into an object-like macro @@ -3568,7 +3608,7 @@ fn parse_directive(rest: &str) -> Directive<'_> { // to the object-like branch with the whole tail as the body, // matching how the lexer would see a syntactically broken // `#define`. - if let Some(after_paren) = stripped.strip_prefix('(') + if let Some(after_paren) = rest_after_name.strip_prefix('(') && let Some(close) = after_paren.find(')') { let params_str = &after_paren[..close]; @@ -3580,7 +3620,7 @@ fn parse_directive(rest: &str) -> Directive<'_> { }; return Directive::DefineFn(name, params, body); } - return Directive::Define(name, stripped.trim()); + return Directive::Define(name, rest_after_name.trim()); } if let Some(after) = rest.strip_prefix("undef") { return Directive::Undef(after.trim()); @@ -4038,6 +4078,11 @@ struct IfExprParser<'a> { src: &'a str, pos: usize, pp: &'a Preprocessor, + /// Path of the file whose `#if` is being evaluated; + /// `__has_include("h")` resolves its quoted form against this + /// file's directory, and `__has_include_next` resumes the search + /// past this file's search-path entry. + filename: &'a str, /// Recursion depth, bounded by [`MAX_IF_EXPR_DEPTH`]. Every recursive /// cycle in the grammar passes through `parse_unary`, so the bound is /// checked there. @@ -4050,11 +4095,12 @@ struct IfExprParser<'a> { } impl<'a> IfExprParser<'a> { - fn new(src: &'a str, pp: &'a Preprocessor) -> Self { + fn new(src: &'a str, pp: &'a Preprocessor, filename: &'a str) -> Self { Self { src, pos: 0, pp, + filename, depth: 0, live: true, } @@ -4138,7 +4184,15 @@ impl<'a> IfExprParser<'a> { self.live = saved && !cond.truthy(); let else_v = self.parse_ternary()?; self.live = saved; - Ok(if cond.truthy() { then_v } else { else_v }) + // C99 6.5.15p5: the arms undergo the usual arithmetic + // conversions, so either arm being unsigned makes the result + // unsigned regardless of which arm is picked. + let uns = then_v.is_unsigned() || else_v.is_unsigned(); + let picked = if cond.truthy() { then_v } else { else_v }; + Ok(match picked { + IfValue::Int { val, .. } => IfValue::with_sign(val, uns), + other => other, + }) } fn parse_and(&mut self) -> Result { @@ -4439,34 +4493,73 @@ impl<'a> IfExprParser<'a> { self.pos += 1; } if self.eat_byte(b'\'') { - // Character literal -- a single byte, optionally escaped. - // Multi-char (`'AB'`) is implementation-defined; we use - // the last byte, which matches gcc's choice. + // Character literal. Multi-char (`'AB'`) is + // implementation-defined; each byte shifts into the + // accumulator, matching gcc. let bytes = self.src.as_bytes(); let mut acc: i64 = 0; + let mut count = 0usize; while let Some(b) = self.peek_byte() { if b == b'\'' { self.pos += 1; + // C99 6.4.4.4p10: a single-character constant has + // the char's value as int -- sign-extended on + // signed-plain-char targets, matching the lexer. + if count == 1 && self.pp.target.plain_char_signed() && (0..=0xFF).contains(&acc) + { + acc = acc as u8 as i8 as i64; + } return Ok(IfValue::signed(acc)); } + count += 1; if b == b'\\' && self.pos + 1 < bytes.len() { self.pos += 2; let esc = bytes[self.pos - 1]; - let ch = match esc { + // C99 6.4.4.4: simple, octal (`\N` up to three + // digits), and hexadecimal (`\xN...`) escapes. + let ch: i64 = match esc { b'n' => 0x0A, b't' => 0x09, b'r' => 0x0D, - b'0' => 0x00, - b'\\' => b'\\', - b'\'' => b'\'', - b'"' => b'"', + b'\\' => b'\\' as i64, + b'\'' => b'\'' as i64, + b'"' => b'"' as i64, b'a' => 0x07, b'b' => 0x08, b'f' => 0x0C, b'v' => 0x0B, - other => other, + b'x' => { + let mut v: i64 = 0; + while let Some(&h) = bytes.get(self.pos) { + let d = match h { + b'0'..=b'9' => h - b'0', + b'a'..=b'f' => h - b'a' + 10, + b'A'..=b'F' => h - b'A' + 10, + _ => break, + }; + v = (v << 4) | d as i64; + self.pos += 1; + } + v & 0xFF + } + b'0'..=b'7' => { + let mut v = (esc - b'0') as i64; + let mut n = 1; + while n < 3 { + match bytes.get(self.pos) { + Some(&o @ b'0'..=b'7') => { + v = (v << 3) | (o - b'0') as i64; + self.pos += 1; + n += 1; + } + _ => break, + } + } + v + } + other => other as i64, }; - acc = (acc << 8) | (ch as i64); + acc = (acc << 8) | ch; } else { acc = (acc << 8) | (b as i64); self.pos += 1; @@ -4648,7 +4741,22 @@ impl<'a> IfExprParser<'a> { "preprocessor: missing `)` in `__has_include`".to_string(), )); } - let found = self.pp.find_include(&header, None).is_some(); + // Resolve exactly as the matching directive would: the + // quoted form probes the including file's directory first + // (C99 6.10.2p2), and `__has_include_next` resumes past + // the search-path entry that supplied the current file. + let found = if name == "__has_include_next" { + self.pp.find_include_next(&header, self.filename).is_some() + } else { + let source_dir = if close == b'"' { + include_parent_dir(self.filename) + } else { + None + }; + self.pp + .find_include(&header, source_dir.as_deref()) + .is_some() + }; return Ok(IfValue::signed(found as i64)); } // Identifier -- look up in the macro table. Function-like @@ -5398,6 +5506,31 @@ mod tests { assert!(!out.contains("// a constant")); } + #[test] + fn define_body_keeps_slashes_inside_string_literal() { + // Comment removal happens in translation phase 3 (C99 + // 5.1.1.2), where a quoted string is opaque; `//` and `/*` + // inside one are literal content, not comment openers. + let out = process( + "#define URL \"http://x.com/*y*/\"\n#define P 'a' // note\nconst char *u = URL;\nchar c = P;\n", + ); + assert!( + out.contains("const char *u = \"http://x.com/*y*/\";"), + "string body truncated:\n{out}" + ); + assert!(out.contains("char c = 'a';"), "{out}"); + } + + #[test] + fn if_string_comparison_keeps_slashes_inside_literal() { + // The `#if` expression strip must also treat literals as + // opaque; `//` inside a compared string is not a comment. + let src = "#define U \"a//b\"\n#if U == \"a//b\"\nint yes;\n#else\nint no;\n#endif\n"; + let out = process(src); + assert!(out.contains("int yes;"), "{out:?}"); + assert!(!out.contains("int no;"), "{out:?}"); + } + #[test] fn ifdef_keeps_active_branch() { let src = "#define FOO 1\n#ifdef FOO\nint a;\n#else\nint b;\n#endif\n"; @@ -5618,23 +5751,18 @@ mod tests { } #[test] - fn unknown_include_is_silently_dropped() { - // Headers not in the embedded registry no-op so legacy - // sources sprinkled with `#include ` keep building - // until a real header takes that slot. The compile keeps - // going; the warning surfaces separately via - // `pp.warnings`. + fn unknown_include_is_a_hard_error() { + // A header that resolves nowhere aborts the compile, as in + // gcc/clang; continuing with an empty body would miscompile. let mut pp = Preprocessor::new("macos-aarch64", Target::MacOSAarch64, "0.1.0"); - let out = pp + let err = pp .process("#include \nint main() { return 0; }\n") - .expect("preprocessor failed"); - assert!(out.contains("int main()")); - assert_eq!(pp.warnings.len(), 1); - assert!( - pp.warnings[0].contains("not found"), - "missing-include warning shape: {}", - pp.warnings[0] - ); + .expect_err("missing include must fail"); + let C5Error::Compile(msg) = err else { + panic!("expected a compile error"); + }; + assert!(msg.contains("not-a-real-header.h"), "{msg}"); + assert!(msg.contains("not found"), "{msg}"); } #[test] @@ -5846,7 +5974,7 @@ int x_2 = __COUNTER__; pp.set_show_includes(true); let _ = pp .process("#include \nint main() { return 0; }\n") - .expect("preprocessor failed"); + .expect_err("missing include must fail"); assert!( pp.include_trace .iter() @@ -5858,11 +5986,18 @@ int x_2 = __COUNTER__; #[test] fn quoted_include_form_is_recognised() { - // `"foo.h"` and `` go through the same registry today. - // The quoted form is still parsed -- we'd just look it up the - // same way -- so an unknown name no-ops cleanly. - let out = process("#include \"not-a-real-header.h\"\nint main() {}\n"); - assert!(out.contains("int main()")); + // `"foo.h"` resolves through the same search chain as + // `` (C99 6.10.2p2/p3), so a search-path hit works + // for both spellings. + let base = std::env::temp_dir().join(format!("badc-quoted-inc-{}", std::process::id())); + std::fs::create_dir_all(&base).unwrap(); + std::fs::write(base.join("foo.h"), "int from_quoted;\n").unwrap(); + let mut pp = Preprocessor::new("macos-aarch64", Target::MacOSAarch64, "0.1.0"); + pp.add_search_path(base.to_str().unwrap()); + let out = pp.process("#include \"foo.h\"\nint main() {}\n").unwrap(); + std::fs::remove_dir_all(&base).ok(); + assert!(out.contains("from_quoted"), "{out}"); + assert!(out.contains("int main()"), "{out}"); } #[test] @@ -5879,6 +6014,119 @@ int x_2 = __COUNTER__; super::include_parent_dir("/abs/dir/src.c"), Some("/abs/dir".to_string()) ); + // The stdin label behaves like a bare filename: gcc resolves a + // quoted include in piped source against the working directory. + assert_eq!(super::include_parent_dir("-"), Some(String::new())); + } + + #[test] + fn object_like_alias_chain_blue_paints_intermediates() { + // C99 6.10.3.4p2: every name replaced on the way to the terminal + // body stays painted for the rescan. Without that, the rescan of + // `B x` re-fires B -> C -> `B x` and duplicates the tail. + let out = process("#define A B\n#define B C\n#define C B x\nA\n"); + let line = out.lines().rfind(|l| !l.trim().is_empty()).unwrap_or(""); + assert_eq!(line.trim(), "B x", "{out}"); + // Mutual recursion through an alias stops at the painted name. + let out = process("#define P Q\n#define Q P\nP\n"); + let line = out.lines().rfind(|l| !l.trim().is_empty()).unwrap_or(""); + assert_eq!(line.trim(), "P", "{out}"); + } + + #[test] + fn if_char_constant_decodes_hex_and_octal_escapes() { + for e in [ + "'\\x41' == 65", + "'\\101' == 65", + // Signed plain char on this target: '\xff' sign-extends. + "'\\xff' == -1", + "'\\x7f' == 127", + "'\\0' == 0", + "'\\11' == 9", + "'AB' == 0x4142", + ] { + let out = process(&format!("#if {e}\nTAKEN\n#else\nNOT\n#endif\n")); + assert!(out.contains("TAKEN"), "{e}: {out}"); + } + } + + #[test] + fn if_ternary_applies_usual_arithmetic_conversions() { + // C99 6.5.15p5: the arms convert to a common type, so an + // unsigned arm makes the picked signed arm's value unsigned. + for e in ["(1 ? -1 : 0u) > 0", "(0 ? 0u : -1) > 0"] { + let out = process(&format!("#if {e}\nTAKEN\n#else\nNOT\n#endif\n")); + assert!(out.contains("TAKEN"), "{e}: {out}"); + } + // Both arms signed: the value stays signed. + let out = process("#if (1 ? -1 : 0) < 0\nTAKEN\n#endif\n"); + assert!(out.contains("TAKEN"), "{out}"); + } + + #[test] + fn macro_args_split_across_an_enclosing_conditional() { + // An `#else` / `#endif` seen while joining macro-argument lines + // with no locally opened frame belongs to the enclosing + // conditional: the joiner must apply it to the outer stack, skip + // the inactive branch's lines, and leave the block terminated. + let src = "#define m(a,b) a+b\n#define A 1\n#if A\nint x = m(1,\n#else\nint x = m(2,\n#endif\n3);\n"; + let out = process(src); + assert!(out.contains("1+3"), "{out}"); + assert!(!out.contains("2+"), "{out}"); + // The not-taken arm joins the other branch's argument line. + let src = "#define m(a,b) a+b\n#if 0\nint x = m(1,\n#else\nint x = m(2,\n#endif\n3);\n"; + let out = process(src); + assert!(out.contains("2+3"), "{out}"); + } + + #[test] + fn has_include_quoted_form_searches_the_including_dir() { + // C99 6.10.2p2 via C23 6.10.1: the quoted `__has_include` form + // probes the including file's directory exactly as the matching + // `#include "h"` would. + let base = std::env::temp_dir().join(format!("badc-hasinc-{}", std::process::id())); + std::fs::create_dir_all(&base).unwrap(); + std::fs::write(base.join("inner.h"), "int inner;\n").unwrap(); + std::fs::write( + base.join("probe.h"), + "#if __has_include(\"inner.h\")\nint FOUND;\n#else\nint MISSING;\n#endif\n", + ) + .unwrap(); + let mut pp = Preprocessor::new("macos-aarch64", Target::MacOSAarch64, "0.1.0"); + pp.add_search_path(base.to_str().unwrap()); + let out = pp.process("#include \n").unwrap(); + std::fs::remove_dir_all(&base).ok(); + assert!(out.contains("FOUND"), "{out}"); + } + + #[test] + fn has_include_next_resumes_after_the_current_entry() { + // `__has_include_next` must answer what `#include_next` would + // resolve: found through a later search-path entry, not the + // probing shim's own file. + let base = std::env::temp_dir().join(format!("badc-hasincnext-{}", std::process::id())); + let d1 = base.join("d1"); + let d2 = base.join("d2"); + std::fs::create_dir_all(&d1).unwrap(); + std::fs::create_dir_all(&d2).unwrap(); + std::fs::write( + d1.join("foo.h"), + "#if __has_include_next()\nint NEXT_FOUND;\n#else\nint NEXT_MISSING;\n#endif\n", + ) + .unwrap(); + std::fs::write(d2.join("foo.h"), "int real;\n").unwrap(); + + let mut pp = Preprocessor::new("macos-aarch64", Target::MacOSAarch64, "0.1.0"); + pp.add_search_path(d1.to_str().unwrap()); + pp.add_search_path(d2.to_str().unwrap()); + let out = pp.process("#include \n").unwrap(); + assert!(out.contains("NEXT_FOUND"), "{out}"); + + let mut pp = Preprocessor::new("macos-aarch64", Target::MacOSAarch64, "0.1.0"); + pp.add_search_path(d1.to_str().unwrap()); + let out = pp.process("#include \n").unwrap(); + std::fs::remove_dir_all(&base).ok(); + assert!(out.contains("NEXT_MISSING"), "{out}"); } #[test] diff --git a/src/c5/program.rs b/src/c5/program.rs index b8ec56ac2..8833bbf32 100644 --- a/src/c5/program.rs +++ b/src/c5/program.rs @@ -50,6 +50,13 @@ pub struct DataReloc { /// pointed at. Same data segment; cross-segment /// relocations (e.g., into `tls_data`) are future work. pub target_offset: u64, + /// Start offset of the object `target_offset` points into. + /// The raw offset alone cannot attribute a one-past-the-end + /// address (C99 6.5.6p8): it coincides with the next object's + /// start, so data compaction would track the wrong object. + /// Equals `target_offset` when the producer has no object + /// identity. + pub target_anchor: u64, } /// A function-pointer initializer that needs run-time relocation. @@ -91,6 +98,11 @@ pub struct CodeReloc { #[derive(Debug, Clone)] pub struct Program { pub data: Vec, + /// Base alignment `data` requires in the image, at least 8; + /// raised to 16 when a file-scope object carries `_Alignas(16)` + /// (or the attribute equivalents). The native writers place the + /// data section at a multiple of it. + pub data_align: usize, /// Start offsets of anonymous data objects (string literals and the /// implicit `__func__` arrays of C99 6.4.2.2) within `data`. Named /// globals already carry their offset in `symbols[..].val`; these are @@ -107,10 +119,9 @@ pub struct Program { /// indexed by `Inst::TlsAddr`'s operand. The image writers copy /// this into `.tdata` (initialised slice = `tls_data[..tls_init_size]`) /// and `.tbss` (zero-fill remainder = `tls_data[tls_init_size..]`). - /// Today everything starts zero (no `_Thread_local int x = 5;` - /// initialiser syntax), so `tls_init_size == 0` and the whole - /// block lives in .tbss; the layout is structured for future - /// expansion. + /// A `_Thread_local int x = 5;` initialiser raises + /// `tls_init_size` so its bytes land in `.tdata`; an + /// uninitialised variable keeps its slice zero and in `.tbss`. pub tls_data: Vec, /// Number of bytes of `tls_data` that are statically initialised /// (i.e., emitted into `.tdata`). The remainder @@ -253,6 +264,18 @@ pub struct Program { /// `__getmainargs` for `__wgetmainargs`); other writers /// ignore it. pub entry_name: Option, + /// The literal `#pragma entrypoint()` value; `None` when + /// the source has no such pragma. Distinct from `entry_name`, + /// which also reflects the CRT fallbacks. The driver reads this + /// to warn when a relocatable emit drops the pragma (an object + /// file does not carry it). + pub entry_pragma: Option, + /// Function names the auto-include retry bound to a bundled + /// header during [`crate::c5::Compiler::compile`]. The driver + /// consults this in a multi-TU build: a name another input + /// defines is recompiled as an implicit extern so the user's + /// definition wins over the header's library binding. + pub auto_includes: Vec, /// Source-declared Windows subsystem. Set by /// `#pragma subsystem()`; `None` falls back to the /// PE writer's default (`Console`). Read only by the PE diff --git a/src/c5/runtime.rs b/src/c5/runtime.rs index b8abf1468..a351fd920 100644 --- a/src/c5/runtime.rs +++ b/src/c5/runtime.rs @@ -8,14 +8,16 @@ //! native ELF ET_REL alongside the user's translation units. //! //! Single registry [`EMBEDDED_RUNTIME`]. Its one source -//! (`runtime.c`) gates everything -- the `environ` / `_environ` data -//! and the `__c5_exit` / `__c5_entry` startup -- on -//! `__BADC_C5_START__`, which the driver defines only when the image -//! writer emits an entry stub. Shared libraries and passthrough-entry -//! subsystems (native / EFI) leave it undefined, so the source -//! compiles to nothing for them: no user-mode CRT import, and no -//! `environ` definition (a library inherits it from the host -//! process). +//! (`runtime.c`) gates its sections on driver-defined macros: +//! `__BADC_C5_CRT__` (the image may import the user-mode C library -- +//! hosted executables and shared libraries) selects the Windows C99 +//! snprintf / vsnprintf definitions, and `__BADC_C5_START__` (an +//! entry stub is emitted -- hosted executables only) selects the +//! `environ` / `tzname` data and the `__c5_exit` / `__c5_entry` +//! startup. Passthrough-entry subsystems (native / EFI) and +//! freestanding images leave both undefined, so the source compiles +//! to nothing for them: no user-mode CRT import, and no `environ` +//! definition (a library inherits it from the host process). /// Runtime sources compiled + linked alongside the user's /// translation units on the native-link path. diff --git a/src/c5/symbol.rs b/src/c5/symbol.rs index f41ef5c0b..a77548f21 100644 --- a/src/c5/symbol.rs +++ b/src/c5/symbol.rs @@ -94,6 +94,24 @@ pub(crate) struct Symbol { /// Shadow slot for `array_dims`. See `h_array_size`. pub h_array_dims: Vec, + /// True for a C99 6.7.6.2 variable-length array local: the + /// element count is a runtime expression, so the storage is + /// allocated from the per-frame alloca arena rather than a fixed + /// frame slot. `type_` holds the element type; `array_size` stays + /// 0 (it is not a constant array). `vla_ptr_slot` is the hidden + /// frame slot holding the runtime base pointer; `vla_size_slot` + /// holds the runtime byte count so `sizeof` reports `n * + /// sizeof(elem)` per 6.5.3.4p2. + pub is_vla: bool, + pub vla_ptr_slot: i64, + pub vla_size_slot: i64, + /// Shadow slots for the VLA fields, saved / restored alongside + /// `array_size` so an inner binding that reuses the name does not + /// corrupt an outer VLA (C99 6.2.1p4). + pub h_is_vla: bool, + pub h_vla_ptr_slot: i64, + pub h_vla_size_slot: i64, + /// True once a `Token::Glo` symbol has been seen with an /// explicit initializer (`= ...`). Tentative-definition /// merges (C11 6.9.2): a forward `static T x;` (or the same diff --git a/src/c5/tests/codegen.rs b/src/c5/tests/codegen.rs index 12104e193..8ee583462 100644 --- a/src/c5/tests/codegen.rs +++ b/src/c5/tests/codegen.rs @@ -231,6 +231,33 @@ fn environ_data_binding_records_copy_relocation() { ); } +/// POSIX `setenv` carries a third `overwrite` argument that msvcrt's +/// 2-parameter `_putenv_s` lacks, so `` defines `setenv` as +/// an inline wrapper that probes `getenv` before calling `_putenv_s`, +/// honoring the flag. The wrapper compiles in place -- the object +/// imports `_putenv_s` and carries no undefined `setenv` symbol -- and +/// the same definition serves the interpreter and JIT paths. +#[test] +fn setenv_inline_wrapper_imports_putenv_s_on_windows() { + use crate::{Compiler, NativeOptions, OutputKind, Target, emit_native_with_options}; + let program = Compiler::with_target( + "#include \nint main(void){ setenv(\"K\", \"V\", 0); return 0; }".to_string(), + Target::WindowsX64, + ) + .compile() + .expect("compile setenv TU for WindowsX64"); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..NativeOptions::default() + }; + let obj = emit_native_with_options(&program, Target::WindowsX64, opts).expect("emit"); + let contains = |needle: &[u8]| obj.windows(needle.len()).any(|w| w == needle); + assert!( + contains(b"_putenv_s"), + "the inline setenv wrapper must import _putenv_s" + ); +} + /// A `#pragma binding(data lib::sym, ...)` import on the Windows /// x86-64 PE target must lower the data reference as a load of the /// import's IAT slot, not as the address of a `jmp [IAT]` call @@ -496,6 +523,82 @@ fn data_import_routes_to_declaring_dylib_on_windows_x64() { ); } +/// C99 7.19.6.5p3 / 7.19.6.12p3: snprintf / vsnprintf return the +/// untruncated length and NUL-terminate a nonempty buffer; msvcrt's +/// `_snprintf` / `_vsnprintf` return -1 and omit the NUL. The standard +/// spellings therefore carry no msvcrt binding on Windows: they resolve +/// against the runtime's conforming definitions, which wrap +/// `_vsnprintf` + `_vscprintf`. +#[test] +fn windows_snprintf_resolves_to_the_runtime_definition() { + use crate::{CompileOptions, Compiler, NativeOptions, Target}; + for target in [Target::WindowsX64, Target::WindowsAarch64] { + let program = Compiler::with_options( + "#include \n\ + int main(void){char b[4]; return snprintf(b, 4, \"%d\", 123456);}\n" + .to_string(), + target, + CompileOptions::default().with_no_entry_point(true), + ) + .compile() + .expect("compile snprintf TU"); + let image = super::link_executable_with_runtime(&program, target, NativeOptions::default()) + .expect("link Windows executable"); + for imported in ["_vscprintf", "_vsnprintf"] { + assert_eq!( + pe_import_dll_of(&image, imported).as_deref(), + Some("msvcrt.dll"), + "{target:?}: the runtime definition must import `{imported}`" + ); + } + for absent in ["_snprintf", "snprintf", "vsnprintf"] { + assert!( + pe_iat_slot_rva(&image, absent).is_none(), + "{target:?}: `{absent}` must not appear in the import table" + ); + } + } +} + +/// A shared library compiles the runtime with `__BADC_C5_CRT__` but +/// without the startup gate; the CRT section alone must still define +/// the C99 snprintf / vsnprintf so a DLL's calls resolve locally. +#[test] +fn windows_runtime_crt_section_defines_snprintf_without_start_gate() { + use crate::{ + CompileOptions, Compiler, NativeOptions, OutputKind, Target, embedded_runtime, + link_native_objects, parse_native_elf, + }; + let target = Target::WindowsX64; + let reloc = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let mut objs = Vec::new(); + for (name, body) in embedded_runtime() { + let copts = CompileOptions::default() + .with_no_entry_point(true) + .with_defines(vec![("__BADC_C5_CRT__".to_string(), "1".to_string())]); + let rt = Compiler::with_options(body.to_string(), target, copts) + .compile() + .unwrap_or_else(|e| panic!("compile runtime {name}: {e}")); + let bytes = crate::emit_native_with_options(&rt, target, reloc) + .unwrap_or_else(|e| panic!("emit runtime {name}: {e}")); + objs.push(parse_native_elf(&bytes).expect("parse runtime object")); + } + let merged = link_native_objects(&objs).expect("link CRT-only runtime"); + for def in ["snprintf", "vsnprintf"] { + assert!( + merged.defined.contains_key(def), + "the CRT section must define `{def}`" + ); + } + assert!( + !merged.defined.contains_key("__c5_entry"), + "the startup section must stay gated out" + ); +} + /// Return the `(VirtualAddress, raw bytes)` of the PE `.text` /// section. RVA-relative byte scans use the VirtualAddress; the raw /// bytes are the section's file image. @@ -1494,3 +1597,449 @@ fn debug_info_does_not_change_codegen() { ); } } + +/// PE/COFF orders the export name pointer table lexically: the loader's +/// import binding and GetProcAddress binary-search it, so a table in +/// declaration order resolves names data-dependently (a miss surfaces as +/// STATUS_ENTRYPOINT_NOT_FOUND). Export in non-alphabetical declaration +/// order and byte-walk the emitted directory: the name table must come +/// out sorted with each name's ordinal still selecting its own +/// function's AddressOfFunctions slot. +#[test] +fn pe_export_name_table_is_lexically_sorted() { + use crate::c5::linker::{ + emit_x86_64_plt, link_native_objects, parse_native_elf, write_native_image_from_merged, + }; + use crate::{ + CompileOptions, Compiler, NativeOptions, OutputKind, Target, emit_native_with_options, + }; + // Each function carries a unique imm32 marker so the export's + // resolved address can be tied back to the right body. + let program = Compiler::with_options( + "#pragma export(zeta)\n\ + #pragma export(mike)\n\ + #pragma export(alpha)\n\ + int zeta(void) { return 0x5a17aa01; }\n\ + int mike(void) { return 0x5a17aa02; }\n\ + int alpha(void) { return 0x5a17aa03; }\n" + .to_string(), + Target::WindowsX64, + CompileOptions::default().with_no_entry_point(true), + ) + .compile() + .expect("compile export TU"); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let bytes = emit_native_with_options(&program, Target::WindowsX64, opts).expect("emit"); + let obj = parse_native_elf(&bytes).expect("parse ET_REL"); + let mut merged = link_native_objects(&[obj]).expect("link"); + let plt = emit_x86_64_plt(&mut merged).expect("plt"); + let dll = write_native_image_from_merged( + &merged, + &plt, + "", + None, + OutputKind::SharedLibrary, + Target::WindowsX64, + Some("exp.dll"), + ) + .expect("write DLL"); + + let u16a = |o: usize| u16::from_le_bytes(dll[o..o + 2].try_into().unwrap()); + let u32a = |o: usize| u32::from_le_bytes(dll[o..o + 4].try_into().unwrap()); + let pe = u32a(0x3c) as usize; + let opt = pe + 24; + // Section table maps RVAs to file offsets. + let num_sections = u16a(pe + 6) as usize; + let opt_size = u16a(pe + 20) as usize; + let sec_table = pe + 24 + opt_size; + let rva_to_off = |rva: u32| -> usize { + for s in 0..num_sections { + let sh = sec_table + s * 40; + let va = u32a(sh + 12); + let vsize = u32a(sh + 8); + let raw_off = u32a(sh + 20); + if rva >= va && rva < va + vsize { + return (raw_off + (rva - va)) as usize; + } + } + panic!("rva {rva:#x} outside every section"); + }; + let cstr_at = |off: usize| -> alloc::string::String { + let end = dll[off..] + .iter() + .position(|&c| c == 0) + .map_or(off, |n| off + n); + alloc::string::String::from_utf8_lossy(&dll[off..end]).into_owned() + }; + // Data directory 0 is the Export Directory (PE32+: opt + 112). + let edata_rva = u32a(opt + 112); + assert_ne!(edata_rva, 0, "DLL must carry an export directory"); + let ed = rva_to_off(edata_rva); + let n_names = u32a(ed + 24) as usize; + assert_eq!(n_names, 3); + let funcs_off = rva_to_off(u32a(ed + 28)); + let names_off = rva_to_off(u32a(ed + 32)); + let ords_off = rva_to_off(u32a(ed + 36)); + + let names: alloc::vec::Vec = (0..n_names) + .map(|i| cstr_at(rva_to_off(u32a(names_off + 4 * i)))) + .collect(); + assert_eq!( + names, + ["alpha", "mike", "zeta"], + "name pointer table must be lexically sorted" + ); + // Ground truth per function: the file offset of its unique marker. + let marker_off = |imm: u32| -> usize { + let needle = imm.to_le_bytes(); + let hits: alloc::vec::Vec = dll + .windows(4) + .enumerate() + .filter(|(_, w)| *w == needle) + .map(|(i, _)| i) + .collect(); + assert_eq!(hits.len(), 1, "marker {imm:#x} must be unique"); + hits[0] + }; + let markers = [ + ("zeta", marker_off(0x5a17aa01)), + ("mike", marker_off(0x5a17aa02)), + ("alpha", marker_off(0x5a17aa03)), + ]; + for (i, name) in names.iter().enumerate() { + let ordinal = u16a(ords_off + 2 * i) as usize; + let fn_off = rva_to_off(u32a(funcs_off + 4 * ordinal)); + // The nearest marker at or past the function's entry must be + // this export's own -- the ordinal table maps name -> body. + let (owner, _) = markers + .iter() + .filter(|&&(_, m)| m >= fn_off) + .min_by_key(|&&(_, m)| m) + .expect("a marker must follow the entry"); + assert_eq!( + owner, name, + "export `{name}` (ordinal {ordinal}) must resolve to its own body" + ); + } +} + +/// Minimal foreign ET_REL mirroring clang -O2's SSE constant pool: a +/// 4-byte `.rodata` (align 4) followed by `.rodata.cst16` (align 16) +/// holding `mask`, with a global object symbol `c16_mask` on it. +fn foreign_et_rel_with_cst16(mask: &[u8; 16]) -> alloc::vec::Vec { + let rodata: [u8; 4] = [1, 2, 3, 4]; + let strtab = b"\0c16_mask\0"; + let shstrtab = b"\0.rodata\0.rodata.cst16\0.symtab\0.strtab\0.shstrtab\0"; + let rodata_off = 64usize; + let cst16_off = rodata_off + rodata.len(); + let symtab_off = cst16_off + mask.len(); + // Elf64Sym pair: the null symbol, then GLOBAL OBJECT `c16_mask` + // at offset 0 of section 2 (`.rodata.cst16`). + let mut symtab = alloc::vec![0u8; 24]; + symtab.extend_from_slice(&1u32.to_le_bytes()); + symtab.push(0x11); // (STB_GLOBAL << 4) | STT_OBJECT + symtab.push(0); + symtab.extend_from_slice(&2u16.to_le_bytes()); + symtab.extend_from_slice(&0u64.to_le_bytes()); + symtab.extend_from_slice(&16u64.to_le_bytes()); + let strtab_off = symtab_off + symtab.len(); + let shstr_off = strtab_off + strtab.len(); + let shoff = (shstr_off + shstrtab.len()).next_multiple_of(8); + + let mut out = alloc::vec![0u8; 64]; + out[0..4].copy_from_slice(b"\x7fELF"); + out[4] = 2; // ELFCLASS64 + out[5] = 1; // ELFDATA2LSB + out[6] = 1; // EV_CURRENT + out[16..18].copy_from_slice(&1u16.to_le_bytes()); // ET_REL + out[18..20].copy_from_slice(&62u16.to_le_bytes()); // EM_X86_64 + out[20..24].copy_from_slice(&1u32.to_le_bytes()); // e_version + out[40..48].copy_from_slice(&(shoff as u64).to_le_bytes()); + out[52..54].copy_from_slice(&64u16.to_le_bytes()); // e_ehsize + out[58..60].copy_from_slice(&64u16.to_le_bytes()); // e_shentsize + out[60..62].copy_from_slice(&6u16.to_le_bytes()); // e_shnum + out[62..64].copy_from_slice(&5u16.to_le_bytes()); // e_shstrndx + out.extend_from_slice(&rodata); + out.extend_from_slice(mask); + out.extend_from_slice(&symtab); + out.extend_from_slice(strtab); + out.extend_from_slice(shstrtab); + out.resize(shoff, 0); + let mut shdr = |name: u32, + ty: u32, + flags: u64, + off: usize, + size: usize, + link: u32, + info: u32, + align: u64, + entsize: u64| { + out.extend_from_slice(&name.to_le_bytes()); + out.extend_from_slice(&ty.to_le_bytes()); + out.extend_from_slice(&flags.to_le_bytes()); + out.extend_from_slice(&0u64.to_le_bytes()); // sh_addr + out.extend_from_slice(&(off as u64).to_le_bytes()); + out.extend_from_slice(&(size as u64).to_le_bytes()); + out.extend_from_slice(&link.to_le_bytes()); + out.extend_from_slice(&info.to_le_bytes()); + out.extend_from_slice(&align.to_le_bytes()); + out.extend_from_slice(&entsize.to_le_bytes()); + }; + shdr(0, 0, 0, 0, 0, 0, 0, 0, 0); + shdr(1, 1, 2, rodata_off, rodata.len(), 0, 0, 4, 0); // .rodata + shdr(9, 1, 2, cst16_off, mask.len(), 0, 0, 16, 0); // .rodata.cst16 + shdr(23, 2, 0, symtab_off, symtab.len(), 4, 1, 8, 24); // .symtab + shdr(31, 3, 0, strtab_off, strtab.len(), 0, 0, 1, 0); // .strtab + shdr(39, 3, 0, shstr_off, shstrtab.len(), 0, 0, 1, 0); // .shstrtab + out +} + +/// `(sh_addr, sh_offset)` of the named section in an ELF64 image. +fn elf64_shdr_addr_off(b: &[u8], want: &str) -> Option<(u64, u64)> { + let u16a = |o: usize| u16::from_le_bytes(b[o..o + 2].try_into().unwrap()); + let u32a = |o: usize| u32::from_le_bytes(b[o..o + 4].try_into().unwrap()); + let u64a = |o: usize| u64::from_le_bytes(b[o..o + 8].try_into().unwrap()); + let shoff = u64a(0x28) as usize; + let shentsize = u16a(0x3a) as usize; + let shnum = u16a(0x3c) as usize; + let shstrndx = u16a(0x3e) as usize; + let str_off = u64a(shoff + shstrndx * shentsize + 0x18) as usize; + for i in 0..shnum { + let sh = shoff + i * shentsize; + let name_off = str_off + u32a(sh) as usize; + let end = b[name_off..] + .iter() + .position(|&c| c == 0) + .map_or(name_off, |n| name_off + n); + if &b[name_off..end] == want.as_bytes() { + return Some((u64a(sh + 0x10), u64a(sh + 0x18))); + } + } + None +} + +/// A foreign object's `.rodata.cst16`-style section (sh_addralign 16 -- +/// clang/gcc -O2 SSE constant pools) must keep its alignment through the +/// family concatenation, the unit merge, and the final image placement: +/// legacy-SSE aligned loads (`xorps`/`movaps`) fault on a misaligned +/// operand. Link the foreign object after a badc unit and check the +/// constant's final vaddr. +#[test] +fn foreign_cst16_section_lands_sixteen_aligned_in_image() { + use crate::c5::linker::{ + emit_x86_64_plt, link_native_objects, parse_native_elf, write_native_image_from_merged, + }; + use crate::{NativeOptions, OutputKind, Target, emit_native_with_options}; + let mask: [u8; 16] = [ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, + 0xaf, + ]; + let foreign = parse_native_elf(&foreign_et_rel_with_cst16(&mask)).expect("parse foreign"); + assert_eq!(foreign.data_align, 16, "sh_addralign must be recorded"); + // Intra-object: the 4-byte `.rodata` ahead forces 12 bytes of pad. + assert_eq!(&foreign.data[16..32], &mask); + + // A badc unit with an import so the image carries `.dynamic` and a + // non-empty `.got` ahead of `.data` (the placement the alignment + // rounding must correct). + let program = super::compile_str_bare( + "#pragma dylib(libc, \"libc.so.6\")\n\ + #pragma binding(libc::puts, \"puts\")\n\ + int puts(const char *s); \ + int main(void) { return puts(\"x\"); }", + ); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let bytes = emit_native_with_options(&program, Target::LinuxX64, opts).expect("emit"); + let tu = parse_native_elf(&bytes).expect("parse TU"); + let mut merged = link_native_objects(&[tu, foreign]).expect("link"); + assert_eq!(merged.data_align, 16, "merge must carry the max alignment"); + let sym_value = merged + .defined + .get("c16_mask") + .expect("foreign data symbol must survive the merge") + .value; + assert_eq!(sym_value % 16, 0, "merged .data offset must stay aligned"); + let plt = emit_x86_64_plt(&mut merged).expect("plt"); + let exe = write_native_image_from_merged( + &merged, + &plt, + "main", + None, + OutputKind::Executable, + Target::LinuxX64, + None, + ) + .expect("write executable"); + let (data_addr, data_off) = elf64_shdr_addr_off(&exe, ".data").expect(".data section header"); + assert_eq!( + (data_addr + sym_value) % 16, + 0, + "the 16-byte constant's runtime address must be 16-aligned" + ); + let at = (data_off + sym_value) as usize; + assert_eq!( + &exe[at..at + 16], + &mask, + "the constant's bytes must land at the placed offset" + ); +} + +/// A constant struct-field offset folds into the displacement of a +/// floating-point load and store, and the AArch64 emit carries that +/// displacement into the immediate-offset encoding. The load side used +/// to hard-code offset 0 while the store side honored it, masked only +/// by the fold declining FP kinds. +#[test] +fn aarch64_fp_access_folds_constant_displacement() { + use crate::c5::ir::{Inst, LoadKind, StoreKind}; + use crate::{Compiler, NativeOptions, OutputKind, Target, emit_native_with_options}; + let target = Target::LinuxAarch64; + let program = Compiler::with_target( + "struct s { long tag; float f; double d; }; \ + float rf(struct s *p) { return p->f; } \ + double rd(struct s *p) { return p->d; } \ + void wd(struct s *p) { p->d = p->d + 0.5; } \ + int main(void) { return 0; }" + .to_string(), + target, + ) + .compile() + .expect("compile"); + let mut funcs = + crate::c5::codegen::ssa::shadow::produce_ssa_funcs(&program, target).expect("ssa"); + crate::c5::codegen::passes::index_fold::run(&mut funcs); + let mut f32_load = false; + let mut f64_load = false; + let mut f64_store = false; + for inst in funcs.iter().flat_map(|f| f.insts.iter()) { + match inst { + Inst::Load { + disp: 8, + kind: LoadKind::F32, + .. + } => f32_load = true, + Inst::Load { + disp: 16, + kind: LoadKind::F64, + .. + } => f64_load = true, + Inst::Store { + disp: 16, + kind: StoreKind::F64, + .. + } => f64_store = true, + _ => {} + } + } + assert!(f32_load, "p->f must fold to Load {{ disp: 8, F32 }}"); + assert!(f64_load, "p->d must fold to Load {{ disp: 16, F64 }}"); + assert!( + f64_store, + "p->d = ... must fold to Store {{ disp: 16, F64 }}" + ); + let obj = emit_native_with_options( + &program, + target, + NativeOptions { + output_kind: OutputKind::Relocatable, + ..NativeOptions::new().with_optimize() + }, + ) + .expect("emit relocatable"); + let text = elf64_section(&obj, ".text").expect(".text"); + let words = || { + text.chunks_exact(4) + .map(|c| u32::from_le_bytes([c[0], c[1], c[2], c[3]])) + }; + // Unsigned-offset FP loads/stores scale the immediate by the access + // width, so #8 (F32) and #16 (F64) both encode imm12 = 2. Register + // fields are masked out. + let imm2 = |w: u32, class: u32| (w & 0xFFC0_0000) == class && (w >> 10) & 0xFFF == 2; + assert!( + words().any(|w| imm2(w, 0xBD40_0000)), + "expected `ldr s, [xN, #8]` for the folded F32 load" + ); + assert!( + words().any(|w| imm2(w, 0xFD40_0000)), + "expected `ldr d, [xN, #16]` for the folded F64 load" + ); + assert!( + words().any(|w| imm2(w, 0xFD00_0000)), + "expected `str d, [xN, #16]` for the folded F64 store" + ); +} + +/// A call whose outgoing-argument area exceeds the 12-bit add/sub +/// immediate must split the call-site SP adjustment into the +/// shifted-12 + remainder pair, as the prologue path does. 261 +/// by-value 16-byte structs leave 257 on the AAPCS64 stack: 257 * 16 = +/// 4112 = 4096 + 16 bytes. The raw encoder used to fold 4112 into the +/// `lsl #12` bit and adjust SP by 65536 instead. +#[test] +fn aarch64_call_sp_adjust_covers_wide_outgoing_area() { + use crate::{Compiler, NativeOptions, OutputKind, Target, emit_native_with_options}; + let mut src = String::from("struct pair { long a; long b; };\nstatic struct pair g[261];\n"); + src.push_str("long take("); + for i in 0..261 { + src.push_str(&format!("struct pair p{i}")); + src.push_str(if i < 260 { ", " } else { ");\n" }); + } + src.push_str("long caller(void) { return take("); + for i in 0..261 { + src.push_str(&format!("g[{i}]")); + src.push_str(if i < 260 { ", " } else { "); }\n" }); + } + src.push_str("int main(void) { return (int)caller(); }\n"); + let program = Compiler::with_target(src, Target::LinuxAarch64) + .compile() + .expect("compile"); + let obj = emit_native_with_options( + &program, + Target::LinuxAarch64, + NativeOptions { + output_kind: OutputKind::Relocatable, + ..NativeOptions::new() + }, + ) + .expect("emit relocatable"); + let text = elf64_section(&obj, ".text").expect(".text"); + let entry = elf_func_value(&obj, "caller").expect("caller symbol") as usize; + let size = elf_func_symbols(&obj) + .into_iter() + .find(|(n, _)| n == "caller") + .map(|(_, s)| s as usize) + .expect("caller size"); + let body = &text[entry..(entry + size).min(text.len())]; + let words: alloc::vec::Vec = body + .chunks_exact(4) + .map(|c| u32::from_le_bytes([c[0], c[1], c[2], c[3]])) + .collect(); + // 4112 bytes split as `sub sp, sp, #1, lsl #12` + `sub sp, sp, #16` + // and restore with the matching adds. The caller's own frame stays + // below 4096, so only the call site produces the shifted forms. + for (word, what) in [ + (0xD140_07FFu32, "sub sp, sp, #1, lsl #12"), + (0xD100_43FF, "sub sp, sp, #16"), + (0x9140_07FF, "add sp, sp, #1, lsl #12"), + (0x9100_43FF, "add sp, sp, #16"), + ] { + assert!( + words.contains(&word), + "caller must contain `{what}` ({word:#010x}) for the 4112-byte outgoing area" + ); + } + // The raw-encoder overflow artifact: 4112 << 10 sets the shift bit + // and leaves imm12 = 16, i.e. a 65536-byte adjustment. + for word in [0xD140_43FFu32, 0x9140_43FF] { + assert!( + !words.contains(&word), + "caller must not adjust SP by 65536 (mis-encoded 4112): {word:#010x}" + ); + } +} diff --git a/src/c5/tests/dwarf.rs b/src/c5/tests/dwarf.rs index 37f70cc8b..9c31afbfb 100644 --- a/src/c5/tests/dwarf.rs +++ b/src/c5/tests/dwarf.rs @@ -716,29 +716,35 @@ fn debug_line_has_per_statement_rows() { /// Locals that stay in the frame keep their fbreg location. #[test] fn promoted_local_has_empty_location() { - let src = "long f(long n){ long base = n + 100; long acc = 0; long i = 0;\ - while (i < 3) { acc = acc + base; i = i + 1; } return acc; }\ + let src = "long f(long n){ long base = n + 100; long keep = n; long *pk = &keep;\ + long acc = 0; long i = 0;\ + while (i < 3) { acc = acc + base + *pk; i = i + 1; } return acc; }\ int main(void){ return (int)f(5); }"; let path = build_signed_mach_o_opt(src, "promoted_local_loc", true); let Some(out) = dwarfdump_debug_info(&path) else { return; }; - // `base` is single-def and read across the loop -> promoted; its - // location is empty. `acc` and `i` are loop-carried (a join phi), - // so they stay in the frame with a real fbreg location. - let base_at = out - .find("(\"base\")") - .unwrap_or_else(|| panic!("no `base` variable in:\n{out}")); - let after_base = &out[base_at..]; - let base_loc_end = after_base.find("DW_TAG").unwrap_or(after_base.len()); + // `base` is address-free -> promoted; its location is empty. + // `keep` has its address taken (`pk`), so it stays in the frame + // with a real fbreg location. Both checks are scoped to the + // variable's own DIE so unrelated subprograms can't satisfy them. + let loc_of = |name: &str| { + let at = out + .find(&format!("(\"{name}\")")) + .unwrap_or_else(|| panic!("no `{name}` variable in:\n{out}")); + let after = &out[at..]; + let end = after.find("DW_TAG").unwrap_or(after.len()); + &after[..end] + }; assert!( - after_base[..base_loc_end].contains("DW_AT_location\t()"), + loc_of("base").contains("DW_AT_location\t()"), "promoted local `base` should have an empty location, got:\n{}", - &after_base[..base_loc_end] + loc_of("base"), ); assert!( - out.contains("(\"acc\")") && out.contains("DW_OP_fbreg"), - "non-promoted locals should keep an fbreg location:\n{out}" + loc_of("keep").contains("DW_OP_fbreg"), + "address-taken local `keep` should keep an fbreg location, got:\n{}", + loc_of("keep"), ); let _ = std::fs::remove_file(&path); } diff --git a/src/c5/tests/jit.rs b/src/c5/tests/jit.rs index 0866e754d..487e119ed 100644 --- a/src/c5/tests/jit.rs +++ b/src/c5/tests/jit.rs @@ -1082,11 +1082,20 @@ const JIT_FIXTURES: &[(&str, i32)] = &[ ("goto.c", 5), ("switch_statement.c", 25), ("switch_binary_search.c", 0), + ("switch_case_label_promoted.c", 0), + ("int_literal_boundary_types.c", 0), + ("const_expr_unsigned_fold.c", 0), + ("shift_result_promoted_type.c", 0), + ("ternary_arith_common_type.c", 0), + ("compound_assign_unsigned_div.c", 0), + ("decl_specifier_any_order.c", 0), ("branch_relaxation.c", 21), ("float_register_resident.c", 45), ("variadic_struct_arg.c", 18), ("variadic_struct_arg_16b.c", 51), ("libc_div.c", 0), + ("strtof_parses_float.c", 0), + ("snprintf_truncation_c99.c", 0), ("strength_reduce_pow2_divmod.c", 0), ("return_callee_saved_value.c", 0), ("spill_slot_reuse_disjoint_calls.c", 0), @@ -1099,6 +1108,9 @@ const JIT_FIXTURES: &[(&str, i32)] = &[ ("inline_two_reg_struct_param.c", 0), ("struct_param_stack_spill.c", 0), ("struct_stack_arg_then_scalar.c", 0), + ("call_sp_adjust_imm12_overflow.c", 0), + ("indirect_call_target_scratch_exhausted.c", 0), + ("fp_load_folded_disp.c", 0), ("mixed_struct_gpr_abi.c", 0), ("unary_plus_preserves_type.c", 0), ("local_multidim_aggregate_array_init.c", 0), @@ -1110,6 +1122,9 @@ const JIT_FIXTURES: &[(&str, i32)] = &[ ("pthread_key_once_width.c", 0), ("dev_t_width.c", 0), ("libc_int_arith.c", 0), + // Data binding (environ) read through the fake GOT; the site + // patching is the JIT counterpart of the AOT flat-lookup import. + ("environ_single_tu.c", 0), ("switch_default_routing.c", 100), ("control_flow.c", 1), ("do_while.c", 5), @@ -1533,12 +1548,34 @@ const JIT_FIXTURES: &[(&str, i32)] = &[ // an operand; the fix routes through r13 (outside both // `caller_gprs` and `callee_gprs`). ("ssa_va_start_va_copy_aliasing.c", 0), + // C99 6.7.3p6 / 5.1.2.3p2 volatile access preservation (the + // setjmp variant lives only in the native lists; setjmp is not + // wired for the JIT lane). + ("volatile_ptr_alias_loop.c", 0), + ("volatile_unused_read.c", 0), + ("volatile_param_classes.c", 0), // `thread_local_*.c` aren't here -- the JIT path's host is // macOS arm64 in this repo, where TLS lowering isn't // implemented yet (Mach-O __thread_data + dyld // __tlv_bootstrap is future work). The native_elf and // native_elf_x64 runners validate the Linux paths once the // built ELF lands on the orb VMs. + ("packed_bitfield_repack.c", 0), + ("nested_designator_string_member.c", 0), + ("union_member_unbraced_init.c", 0), + ("inline_multi_block_result_forward.c", 10), + ("sxtw_fold_source_liveness.c", 18), + ("data_reloc_one_past_end.c", 10), + ("variadic_libc_fnptr_static_init.c", 0), + ("block_scope_typedef_variadic_fnptr.c", 0), + ("atomic_operand_in_working_regs.c", 0), + ("setjmp_value_live_across.c", 0), + ("mixed_sse_int_aggregate_args.c", 0), + ("variadic_agg_return_classes.c", 0), + ("va_copy_under_pressure.c", 0), + ("variable_shift_rcx_loop.c", 0), + ("va_arg_composite_straddle.c", 0), + ("variadic_cast_fnptr_dispatch.c", 0), ]; #[test] @@ -1745,3 +1782,102 @@ fn jit_resolves_pointer_to_extern_data() { int main(void) { return (*p == 0) ? 1 : 0; }\n"; assert_eq!(jit_exit(src, &[]), 0); } + +// A `#pragma binding(data ...)` global read from code (not just a +// static initializer) must patch like the AOT path: the site loads +// the host cell's address from the fake GOT. Previously the +// UserExternDataRef sites were never patched and the read faulted. +#[cfg(unix)] +#[test] +fn jit_reads_binding_data_global() { + let src = "#include \n\ + int main(void) {\n\ + int n = 0;\n\ + for (char **e = environ; *e; e++) n++;\n\ + return n > 0 ? 0 : 1;\n\ + }\n"; + let program = Compiler::new(src.to_string()).compile().expect("compile"); + assert_eq!( + jit_run(&program, &["jit-environ".to_string()]).expect("jit_run"), + 0 + ); +} + +/// Mirror the linker: a call to a declared-but-undefined extern must +/// refuse to run instead of dispatching to whatever function sits at +/// the placeholder-colliding ent_pc. +#[test] +fn undefined_extern_call_is_a_link_error() { + let program = Compiler::new( + "int bar(int);\n\ + int helper(int x) { return x + 1; }\n\ + int main(void) { return bar(41); }" + .to_string(), + ) + .compile() + .expect("compile"); + let err = jit_run(&program, &["jit-undef-call".to_string()]).expect_err("must not run"); + let msg = err.to_string(); + assert!(msg.contains("undefined reference to `bar`"), "{msg}"); +} + +#[test] +fn undefined_extern_object_is_a_link_error() { + let program = Compiler::new( + "extern int missing_obj;\n\ + int main(void) { return missing_obj + 7; }" + .to_string(), + ) + .compile() + .expect("compile"); + let err = jit_run(&program, &["jit-undef-obj".to_string()]).expect_err("must not run"); + let msg = err.to_string(); + assert!( + msg.contains("undefined reference to `missing_obj`"), + "{msg}" + ); +} + +/// C99 7.20.4.3p2: `exit` runs the registered atexit handlers. The +/// JIT intercepts both `atexit` and `exit`, so the handler chain must +/// drain before the process terminates with the passed status. `exit` +/// ends the whole process, so the assertion drives a re-executed copy +/// of this test binary gated by the marker env var. +#[test] +fn atexit_handlers_run_on_libc_exit() { + if let Ok(marker) = std::env::var("BADC_JIT_EXIT_MARKER") { + let src = format!( + "#include \n\ + #include \n\ + static void h(void) {{\n\ + FILE *f = fopen(\"{marker}\", \"w\");\n\ + if (f) {{ fputs(\"ran\", f); fclose(f); }}\n\ + }}\n\ + int main(void) {{ atexit(h); exit(42); }}\n", + ); + let program = Compiler::new(src).compile().expect("compile"); + let _ = jit_run(&program, &["jit-exit".to_string()]); + unreachable!("exit(42) must terminate the process"); + } + let marker = std::env::temp_dir().join(format!("badc_jit_exit_{}", std::process::id())); + let _ = std::fs::remove_file(&marker); + // libtest names tests without the crate segment of module_path!. + let module = module_path!(); + let module = module.split_once("::").map_or(module, |(_, rest)| rest); + let test_name = format!("{module}::atexit_handlers_run_on_libc_exit"); + let out = std::process::Command::new(std::env::current_exe().expect("current_exe")) + .args(["--exact", &test_name, "--test-threads=1"]) + .env("BADC_JIT_EXIT_MARKER", &marker) + .output() + .expect("re-exec the test binary"); + assert_eq!( + out.status.code(), + Some(42), + "stdout: {}\nstderr: {}", + String::from_utf8_lossy(&out.stdout), + String::from_utf8_lossy(&out.stderr), + ); + let contents = std::fs::read_to_string(&marker).expect("atexit handler must write the marker"); + let _ = std::fs::remove_file(&marker); + assert_eq!(contents, "ran"); +} diff --git a/src/c5/tests/lexer.rs b/src/c5/tests/lexer.rs index dce9cf61e..0abf21ef7 100644 --- a/src/c5/tests/lexer.rs +++ b/src/c5/tests/lexer.rs @@ -31,6 +31,29 @@ fn hex_literal_lower_and_upper() { assert_eq!(h.ival(), 0xABCD); } +// C99 6.4.4.1: every integer base carries the same u/U/l/L suffix; +// octal and binary literals must record it like decimal and hex do. +#[test] +fn integer_suffix_recorded_for_every_base() { + let cases: &[(&str, i64, u8, bool)] = &[ + ("010u", 8, 0, true), + ("0777UL", 511, 1, true), + ("01ll", 1, 2, false), + ("0b101u", 5, 0, true), + ("0b1LL", 1, 2, false), + ("0xFFull", 255, 2, true), + ("42lu", 42, 1, true), + ("7", 7, 0, false), + ]; + for &(src, val, l_count, unsigned) in cases { + let mut h = LexHarness::new(src); + assert_eq!(h.next(), Token::Num, "{src}"); + assert_eq!(h.ival(), val, "{src}"); + assert_eq!(h.int_suffix(), (l_count, unsigned), "{src}"); + assert_eq!(h.next(), Tok::EOF, "{src}"); + } +} + #[test] fn keywords_resolve_to_their_tokens() { let mut h = LexHarness::new("int char if else while return sizeof"); diff --git a/src/c5/tests/linker.rs b/src/c5/tests/linker.rs index 3aacace98..eefdeb93f 100644 --- a/src/c5/tests/linker.rs +++ b/src/c5/tests/linker.rs @@ -944,6 +944,200 @@ fn export_data_exposes_data_globals_in_dynsym() { ); } +#[test] +fn macho_executable_exports_globals_through_dyld_info_trie() { + // macOS publishes every global of an executable so a dlopen'd module + // resolves them against the host. dyld resolves an image carrying + // LC_DYLD_INFO exclusively through the export trie -- a symtab-only + // entry is invisible to it -- so a text and a data global must both + // resolve through the trie at their symtab addresses. + use crate::c5::linker::{ + emit_aarch64_plt, link_native_objects, parse_native_elf, write_native_image_from_merged, + }; + use crate::c5::{CompileOptions, NativeOptions, OutputKind, Target, emit_native_with_options}; + let program = Compiler::with_options( + alloc::format!( + "{TEST_PRELUDE}\ + int host_data = 7;\n\ + int host_api(int x) {{ return x + host_data; }}\n\ + int main(void) {{ return host_api(0); }}\n" + ), + Target::MacOSAarch64, + CompileOptions::default(), + ) + .compile() + .expect("compile"); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let bytes = emit_native_with_options(&program, Target::MacOSAarch64, opts).expect("emit"); + let obj = parse_native_elf(&bytes).expect("parse ET_REL"); + let mut merged = link_native_objects(&[obj]).expect("link"); + let plt = emit_aarch64_plt(&mut merged).expect("plt"); + let exe = write_native_image_from_merged( + &merged, + &plt, + "main", + None, + OutputKind::Executable, + Target::MacOSAarch64, + None, + ) + .expect("write executable"); + + fn uleb(buf: &[u8], p: &mut usize) -> u64 { + let (mut v, mut shift) = (0u64, 0); + loop { + let b = buf[*p]; + *p += 1; + v |= ((b & 0x7F) as u64) << shift; + if b & 0x80 == 0 { + return v; + } + shift += 7; + } + } + fn trie_lookup(trie: &[u8], name: &str) -> Option { + let bytes = name.as_bytes(); + let (mut node, mut pos) = (0usize, 0usize); + loop { + let mut p = node; + let term_size = uleb(trie, &mut p) as usize; + if pos == bytes.len() { + if term_size == 0 { + return None; + } + let _flags = uleb(trie, &mut p); + return Some(uleb(trie, &mut p)); + } + p += term_size; + let child_count = trie[p]; + p += 1; + let mut next = None; + for _ in 0..child_count { + let start = p; + while trie[p] != 0 { + p += 1; + } + let label = &trie[start..p]; + p += 1; + let child = uleb(trie, &mut p) as usize; + if bytes[pos..].starts_with(label) { + next = Some((label.len(), child)); + break; + } + } + match next { + Some((len, child)) => { + pos += len; + node = child; + } + None => return None, + } + } + } + + let read_u32 = |off: usize| u32::from_le_bytes(exe[off..off + 4].try_into().unwrap()); + let read_u64 = |off: usize| u64::from_le_bytes(exe[off..off + 8].try_into().unwrap()); + assert_eq!(read_u32(0), 0xfeed_facf, "executable must be MH_MAGIC_64"); + // Walk the load commands for LC_DYLD_INFO_ONLY (export_off/size at + // +40/+44), LC_SYMTAB (symoff/nsyms/stroff at +8/+12/+16), and the + // __TEXT segment vmaddr (image base; trie addresses are relative to it). + let sizeofcmds = read_u32(20) as usize; + let (mut export_range, mut symtab_loc, mut image_base) = (None, None, None); + let mut p = 32usize; + while p < 32 + sizeofcmds { + match read_u32(p) { + 0x8000_0022 => { + export_range = Some((read_u32(p + 40) as usize, read_u32(p + 44) as usize)); + } + 0x2 => { + symtab_loc = Some(( + read_u32(p + 8) as usize, + read_u32(p + 12) as usize, + read_u32(p + 16) as usize, + )); + } + 0x19 if exe[p + 8..p + 15] == *b"__TEXT\0" => { + image_base = Some(read_u64(p + 24)); + } + _ => {} + } + p += read_u32(p + 4) as usize; + } + let (export_off, export_size) = export_range.expect("LC_DYLD_INFO_ONLY must be present"); + let trie = &exe[export_off..export_off + export_size]; + let (symoff, nsyms, stroff) = symtab_loc.expect("LC_SYMTAB must be present"); + let image_base = image_base.expect("__TEXT segment must be present"); + let n_value_of = |name: &str| -> u64 { + (0..nsyms) + .find_map(|i| { + let base = symoff + i * 16; + let s = &exe[stroff + read_u32(base) as usize..]; + let end = s.iter().position(|&b| b == 0).unwrap(); + (&s[..end] == name.as_bytes()).then(|| read_u64(base + 8)) + }) + .unwrap_or_else(|| panic!("symtab must carry {name}")) + }; + for name in ["_host_api", "_host_data"] { + assert_eq!( + trie_lookup(trie, name), + Some(n_value_of(name) - image_base), + "{name} must resolve through the export trie at its symtab address" + ); + } +} + +#[test] +fn thread_local_in_elf_shared_library_is_a_link_error() { + // The emitted `_Thread_local` sequences use the local-exec TLS + // model, whose TP-relative offsets are valid only in the + // executable's static TLS block; baked into ET_DYN they address + // another module's TLS. The writer must reject the combination + // until the general-dynamic model is implemented. + use crate::c5::linker::{ + emit_x86_64_plt, link_native_objects, parse_native_elf, write_native_image_from_merged, + }; + use crate::c5::{CompileOptions, NativeOptions, OutputKind, Target, emit_native_with_options}; + let program = Compiler::with_options( + "_Thread_local int counter = 7;\n\ + int bump(void) { counter += 1; return counter; }\n" + .to_string(), + Target::LinuxX64, + CompileOptions::default().with_no_entry_point(true), + ) + .compile() + .expect("compile"); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let bytes = emit_native_with_options(&program, Target::LinuxX64, opts).expect("emit"); + let obj = parse_native_elf(&bytes).expect("parse ET_REL"); + let mut merged = link_native_objects(&[obj]).expect("link"); + assert!( + !merged.tls_data.is_empty(), + "the merged unit must carry TLS data" + ); + let plt = emit_x86_64_plt(&mut merged).expect("plt"); + let err = write_native_image_from_merged( + &merged, + &plt, + "", + None, + OutputKind::SharedLibrary, + Target::LinuxX64, + None, + ) + .expect_err("a _Thread_local shared library must be rejected"); + assert!( + err.to_string() + .contains("_Thread_local data is not supported in ELF shared-library output"), + "unexpected diagnostic: {err}" + ); +} + #[test] fn shared_object_relocates_internal_data_pointers() { // A function / data pointer baked into a shared object's static data @@ -1557,3 +1751,575 @@ fn cpuid_xgetbv_asm_emit_for_x86_64() { "push rbx (callee-saved, clobbered by cpuid) must be saved" ); } + +#[test] +fn same_named_statics_keep_their_own_prologue_anchor() { + // The post-prologue anchor map is keyed by the function's merged + // entry offset. Name-keying handed a later unit's same-named + // static the first unit's anchor, describing a framed function as + // frameless in the Win-x64 .pdata / DWARF CFA output. + use crate::c5::linker::{link_native_objects, parse_native_elf}; + use crate::c5::{CompileOptions, NativeOptions, OutputKind, Target, emit_native_with_options}; + let compile = |src: &str| { + let program = Compiler::with_options( + src.to_string(), + Target::LinuxX64, + CompileOptions::default().with_no_entry_point(true), + ) + .compile() + .expect("compile"); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let bytes = emit_native_with_options(&program, Target::LinuxX64, opts).expect("emit"); + parse_native_elf(&bytes).expect("parse ET_REL") + }; + let a = compile( + "static int helper(int x) { int buf[16]; buf[0] = x; return buf[0] + 1; }\n\ + int call_a(int x) { return helper(x); }\n", + ); + let b = compile( + "static int helper(int x) { int buf[32]; buf[1] = x; return buf[1] + 2; }\n\ + int call_b(int x) { return helper(x); }\n", + ); + let merged = link_native_objects(&[a, b]).expect("link"); + let helpers: alloc::vec::Vec = merged + .local_funcs + .iter() + .filter(|(n, _)| n == "helper") + .map(|(_, off)| *off) + .collect(); + assert_eq!(helpers.len(), 2, "both statics survive: {helpers:?}"); + let mut posts = alloc::vec::Vec::new(); + for entry in &helpers { + let post = merged + .prologue_ends + .get(entry) + .unwrap_or_else(|| panic!("anchor for helper at 0x{entry:x} missing")); + assert!( + post > entry, + "post-prologue 0x{post:x} must lie past the entry 0x{entry:x}" + ); + posts.push(*post); + } + assert_ne!(posts[0], posts[1], "each static keeps its own anchor"); +} + +#[test] +fn unrouted_weak_undef_resolves_to_zero() { + // ELF behavior: a weak reference nothing on the link line + // satisfies resolves to address 0 -- not a required import + // against the first dylib. The call becomes a no-op, the + // address-of reads null, and a pointer initializer slot holds 0. + use crate::c5::linker::object::{NativeReloc, NativeSymbol}; + use crate::c5::linker::{NativeMachine, NativeSymSection, link_native_objects}; + let null_sym = || NativeSymbol { + name: String::new(), + section: NativeSymSection::Undef, + value: 0, + size: 0, + binding: 0, + kind: 0, + }; + let weak_undef = || NativeSymbol { + name: "hook".to_string(), + section: NativeSymSection::Undef, + value: 0, + size: 0, + binding: 2, // STB_WEAK + kind: 0, + }; + let mk = |machine: NativeMachine, + text: alloc::vec::Vec, + data: alloc::vec::Vec, + text_relocs: alloc::vec::Vec, + data_relocs: alloc::vec::Vec| { + crate::c5::linker::NativeObject { + machine, + text, + data, + data_align: 8, + bss_size: 0, + tls_data: alloc::vec::Vec::new(), + tls_bss_size: 0, + symbols: alloc::vec![null_sym(), weak_undef()], + text_relocs, + data_relocs, + dylibs: alloc::vec::Vec::new(), + import_dylib_map: alloc::vec::Vec::new(), + exports: alloc::vec::Vec::new(), + tls_index_fixups: alloc::vec::Vec::new(), + macho_tlv_descriptors: alloc::vec::Vec::new(), + macho_tlv_fixups: alloc::vec::Vec::new(), + tls_symbols: alloc::vec::Vec::new(), + macho_tlv_descriptor_syms: alloc::vec::Vec::new(), + elf_tpoff_fixups: alloc::vec::Vec::new(), + copy_relocs: alloc::vec::Vec::new(), + debug_info: alloc::vec::Vec::new(), + debug_abbrev: alloc::vec::Vec::new(), + debug_line: alloc::vec::Vec::new(), + debug_str: alloc::vec::Vec::new(), + debug_info_relocs: alloc::vec::Vec::new(), + debug_line_relocs: alloc::vec::Vec::new(), + } + }; + + // x86_64: `lea rax, [rip+hook]` (R_X86_64_PC32) then `call hook` + // (R_X86_64_PLT32), plus a `.data` pointer slot (R_X86_64_64). + let x64 = mk( + NativeMachine::X86_64, + alloc::vec![ + 0x48, 0x8D, 0x05, 0, 0, 0, 0, // lea rax, [rip+0] + 0xE8, 0, 0, 0, 0, // call rel32 + ], + alloc::vec![0u8; 8], + alloc::vec![ + NativeReloc { + offset: 3, + sym_idx: 1, + rtype: 2, // R_X86_64_PC32 + addend: -4, + }, + NativeReloc { + offset: 8, + sym_idx: 1, + rtype: 4, // R_X86_64_PLT32 + addend: -4, + }, + ], + alloc::vec![NativeReloc { + offset: 0, + sym_idx: 1, + rtype: 1, // R_X86_64_64 + addend: 0, + }], + ); + let merged = link_native_objects(&[x64]).expect("weak undef links"); + assert!( + merged.imports.is_empty(), + "no import for an unresolved weak ref: {:?}", + merged.imports + ); + assert_eq!( + &merged.text[0..7], + &[0x48, 0xC7, 0xC0, 0, 0, 0, 0], + "lea rewritten to mov rax, 0" + ); + assert_eq!( + &merged.text[7..12], + &[0x0F, 0x1F, 0x44, 0x00, 0x00], + "call rewritten to a 5-byte nop" + ); + assert_eq!(&merged.data[0..8], &[0u8; 8], "pointer slot holds null"); + + // aarch64: `adrp x0, hook` + `add x0, x0, :lo12:hook` + `bl hook`. + let a64 = mk( + NativeMachine::Aarch64, + alloc::vec![ + 0x00, 0x00, 0x00, 0x90, // adrp x0, 0 + 0x00, 0x00, 0x00, 0x91, // add x0, x0, #0 + 0x00, 0x00, 0x00, 0x94, // bl 0 + ], + alloc::vec::Vec::new(), + alloc::vec![ + NativeReloc { + offset: 0, + sym_idx: 1, + rtype: 275, // R_AARCH64_ADR_PREL_PG_HI21 + addend: 0, + }, + NativeReloc { + offset: 4, + sym_idx: 1, + rtype: 277, // R_AARCH64_ADD_ABS_LO12_NC + addend: 0, + }, + NativeReloc { + offset: 8, + sym_idx: 1, + rtype: 283, // R_AARCH64_CALL26 + addend: 0, + }, + ], + alloc::vec::Vec::new(), + ); + let merged = link_native_objects(&[a64]).expect("weak undef links"); + assert!(merged.imports.is_empty(), "{:?}", merged.imports); + let word = |i: usize| u32::from_le_bytes(merged.text[i..i + 4].try_into().unwrap()); + assert_eq!(word(0), 0xd280_0000, "adrp rewritten to movz x0, #0"); + assert_eq!(word(4), 0xd503_201f, "add pair half becomes a nop"); + assert_eq!(word(8), 0xd503_201f, "bl becomes a nop"); +} + +#[test] +fn elf_section_offsets_respect_their_claimed_alignment() { + // gABI: `sh_addr` (and the file offset for SHF_ALLOC sections) + // must be congruent to 0 modulo `sh_addralign`. Version-name + // strings appended to `.dynstr` after its pad used to leave + // `.hash` / `.gnu.version` misaligned; the check runs over every + // section so any future layout drift is caught. Version sections + // only appear when the build host's libc yields versioned imports. + use crate::c5::linker::{ + emit_aarch64_plt, link_native_objects, parse_native_elf, write_native_image_from_merged, + }; + use crate::c5::{NativeOptions, OutputKind, Target, emit_native_with_options}; + let program = Compiler::new(alloc::format!( + "{TEST_PRELUDE}\ + int main(void) {{ printf(\"x\"); return 0; }}\n" + )) + .compile() + .expect("compile"); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let bytes = emit_native_with_options(&program, Target::LinuxAarch64, opts).expect("emit"); + let obj = parse_native_elf(&bytes).expect("parse ET_REL"); + let mut merged = link_native_objects(&[obj]).expect("link"); + let plt = emit_aarch64_plt(&mut merged).expect("plt"); + let exe = write_native_image_from_merged( + &merged, + &plt, + "main", + None, + OutputKind::Executable, + Target::LinuxAarch64, + None, + ) + .expect("write executable"); + let shoff = u64::from_le_bytes(exe[0x28..0x30].try_into().unwrap()) as usize; + let shentsize = u16::from_le_bytes(exe[0x3a..0x3c].try_into().unwrap()) as usize; + let shnum = u16::from_le_bytes(exe[0x3c..0x3e].try_into().unwrap()) as usize; + assert!(shnum > 0, "executable must carry section headers"); + const SHT_NOBITS: u32 = 8; + for i in 0..shnum { + let base = shoff + i * shentsize; + let sh_type = u32::from_le_bytes(exe[base + 4..base + 8].try_into().unwrap()); + let sh_addr = u64::from_le_bytes(exe[base + 16..base + 24].try_into().unwrap()); + let sh_offset = u64::from_le_bytes(exe[base + 24..base + 32].try_into().unwrap()); + let sh_addralign = u64::from_le_bytes(exe[base + 48..base + 56].try_into().unwrap()); + if sh_addralign <= 1 { + continue; + } + assert_eq!( + sh_addr % sh_addralign, + 0, + "section {i} sh_addr 0x{sh_addr:x} violates sh_addralign {sh_addralign}" + ); + if sh_type != SHT_NOBITS { + assert_eq!( + sh_offset % sh_addralign, + 0, + "section {i} sh_offset 0x{sh_offset:x} violates sh_addralign {sh_addralign}" + ); + } + } +} + +#[test] +fn extern_redeclaration_keeps_the_tentative_definition() { + // C99 6.2.2p4 + 6.9.2p2: `int x; extern int x;` retains the + // tentative definition (the extern redeclaration refers to the + // same object), so the TU's object defines `x`. The same holds + // for the array form and for an initialized definition. + use crate::c5::linker::{NativeSymSection, parse_native_elf}; + use crate::c5::{CompileOptions, NativeOptions, OutputKind, Target, emit_native_with_options}; + let defined_sections = |src: &str, names: &[&str]| -> alloc::vec::Vec { + let program = Compiler::with_options( + src.to_string(), + Target::LinuxX64, + CompileOptions::default().with_no_entry_point(true), + ) + .compile() + .expect("compile"); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let bytes = emit_native_with_options(&program, Target::LinuxX64, opts).expect("emit"); + let obj = parse_native_elf(&bytes).expect("parse ET_REL"); + names + .iter() + .map(|n| { + obj.symbols + .iter() + .any(|s| &s.name == n && s.section != NativeSymSection::Undef) + }) + .collect() + }; + let defined = defined_sections( + "int x;\nextern int x;\n\ + int a[4];\nextern int a[];\n\ + int y = 5;\nextern int y;\n\ + int use_all(void) { return x + a[0] + y; }\n", + &["x", "a", "y"], + ); + assert_eq!( + defined, + alloc::vec![true, true, true], + "the definitions must survive the extern redeclarations (x, a, y)" + ); + // A genuinely extern-only declaration still emits an UNDEF. + let defined = defined_sections("extern int z;\nint use_z(void) { return z; }\n", &["z"]); + assert_eq!(defined, alloc::vec![false], "extern-only stays undefined"); +} + +#[test] +fn alignas_sixteen_places_objects_and_raises_data_align() { + // C11 6.7.5: a 16-byte alignment request on a file-scope object + // is honored -- the object's section offset is 16-aligned through + // compaction and the unit records `data_align = 16` so the linker + // and the image writers keep the base congruent. Larger requests + // and unsupported positions are diagnostics, never silent drops. + use crate::c5::linker::{NativeSymSection, link_native_objects, parse_native_elf}; + use crate::c5::{CompileOptions, NativeOptions, OutputKind, Target, emit_native_with_options}; + let compile = |src: &str| { + let program = Compiler::with_options( + src.to_string(), + Target::LinuxX64, + CompileOptions::default().with_no_entry_point(true), + ) + .compile() + .expect("compile"); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let bytes = emit_native_with_options(&program, Target::LinuxX64, opts).expect("emit"); + parse_native_elf(&bytes).expect("parse ET_REL") + }; + let aligned_unit = "\ + _Alignas(16) unsigned char pool[24];\n\ + char skew[3] = \"ab\";\n\ + __attribute__((aligned(16))) unsigned char pool2[8];\n\ + int use_all(void) { return pool[0] + skew[0] + pool2[0]; }\n"; + let obj = compile(aligned_unit); + assert_eq!(obj.data_align, 16, "unit must claim 16-byte data alignment"); + for name in ["pool", "pool2"] { + let sym = obj + .symbols + .iter() + .find(|s| s.name == name) + .unwrap_or_else(|| panic!("{name} missing")); + assert!( + sym.section != NativeSymSection::Undef && sym.value.is_multiple_of(16), + "{name} at {:?}+0x{:x} must be 16-aligned", + sym.section, + sym.value + ); + } + // Linked after a unit with an odd-sized data tail, the offsets + // stay 16-congruent (the unit base honors the claimed alignment) + // and the file image is padded so bss offsets keep their residue. + let odd = compile("char tail[5] = \"abcd\";\nint use_tail(void) { return tail[0]; }\n"); + let merged = link_native_objects(&[odd, compile(aligned_unit)]).expect("link"); + assert_eq!(merged.data_align, 16); + if merged.bss_size > 0 { + assert!(merged.data.len().is_multiple_of(16)); + } + for name in ["pool", "pool2"] { + let sym = merged.defined.get(name).unwrap_or_else(|| panic!("{name}")); + assert!( + sym.value.is_multiple_of(16), + "{name} merged offset 0x{:x} must stay 16-aligned", + sym.value + ); + } + // Diagnostics: above 16, automatic objects above 8, members above 8. + for src in [ + "_Alignas(64) static char big[8];\nint main(void) { return 0; }\n", + "int main(void) { _Alignas(16) char buf[8]; return buf[0]; }\n", + "struct S { _Alignas(16) int f; };\nint main(void) { struct S s; s.f = 0; return s.f; }\n", + ] { + assert!( + Compiler::new(src.to_string()).compile().is_err(), + "must be diagnosed: {src}" + ); + } +} + +#[test] +fn windows_x64_tz_globals_bind_to_msvcrt_data_exports() { + // msvcrt's `_tzset` writes the DLL's own `_tzname` / `_timezone` / + // `_daylight`; the x64 image must import them as data (the + // `environ` treatment) instead of resolving the externs to local + // zero-filled slots `_tzset` never writes. + use crate::c5::{NativeOptions, OutputKind, Target, emit_native_with_options}; + let src = "#include \n\ + #include \n\ + #pragma export(use_tz)\n\ + long use_tz(void) { tzset(); return timezone + daylight + (tzname[0] != 0); }\n"; + let program = Compiler::with_target(src.to_string(), Target::WindowsX64) + .compile() + .expect("compile tz TU"); + let obj = emit_native_with_options( + &program, + Target::WindowsX64, + NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }, + ) + .expect("emit object"); + let contains = |needle: &[u8]| obj.windows(needle.len()).any(|w| w == needle); + for sym in [ + &b"\0_tzname\0"[..], + &b"\0_timezone\0"[..], + &b"\0_daylight\0"[..], + ] { + assert!( + contains(sym), + "x64 tz output {:?} must be a data import", + core::str::from_utf8(sym) + ); + } +} + +#[test] +fn dead_libc_bindings_fail_at_build_not_at_load() { + // libSystem exports none of these (dlsym-verified); the header must + // leave them unbound so a use fails the build loudly instead of + // producing an image that aborts at load with a dyld error. + let cases = [ + ( + "#include \nint main(void) { struct timespec t; t.tv_sec = 0; t.tv_nsec = 0; return clock_nanosleep(0, 0, &t, 0); }\n", + "clock_nanosleep", + ), + ( + "#include \nint main(void) { return mremap((void *)0, 0, 0, 0) != 0; }\n", + "mremap", + ), + ( + "#include \nint main(void) { return sched_getscheduler(0); }\n", + "sched_getscheduler", + ), + ( + "#include \nint main(void) { return fexecve(0, 0, 0); }\n", + "fexecve", + ), + ]; + use crate::c5::linker::{link_native_objects, parse_native_elf}; + use crate::c5::{CompileOptions, NativeOptions, OutputKind, Target, emit_native_with_options}; + let link_one = |src: &str| { + let program = Compiler::with_options( + src.to_string(), + Target::MacOSAarch64, + CompileOptions::default().with_no_entry_point(true), + ) + .compile() + .expect("compile"); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let bytes = emit_native_with_options(&program, Target::MacOSAarch64, opts).expect("emit"); + link_native_objects(&[parse_native_elf(&bytes).expect("parse")]) + }; + for (src, name) in cases { + let err = link_one(src) + .err() + .unwrap_or_else(|| panic!("{name}: use of an unexported symbol must not link")); + assert!( + format!("{err}").contains(name), + "{name}: diagnostic must name the symbol: {err}" + ); + } + // The bound neighbors still link. + for src in [ + "#include \nint main(void) { struct timespec t; return clock_gettime(0, &t); }\n", + "#include \nint main(void) { return sched_yield(); }\n", + ] { + link_one(src).expect("bound libc call must link"); + } +} + +#[test] +fn macho_data_import_gets_no_bogus_local_text_symbol() { + // A Mach-O data import (`environ`, bound through the GOT) carries no + // PLT trampoline. The symtab previously fabricated a local text + // symbol for it at code offset 0 -- the first function's address -- + // mislabeling backtraces and breakpoints. Only imports that actually + // have a trampoline get a local text symbol; a data import keeps just + // its undefined entry. + use crate::c5::linker::{ + emit_aarch64_plt, link_native_objects, parse_native_elf, write_native_image_from_merged, + }; + use crate::c5::{CompileOptions, NativeOptions, OutputKind, Target, emit_native_with_options}; + let program = Compiler::with_options( + "#include \n\ + #include \n\ + int main(void) { return environ != 0 ? (int)strlen(\"x\") : 0; }\n" + .to_string(), + Target::MacOSAarch64, + CompileOptions::default(), + ) + .compile() + .expect("compile"); + let opts = NativeOptions { + output_kind: OutputKind::Relocatable, + ..Default::default() + }; + let bytes = emit_native_with_options(&program, Target::MacOSAarch64, opts).expect("emit"); + let obj = parse_native_elf(&bytes).expect("parse ET_REL"); + let mut merged = link_native_objects(&[obj]).expect("link"); + let plt = emit_aarch64_plt(&mut merged).expect("plt"); + let exe = write_native_image_from_merged( + &merged, + &plt, + "main", + None, + OutputKind::Executable, + Target::MacOSAarch64, + None, + ) + .expect("write executable"); + + // Walk LC_SYMTAB collecting (name, n_type). N_STAB=0xe0, N_TYPE=0x0e, + // N_SECT=0x0e, N_EXT=0x01. + const LC_SYMTAB: u32 = 2; + let ncmds = u32::from_le_bytes(exe[16..20].try_into().unwrap()); + let mut p = 32usize; + let mut names: alloc::vec::Vec<(String, u8)> = alloc::vec::Vec::new(); + for _ in 0..ncmds { + let cmd = u32::from_le_bytes(exe[p..p + 4].try_into().unwrap()); + let cmdsize = u32::from_le_bytes(exe[p + 4..p + 8].try_into().unwrap()) as usize; + if cmd == LC_SYMTAB { + let symoff = u32::from_le_bytes(exe[p + 8..p + 12].try_into().unwrap()) as usize; + let nsyms = u32::from_le_bytes(exe[p + 12..p + 16].try_into().unwrap()) as usize; + let stroff = u32::from_le_bytes(exe[p + 16..p + 20].try_into().unwrap()) as usize; + for k in 0..nsyms { + let e = symoff + k * 16; + let n_strx = u32::from_le_bytes(exe[e..e + 4].try_into().unwrap()) as usize; + let n_type = exe[e + 4]; + let s = stroff + n_strx; + let len = exe[s..].iter().position(|&b| b == 0).unwrap(); + names.push(( + String::from_utf8_lossy(&exe[s..s + len]).into_owned(), + n_type, + )); + } + break; + } + p += cmdsize; + } + // No local (N_SECT set, N_EXT clear) symbol named `environ`. + assert!( + !names + .iter() + .any(|(n, t)| n == "environ" && t & 0x0e == 0x0e && t & 0x01 == 0), + "data import `environ` must not get a bogus local text symbol: {names:?}" + ); + // Its undefined import entry (`_environ`, N_SECT clear) survives. + assert!( + names.iter().any(|(n, t)| n == "_environ" && t & 0x0e == 0), + "data import must keep its undefined `_environ` entry: {names:?}" + ); + // A real function import (`_strlen`) still gets its local text symbol. + assert!( + names + .iter() + .any(|(n, t)| n == "_strlen" && t & 0x0e == 0x0e && t & 0x01 == 0), + "a trampolined import must keep its local text symbol: {names:?}" + ); +} diff --git a/src/c5/tests/mod.rs b/src/c5/tests/mod.rs index 0ace32560..93f609543 100644 --- a/src/c5/tests/mod.rs +++ b/src/c5/tests/mod.rs @@ -46,6 +46,7 @@ mod programs; #[cfg(feature = "full")] mod reloc_golden; mod types; +mod vla; /// Absolute path of `tests/fixtures/c/` relative to the crate root. fn fixture_path(name: &str) -> PathBuf { @@ -140,12 +141,14 @@ pub fn link_executable_with_runtime( objs.push(parse_native_elf(&prog_bytes).map_err(|e| format!("parse program object: {e}"))?); // This helper always builds a hosted executable, so the runtime's - // startup section is compiled in (`__BADC_C5_START__`). + // CRT and startup sections are both compiled in. // The entry shape follows the entry symbol: `__BADC_WIN_WINMAIN__` // for a `WinMain` entry, `__BADC_WIN_WIDE__` for `wmain`, else `main` // with argc/argv -- independent of the PE subsystem. - let mut rt_defines: Vec<(String, String)> = - vec![("__BADC_C5_START__".to_string(), "1".to_string())]; + let mut rt_defines: Vec<(String, String)> = vec![ + ("__BADC_C5_CRT__".to_string(), "1".to_string()), + ("__BADC_C5_START__".to_string(), "1".to_string()), + ]; rt_defines.push(( "__BADC_ENTRY__".to_string(), program @@ -218,8 +221,10 @@ pub fn link_executable_with_runtime_multi( // PLT pass numbers trampolines in object order, so the order must be // stable across linkers. let mut objs = Vec::new(); - let mut rt_defines: Vec<(String, String)> = - vec![("__BADC_C5_START__".to_string(), "1".to_string())]; + let mut rt_defines: Vec<(String, String)> = vec![ + ("__BADC_C5_CRT__".to_string(), "1".to_string()), + ("__BADC_C5_START__".to_string(), "1".to_string()), + ]; rt_defines.push(( "__BADC_ENTRY__".to_string(), entry @@ -398,6 +403,11 @@ impl LexHarness { pub fn ival(&self) -> i64 { self.lex.ival } + /// `(l_count, unsigned)` suffix record of the most recently lexed + /// integer literal. + pub fn int_suffix(&self) -> (u8, bool) { + (self.lex.int_suffix_long, self.lex.int_suffix_unsigned) + } pub fn line(&self) -> usize { self.lex.line } diff --git a/src/c5/tests/native.rs b/src/c5/tests/native.rs index c2a10683a..decd95767 100644 --- a/src/c5/tests/native.rs +++ b/src/c5/tests/native.rs @@ -365,6 +365,11 @@ fn build_and_run_fixture_with_options(name: &str, opts: NativeOptions, suffix: & /// pointers resolve to native offsets via `FuncFixup`, so fixtures /// that exercise those paths run end-to-end. const NATIVE_FIXTURES: &[(&str, i32)] = &[ + ("vla_basic_sum.c", 0), + ("vla_runtime_sizeof.c", 0), + ("vla_size_from_arg.c", 0), + ("vla_scope_reclaim_loop.c", 0), + ("vla_param_decay.c", 0), ("mem2reg_param_promoted.c", 0), ("phi_class_for_loop_sum.c", 45), ("phi_class_nested_loops.c", 49), @@ -373,11 +378,22 @@ const NATIVE_FIXTURES: &[(&str, i32)] = &[ ("goto.c", 5), ("switch_statement.c", 25), ("switch_binary_search.c", 0), + ("switch_case_label_promoted.c", 0), + ("int_literal_boundary_types.c", 0), + ("const_expr_unsigned_fold.c", 0), + ("shift_result_promoted_type.c", 0), + ("ternary_arith_common_type.c", 0), + ("compound_assign_unsigned_div.c", 0), + ("decl_specifier_any_order.c", 0), ("branch_relaxation.c", 21), ("float_register_resident.c", 45), ("variadic_struct_arg.c", 18), ("variadic_struct_arg_16b.c", 51), ("libc_div.c", 0), + ("strtof_parses_float.c", 0), + ("snprintf_truncation_c99.c", 0), + ("ioctl_fionread_pipe.c", 0), + ("shm_open_mode_arg.c", 0), ("wide_string_literal_alignment.c", 0), ("va_arg_through_pointer.c", 0), ("pthread_key_once_width.c", 0), @@ -406,6 +422,9 @@ const NATIVE_FIXTURES: &[(&str, i32)] = &[ ("inline_two_reg_struct_param.c", 0), ("struct_param_stack_spill.c", 0), ("struct_stack_arg_then_scalar.c", 0), + ("call_sp_adjust_imm12_overflow.c", 0), + ("indirect_call_target_scratch_exhausted.c", 0), + ("fp_load_folded_disp.c", 0), ("mixed_struct_gpr_abi.c", 0), ("unary_plus_preserves_type.c", 0), ("local_multidim_aggregate_array_init.c", 0), @@ -692,6 +711,13 @@ const NATIVE_FIXTURES: &[(&str, i32)] = &[ // expansions in the codegen replace the missing CRT // surface. ("setjmp_longjmp_roundtrip.c", 0), + // C99 7.13.2.1p3 / 6.7.3p6 / 5.1.2.3p2: volatile objects keep + // their post-longjmp value, are re-read through aliases, and + // unused volatile reads still execute. + ("volatile_setjmp_longjmp.c", 0), + ("volatile_ptr_alias_loop.c", 0), + ("volatile_unused_read.c", 0), + ("volatile_param_classes.c", 0), ("struct_basic.c", 25), ("struct_linked_list.c", 10), ("global_initializer_int.c", 141), @@ -735,6 +761,7 @@ const NATIVE_FIXTURES: &[(&str, i32)] = &[ ("type_warning_silenced_by_cast.c", 0), ("type_warning_arity.c", 0), ("setenv_then_get.c", 'Z' as i32), + ("setenv_overwrite.c", 0), // Runtime dynamic linking. Opens the global symbol table, // resolves libc atoi via dlsym, calls it through indirect call // (which loads args into x0..x7 in case the target is native), @@ -910,6 +937,24 @@ const NATIVE_FIXTURES: &[(&str, i32)] = &[ // retry. Exits 0 when the auto-include path is wired up; // a `BuildError` on this entry means the retry regressed. ("auto_include_undeclared_libc.c", 0), + ("packed_bitfield_repack.c", 0), + ("nested_designator_string_member.c", 0), + ("union_member_unbraced_init.c", 0), + ("inline_multi_block_result_forward.c", 10), + ("sxtw_fold_source_liveness.c", 18), + ("data_reloc_one_past_end.c", 10), + ("variadic_libc_fnptr_static_init.c", 0), + ("block_scope_typedef_variadic_fnptr.c", 0), + ("atomic_operand_in_working_regs.c", 0), + ("setjmp_value_live_across.c", 0), + ("mixed_sse_int_aggregate_args.c", 0), + ("variadic_agg_return_classes.c", 0), + ("va_copy_under_pressure.c", 0), + ("variable_shift_rcx_loop.c", 0), + ("va_arg_composite_straddle.c", 0), + ("variadic_hfa_struct_arg.c", 0), + ("variadic_cast_fnptr_dispatch.c", 0), + ("fcntl_lock_via_cast_fnptr.c", 0), ]; /// Build a fixture, sign it, run it with the given args, and return diff --git a/src/c5/tests/native_elf.rs b/src/c5/tests/native_elf.rs index 18828fa52..fee4718aa 100644 --- a/src/c5/tests/native_elf.rs +++ b/src/c5/tests/native_elf.rs @@ -315,6 +315,11 @@ fn build_and_run_fixture_with_options(name: &str, opts: NativeOptions, suffix: & /// stay in sync because both backends should faithfully execute the /// same fixtures; if they drift, one of them has a bug. const NATIVE_ELF_FIXTURES: &[(&str, i32)] = &[ + ("vla_basic_sum.c", 0), + ("vla_runtime_sizeof.c", 0), + ("vla_size_from_arg.c", 0), + ("vla_scope_reclaim_loop.c", 0), + ("vla_param_decay.c", 0), ("arithmetic.c", 60), ("goto.c", 5), ("switch_statement.c", 25), @@ -324,6 +329,10 @@ const NATIVE_ELF_FIXTURES: &[(&str, i32)] = &[ ("variadic_struct_arg.c", 18), ("variadic_struct_arg_16b.c", 51), ("libc_div.c", 0), + ("strtof_parses_float.c", 0), + ("snprintf_truncation_c99.c", 0), + ("ioctl_fionread_pipe.c", 0), + ("shm_open_mode_arg.c", 0), ("strength_reduce_pow2_divmod.c", 0), ("return_callee_saved_value.c", 0), ("spill_slot_reuse_disjoint_calls.c", 0), @@ -470,6 +479,7 @@ const NATIVE_ELF_FIXTURES: &[(&str, i32)] = &[ ("type_warning_silenced_by_cast.c", 0), ("type_warning_arity.c", 0), ("setenv_then_get.c", 'Z' as i32), + ("setenv_overwrite.c", 0), // Runtime dynamic linking through libdl (libdl.so.2 + // libc.so.6 are both DT_NEEDED). dlopen+dlsym+blr finds // libc atoi and the indirect call passes "123" in x0. @@ -700,6 +710,26 @@ const NATIVE_ELF_FIXTURES: &[(&str, i32)] = &[ // Without that, `strtold` would land at 0.0 for any power-of- // two value (mantissa = 0, exponent only in v0's high half). ("strtold_aapcs_return.c", 0), + ("packed_bitfield_repack.c", 0), + ("nested_designator_string_member.c", 0), + ("union_member_unbraced_init.c", 0), + ("inline_multi_block_result_forward.c", 10), + ("sxtw_fold_source_liveness.c", 18), + ("data_reloc_one_past_end.c", 10), + ("variadic_libc_fnptr_static_init.c", 0), + ("block_scope_typedef_variadic_fnptr.c", 0), + ("atomic_operand_in_working_regs.c", 0), + ("setjmp_value_live_across.c", 0), + ("mixed_sse_int_aggregate_args.c", 0), + ("variadic_agg_return_classes.c", 0), + ("va_copy_under_pressure.c", 0), + ("variable_shift_rcx_loop.c", 0), + ("va_arg_composite_straddle.c", 0), + ("variadic_cast_fnptr_dispatch.c", 0), + ("fcntl_lock_via_cast_fnptr.c", 0), + ("call_sp_adjust_imm12_overflow.c", 0), + ("indirect_call_target_scratch_exhausted.c", 0), + ("fp_load_folded_disp.c", 0), ]; #[test] diff --git a/src/c5/tests/native_elf_x64.rs b/src/c5/tests/native_elf_x64.rs index 792a9e450..15407c8aa 100644 --- a/src/c5/tests/native_elf_x64.rs +++ b/src/c5/tests/native_elf_x64.rs @@ -275,6 +275,11 @@ fn build_and_run_fixture_with_options(name: &str, opts: NativeOptions, suffix: & } const NATIVE_ELF_X64_FIXTURES: &[(&str, i32)] = &[ + ("vla_basic_sum.c", 0), + ("vla_runtime_sizeof.c", 0), + ("vla_size_from_arg.c", 0), + ("vla_scope_reclaim_loop.c", 0), + ("vla_param_decay.c", 0), ("arithmetic.c", 60), ("goto.c", 5), ("switch_statement.c", 25), @@ -284,6 +289,10 @@ const NATIVE_ELF_X64_FIXTURES: &[(&str, i32)] = &[ ("variadic_struct_arg.c", 18), ("variadic_struct_arg_16b.c", 51), ("libc_div.c", 0), + ("strtof_parses_float.c", 0), + ("snprintf_truncation_c99.c", 0), + ("ioctl_fionread_pipe.c", 0), + ("shm_open_mode_arg.c", 0), ("wide_string_literal_alignment.c", 0), ("va_arg_through_pointer.c", 0), ("pthread_key_once_width.c", 0), @@ -421,6 +430,7 @@ const NATIVE_ELF_X64_FIXTURES: &[(&str, i32)] = &[ ("type_warning_silenced_by_cast.c", 0), ("type_warning_arity.c", 0), ("setenv_then_get.c", 'Z' as i32), + ("setenv_overwrite.c", 0), ("dlopen_atoi.c", 123), ("dlopen_strlen.c", 13), // Multi-arg dlsym call path. glibc 2.34+ folded pthread into @@ -649,6 +659,26 @@ const NATIVE_ELF_X64_FIXTURES: &[(&str, i32)] = &[ // glibc's old @GLIBC_2.2.5 stub and 0 under the @@GLIBC_2.3.2 // default. ("elf_symbol_version_default.c", 0), + ("packed_bitfield_repack.c", 0), + ("nested_designator_string_member.c", 0), + ("union_member_unbraced_init.c", 0), + ("inline_multi_block_result_forward.c", 10), + ("sxtw_fold_source_liveness.c", 18), + ("data_reloc_one_past_end.c", 10), + ("variadic_libc_fnptr_static_init.c", 0), + ("block_scope_typedef_variadic_fnptr.c", 0), + ("atomic_operand_in_working_regs.c", 0), + ("setjmp_value_live_across.c", 0), + ("mixed_sse_int_aggregate_args.c", 0), + ("variadic_agg_return_classes.c", 0), + ("va_copy_under_pressure.c", 0), + ("variable_shift_rcx_loop.c", 0), + ("va_arg_composite_straddle.c", 0), + ("variadic_cast_fnptr_dispatch.c", 0), + ("fcntl_lock_via_cast_fnptr.c", 0), + ("call_sp_adjust_imm12_overflow.c", 0), + ("indirect_call_target_scratch_exhausted.c", 0), + ("fp_load_folded_disp.c", 0), ]; #[test] diff --git a/src/c5/tests/native_pe_arm64.rs b/src/c5/tests/native_pe_arm64.rs index 6b7ab2e70..e003473ba 100644 --- a/src/c5/tests/native_pe_arm64.rs +++ b/src/c5/tests/native_pe_arm64.rs @@ -619,7 +619,17 @@ fn build_and_run_fixture_with_options(name: &str, opts: NativeOptions, suffix: & /// limitations (POSIX-only setenv shape, dlopen-against-libc-soname) /// are arch-independent. const NATIVE_PE_ARM64_FIXTURES: &[(&str, i32)] = &[ + ("vla_basic_sum.c", 0), + ("vla_runtime_sizeof.c", 0), + ("vla_size_from_arg.c", 0), + ("vla_scope_reclaim_loop.c", 0), + ("vla_param_decay.c", 0), ("arithmetic.c", 60), + ("strtof_parses_float.c", 0), + ("snprintf_truncation_c99.c", 0), + // Runtime CRT shim: POSIX setenv overwrite semantics over msvcrt's + // 2-parameter _putenv_s. + ("setenv_overwrite.c", 0), ("control_flow.c", 1), ("do_while.c", 5), ("break_continue.c", 4), @@ -909,6 +919,23 @@ const NATIVE_PE_ARM64_FIXTURES: &[(&str, i32)] = &[ ("setjmp_basic_stack.c", 0), ("setjmp_misaligned.c", 0), ("setjmp_longjmp_roundtrip.c", 0), + ("packed_bitfield_repack.c", 0), + ("nested_designator_string_member.c", 0), + ("union_member_unbraced_init.c", 0), + ("inline_multi_block_result_forward.c", 10), + ("sxtw_fold_source_liveness.c", 18), + ("data_reloc_one_past_end.c", 10), + ("variadic_libc_fnptr_static_init.c", 0), + ("block_scope_typedef_variadic_fnptr.c", 0), + ("atomic_operand_in_working_regs.c", 0), + ("setjmp_value_live_across.c", 0), + ("mixed_sse_int_aggregate_args.c", 0), + ("variadic_agg_return_classes.c", 0), + ("va_copy_under_pressure.c", 0), + ("variable_shift_rcx_loop.c", 0), + ("va_arg_composite_straddle.c", 0), + ("variadic_hfa_struct_arg.c", 0), + ("variadic_cast_fnptr_dispatch.c", 0), ]; #[test] diff --git a/src/c5/tests/native_pe_x64.rs b/src/c5/tests/native_pe_x64.rs index 0c6780b98..eb83de562 100644 --- a/src/c5/tests/native_pe_x64.rs +++ b/src/c5/tests/native_pe_x64.rs @@ -632,7 +632,17 @@ fn build_and_run_fixture_with_options(name: &str, opts: NativeOptions, suffix: & /// Subset of the cross-arch fixture corpus that doesn't lean on /// POSIX-only semantics. const NATIVE_PE_X64_FIXTURES: &[(&str, i32)] = &[ + ("vla_basic_sum.c", 0), + ("vla_runtime_sizeof.c", 0), + ("vla_size_from_arg.c", 0), + ("vla_scope_reclaim_loop.c", 0), + ("vla_param_decay.c", 0), ("arithmetic.c", 60), + ("strtof_parses_float.c", 0), + ("snprintf_truncation_c99.c", 0), + // Runtime CRT shim: POSIX setenv overwrite semantics over msvcrt's + // 2-parameter _putenv_s. + ("setenv_overwrite.c", 0), ("control_flow.c", 1), ("do_while.c", 5), ("break_continue.c", 4), @@ -927,6 +937,22 @@ const NATIVE_PE_X64_FIXTURES: &[(&str, i32)] = &[ // `setjmp_longjmp.c` can join this list. ("setjmp_basic_stack.c", 0), ("setjmp_misaligned.c", 0), + ("packed_bitfield_repack.c", 0), + ("nested_designator_string_member.c", 0), + ("union_member_unbraced_init.c", 0), + ("inline_multi_block_result_forward.c", 10), + ("sxtw_fold_source_liveness.c", 18), + ("data_reloc_one_past_end.c", 10), + ("variadic_libc_fnptr_static_init.c", 0), + ("block_scope_typedef_variadic_fnptr.c", 0), + ("atomic_operand_in_working_regs.c", 0), + ("setjmp_value_live_across.c", 0), + ("mixed_sse_int_aggregate_args.c", 0), + ("variadic_agg_return_classes.c", 0), + ("va_copy_under_pressure.c", 0), + ("variable_shift_rcx_loop.c", 0), + ("va_arg_composite_straddle.c", 0), + ("variadic_cast_fnptr_dispatch.c", 0), ]; #[test] diff --git a/src/c5/tests/parser.rs b/src/c5/tests/parser.rs index 9904a62fd..4704ff0bc 100644 --- a/src/c5/tests/parser.rs +++ b/src/c5/tests/parser.rs @@ -357,14 +357,12 @@ fn thread_local_compiles_to_op_tlslea() { // those gates. let src = "_Thread_local int counter;\n\ int main() { counter = 42; return counter; }"; - let p = super::Compiler::new(super::with_prelude(src)) - .compile() - .expect("compile failed"); - assert_eq!(p.tls_data.len(), 8, "single 8-byte TLS slot"); // Every supported target now lowers `_Thread_local`. Linux // and Windows have full code paths; macOS arm64 routes // through the Mach-O `__thread_vars` + `__tlv_bootstrap` - // pipeline. + // pipeline, which needs libSystem in the dylib set -- so + // compile per target rather than re-emitting a host-compiled + // program whose dylib bindings are the host's. for target in [ super::super::codegen::Target::LinuxAarch64, super::super::codegen::Target::LinuxX64, @@ -372,6 +370,10 @@ fn thread_local_compiles_to_op_tlslea() { super::super::codegen::Target::WindowsAarch64, super::super::codegen::Target::MacOSAarch64, ] { + let p = super::Compiler::with_target(super::with_prelude(src), target) + .compile() + .unwrap_or_else(|e| panic!("`{target:?}` compile failed: {e}")); + assert_eq!(p.tls_data.len(), 8, "single 8-byte TLS slot for {target:?}"); super::super::object::emit_native_single_tu_for_test( &p, target, @@ -422,22 +424,33 @@ fn field_access_on_opaque_struct_is_rejected() { #[test] fn extern_and_static_keywords_are_no_op_at_global_scope() { use super::run_str; - // `extern` and `static` may appear before the type prefix - // (with or without `_Thread_local`); both are accepted and - // ignored. The semantics of the resulting decl are - // identical to the no-prefix form -- the global lives in - // .data with zero init -- so the program runs the same - // way it would without the keywords. + // `static` (and the accepted `static extern` combination) + // before the type prefix produce a tentative definition (C99 + // 6.9.2p2): the global lives in .data with zero init. let src = " - extern int a; static int b; static extern int c; int main() { - a = 1; b = 2; c = 3; - return a + b + c; + b = 2; c = 3; + return b + c; } "; - assert_eq!(run_str(&super::with_prelude(src)), 6); + assert_eq!(run_str(src), 5); + // A file-scope `extern int a;` defines no storage (C99 6.2.2p4 + // / 6.9.2); with no defining TU anywhere, a program that uses + // it fails with the linker's undefined-reference diagnosis + // instead of reading phantom zeroed storage. + let src = " + extern int a; + int main() { a = 1; return a; } + "; + let err = crate::Vm::new(super::compile_str(src)) + .run() + .expect_err("undefined extern object must not run"); + assert!( + err.to_string().contains("undefined reference to `a`"), + "{err}" + ); } #[test] @@ -761,3 +774,119 @@ fn deeply_nested_macro_expansion_does_not_overflow_the_stack() { // Must return (Ok or Err), not crash the test process. let _ = crate::c5::Compiler::new(src).compile(); } + +// C99 6.6p4: a zero divisor in an evaluated constant expression is a +// compile error, not a silent fold to 0; a short-circuited or +// not-taken operand stays unevaluated and must compile. +#[test] +fn constant_expression_division_by_zero_is_diagnosed() { + expect_compile_error( + "int x[1/0];\nint main(void){ return 0; }", + "division by zero in a constant expression", + ); + expect_compile_error( + "enum { A = 1 % 0 };\nint main(void){ return 0; }", + "division by zero in a constant expression", + ); + expect_compile_error( + "static int g = 8 / (4 - 4);\nint main(void){ return 0; }", + "division by zero in a constant expression", + ); + crate::c5::Compiler::new( + "int a[1 ? 2 : 1/0];\nint b[0 || 1 ? 2 : 5/0];\nenum { K = 0 && 1/0 };\n\ + int main(void){ return 0; }" + .to_string(), + ) + .compile() + .expect("unevaluated zero divisors must compile"); +} + +// C99 6.5.5 with the both-operands-wrap model: LLONG_MIN / -1 and +// LLONG_MIN % -1 fold (wrapping) instead of aborting the compiler. +#[test] +fn constant_expression_llong_min_div_neg_one_folds() { + crate::c5::Compiler::new( + "static long long k = (-9223372036854775807LL - 1) / -1;\n\ + static long long r = (-9223372036854775807LL - 1) % -1;\n\ + int main(void){ return r == 0 && k != 0 ? 0 : 1; }" + .to_string(), + ) + .compile() + .expect("LLONG_MIN / -1 must fold, not panic"); +} + +/// Run on a thread with the same explicit stack reservation the CLI +/// driver uses: deeply nested source costs more native stack in debug +/// builds than the default test-thread allotment provides. +fn on_big_stack(f: impl FnOnce() + Send + 'static) { + std::thread::Builder::new() + .stack_size(256 * 1024 * 1024) + .spawn(f) + .expect("spawn compile thread") + .join() + .expect("join compile thread"); +} + +fn expect_compile_error_on_big_stack(src: String, needle: &'static str) { + on_big_stack(move || expect_compile_error(&src, needle)); +} + +#[test] +fn deep_expression_nesting_is_diagnosed() { + let n = 2000; + let src = format!( + "int main(void) {{ return {}1{}; }}", + "(".repeat(n), + ")".repeat(n) + ); + expect_compile_error_on_big_stack(src, "expression nesting too deep"); +} + +#[test] +fn deep_global_initializer_expression_nesting_is_diagnosed() { + let n = 2000; + let src = format!("int x = {}1{};", "(".repeat(n), ")".repeat(n)); + expect_compile_error_on_big_stack(src, "nesting too deep"); +} + +#[test] +fn deep_declarator_nesting_is_diagnosed() { + let n = 2000; + let src = format!("int {}x{};", "(".repeat(n), ")".repeat(n)); + expect_compile_error_on_big_stack(src, "declarator nesting too deep"); +} + +#[test] +fn deep_initializer_brace_nesting_is_diagnosed() { + let n = 2000; + let src = format!( + "int main(void) {{ int q[1] = {}1{}; return q[0]; }}", + "{".repeat(n), + "}".repeat(n) + ); + expect_compile_error_on_big_stack(src, "initializer nesting too deep"); +} + +#[test] +fn deep_statement_block_nesting_is_diagnosed() { + let n = 2000; + let src = format!( + "int main(void) {{ {}{} return 0; }}", + "{".repeat(n), + "}".repeat(n) + ); + expect_compile_error_on_big_stack(src, "statement nesting too deep"); +} + +#[test] +fn c99_minimum_expression_nesting_compiles() { + // C99 5.2.4.1: 63 nesting levels of parenthesized expressions + // must be accepted; the depth bound sits far above this. + let n = 63; + let src = format!( + "int main(void) {{ return {}0{}; }}", + "(".repeat(n), + ")".repeat(n) + ); + on_big_stack(move || assert_eq!(super::run_str(&src), 0)); +} diff --git a/src/c5/tests/programs.rs b/src/c5/tests/programs.rs index f7aa2d084..2db15108f 100644 --- a/src/c5/tests/programs.rs +++ b/src/c5/tests/programs.rs @@ -104,6 +104,14 @@ fn fn_ptr_float_return() { assert_eq!(run_fixture("fn_ptr_float_return.c"), 0); } +#[test] +fn float_ternary_promote() { + // C99 6.5.15: an FP-typed conditional expression rides the fused + // StoreLocal / LoadLocal F32 path, keeping the synthetic merge slot + // mem2reg-promotable while preserving single-precision value. + assert_eq!(run_fixture("float_ternary_promote.c"), 0); +} + #[test] fn fn_ptr_float_arg() { // C99 6.5.2.2p7: a float argument through a function pointer is diff --git a/src/c5/tests/reloc_golden.rs b/src/c5/tests/reloc_golden.rs index 2cd83a142..bde2396b2 100644 --- a/src/c5/tests/reloc_golden.rs +++ b/src/c5/tests/reloc_golden.rs @@ -108,74 +108,74 @@ fn reloc_bytes(src: &str, target: Target) -> alloc::vec::Vec { /// of (source, target, options) only. Regenerate by running /// `reloc_object_bytes_match_golden` -- it panics with the current table. const GOLDEN: &[(&str, &str, u64, usize)] = &[ - ("ret42", "linux-x64", 0x19e783356189ee32, 1472), - ("ret42", "linux-arm64", 0x07fc9f07b272d045, 1472), - ("ret42", "macos-arm64", 0x07fc9f07b272d045, 1472), - ("ret42", "win-x64", 0x19e783356189ee32, 1472), - ("ret42", "win-arm64", 0x07fc9f07b272d045, 1472), - ("intarith", "linux-x64", 0x32e7f9a8a23d2879, 1776), - ("intarith", "linux-arm64", 0x3680fddfc8f85338, 1744), - ("intarith", "macos-arm64", 0x3680fddfc8f85338, 1744), - ("intarith", "win-x64", 0xf005b58ff0e2f9d2, 1800), - ("intarith", "win-arm64", 0x862165d8b7d20f14, 1784), - ("fparith", "linux-x64", 0x6dd6a94a4ceb8f5e, 1752), - ("fparith", "linux-arm64", 0x4bc00602138d1458, 1688), - ("fparith", "macos-arm64", 0x4bc00602138d1458, 1688), - ("fparith", "win-x64", 0x0daf626ffa7c9b1a, 1840), - ("fparith", "win-arm64", 0x4bc00602138d1458, 1688), - ("fpunary", "linux-x64", 0xd6da793aba57f99a, 1848), - ("fpunary", "linux-arm64", 0xf4b5b3f74419f790, 1752), - ("fpunary", "macos-arm64", 0xf4b5b3f74419f790, 1752), - ("fpunary", "win-x64", 0x4c3544b7d7598186, 1984), - ("fpunary", "win-arm64", 0xf4b5b3f74419f790, 1752), - ("mem", "linux-x64", 0xa0f7e9b7194eaa86, 1600), - ("mem", "linux-arm64", 0x44394734000af3f7, 1608), - ("mem", "macos-arm64", 0x44394734000af3f7, 1608), - ("mem", "win-x64", 0x9d9c12dbe29b0a26, 1600), - ("mem", "win-arm64", 0x44394734000af3f7, 1608), - ("data_calls", "linux-x64", 0x021bff3d4de3acec, 1664), - ("data_calls", "linux-arm64", 0x2eaa6b7fcabb0b37, 1688), - ("data_calls", "macos-arm64", 0x2eaa6b7fcabb0b37, 1688), - ("data_calls", "win-x64", 0x8701619c09b78c22, 1680), - ("data_calls", "win-arm64", 0x2eaa6b7fcabb0b37, 1688), - ("struct_param_spill", "linux-x64", 0x4c486c8df4456e10, 1680), + ("ret42", "linux-x64", 0x2fab302afe7d051f, 1472), + ("ret42", "linux-arm64", 0xa1f9fbf7bb9cbb2c, 1472), + ("ret42", "macos-arm64", 0xa1f9fbf7bb9cbb2c, 1472), + ("ret42", "win-x64", 0x2fab302afe7d051f, 1472), + ("ret42", "win-arm64", 0xa1f9fbf7bb9cbb2c, 1472), + ("intarith", "linux-x64", 0x23f78314c1cff274, 1776), + ("intarith", "linux-arm64", 0xfe88c2dcdf472389, 1744), + ("intarith", "macos-arm64", 0xfe88c2dcdf472389, 1744), + ("intarith", "win-x64", 0x996e3098a493f373, 1800), + ("intarith", "win-arm64", 0xd65c6cec47efdad5, 1784), + ("fparith", "linux-x64", 0xaed28d15dbe12f9f, 1752), + ("fparith", "linux-arm64", 0x10b5c40cae1c98b9, 1688), + ("fparith", "macos-arm64", 0x10b5c40cae1c98b9, 1688), + ("fparith", "win-x64", 0xbc441586c78cb6ab, 1840), + ("fparith", "win-arm64", 0x10b5c40cae1c98b9, 1688), + ("fpunary", "linux-x64", 0xa7c6296710fb7597, 1848), + ("fpunary", "linux-arm64", 0x23cf0e4149bb3595, 1752), + ("fpunary", "macos-arm64", 0x23cf0e4149bb3595, 1752), + ("fpunary", "win-x64", 0xbc02ab7882ec515f, 1984), + ("fpunary", "win-arm64", 0x23cf0e4149bb3595, 1752), + ("mem", "linux-x64", 0xb5e67861feca0b63, 1600), + ("mem", "linux-arm64", 0x30acdb6f0e6ff6be, 1608), + ("mem", "macos-arm64", 0x30acdb6f0e6ff6be, 1608), + ("mem", "win-x64", 0x445055ce1605ec83, 1600), + ("mem", "win-arm64", 0x30acdb6f0e6ff6be, 1608), + ("data_calls", "linux-x64", 0xe8c2b32035325e81, 1664), + ("data_calls", "linux-arm64", 0x6f46939d6a2a0046, 1688), + ("data_calls", "macos-arm64", 0x6f46939d6a2a0046, 1688), + ("data_calls", "win-x64", 0xc3ebc6db69470097, 1680), + ("data_calls", "win-arm64", 0x6f46939d6a2a0046, 1688), + ("struct_param_spill", "linux-x64", 0x46151b2f7769d061, 1680), ( "struct_param_spill", "linux-arm64", - 0x57d897a30a6971ba, + 0xff95238ed7250147, 1664, ), ( "struct_param_spill", "macos-arm64", - 0x57d897a30a6971ba, + 0xff95238ed7250147, 1664, ), - ("struct_param_spill", "win-x64", 0xc8b021ee3b3b7577, 1720), - ("struct_param_spill", "win-arm64", 0x0bcb20a73947ed86, 1696), + ("struct_param_spill", "win-x64", 0x3fef0b9e920a5ec2, 1720), + ("struct_param_spill", "win-arm64", 0xb9721374270c6243, 1696), ( "fp_across_struct_call", "linux-x64", - 0x9e3edfe0dc19dbdb, + 0x2ff371699761f6ca, 1744, ), ( "fp_across_struct_call", "linux-arm64", - 0x728818c3ad0a7bc6, + 0x8bfeabe2701aede3, 1688, ), ( "fp_across_struct_call", "macos-arm64", - 0x728818c3ad0a7bc6, + 0x8bfeabe2701aede3, 1688, ), - ("fp_across_struct_call", "win-x64", 0xefdbefe433ac8e18, 1816), + ("fp_across_struct_call", "win-x64", 0x87d8fca72654ef11, 1816), ( "fp_across_struct_call", "win-arm64", - 0x728818c3ad0a7bc6, + 0x8bfeabe2701aede3, 1688, ), ]; diff --git a/src/c5/tests/vla.rs b/src/c5/tests/vla.rs new file mode 100644 index 000000000..721ed3b67 --- /dev/null +++ b/src/c5/tests/vla.rs @@ -0,0 +1,92 @@ +//! C99 6.7.6.2 variable-length array regression tests. +//! +//! The runnable fixtures go through the JIT, whose lowering is the same +//! as the AOT Mach-O / ELF backends; those backends also run the same +//! fixtures through their `fixture_parity` tables (see +//! `super::native::NATIVE_FIXTURES`, `super::native_elf`, +//! `super::native_elf_x64`). The constraint-violation fixtures assert a +//! clean compile-time diagnostic rather than a miscompile. + +use crate::Compiler; + +/// Compile a fixture and return the diagnostic message, panicking if it +/// compiled. Used for the C99 constraint violations that must be +/// rejected, not silently accepted. +fn compile_error(name: &str) -> String { + let src = super::load_fixture(name); + match Compiler::new(super::with_prelude(&src)).compile() { + Ok(_) => panic!("{name}: expected a compile error, but it compiled"), + Err(e) => alloc::format!("{e}"), + } +} + +#[test] +fn multidim_vla_rejected() { + assert!( + compile_error("vla_multidim_rejected.c").contains("multidimensional variable-length"), + "wrong diagnostic for a multidimensional VLA" + ); +} + +#[test] +fn file_scope_vla_rejected() { + assert!( + compile_error("vla_file_scope_rejected.c").contains("variable-length array"), + "wrong diagnostic for a file-scope VLA" + ); +} + +#[test] +fn vla_initializer_rejected() { + assert!( + compile_error("vla_initializer_rejected.c").contains("may not have an initializer"), + "wrong diagnostic for an initialized VLA" + ); +} + +/// The runnable fixtures execute through the JIT on the hosts where the +/// loader is implemented (Linux aarch64 / x86_64, macOS arm64). Each +/// fixture self-checks and returns 0 on success. +#[cfg(any( + all( + target_os = "linux", + any(target_arch = "aarch64", target_arch = "x86_64") + ), + all(target_os = "macos", target_arch = "aarch64"), +))] +mod jit_lane { + use crate::{Compiler, jit_run}; + + fn jit_fixture_exit(name: &str) -> i32 { + let src = super::super::load_fixture(name); + let program = Compiler::new(super::super::with_prelude(&src)) + .compile() + .expect("compile failed"); + jit_run(&program, &[name.to_string()]).expect("jit_run failed") + } + + #[test] + fn basic_sum() { + assert_eq!(jit_fixture_exit("vla_basic_sum.c"), 0); + } + + #[test] + fn runtime_sizeof() { + assert_eq!(jit_fixture_exit("vla_runtime_sizeof.c"), 0); + } + + #[test] + fn size_from_arg() { + assert_eq!(jit_fixture_exit("vla_size_from_arg.c"), 0); + } + + #[test] + fn scope_reclaim_loop() { + assert_eq!(jit_fixture_exit("vla_scope_reclaim_loop.c"), 0); + } + + #[test] + fn param_decay() { + assert_eq!(jit_fixture_exit("vla_param_decay.c"), 0); + } +} diff --git a/src/c5/vm/mod.rs b/src/c5/vm/mod.rs index 9a5e05af6..f5e667b19 100644 --- a/src/c5/vm/mod.rs +++ b/src/c5/vm/mod.rs @@ -57,6 +57,18 @@ pub struct Vm { /// (walker compile errors, etc.) are deferred to `run` /// because `with_host` doesn't return `Result`. ssa_funcs: Result, C5Error>, + /// Cross-TU placeholder ent_pc -> symbol name for every + /// declared-but-undefined extern function. `run` refuses any + /// reference to these, mirroring the linker. + extern_fn_names: alloc::collections::BTreeMap, + /// `(name, defined_here)` per parser symbol, indexed by the + /// sym idx the `FunctionSsa::extern_*_refs` tables carry. + symbol_defs: Vec<(String, bool)>, + /// Local names bound to host data (`#pragma binding(data ...)`). + data_binding_locals: alloc::collections::BTreeSet, + /// `target_ent_pc` of every static-initializer function + /// pointer, checked against `extern_fn_names` at `run`. + code_reloc_pcs: Vec, } /// `Vm::new` is only available with the `std` feature; it picks the @@ -86,6 +98,28 @@ impl Vm { .iter() .flat_map(|d| d.bindings.iter().map(|b| b.local_name.clone())) .collect(); + let extern_fn_names = program + .extern_function_imports + .iter() + .map(|(pc, name)| (*pc, name.clone())) + .collect(); + let symbol_defs = program + .symbols + .iter() + .map(|s| (s.name.clone(), s.defined_here)) + .collect(); + let data_binding_locals = program + .dylibs + .iter() + .flat_map(|d| d.bindings.iter()) + .filter(|b| b.is_data) + .map(|b| b.local_name.clone()) + .collect(); + let code_reloc_pcs = program + .code_relocs + .iter() + .map(|r| r.target_ent_pc as usize) + .collect(); // Concatenate the TLS block onto the data segment so // `Inst::TlsAddr` resolutions ride the existing data-side // access checks. The starting offset is captured before @@ -115,7 +149,65 @@ impl Vm { track_pointers: false, tls_base, ssa_funcs, + extern_fn_names, + symbol_defs, + data_binding_locals, + code_reloc_pcs, + } + } + + /// Refuse any reference to a symbol with no definition in + /// this unit before execution starts, mirroring the linker's + /// undefined-symbol diagnosis. Without this, a call whose + /// placeholder pc collides with a real `ent_pc` dispatches to + /// the wrong function and an extern object reads a zero slot. + fn check_extern_refs(&self, funcs: &[FunctionSsa]) -> Result<(), C5Error> { + use super::ir::Inst; + let undef = + |name: &str| C5Error::Runtime(alloc::format!("undefined reference to `{name}`")); + for f in funcs { + for inst in &f.insts { + let pc = match inst { + Inst::Call { target_pc, .. } => *target_pc, + Inst::ImmCode(pc) => *pc, + _ => continue, + }; + if let Some(name) = self.extern_fn_names.get(&pc) { + return Err(undef(name)); + } + } + // `target_pc == 0` call / code-address sites record the + // parser sym; the sentinel is ambiguous (the first + // function's ent_pc is also 0), so consult the symbol. + for &(_, sym) in f.extern_call_refs.iter().chain(&f.extern_imm_code_refs) { + if let Some((name, defined)) = self.symbol_defs.get(sym as usize) + && !defined + { + return Err(undef(name)); + } + } + for &(_, sym) in f.extern_imm_data_refs.iter().chain(&f.extern_tls_refs) { + let Some((name, defined)) = self.symbol_defs.get(sym as usize) else { + continue; + }; + if *defined { + continue; + } + if self.data_binding_locals.contains(name) { + return Err(C5Error::Runtime(alloc::format!( + "`{name}` is bound to host data; the interpreter cannot \ + reach host memory (use --jit or compile natively)" + ))); + } + return Err(undef(name)); + } + } + for pc in &self.code_reloc_pcs { + if let Some(name) = self.extern_fn_names.get(pc) { + return Err(undef(name)); + } } + Ok(()) } /// Enable per-instruction trace output. Mirrors @@ -164,6 +256,7 @@ impl Vm { if funcs.is_empty() { return Err(C5Error::Runtime("empty program".to_string())); } + self.check_extern_refs(funcs)?; ssa::run_program_with_args_tracked( funcs, &self.data, diff --git a/src/c5/vm/ssa.rs b/src/c5/vm/ssa.rs index da40d3fff..ae21313be 100644 --- a/src/c5/vm/ssa.rs +++ b/src/c5/vm/ssa.rs @@ -244,10 +244,13 @@ impl Memory { "vm_ssa: stack overflow allocating {frame_bytes} bytes from {base}", )) })?; - if next > self.bytes.len() { + // Frames must stay inside [stack_base, heap_base); a frame + // written past heap_base would zero live heap allocations. + if next > self.heap_base { return Err(C5Error::Runtime(format!( - "vm_ssa: stack overflow ({next} > {})", - self.bytes.len(), + "vm_ssa: stack overflow: frame of {frame_bytes} bytes exceeds the \ + {}-byte stack region", + self.heap_base - self.stack_base, ))); } // Zero the new frame's bytes so undefined reads observe @@ -512,7 +515,30 @@ pub(super) fn run_program_with_args_tracked( } else { &entry_args }; - run_func(&prog, &mut mem, host, entry, slice) + match run_func(&prog, &mut mem, host, entry, slice) { + Err(e) => match exit_status_of(&e) { + Some(status) => Ok(status), + None => Err(e), + }, + ok => ok, + } +} + +/// `exit(status)` unwinds the interpreter through the `Result` +/// channel. The sentinel stays private to this module: it is +/// produced only by the `exit` shim and consumed at the program +/// boundary above, so it never surfaces as a user-visible error. +const EXIT_SIGNAL_PREFIX: &str = "vm_ssa-exit-status:"; + +fn exit_signal(status: i64) -> C5Error { + C5Error::Runtime(format!("{EXIT_SIGNAL_PREFIX}{status}")) +} + +fn exit_status_of(e: &C5Error) -> Option { + match e { + C5Error::Runtime(msg) => msg.strip_prefix(EXIT_SIGNAL_PREFIX)?.parse().ok(), + _ => None, + } } /// Lay out the argv strings + the argv pointer array at the end @@ -803,7 +829,9 @@ fn run_inst( frame.regs[v as usize] = (prog.tls_base as i64).wrapping_add(*off); return Ok(()); } - Inst::Load { addr, disp, kind } => { + Inst::Load { + addr, disp, kind, .. + } => { let a = frame.regs[*addr as usize].wrapping_add(*disp as i64); if a & CODE_ADDR_MASK != 0 || a < 0 @@ -823,6 +851,7 @@ fn run_inst( disp, value, kind, + .. } => { let a = frame.regs[*addr as usize].wrapping_add(*disp as i64); if a & CODE_ADDR_MASK != 0 @@ -842,14 +871,16 @@ fn run_inst( frame.regs[v as usize] = stored; return Ok(()); } - Inst::LoadLocal { off, kind } => { + Inst::LoadLocal { off, kind, .. } => { let addr = frame.slot_addr(*off).ok_or_else(|| { C5Error::Runtime(format!("vm_ssa: LoadLocal: slot {off} out of range")) })?; frame.regs[v as usize] = load_from_memory(mem, addr, *kind)?; return Ok(()); } - Inst::StoreLocal { off, value, kind } => { + Inst::StoreLocal { + off, value, kind, .. + } => { let addr = frame.slot_addr(*off).ok_or_else(|| { C5Error::Runtime(format!("vm_ssa: StoreLocal: slot {off} out of range")) })?; @@ -1137,13 +1168,13 @@ fn dispatch_callext( host: &mut H, ) -> Result { match name { - // `exit(int code)` terminates the host process in libc; - // inside the SSA-VM we route it through a sentinel error - // that the outer driver can catch and convert to the - // overall return value. + // `exit(int code)` terminates the hosted program (C99 + // 7.20.4.3). The Err unwinds every interpreter frame; + // `run_program_with_args_tracked` converts the sentinel + // back into an Ok(status) at the program boundary. "exit" => { let code = args.first().copied().unwrap_or(0); - Err(C5Error::Runtime(format!("vm_ssa: exit({code})"))) + Err(exit_signal(code)) } // `void *memcpy(void *dst, const void *src, size_t n)`. // c5's cdecl pushes args right-to-left; the walker @@ -1277,12 +1308,10 @@ fn dispatch_callext( } Ok(0) } - // `int printf(const char *fmt, ...)` -- minimal subset - // (%d / %u / %x / %c / %s / %%). Walks the variadic - // tail in `args[1..]`, formats into a String, and writes - // it to stdout via the host. Returns 0 (printf returns - // bytes written; no caller depends on the exact value - // in the current fixture set). + // `int printf(const char *fmt, ...)` -- formats the + // variadic tail in `args[1..]` per C99 7.19.6.1 and + // writes the bytes to stdout via the host. Returns the + // number of bytes transmitted (7.19.6.3p3). "printf" => { let fmt_addr = *args .first() @@ -1295,7 +1324,7 @@ fn dispatch_callext( let fmt = read_cstring_bytes(mem, fmt_addr as usize)?; let out = format_printf(&fmt, &args[1..], mem)?; let _ = host.write(1, &out); - Ok(0) + Ok(out.len() as i64) } // `int putchar(int c)` -- write one byte to stdout, returns // the byte (or EOF on error; we return the byte unconditionally). @@ -1368,6 +1397,28 @@ fn dispatch_callext( host.setenv(&env_name, &env_val, overwrite); Ok(0) } + // `int _putenv_s(const char *name, const char *value)` -- msvcrt's + // 2-argument setter, always replacing. The Windows `` + // setenv wrapper calls it after its own overwrite check, so the + // bridge forces the write. + "_putenv_s" => { + if args.len() < 2 { + return Err(C5Error::Runtime( + "vm_ssa: _putenv_s expects 2 args".to_string(), + )); + } + let name_addr = args[0]; + let val_addr = args[1]; + if name_addr < 0 || val_addr < 0 { + return Err(C5Error::Runtime(format!( + "vm_ssa: _putenv_s: bad addrs name=0x{name_addr:x} val=0x{val_addr:x}", + ))); + } + let env_name = read_cstring(mem, name_addr as usize)?; + let env_val = read_cstring(mem, val_addr as usize)?; + host.setenv(&env_name, &env_val, super::super::host::Overwrite::Force); + Ok(0) + } // `void *dlopen(const char *filename, int flags)` -- a NULL // filename maps to `Option::None` so the host can produce // dlopen(NULL, ...) (the global symbol table). @@ -1453,16 +1504,51 @@ fn read_cstring(mem: &Memory, addr: usize) -> Result Result, C5Error> { - use core::fmt::Write; +/// Argument-width selector from a conversion spec's length +/// modifier (C99 7.19.6.1p7). The variadic tail holds one i64 +/// per argument; the modifier decides how many low bits carry +/// the value. +#[derive(Clone, Copy, PartialEq, Eq)] +enum ArgLen { + Char, // hh + Short, // h + Int, // (none) + Long, // l / ll / j / z / t / L +} + +/// One parsed conversion specification (C99 7.19.6.1p4). +struct PrintfSpec { + minus: bool, + plus: bool, + space: bool, + alt: bool, + zero: bool, + width: Option, + precision: Option, + len: ArgLen, + conv: u8, +} + +/// printf formatter (C99 7.19.6.1). Parses the full spec grammar +/// -- flags, width (incl. `*`), precision (incl. `.*`), length +/// modifiers -- and pulls arguments from `args` as each +/// conversion requires. Returns the raw output bytes for the +/// caller to hand to `host.write`. An unrecognised conversion +/// emits its spec text verbatim without consuming an argument +/// (undefined per 7.19.6.1p9). +fn format_printf(fmt: &[u8], args: &[i64], mem: &mut Memory) -> Result, C5Error> { let mut out: Vec = Vec::new(); - let mut num = alloc::string::String::new(); let mut arg_idx = 0usize; + let next_arg = |arg_idx: &mut usize| -> Result { + let val = args.get(*arg_idx).copied().ok_or_else(|| { + C5Error::Runtime(format!( + "vm_ssa: printf: format wants arg #{arg_idx} but only {} supplied", + args.len(), + )) + })?; + *arg_idx += 1; + Ok(val) + }; let mut i = 0usize; while i < fmt.len() { let c = fmt[i]; @@ -1471,70 +1557,326 @@ fn format_printf(fmt: &[u8], args: &[i64], mem: &Memory) -> Result, C5Er out.push(c); continue; } - let Some(&spec) = fmt.get(i) else { - break; + let spec_start = i; + let mut s = PrintfSpec { + minus: false, + plus: false, + space: false, + alt: false, + zero: false, + width: None, + precision: None, + len: ArgLen::Int, + conv: 0, }; - i += 1; - if spec == b'%' { - out.push(b'%'); - continue; + while let Some(&f) = fmt.get(i) { + match f { + b'-' => s.minus = true, + b'+' => s.plus = true, + b' ' => s.space = true, + b'#' => s.alt = true, + b'0' => s.zero = true, + _ => break, + } + i += 1; + } + if fmt.get(i) == Some(&b'*') { + i += 1; + // A negative `*` width means `-` flag plus the + // absolute value (7.19.6.1p5). + let w = next_arg(&mut arg_idx)? as i32; + s.width = Some(w.unsigned_abs() as usize); + s.minus |= w < 0; + } else { + while let Some(d) = fmt.get(i).filter(|d| d.is_ascii_digit()) { + s.width = Some(s.width.unwrap_or(0) * 10 + (d - b'0') as usize); + i += 1; + } } - let Some(val) = args.get(arg_idx).copied() else { - return Err(C5Error::Runtime(format!( - "vm_ssa: printf: format wants arg #{arg_idx} but only {} supplied", - args.len(), - ))); - }; - arg_idx += 1; - match spec { - b'd' | b'i' => { - num.clear(); - let _ = write!(num, "{}", val as i32 as i64); - out.extend_from_slice(num.as_bytes()); + if fmt.get(i) == Some(&b'.') { + i += 1; + if fmt.get(i) == Some(&b'*') { + i += 1; + // A negative `*` precision reads as omitted (p5). + let p = next_arg(&mut arg_idx)? as i32; + s.precision = (p >= 0).then_some(p as usize); + } else { + s.precision = Some(0); + while let Some(d) = fmt.get(i).filter(|d| d.is_ascii_digit()) { + s.precision = Some(s.precision.unwrap_or(0) * 10 + (d - b'0') as usize); + i += 1; + } + } + } + match fmt.get(i) { + Some(b'h') => { + i += 1; + s.len = ArgLen::Short; + if fmt.get(i) == Some(&b'h') { + i += 1; + s.len = ArgLen::Char; + } + } + Some(b'l') => { + i += 1; + s.len = ArgLen::Long; + if fmt.get(i) == Some(&b'l') { + i += 1; + } } - b'u' => { - num.clear(); - let _ = write!(num, "{}", val as u32 as u64); - out.extend_from_slice(num.as_bytes()); + Some(b'j') | Some(b'z') | Some(b't') | Some(b'L') => { + i += 1; + s.len = ArgLen::Long; } - b'x' => { - num.clear(); - let _ = write!(num, "{:x}", val as u32); - out.extend_from_slice(num.as_bytes()); + _ => {} + } + let Some(&conv) = fmt.get(i) else { + // Incomplete trailing spec: emit verbatim. + out.push(b'%'); + out.extend_from_slice(&fmt[spec_start..]); + break; + }; + i += 1; + s.conv = conv; + match conv { + b'%' => out.push(b'%'), + b'd' | b'i' => { + let raw = next_arg(&mut arg_idx)?; + let v = match s.len { + ArgLen::Char => raw as i8 as i64, + ArgLen::Short => raw as i16 as i64, + ArgLen::Int => raw as i32 as i64, + ArgLen::Long => raw, + }; + let sign = if v < 0 { + "-" + } else if s.plus { + "+" + } else if s.space { + " " + } else { + "" + }; + let digits = format!("{}", v.unsigned_abs()); + push_int(&mut out, &s, sign, &digits, v == 0); } - b'X' => { - num.clear(); - let _ = write!(num, "{:X}", val as u32); - out.extend_from_slice(num.as_bytes()); + b'u' | b'o' | b'x' | b'X' => { + let raw = next_arg(&mut arg_idx)?; + let v = match s.len { + ArgLen::Char => raw as u8 as u64, + ArgLen::Short => raw as u16 as u64, + ArgLen::Int => raw as u32 as u64, + ArgLen::Long => raw as u64, + }; + let digits = match conv { + b'u' => format!("{v}"), + b'o' => format!("{v:o}"), + b'x' => format!("{v:x}"), + _ => format!("{v:X}"), + }; + // `#`: force a leading 0 on octal; prefix 0x / 0X + // on a nonzero hex value (7.19.6.1p6). + let (prefix, digits) = match conv { + b'o' if s.alt && !digits.starts_with('0') => ("", format!("0{digits}")), + b'x' if s.alt && v != 0 => ("0x", digits), + b'X' if s.alt && v != 0 => ("0X", digits), + _ => ("", digits), + }; + push_int(&mut out, &s, prefix, &digits, v == 0); } b'c' => { - out.push(val as u8); + let v = next_arg(&mut arg_idx)?; + push_padded(&mut out, &s, &[v as u8]); } b's' => { + let val = next_arg(&mut arg_idx)?; if val < 0 { return Err(C5Error::Runtime(format!( "vm_ssa: printf %s: bad ptr 0x{val:x}", ))); } - let s = read_cstring_bytes(mem, val as usize)?; - out.extend_from_slice(&s); + let mut bytes = read_cstring_bytes(mem, val as usize)?; + if let Some(p) = s.precision { + bytes.truncate(p); + } + push_padded(&mut out, &s, &bytes); } b'p' => { - num.clear(); - let _ = write!(num, "0x{:x}", val as u64); - out.extend_from_slice(num.as_bytes()); + let v = next_arg(&mut arg_idx)? as u64; + push_padded(&mut out, &s, format!("0x{v:x}").as_bytes()); + } + b'f' | b'F' | b'e' | b'E' | b'g' | b'G' => { + let v = f64::from_bits(next_arg(&mut arg_idx)? as u64); + let body = format_float(v, &s); + push_int( + &mut out, + &s, + if v.is_sign_negative() && !v.is_nan() { + "-" + } else if s.plus { + "+" + } else if s.space { + " " + } else { + "" + }, + &body, + false, + ); } - other => { - // Unrecognised conversion: emit the literal - // `%X` so the caller sees what was wrong. + b'n' => { + // Store the byte count written so far (7.19.6.1p8). + let addr = next_arg(&mut arg_idx)?; + if addr < 0 { + return Err(C5Error::Runtime(format!( + "vm_ssa: printf %n: bad ptr 0x{addr:x}", + ))); + } + let kind = match s.len { + ArgLen::Char => StoreKind::I8, + ArgLen::Short => StoreKind::I16, + ArgLen::Int => StoreKind::I32, + ArgLen::Long => StoreKind::I64, + }; + store_to_memory(mem, addr as usize, out.len() as i64, kind)?; + } + _ => { out.push(b'%'); - out.push(other); + out.extend_from_slice(&fmt[spec_start..i]); } } } Ok(out) } +/// Pad `body` to the spec's field width (7.19.6.1p5): spaces on +/// the left by default, on the right under `-`. +fn push_padded(out: &mut Vec, s: &PrintfSpec, body: &[u8]) { + let pad = s.width.unwrap_or(0).saturating_sub(body.len()); + if !s.minus { + out.resize(out.len() + pad, b' '); + } + out.extend_from_slice(body); + if s.minus { + out.resize(out.len() + pad, b' '); + } +} + +/// Assemble a numeric conversion: precision zero-extends the +/// digit string (and suppresses a zero value at precision 0); +/// the `0` flag zero-pads between the sign / base prefix and the +/// digits unless `-` or an explicit precision overrides it +/// (7.19.6.1p6). +fn push_int(out: &mut Vec, s: &PrintfSpec, prefix: &str, digits: &str, is_zero: bool) { + let mut digits = alloc::string::String::from(digits); + if let Some(p) = s.precision + && !matches!(s.conv, b'f' | b'F' | b'e' | b'E' | b'g' | b'G') + { + if is_zero && p == 0 { + digits.clear(); + } + while digits.len() < p { + digits.insert(0, '0'); + } + } + let body_len = prefix.len() + digits.len(); + let pad = s.width.unwrap_or(0).saturating_sub(body_len); + let zero_pad = s.zero + && !s.minus + && (matches!(s.conv, b'f' | b'F' | b'e' | b'E' | b'g' | b'G') || s.precision.is_none()); + if zero_pad { + out.extend_from_slice(prefix.as_bytes()); + out.resize(out.len() + pad, b'0'); + out.extend_from_slice(digits.as_bytes()); + return; + } + if !s.minus { + out.resize(out.len() + pad, b' '); + } + out.extend_from_slice(prefix.as_bytes()); + out.extend_from_slice(digits.as_bytes()); + if s.minus { + out.resize(out.len() + pad, b' '); + } +} + +/// Format `|v|` for the f / e / g conversion families +/// (7.19.6.1p8); the caller prepends the sign and applies the +/// field width. Uppercase conversions upper-case the result. +fn format_float(v: f64, s: &PrintfSpec) -> alloc::string::String { + let upper = matches!(s.conv, b'F' | b'E' | b'G'); + if v.is_nan() { + return if upper { "NAN".into() } else { "nan".into() }; + } + if v.is_infinite() { + return if upper { "INF".into() } else { "inf".into() }; + } + let av = v.abs(); + let p = s.precision.unwrap_or(6); + let body = match s.conv { + b'f' | b'F' => { + let mut b = format!("{av:.p$}"); + if s.alt && p == 0 { + b.push('.'); + } + b + } + b'e' | b'E' => format_exp(av, p, s.alt), + _ => { + // g/G: precision P counts significant digits (0 reads + // as 1). Style e when the exponent X < -4 or X >= P, + // else style f with precision P-1-X; trailing zeros + // drop unless `#`. + let pp = p.max(1); + let exp = decimal_exponent(av, pp - 1); + let mut b = if exp < -4 || exp >= pp as i32 { + format_exp(av, pp - 1, s.alt) + } else { + format!("{:.*}", (pp as i32 - 1 - exp).max(0) as usize, av) + }; + if !s.alt && b.contains('.') { + let frac_end = b.find(['e', 'E']).unwrap_or(b.len()); + let trimmed = b[..frac_end].trim_end_matches('0').trim_end_matches('.'); + b = format!("{}{}", trimmed, &b[frac_end..]); + } + b + } + }; + if upper { body.to_uppercase() } else { body } +} + +/// `d.dddde+/-dd` with `prec` fraction digits (7.19.6.1p8, the e +/// conversion). Rust's `{:e}` produces `d.ddddeN`; rewrite the +/// exponent into the sign + minimum-two-digit C form. +fn format_exp(av: f64, prec: usize, alt: bool) -> alloc::string::String { + let raw = format!("{av:.prec$e}"); + let (mantissa, exp) = raw.split_once('e').unwrap_or((raw.as_str(), "0")); + let exp: i32 = exp.parse().unwrap_or(0); + let mut mantissa = alloc::string::String::from(mantissa); + if alt && prec == 0 { + mantissa.push('.'); + } + format!( + "{mantissa}e{}{:02}", + if exp < 0 { '-' } else { '+' }, + exp.unsigned_abs(), + ) +} + +/// Decimal exponent of `av` after rounding to `prec` fraction +/// digits in e-style -- the X in C99 7.19.6.1p8's g rules. +/// Deriving it from the rounded e form keeps the boundary cases +/// (9.99... rounding up a decade) consistent with the output. +fn decimal_exponent(av: f64, prec: usize) -> i32 { + if av == 0.0 { + return 0; + } + let raw = format!("{av:.prec$e}"); + raw.split_once('e') + .and_then(|(_, e)| e.parse().ok()) + .unwrap_or(0) +} + /// Parse `(dst/buf, src/buf, n)` argument triples used by /// memcpy / memcmp. Validates the size argument and converts /// pointer args to `usize`. @@ -1614,6 +1956,23 @@ fn run_intrinsic( frame.regs[v as usize] = base as i64; Ok(()) } + // VLA block reclamation (C99 6.7.6.2): snapshot / restore the + // frame's bump-allocation cursor so a VLA declared in a block + // (or a loop body, once per iteration) frees on exit. + Intrinsic::AllocaSave => { + frame.regs[v as usize] = mem.stack_top as i64; + Ok(()) + } + Intrinsic::AllocaRestore => { + let saved = args + .first() + .map(|&a| frame.regs[a as usize]) + .ok_or_else(|| { + C5Error::Runtime("vm_ssa: AllocaRestore expects 1 argument".to_string()) + })?; + mem.release_frame(saved as usize); + Ok(()) + } Intrinsic::VaStart => { let ap_addr = frame.regs[args[0] as usize] as usize; let last_addr = frame.regs[args[1] as usize]; @@ -1984,18 +2343,85 @@ mod tests { // 0xC3 0xA9 (the UTF-8 encoding of U+00E9) must reach stdout as // those two raw bytes, not the 4-byte Latin-1 -> UTF-8 re-encoding // the old path produced. - let mem = Memory::new(b"\xC3\xA9\x00"); - let out = format_printf(b"%s", &[0], &mem).expect("format"); + let mut mem = Memory::new(b"\xC3\xA9\x00"); + let out = format_printf(b"%s", &[0], &mut mem).expect("format"); assert_eq!(out, alloc::vec![0xC3u8, 0xA9]); } #[test] fn printf_char_preserves_high_byte() { - let mem = Memory::new(b"\x00"); - let out = format_printf(b"%c", &[0x80], &mem).expect("format"); + let mut mem = Memory::new(b"\x00"); + let out = format_printf(b"%c", &[0x80], &mut mem).expect("format"); assert_eq!(out, alloc::vec![0x80u8]); } + fn fmt1(fmt: &[u8], args: &[i64]) -> alloc::string::String { + let mut mem = Memory::new(b"abcdef\x00"); + let out = format_printf(fmt, args, &mut mem).expect("format"); + alloc::string::String::from_utf8(out).expect("utf8") + } + + #[test] + fn printf_width_precision_flags() { + // C99 7.19.6.1p5-p6: field width, precision, and the + // -, +, 0, # flags across the integer conversions. + assert_eq!(fmt1(b"%5d", &[42]), " 42"); + assert_eq!(fmt1(b"%-5d|", &[42]), "42 |"); + assert_eq!(fmt1(b"%05d", &[-42]), "-0042"); + assert_eq!(fmt1(b"%+d %+d", &[7, -7]), "+7 -7"); + assert_eq!(fmt1(b"% d", &[7]), " 7"); + assert_eq!(fmt1(b"%.5d", &[42]), "00042"); + assert_eq!(fmt1(b"%8.5d", &[42]), " 00042"); + assert_eq!(fmt1(b"%.0d", &[0]), ""); + assert_eq!(fmt1(b"%#x %#o", &[255, 8]), "0xff 010"); + assert_eq!(fmt1(b"%08x", &[0xbeef]), "0000beef"); + assert_eq!(fmt1(b"%*d", &[5, 42]), " 42"); + assert_eq!(fmt1(b"%-*d|", &[5, 42]), "42 |"); + assert_eq!(fmt1(b"%.*d", &[4, 42]), "0042"); + assert_eq!(fmt1(b"%10.3s|", &[0]), " abc|"); + assert_eq!(fmt1(b"%-6.2s|", &[0]), "ab |"); + assert_eq!(fmt1(b"%3c|", &[b'z' as i64]), " z|"); + } + + #[test] + fn printf_length_modifiers() { + // C99 7.19.6.1p7: hh / h narrow, l / ll / z / j keep the + // full 64-bit value; the default int case truncates to 32. + assert_eq!(fmt1(b"%ld", &[0x1_0000_0001]), "4294967297"); + assert_eq!(fmt1(b"%lld", &[-1]), "-1"); + assert_eq!(fmt1(b"%d", &[0x1_0000_0001]), "1"); + assert_eq!(fmt1(b"%hhd", &[0x1ff]), "-1"); + assert_eq!(fmt1(b"%hu", &[0x1_0005]), "5"); + assert_eq!(fmt1(b"%zu", &[u64::MAX as i64]), "18446744073709551615"); + assert_eq!(fmt1(b"%lx", &[-1]), "ffffffffffffffff"); + } + + #[test] + fn printf_float_conversions() { + let b = |v: f64| v.to_bits() as i64; + assert_eq!(fmt1(b"%f", &[b(3.5)]), "3.500000"); + assert_eq!(fmt1(b"%.2f", &[b(6.54321)]), "6.54"); + assert_eq!(fmt1(b"%8.3f", &[b(-6.54321)]), " -6.543"); + assert_eq!(fmt1(b"%08.3f", &[b(-6.54321)]), "-006.543"); + assert_eq!(fmt1(b"%e", &[b(65432.1875)]), "6.543219e+04"); + assert_eq!(fmt1(b"%.2E", &[b(0.00123)]), "1.23E-03"); + assert_eq!(fmt1(b"%g", &[b(0.0001)]), "0.0001"); + assert_eq!(fmt1(b"%g", &[b(0.00001)]), "1e-05"); + assert_eq!(fmt1(b"%g", &[b(100.0)]), "100"); + assert_eq!(fmt1(b"%.3g", &[b(1234.5)]), "1.23e+03"); + assert_eq!(fmt1(b"%f", &[b(f64::NAN)]), "nan"); + assert_eq!(fmt1(b"%F", &[b(f64::INFINITY)]), "INF"); + } + + #[test] + fn printf_percent_n_stores_count() { + // C99 7.19.6.1p8: %n stores the bytes written so far. + let mut mem = Memory::new(&[0u8; 16]); + let out = format_printf(b"abc%nd", &[8], &mut mem).expect("format"); + assert_eq!(out, b"abcd".to_vec()); + assert_eq!(load_from_memory(&mem, 8, LoadKind::I32).unwrap(), 3); + } + fn ssa_main_of(src: &str) -> FunctionSsa { let program = Compiler::new(src.to_string()) .compile() @@ -2036,6 +2462,140 @@ mod tests { .expect("ssa run") } + #[test] + fn exit_terminates_with_status() { + // C99 7.20.4.3: `exit(status)` ends the program with that + // status; the interpreter reports it as the program result + // instead of a runtime error. + assert_eq!( + run_full_program( + "#include + int main(void) { exit(7); return 1; }", + ), + 7, + ); + } + + #[test] + fn frame_allocation_is_bounded_by_the_stack_region() { + // A frame past `heap_base` would zero live heap + // allocations; exhaustion must be a hard error instead. + let mut mem = Memory::new(&[]); + let heap = mem.heap_alloc(16); + mem.bytes[heap] = 7; + let stack_bytes = mem.heap_base - mem.stack_base; + let err = mem.alloc_frame(stack_bytes + 8).expect_err("must overflow"); + match err { + C5Error::Runtime(m) => assert!(m.contains("stack overflow"), "{m}"), + other => panic!("expected Runtime, got {other:?}"), + } + assert_eq!( + mem.bytes[heap], 7, + "heap byte must survive the failed frame" + ); + } + + #[test] + fn deep_recursion_errors_instead_of_corrupting_the_heap() { + // 40 frames x ~8 KiB exceeds the 256 KiB stack region but + // stays inside the old `bytes.len()` bound, which silently + // wiped heap allocations. + let program = Compiler::new( + "int f(int n) { char buf[8192]; buf[0] = (char)n; \ + if (n == 0) return buf[0]; return f(n - 1); } \ + int main(void) { return f(40); }" + .to_string(), + ) + .compile() + .expect("compile fixture"); + let funcs = super::super::super::codegen::ssa::shadow::produce_ssa_funcs( + &program, + super::super::super::Target::MacOSAarch64, + ) + .expect("ssa lift"); + let mut host = super::super::super::host::StdHost::default(); + let err = run_program(&funcs, &program.data, &[], program.entry_pc, &mut host) + .expect_err("recursion past the stack region must fail"); + match err { + crate::C5Error::Runtime(m) => assert!(m.contains("stack overflow"), "{m}"), + other => panic!("expected Runtime, got {other:?}"), + } + } + + fn expect_runtime_err(src: &str, needle: &str) { + let program = Compiler::new(src.to_string()) + .compile() + .expect("compile fixture"); + let err = crate::Vm::new(program).run().expect_err("run must fail"); + match err { + crate::C5Error::Runtime(m) => assert!(m.contains(needle), "`{m}` lacks `{needle}`"), + other => panic!("expected Runtime, got {other:?}"), + } + } + + #[test] + fn undefined_extern_call_is_undefined_reference() { + // A declared-but-undefined callee must not dispatch to the + // function whose ent_pc collides with the placeholder. + expect_runtime_err( + "int bar(int); int helper(int x) { return x + 1; } \ + int main(void) { return bar(41); }", + "undefined reference to `bar`", + ); + } + + #[test] + fn undefined_variadic_extern_call_is_undefined_reference() { + // main sits at ent_pc 0 here; the pre-fix sentinel made + // this call recurse into main until the host stack overflowed. + expect_runtime_err( + "int ghost(int, ...); int main(void) { return ghost(1, 2); }", + "undefined reference to `ghost`", + ); + } + + #[test] + fn undefined_extern_object_is_undefined_reference() { + // C99 6.9.2: `extern int x;` defines no storage; reading it + // with no defining TU is a link error, not a zero read. + expect_runtime_err( + "extern int missing_obj; int main(void) { return missing_obj + 7; }", + "undefined reference to `missing_obj`", + ); + } + + #[test] + fn undefined_extern_fn_pointer_is_undefined_reference() { + expect_runtime_err( + "int bar(int); int main(void) { int (*fp)(int) = bar; return fp(1); }", + "undefined reference to `bar`", + ); + } + + #[test] + fn bound_data_global_is_diagnosed_under_interp() { + // `environ` binds to host data; the interpreter's memory + // model cannot reach the host cell, so the reference is a + // clean diagnostic rather than a phantom NULL read. Pinned + // to the macOS target: the Windows headers route `environ` + // per-arch and Linux defines it in the runtime, so the + // host-target shape varies. + let program = Compiler::with_options( + "#include \nint main(void) { return environ != 0; }".to_string(), + crate::Target::MacOSAarch64, + crate::CompileOptions::default(), + ) + .compile() + .expect("compile fixture"); + let err = crate::Vm::new(program).run().expect_err("run must fail"); + match err { + crate::C5Error::Runtime(m) => { + assert!(m.contains("bound to host data"), "{m}") + } + other => panic!("expected Runtime, got {other:?}"), + } + } + #[test] fn return_constant() { // C99 5.1.2.2.3: `int main(void) { return 42; }` -- the diff --git a/src/main.rs b/src/main.rs index 272c6124b..1dced89cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -199,6 +199,21 @@ impl Mode { } fn main() { + // The recursive-descent parser bounds its nesting depth with a + // diagnostic, but debug builds spend tens of KiB of native stack + // per level, more than the platform default provides at the + // bound. Run the driver on a thread with an explicit reservation + // so the diagnostic always fires before the stack runs out. + let driver = std::thread::Builder::new() + .stack_size(256 * 1024 * 1024) + .spawn(run) + .expect("spawn driver thread"); + if let Err(e) = driver.join() { + std::panic::resume_unwind(e); + } +} + +fn run() { let raw: Vec = std::env::args().collect(); // Mode selection: at most one of the mode-picking flags @@ -681,7 +696,7 @@ fn main() { { sources.push("-".to_string()); } - if sources.is_empty() && objects.is_empty() { + if sources.is_empty() && objects.is_empty() && archives.is_empty() { eprint_diagnostic("badc: error: no files"); std::process::exit(1); } @@ -877,8 +892,14 @@ fn main() { // `.c` -> in-memory native ELF64 ET_REL: the source compiles // straight to ET_REL bytes that `parse_native_elf` reads back, // so no intermediate `.o` is written to disk. - let compile_one = |src_path: &str| -> (Vec, Option, Option) { - if multi_tu && !quiet { + type CompiledUnit = ( + Vec, + Option, + Option, + Vec, + ); + let compile_one = |src_path: &str, implicit_externs: &[String]| -> CompiledUnit { + if multi_tu && !quiet && implicit_externs.is_empty() { eprint_diagnostic(format!("info: compiling {src_path}")); } let src_bytes = if src_path == "-" { @@ -902,6 +923,7 @@ fn main() { .with_show_includes(show_includes) .with_warn_dead_store(warn_dead_store) .with_export_all_functions(export_all) + .with_implicit_extern_fns(implicit_externs.to_vec()) .with_no_entry_point(true); let mut compiler = Compiler::with_options(src_bytes, target, copts); if show_includes { @@ -921,8 +943,9 @@ fn main() { } let entry = program.entry_name.clone(); let subsystem = program.subsystem; + let auto_includes = program.auto_includes.clone(); match badc::emit_native_with_options(&program, target, reloc_opts) { - Ok(b) => (b, entry, subsystem), + Ok(b) => (b, entry, subsystem, auto_includes), Err(e) => { eprint_diagnostic(e); std::process::exit(1); @@ -933,9 +956,11 @@ fn main() { // below: same compile + emit chain, no filesystem read. let compile_in_memory = |label: &str, src: String, extra: &[(&str, &str)]| -> Vec { // The embedded runtime gates its sections on macros the - // driver sets per image: `__BADC_C5_START__` (an entry - // stub is emitted), `__BADC_WIN_WINMAIN__` (WinMain-shaped - // entry), `__BADC_WIN_WIDE__` (wide `wmain` / `wWinMain` entry). + // driver sets per image: `__BADC_C5_CRT__` (the image may + // import the user-mode C library), `__BADC_C5_START__` + // (an entry stub is emitted), `__BADC_WIN_WINMAIN__` + // (WinMain-shaped entry), `__BADC_WIN_WIDE__` (wide + // `wmain` / `wWinMain` entry). let mut copts_defines = defines.clone(); for (k, v) in extra { copts_defines.push((k.to_string(), v.to_string())); @@ -977,14 +1002,16 @@ fn main() { // it (the source-level pragma rides the in-memory `Program`, // not a section), then threaded to the PE writer. let mut subsystem_override: Option = None; + let mut source_auto_includes: Vec> = Vec::with_capacity(sources.len()); for src_path in &sources { - let (bytes, entry, subsystem) = compile_one(src_path); + let (bytes, entry, subsystem, auto_includes) = compile_one(src_path, &[]); if entry_override.is_none() { entry_override = entry; } if subsystem_override.is_none() { subsystem_override = subsystem; } + source_auto_includes.push(auto_includes); match badc::parse_native_elf(&bytes) { Ok(o) => native_objs.push(o), Err(e) => { @@ -1008,29 +1035,23 @@ fn main() { } // A freestanding image must supply its own entry symbol; the // embedded runtime that would otherwise define `__c5_entry` is - // not linked. Report a missing entry here rather than as a bare - // undefined-symbol relocation at link time. - if freestanding { - let entry = entry_override.as_deref().unwrap_or("__c5_entry"); - let defined = native_objs.iter().any(|o| { - o.symbols - .iter() - .any(|s| s.name == entry && s.section == badc::NativeSymSection::Text) - }); - if !defined { - eprint_diagnostic(format!( - "badc: error: --freestanding: image entry `{entry}` is not defined; \ - a freestanding image must provide its own entry point" - )); - std::process::exit(1); - } - } - // The embedded runtime's startup (`__c5_entry`, `__c5_exit`, - // `environ`) links only when the writer emits an entry stub -- - // not into shared libraries, passthrough-entry subsystems - // (native / EFI), or freestanding images. - let emits_start_stub = mode != Mode::SharedLibrary - && !freestanding + // not linked. The entry may come from any input -- a compiled + // source, a `.o`, or an archive member -- so the defined-entry + // check runs below, after objects and archive members are + // parsed, rather than as a bare undefined-symbol relocation at + // link time. + let freestanding_entry = freestanding.then(|| { + entry_override + .as_deref() + .unwrap_or("__c5_entry") + .to_string() + }); + // The runtime's CRT section (the C99 snprintf / vsnprintf + // definitions on Windows) links into any image that may + // import the user-mode C library -- hosted executables and + // shared libraries, but not passthrough-entry subsystems + // (native / EFI) or freestanding images. + let links_crt = !freestanding && !matches!( subsystem_override, Some( @@ -1041,10 +1062,17 @@ fn main() { | badc::Subsystem::EfiRom ) ); - // The single runtime source compiles to nothing unless - // `__BADC_C5_START__` is set; the GUI / wide-entry macros - // select the matching `__c5_entry` body on Windows. + // The startup section (`__c5_entry`, `__c5_exit`, `environ`) + // links only when the writer emits an entry stub -- not into + // shared libraries. + let emits_start_stub = mode != Mode::SharedLibrary && links_crt; + // The single runtime source compiles to nothing unless a gate + // macro is set; the GUI / wide-entry macros select the + // matching `__c5_entry` body on Windows. let mut runtime_defines: Vec<(&str, &str)> = Vec::new(); + if links_crt { + runtime_defines.push(("__BADC_C5_CRT__", "1")); + } if emits_start_stub { runtime_defines.push(("__BADC_C5_START__", "1")); // `__c5_entry` calls this symbol; default `main`, @@ -1118,6 +1146,14 @@ fn main() { } } } + // Archive members join the link on demand: a member is + // included iff it defines a symbol some already-included + // object still leaves undefined, iterated to a fixpoint so a + // pulled member's own references can pull further members + // (from any archive). Unreferenced members stay out, so their + // unrelated undefined or duplicate symbols cannot fail a + // valid link. + let mut pending: Vec<(String, badc::NativeObject)> = Vec::new(); for a_path in &archives { let bytes = match std::fs::read(a_path) { Ok(b) => b, @@ -1142,7 +1178,7 @@ fn main() { std::process::exit(1); } match badc::parse_native_elf(&m.bytes) { - Ok(o) => native_objs.push(o), + Ok(o) => pending.push((format!("{a_path}({})", m.name), o)), Err(e) => { eprint_diagnostic(format!("badc: {a_path}({}): {e}", m.name)); std::process::exit(1); @@ -1150,10 +1186,135 @@ fn main() { } } } + // C89 6.3.2.2 link semantics: a definition anywhere in the + // link set satisfies an implicitly declared call, so a name + // the auto-include retry bound to a header's library binding + // is recompiled as an implicit extern when an input defines + // it -- the user's definition wins over the binding. + if source_auto_includes.iter().any(|a| !a.is_empty()) { + let mut defined_fns = std::collections::HashSet::::new(); + for o in native_objs.iter().chain(pending.iter().map(|(_, o)| o)) { + for s in &o.symbols { + // STB_GLOBAL STT_FUNC section-resident definitions. + if s.binding == 1 + && s.kind == 2 + && !matches!( + s.section, + badc::NativeSymSection::Undef | badc::NativeSymSection::Abs + ) + { + defined_fns.insert(s.name.clone()); + } + } + } + for (i, autos) in source_auto_includes.iter().enumerate() { + let redirect: Vec = autos + .iter() + .filter(|n| defined_fns.contains(n.as_str())) + .cloned() + .collect(); + if redirect.is_empty() { + continue; + } + if !quiet { + for n in &redirect { + eprint_diagnostic(format!( + "info: the link defines `{n}`; rebinding the call in {} to it", + sources[i] + )); + } + } + let (bytes, _, _, _) = compile_one(&sources[i], &redirect); + match badc::parse_native_elf(&bytes) { + Ok(o) => native_objs[i] = o, + Err(e) => { + eprint_diagnostic(format!("badc: {}: {e}", sources[i])); + std::process::exit(1); + } + } + } + } + if !pending.is_empty() { + let mut defined = std::collections::HashSet::::new(); + let mut undefined = std::collections::HashSet::::new(); + // A global or weak definition satisfies references; only a + // strong (STB_GLOBAL) undefined reference pulls a member, + // matching ELF archive practice (a weak reference left + // unresolved does not extract members). + let account = + |o: &badc::NativeObject, + defined: &mut std::collections::HashSet, + undefined: &mut std::collections::HashSet| { + for s in &o.symbols { + if s.binding == 0 { + continue; + } + if s.section == badc::NativeSymSection::Undef { + if s.binding == 1 && !defined.contains(&s.name) { + undefined.insert(s.name.clone()); + } + } else { + defined.insert(s.name.clone()); + undefined.remove(&s.name); + } + } + }; + for o in &native_objs { + account(o, &mut defined, &mut undefined); + } + // A freestanding entry is a link root: seed it as undefined + // so an archive member that only defines the entry is pulled. + if let Some(entry) = &freestanding_entry + && !defined.contains(entry) + { + undefined.insert(entry.clone()); + } + // The archive symbol index lists strong section-resident + // definitions; a member is pulled on exactly those. + let mut progress = true; + while progress { + progress = false; + let mut i = 0; + while i < pending.len() { + let wanted = pending[i].1.symbols.iter().any(|s| { + s.binding == 1 + && !matches!( + s.section, + badc::NativeSymSection::Undef | badc::NativeSymSection::Abs + ) + && undefined.contains(&s.name) + }); + if wanted { + let (_, o) = pending.remove(i); + account(&o, &mut defined, &mut undefined); + native_objs.push(o); + progress = true; + } else { + i += 1; + } + } + } + } if native_objs.is_empty() { eprint_diagnostic("badc: error: no inputs"); std::process::exit(1); } + // With every source, object, and pulled archive member now + // parsed, a freestanding image's entry must be defined. + if let Some(entry) = &freestanding_entry { + let defined = native_objs.iter().any(|o| { + o.symbols + .iter() + .any(|s| s.name == *entry && s.section == badc::NativeSymSection::Text) + }); + if !defined { + eprint_diagnostic(format!( + "badc: error: --freestanding: image entry `{entry}` is not defined; \ + a freestanding image must provide its own entry point" + )); + std::process::exit(1); + } + } // Every supported target lays out `_Thread_local` storage // through the native path: ELF PT_TLS, the PE TLS directory + // `_tls_index` note, and the Mach-O TLV descriptors + fixups @@ -1314,6 +1475,7 @@ fn main() { for w in &program.warnings { eprintln!("{}", colorize_diagnostic(w, stderr_is_tty)); } + warn_dropped_link_pragmas(&program, src_path); match badc::emit_native_with_options(&program, target, reloc_opts) { Ok(b) => b, Err(e) => { @@ -1418,6 +1580,7 @@ fn main() { for w in &program.warnings { eprintln!("{}", colorize_diagnostic(w, stderr_is_tty)); } + warn_dropped_link_pragmas(&program, src_path); match badc::emit_native_with_options(&program, target, reloc_opts) { Ok(b) => b, Err(e) => { @@ -1516,6 +1679,27 @@ fn native_defined_globals(bytes: &[u8], path: &str) -> Vec { .collect() } +/// `#pragma entrypoint` / `#pragma subsystem` ride the in-memory +/// `Program` of the invocation that links; an ET_REL object carries +/// neither. Warn when a relocatable emit drops them so the TU is +/// recompiled in the link invocation instead of silently producing a +/// console-subsystem / default-entry image. +fn warn_dropped_link_pragmas(program: &badc::Program, src_path: &str) { + let mut dropped: Vec<&str> = Vec::new(); + if program.entry_pragma.is_some() { + dropped.push("entrypoint"); + } + if program.subsystem.is_some() { + dropped.push("subsystem"); + } + for p in dropped { + eprint_diagnostic(format!( + "{src_path}: warning: `#pragma {p}(...)` is not carried by an object \ + file; compile this source in the link invocation for it to take effect" + )); + } +} + fn eprint_diagnostic(msg: impl core::fmt::Display) { let stderr_is_tty = std::io::stderr().is_terminal(); let s = msg.to_string(); diff --git a/tests/cli_fixture_smoke.rs b/tests/cli_fixture_smoke.rs index b25fb049c..345404de6 100644 --- a/tests/cli_fixture_smoke.rs +++ b/tests/cli_fixture_smoke.rs @@ -48,6 +48,12 @@ const COMPILE_SKIPLIST: &[&str] = &[ "thread_local_initializer.c", "thread_local_per_thread.c", "deferred_jit_thread_local.c", + // VLA fixtures that assert a clean rejection diagnostic rather + // than compiling; the constructs are unsupported by design (C99 + // 6.7.6.2 corners left as TODO). + "vla_multidim_rejected.c", + "vla_file_scope_rejected.c", + "vla_initializer_rejected.c", ]; #[test] diff --git a/tests/cli_linker_smoke.rs b/tests/cli_linker_smoke.rs index 6b9b38f70..c86cf297a 100644 --- a/tests/cli_linker_smoke.rs +++ b/tests/cli_linker_smoke.rs @@ -128,6 +128,195 @@ fn archive_resolves_via_minus_l_search() { assert_eq!(out.status.code(), Some(38), "exit code mismatch"); } +#[test] +fn archive_members_are_pulled_on_demand() { + // Archive semantics (SysV ar / ELF linker practice): a member + // joins the link iff it defines a still-undefined symbol, + // iterated to a fixpoint. An unreferenced member must stay out + // even when it carries an unresolvable reference of its own or + // defines a name the program also defines. + let dir = tempdir("archive-on-demand"); + write_source( + &dir, + "m1.c", + "extern int chain(void);\nint used(void) { return 11 + chain(); }\n", + ); + // Pulled only through m1's reference (fixpoint). + write_source(&dir, "m2.c", "int chain(void) { return 20; }\n"); + // Never referenced: its undefined `never_defined` must not fail + // the link. + write_source( + &dir, + "m3.c", + "extern int never_defined(void);\nint unused_entry(void) { return never_defined(); }\n", + ); + // Never referenced: its `helper` must not collide with main.c's. + write_source(&dir, "m4.c", "int helper(void) { return 99; }\n"); + write_source( + &dir, + "main.c", + "extern int used(void);\nint helper(void) { return 1; }\n\ + int main(void) { return used() + helper(); }\n", + ); + run( + Command::new(badc()) + .arg("--ar") + .arg("-o") + .arg(dir.join("libt.a")) + .arg(dir.join("m1.c")) + .arg(dir.join("m2.c")) + .arg(dir.join("m3.c")) + .arg(dir.join("m4.c")) + .current_dir(&dir), + "build archive", + ); + let exe = dir.join("prog"); + run( + Command::new(badc()) + .arg("-o") + .arg(&exe) + .arg(dir.join("main.c")) + .arg(dir.join("libt.a")) + .current_dir(&dir), + "link against the archive", + ); + let out = Command::new(&exe).output().expect("run prog"); + // 11 + 20 + 1 = 32. + assert_eq!( + out.status.code(), + Some(32), + "exit code mismatch: stderr={:?}", + String::from_utf8_lossy(&out.stderr) + ); +} + +// An archive-only invocation is a valid link: the members supply the +// objects and `main` is pulled by the runtime's reference to it. The +// input-emptiness check must count archives, not just sources/objects. +#[cfg(target_os = "linux")] +#[test] +fn archive_only_invocation_links_and_pulls_main() { + let dir = tempdir("archive-only"); + write_source(&dir, "prog.c", "int main(void) { return 7; }\n"); + run( + Command::new(badc()) + .arg("--ar") + .arg("-o") + .arg(dir.join("libprog.a")) + .arg(dir.join("prog.c")) + .current_dir(&dir), + "build archive", + ); + let exe = dir.join("prog"); + run( + Command::new(badc()) + .arg("-o") + .arg(&exe) + .arg(dir.join("libprog.a")) + .current_dir(&dir), + "link archive-only", + ); + let out = Command::new(&exe).output().expect("run prog"); + assert_eq!(out.status.code(), Some(7), "exit code mismatch"); +} + +// A freestanding image's entry may live in a pre-compiled object; the +// defined-entry check must run after `.o` inputs are parsed, not before. +#[cfg(target_os = "linux")] +#[test] +fn freestanding_entry_defined_in_object_links() { + let dir = tempdir("freestanding-obj"); + write_source(&dir, "fs.c", "void __c5_entry(void) { }\n"); + run( + Command::new(badc()) + .arg("-c") + .arg(dir.join("fs.c")) + .arg("-o") + .arg(dir.join("fs.o")) + .current_dir(&dir), + "compile -c", + ); + let bin = dir.join("fs.bin"); + run( + Command::new(badc()) + .arg("--freestanding") + .arg(dir.join("fs.o")) + .arg("-o") + .arg(&bin) + .current_dir(&dir), + "freestanding link with entry in object", + ); + assert!(bin.exists(), "freestanding image was not produced"); +} + +// The freestanding entry is a link root: an archive member that only +// defines the entry must be pulled so the image links. +#[cfg(target_os = "linux")] +#[test] +fn freestanding_entry_from_archive_is_pulled() { + let dir = tempdir("freestanding-archive"); + write_source(&dir, "fs.c", "void __c5_entry(void) { }\n"); + run( + Command::new(badc()) + .arg("--ar") + .arg("-o") + .arg(dir.join("libfs.a")) + .arg(dir.join("fs.c")) + .current_dir(&dir), + "build archive", + ); + let bin = dir.join("fs.bin"); + run( + Command::new(badc()) + .arg("--freestanding") + .arg(dir.join("libfs.a")) + .arg("-o") + .arg(&bin) + .current_dir(&dir), + "freestanding link with entry in archive", + ); + assert!(bin.exists(), "freestanding image was not produced"); +} + +#[test] +fn compile_only_warns_when_link_pragmas_are_dropped() { + // `#pragma subsystem` / `#pragma entrypoint` ride the in-memory + // program of the invocation that links; an ET_REL object carries + // neither. `-c` must say so instead of silently emitting an + // object that later links as a console / default-entry image. + let dir = tempdir("compile-only-pragmas"); + write_source( + &dir, + "gui.c", + "#pragma subsystem(windows)\nint main(void) { return 0; }\n", + ); + write_source( + &dir, + "ep.c", + "#pragma entrypoint(my_entry)\nint my_entry(void) { return 0; }\n", + ); + write_source(&dir, "plain.c", "int main(void) { return 0; }\n"); + let compile = |name: &str| -> String { + let out = run( + Command::new(badc()) + .arg("--target=windows-x64") + .arg("-c") + .arg(dir.join(name)) + .arg("-o") + .arg(dir.join(name).with_extension("o")) + .current_dir(&dir), + "compile -c", + ); + String::from_utf8_lossy(&out.stderr).into_owned() + }; + let gui = compile("gui.c"); + assert!(gui.contains("#pragma subsystem"), "stderr: {gui}"); + let ep = compile("ep.c"); + assert!(ep.contains("#pragma entrypoint"), "stderr: {ep}"); + let plain = compile("plain.c"); + assert!(!plain.contains("warning"), "stderr: {plain}"); +} + #[test] fn unresolved_extern_function_fails_link() { let dir = tempdir("unresolved"); @@ -2731,3 +2920,62 @@ fn defining_c5_entry_without_flag_is_not_implicitly_freestanding() { "expected a duplicate-symbol error for __c5_entry; got: {stderr:?}" ); } + +#[test] +fn link_defined_symbol_wins_over_auto_included_binding() { + // C89 6.3.2.2 link semantics: an undeclared call binds to + // whatever the link defines. When a sibling TU defines a name + // that also exists as a bundled-header libc binding (getpid), + // the auto-include retry must not override the user's + // definition with the library import. + let dir = tempdir("auto-include-preference"); + write_source( + &dir, + "caller.c", + "int main(void) { return getpid() == 999 ? 0 : 1; }\n", + ); + write_source(&dir, "impl.c", "int getpid(void) { return 999; }\n"); + let exe = dir.join("prog"); + run( + Command::new(badc()) + .arg("-o") + .arg(&exe) + .arg(dir.join("caller.c")) + .arg(dir.join("impl.c")) + .current_dir(&dir), + "link with a user getpid", + ); + let out = Command::new(&exe).output().expect("run prog"); + assert_eq!( + out.status.code(), + Some(0), + "the user's getpid must win: stderr={:?}", + String::from_utf8_lossy(&out.stderr) + ); + // The auto-include still serves calls nothing in the link + // defines: an undeclared printf in a multi-TU build works. + write_source( + &dir, + "p1.c", + "int main(void) { printf(\"hi\\n\"); return 0; }\n", + ); + write_source(&dir, "p2.c", "int unrelated(void) { return 0; }\n"); + let exe2 = dir.join("prog2"); + run( + Command::new(badc()) + .arg("-o") + .arg(&exe2) + .arg(dir.join("p1.c")) + .arg(dir.join("p2.c")) + .current_dir(&dir), + "link with auto-included printf", + ); + let out = Command::new(&exe2).output().expect("run prog2"); + assert_eq!(out.status.code(), Some(0), "auto-included printf runs"); + // The Windows CRT translates `\n` to `\r\n` on stdout; strip CR so + // the comparison holds on every host. + assert_eq!( + String::from_utf8_lossy(&out.stdout).replace('\r', ""), + "hi\n" + ); +} diff --git a/tests/fixtures/c/atomic_operand_in_working_regs.c b/tests/fixtures/c/atomic_operand_in_working_regs.c new file mode 100644 index 000000000..c50cc1d7a --- /dev/null +++ b/tests/fixtures/c/atomic_operand_in_working_regs.c @@ -0,0 +1,22 @@ +/* CAS/RMW operands allocated in the borrowed working registers + (x9..x12 on aarch64) must be read from the save area, not from the + registers an earlier operand move already overwrote. */ +#include + +long f(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) { + static _Atomic long l = 9; + long want = 100; + int c = atomic_compare_exchange_strong(&l, &want, 5); + long r = atomic_fetch_add(&l, a0 + a1); + /* c must be 0, want must be 9 (observed), l must be 9+3=12, r old=9 */ + if (c != 0) return 1; + if (want != 9) return 2; + if (r != 9) return 3; + if (atomic_load(&l) != 9 + a0 + a1) return 4; + return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7; /* keep 8 values live */ +} + +int main(void) { + long r = f(1, 2, 3, 4, 5, 6, 7, 8); + return r == 36 ? 0 : (int)r; +} diff --git a/tests/fixtures/c/block_scope_typedef_variadic_fnptr.c b/tests/fixtures/c/block_scope_typedef_variadic_fnptr.c new file mode 100644 index 000000000..21429c7b7 --- /dev/null +++ b/tests/fixtures/c/block_scope_typedef_variadic_fnptr.c @@ -0,0 +1,17 @@ +/* A block-scope `typedef RET (*NAME)(args, ...)` must carry the pointee + prototype onto variables declared through it, so an indirect call + routes the variadic tail per the host ABI. */ +#include +#include + +int main(void) { + char buf[64]; + typedef int (*psn)(char *, unsigned long, const char *, ...); + static psn sn = snprintf; + buf[0] = 0; + sn(buf, sizeof buf, "%d %s", 7, "tail"); + if (strcmp(buf, "7 tail") != 0) { + return 1; + } + return 0; +} diff --git a/tests/fixtures/c/call_sp_adjust_imm12_overflow.c b/tests/fixtures/c/call_sp_adjust_imm12_overflow.c new file mode 100644 index 000000000..d8ed16913 --- /dev/null +++ b/tests/fixtures/c/call_sp_adjust_imm12_overflow.c @@ -0,0 +1,348 @@ +/* Call-site SP adjustments must cover an outgoing-argument area past + the 12-bit add/sub immediate: 261 by-value 16-byte structs leave 257 + on the AAPCS64 stack (257 * 16 = 4112 bytes), and the indirect call + pushes 260 scalar arguments at the 16-byte stride (4160 bytes). + Both calls run direct and through a function pointer. */ +struct pair { + long a; + long b; +}; + +static struct pair g[261]; + +static long sum_pairs( + struct pair p0, struct pair p1, struct pair p2, struct pair p3, struct pair p4, struct pair p5, + struct pair p6, struct pair p7, struct pair p8, struct pair p9, struct pair p10, struct pair p11, + struct pair p12, struct pair p13, struct pair p14, struct pair p15, struct pair p16, struct pair p17, + struct pair p18, struct pair p19, struct pair p20, struct pair p21, struct pair p22, struct pair p23, + struct pair p24, struct pair p25, struct pair p26, struct pair p27, struct pair p28, struct pair p29, + struct pair p30, struct pair p31, struct pair p32, struct pair p33, struct pair p34, struct pair p35, + struct pair p36, struct pair p37, struct pair p38, struct pair p39, struct pair p40, struct pair p41, + struct pair p42, struct pair p43, struct pair p44, struct pair p45, struct pair p46, struct pair p47, + struct pair p48, struct pair p49, struct pair p50, struct pair p51, struct pair p52, struct pair p53, + struct pair p54, struct pair p55, struct pair p56, struct pair p57, struct pair p58, struct pair p59, + struct pair p60, struct pair p61, struct pair p62, struct pair p63, struct pair p64, struct pair p65, + struct pair p66, struct pair p67, struct pair p68, struct pair p69, struct pair p70, struct pair p71, + struct pair p72, struct pair p73, struct pair p74, struct pair p75, struct pair p76, struct pair p77, + struct pair p78, struct pair p79, struct pair p80, struct pair p81, struct pair p82, struct pair p83, + struct pair p84, struct pair p85, struct pair p86, struct pair p87, struct pair p88, struct pair p89, + struct pair p90, struct pair p91, struct pair p92, struct pair p93, struct pair p94, struct pair p95, + struct pair p96, struct pair p97, struct pair p98, struct pair p99, struct pair p100, struct pair p101, + struct pair p102, struct pair p103, struct pair p104, struct pair p105, struct pair p106, struct pair p107, + struct pair p108, struct pair p109, struct pair p110, struct pair p111, struct pair p112, struct pair p113, + struct pair p114, struct pair p115, struct pair p116, struct pair p117, struct pair p118, struct pair p119, + struct pair p120, struct pair p121, struct pair p122, struct pair p123, struct pair p124, struct pair p125, + struct pair p126, struct pair p127, struct pair p128, struct pair p129, struct pair p130, struct pair p131, + struct pair p132, struct pair p133, struct pair p134, struct pair p135, struct pair p136, struct pair p137, + struct pair p138, struct pair p139, struct pair p140, struct pair p141, struct pair p142, struct pair p143, + struct pair p144, struct pair p145, struct pair p146, struct pair p147, struct pair p148, struct pair p149, + struct pair p150, struct pair p151, struct pair p152, struct pair p153, struct pair p154, struct pair p155, + struct pair p156, struct pair p157, struct pair p158, struct pair p159, struct pair p160, struct pair p161, + struct pair p162, struct pair p163, struct pair p164, struct pair p165, struct pair p166, struct pair p167, + struct pair p168, struct pair p169, struct pair p170, struct pair p171, struct pair p172, struct pair p173, + struct pair p174, struct pair p175, struct pair p176, struct pair p177, struct pair p178, struct pair p179, + struct pair p180, struct pair p181, struct pair p182, struct pair p183, struct pair p184, struct pair p185, + struct pair p186, struct pair p187, struct pair p188, struct pair p189, struct pair p190, struct pair p191, + struct pair p192, struct pair p193, struct pair p194, struct pair p195, struct pair p196, struct pair p197, + struct pair p198, struct pair p199, struct pair p200, struct pair p201, struct pair p202, struct pair p203, + struct pair p204, struct pair p205, struct pair p206, struct pair p207, struct pair p208, struct pair p209, + struct pair p210, struct pair p211, struct pair p212, struct pair p213, struct pair p214, struct pair p215, + struct pair p216, struct pair p217, struct pair p218, struct pair p219, struct pair p220, struct pair p221, + struct pair p222, struct pair p223, struct pair p224, struct pair p225, struct pair p226, struct pair p227, + struct pair p228, struct pair p229, struct pair p230, struct pair p231, struct pair p232, struct pair p233, + struct pair p234, struct pair p235, struct pair p236, struct pair p237, struct pair p238, struct pair p239, + struct pair p240, struct pair p241, struct pair p242, struct pair p243, struct pair p244, struct pair p245, + struct pair p246, struct pair p247, struct pair p248, struct pair p249, struct pair p250, struct pair p251, + struct pair p252, struct pair p253, struct pair p254, struct pair p255, struct pair p256, struct pair p257, + struct pair p258, struct pair p259, struct pair p260) +{ + long s = 0; + s += p0.a + p0.b; s += p1.a + p1.b; s += p2.a + p2.b; s += p3.a + p3.b; + s += p4.a + p4.b; s += p5.a + p5.b; s += p6.a + p6.b; s += p7.a + p7.b; + s += p8.a + p8.b; s += p9.a + p9.b; s += p10.a + p10.b; s += p11.a + p11.b; + s += p12.a + p12.b; s += p13.a + p13.b; s += p14.a + p14.b; s += p15.a + p15.b; + s += p16.a + p16.b; s += p17.a + p17.b; s += p18.a + p18.b; s += p19.a + p19.b; + s += p20.a + p20.b; s += p21.a + p21.b; s += p22.a + p22.b; s += p23.a + p23.b; + s += p24.a + p24.b; s += p25.a + p25.b; s += p26.a + p26.b; s += p27.a + p27.b; + s += p28.a + p28.b; s += p29.a + p29.b; s += p30.a + p30.b; s += p31.a + p31.b; + s += p32.a + p32.b; s += p33.a + p33.b; s += p34.a + p34.b; s += p35.a + p35.b; + s += p36.a + p36.b; s += p37.a + p37.b; s += p38.a + p38.b; s += p39.a + p39.b; + s += p40.a + p40.b; s += p41.a + p41.b; s += p42.a + p42.b; s += p43.a + p43.b; + s += p44.a + p44.b; s += p45.a + p45.b; s += p46.a + p46.b; s += p47.a + p47.b; + s += p48.a + p48.b; s += p49.a + p49.b; s += p50.a + p50.b; s += p51.a + p51.b; + s += p52.a + p52.b; s += p53.a + p53.b; s += p54.a + p54.b; s += p55.a + p55.b; + s += p56.a + p56.b; s += p57.a + p57.b; s += p58.a + p58.b; s += p59.a + p59.b; + s += p60.a + p60.b; s += p61.a + p61.b; s += p62.a + p62.b; s += p63.a + p63.b; + s += p64.a + p64.b; s += p65.a + p65.b; s += p66.a + p66.b; s += p67.a + p67.b; + s += p68.a + p68.b; s += p69.a + p69.b; s += p70.a + p70.b; s += p71.a + p71.b; + s += p72.a + p72.b; s += p73.a + p73.b; s += p74.a + p74.b; s += p75.a + p75.b; + s += p76.a + p76.b; s += p77.a + p77.b; s += p78.a + p78.b; s += p79.a + p79.b; + s += p80.a + p80.b; s += p81.a + p81.b; s += p82.a + p82.b; s += p83.a + p83.b; + s += p84.a + p84.b; s += p85.a + p85.b; s += p86.a + p86.b; s += p87.a + p87.b; + s += p88.a + p88.b; s += p89.a + p89.b; s += p90.a + p90.b; s += p91.a + p91.b; + s += p92.a + p92.b; s += p93.a + p93.b; s += p94.a + p94.b; s += p95.a + p95.b; + s += p96.a + p96.b; s += p97.a + p97.b; s += p98.a + p98.b; s += p99.a + p99.b; + s += p100.a + p100.b; s += p101.a + p101.b; s += p102.a + p102.b; s += p103.a + p103.b; + s += p104.a + p104.b; s += p105.a + p105.b; s += p106.a + p106.b; s += p107.a + p107.b; + s += p108.a + p108.b; s += p109.a + p109.b; s += p110.a + p110.b; s += p111.a + p111.b; + s += p112.a + p112.b; s += p113.a + p113.b; s += p114.a + p114.b; s += p115.a + p115.b; + s += p116.a + p116.b; s += p117.a + p117.b; s += p118.a + p118.b; s += p119.a + p119.b; + s += p120.a + p120.b; s += p121.a + p121.b; s += p122.a + p122.b; s += p123.a + p123.b; + s += p124.a + p124.b; s += p125.a + p125.b; s += p126.a + p126.b; s += p127.a + p127.b; + s += p128.a + p128.b; s += p129.a + p129.b; s += p130.a + p130.b; s += p131.a + p131.b; + s += p132.a + p132.b; s += p133.a + p133.b; s += p134.a + p134.b; s += p135.a + p135.b; + s += p136.a + p136.b; s += p137.a + p137.b; s += p138.a + p138.b; s += p139.a + p139.b; + s += p140.a + p140.b; s += p141.a + p141.b; s += p142.a + p142.b; s += p143.a + p143.b; + s += p144.a + p144.b; s += p145.a + p145.b; s += p146.a + p146.b; s += p147.a + p147.b; + s += p148.a + p148.b; s += p149.a + p149.b; s += p150.a + p150.b; s += p151.a + p151.b; + s += p152.a + p152.b; s += p153.a + p153.b; s += p154.a + p154.b; s += p155.a + p155.b; + s += p156.a + p156.b; s += p157.a + p157.b; s += p158.a + p158.b; s += p159.a + p159.b; + s += p160.a + p160.b; s += p161.a + p161.b; s += p162.a + p162.b; s += p163.a + p163.b; + s += p164.a + p164.b; s += p165.a + p165.b; s += p166.a + p166.b; s += p167.a + p167.b; + s += p168.a + p168.b; s += p169.a + p169.b; s += p170.a + p170.b; s += p171.a + p171.b; + s += p172.a + p172.b; s += p173.a + p173.b; s += p174.a + p174.b; s += p175.a + p175.b; + s += p176.a + p176.b; s += p177.a + p177.b; s += p178.a + p178.b; s += p179.a + p179.b; + s += p180.a + p180.b; s += p181.a + p181.b; s += p182.a + p182.b; s += p183.a + p183.b; + s += p184.a + p184.b; s += p185.a + p185.b; s += p186.a + p186.b; s += p187.a + p187.b; + s += p188.a + p188.b; s += p189.a + p189.b; s += p190.a + p190.b; s += p191.a + p191.b; + s += p192.a + p192.b; s += p193.a + p193.b; s += p194.a + p194.b; s += p195.a + p195.b; + s += p196.a + p196.b; s += p197.a + p197.b; s += p198.a + p198.b; s += p199.a + p199.b; + s += p200.a + p200.b; s += p201.a + p201.b; s += p202.a + p202.b; s += p203.a + p203.b; + s += p204.a + p204.b; s += p205.a + p205.b; s += p206.a + p206.b; s += p207.a + p207.b; + s += p208.a + p208.b; s += p209.a + p209.b; s += p210.a + p210.b; s += p211.a + p211.b; + s += p212.a + p212.b; s += p213.a + p213.b; s += p214.a + p214.b; s += p215.a + p215.b; + s += p216.a + p216.b; s += p217.a + p217.b; s += p218.a + p218.b; s += p219.a + p219.b; + s += p220.a + p220.b; s += p221.a + p221.b; s += p222.a + p222.b; s += p223.a + p223.b; + s += p224.a + p224.b; s += p225.a + p225.b; s += p226.a + p226.b; s += p227.a + p227.b; + s += p228.a + p228.b; s += p229.a + p229.b; s += p230.a + p230.b; s += p231.a + p231.b; + s += p232.a + p232.b; s += p233.a + p233.b; s += p234.a + p234.b; s += p235.a + p235.b; + s += p236.a + p236.b; s += p237.a + p237.b; s += p238.a + p238.b; s += p239.a + p239.b; + s += p240.a + p240.b; s += p241.a + p241.b; s += p242.a + p242.b; s += p243.a + p243.b; + s += p244.a + p244.b; s += p245.a + p245.b; s += p246.a + p246.b; s += p247.a + p247.b; + s += p248.a + p248.b; s += p249.a + p249.b; s += p250.a + p250.b; s += p251.a + p251.b; + s += p252.a + p252.b; s += p253.a + p253.b; s += p254.a + p254.b; s += p255.a + p255.b; + s += p256.a + p256.b; s += p257.a + p257.b; s += p258.a + p258.b; s += p259.a + p259.b; + s += p260.a + p260.b; + return s; +} + +static long sum_longs( + long v1, long v2, long v3, long v4, long v5, long v6, long v7, long v8, + long v9, long v10, long v11, long v12, long v13, long v14, long v15, long v16, + long v17, long v18, long v19, long v20, long v21, long v22, long v23, long v24, + long v25, long v26, long v27, long v28, long v29, long v30, long v31, long v32, + long v33, long v34, long v35, long v36, long v37, long v38, long v39, long v40, + long v41, long v42, long v43, long v44, long v45, long v46, long v47, long v48, + long v49, long v50, long v51, long v52, long v53, long v54, long v55, long v56, + long v57, long v58, long v59, long v60, long v61, long v62, long v63, long v64, + long v65, long v66, long v67, long v68, long v69, long v70, long v71, long v72, + long v73, long v74, long v75, long v76, long v77, long v78, long v79, long v80, + long v81, long v82, long v83, long v84, long v85, long v86, long v87, long v88, + long v89, long v90, long v91, long v92, long v93, long v94, long v95, long v96, + long v97, long v98, long v99, long v100, long v101, long v102, long v103, long v104, + long v105, long v106, long v107, long v108, long v109, long v110, long v111, long v112, + long v113, long v114, long v115, long v116, long v117, long v118, long v119, long v120, + long v121, long v122, long v123, long v124, long v125, long v126, long v127, long v128, + long v129, long v130, long v131, long v132, long v133, long v134, long v135, long v136, + long v137, long v138, long v139, long v140, long v141, long v142, long v143, long v144, + long v145, long v146, long v147, long v148, long v149, long v150, long v151, long v152, + long v153, long v154, long v155, long v156, long v157, long v158, long v159, long v160, + long v161, long v162, long v163, long v164, long v165, long v166, long v167, long v168, + long v169, long v170, long v171, long v172, long v173, long v174, long v175, long v176, + long v177, long v178, long v179, long v180, long v181, long v182, long v183, long v184, + long v185, long v186, long v187, long v188, long v189, long v190, long v191, long v192, + long v193, long v194, long v195, long v196, long v197, long v198, long v199, long v200, + long v201, long v202, long v203, long v204, long v205, long v206, long v207, long v208, + long v209, long v210, long v211, long v212, long v213, long v214, long v215, long v216, + long v217, long v218, long v219, long v220, long v221, long v222, long v223, long v224, + long v225, long v226, long v227, long v228, long v229, long v230, long v231, long v232, + long v233, long v234, long v235, long v236, long v237, long v238, long v239, long v240, + long v241, long v242, long v243, long v244, long v245, long v246, long v247, long v248, + long v249, long v250, long v251, long v252, long v253, long v254, long v255, long v256, + long v257, long v258, long v259, long v260) +{ + long s = 0; + s += v1; s += v2; s += v3; s += v4; s += v5; s += v6; s += v7; s += v8; + s += v9; s += v10; s += v11; s += v12; s += v13; s += v14; s += v15; s += v16; + s += v17; s += v18; s += v19; s += v20; s += v21; s += v22; s += v23; s += v24; + s += v25; s += v26; s += v27; s += v28; s += v29; s += v30; s += v31; s += v32; + s += v33; s += v34; s += v35; s += v36; s += v37; s += v38; s += v39; s += v40; + s += v41; s += v42; s += v43; s += v44; s += v45; s += v46; s += v47; s += v48; + s += v49; s += v50; s += v51; s += v52; s += v53; s += v54; s += v55; s += v56; + s += v57; s += v58; s += v59; s += v60; s += v61; s += v62; s += v63; s += v64; + s += v65; s += v66; s += v67; s += v68; s += v69; s += v70; s += v71; s += v72; + s += v73; s += v74; s += v75; s += v76; s += v77; s += v78; s += v79; s += v80; + s += v81; s += v82; s += v83; s += v84; s += v85; s += v86; s += v87; s += v88; + s += v89; s += v90; s += v91; s += v92; s += v93; s += v94; s += v95; s += v96; + s += v97; s += v98; s += v99; s += v100; s += v101; s += v102; s += v103; s += v104; + s += v105; s += v106; s += v107; s += v108; s += v109; s += v110; s += v111; s += v112; + s += v113; s += v114; s += v115; s += v116; s += v117; s += v118; s += v119; s += v120; + s += v121; s += v122; s += v123; s += v124; s += v125; s += v126; s += v127; s += v128; + s += v129; s += v130; s += v131; s += v132; s += v133; s += v134; s += v135; s += v136; + s += v137; s += v138; s += v139; s += v140; s += v141; s += v142; s += v143; s += v144; + s += v145; s += v146; s += v147; s += v148; s += v149; s += v150; s += v151; s += v152; + s += v153; s += v154; s += v155; s += v156; s += v157; s += v158; s += v159; s += v160; + s += v161; s += v162; s += v163; s += v164; s += v165; s += v166; s += v167; s += v168; + s += v169; s += v170; s += v171; s += v172; s += v173; s += v174; s += v175; s += v176; + s += v177; s += v178; s += v179; s += v180; s += v181; s += v182; s += v183; s += v184; + s += v185; s += v186; s += v187; s += v188; s += v189; s += v190; s += v191; s += v192; + s += v193; s += v194; s += v195; s += v196; s += v197; s += v198; s += v199; s += v200; + s += v201; s += v202; s += v203; s += v204; s += v205; s += v206; s += v207; s += v208; + s += v209; s += v210; s += v211; s += v212; s += v213; s += v214; s += v215; s += v216; + s += v217; s += v218; s += v219; s += v220; s += v221; s += v222; s += v223; s += v224; + s += v225; s += v226; s += v227; s += v228; s += v229; s += v230; s += v231; s += v232; + s += v233; s += v234; s += v235; s += v236; s += v237; s += v238; s += v239; s += v240; + s += v241; s += v242; s += v243; s += v244; s += v245; s += v246; s += v247; s += v248; + s += v249; s += v250; s += v251; s += v252; s += v253; s += v254; s += v255; s += v256; + s += v257; s += v258; s += v259; s += v260; + return s; +} + +int main(void) { + long (*fp)( + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long, long) = sum_longs; + long (*sfp)( + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, struct pair, + struct pair, struct pair, struct pair, struct pair, struct pair) = sum_pairs; + long i; + for (i = 0; i < 261; i++) { + g[i].a = i; + g[i].b = 2 * i; + } + if (sum_pairs( + g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7], g[8], g[9], + g[10], g[11], g[12], g[13], g[14], g[15], g[16], g[17], g[18], g[19], + g[20], g[21], g[22], g[23], g[24], g[25], g[26], g[27], g[28], g[29], + g[30], g[31], g[32], g[33], g[34], g[35], g[36], g[37], g[38], g[39], + g[40], g[41], g[42], g[43], g[44], g[45], g[46], g[47], g[48], g[49], + g[50], g[51], g[52], g[53], g[54], g[55], g[56], g[57], g[58], g[59], + g[60], g[61], g[62], g[63], g[64], g[65], g[66], g[67], g[68], g[69], + g[70], g[71], g[72], g[73], g[74], g[75], g[76], g[77], g[78], g[79], + g[80], g[81], g[82], g[83], g[84], g[85], g[86], g[87], g[88], g[89], + g[90], g[91], g[92], g[93], g[94], g[95], g[96], g[97], g[98], g[99], + g[100], g[101], g[102], g[103], g[104], g[105], g[106], g[107], g[108], g[109], + g[110], g[111], g[112], g[113], g[114], g[115], g[116], g[117], g[118], g[119], + g[120], g[121], g[122], g[123], g[124], g[125], g[126], g[127], g[128], g[129], + g[130], g[131], g[132], g[133], g[134], g[135], g[136], g[137], g[138], g[139], + g[140], g[141], g[142], g[143], g[144], g[145], g[146], g[147], g[148], g[149], + g[150], g[151], g[152], g[153], g[154], g[155], g[156], g[157], g[158], g[159], + g[160], g[161], g[162], g[163], g[164], g[165], g[166], g[167], g[168], g[169], + g[170], g[171], g[172], g[173], g[174], g[175], g[176], g[177], g[178], g[179], + g[180], g[181], g[182], g[183], g[184], g[185], g[186], g[187], g[188], g[189], + g[190], g[191], g[192], g[193], g[194], g[195], g[196], g[197], g[198], g[199], + g[200], g[201], g[202], g[203], g[204], g[205], g[206], g[207], g[208], g[209], + g[210], g[211], g[212], g[213], g[214], g[215], g[216], g[217], g[218], g[219], + g[220], g[221], g[222], g[223], g[224], g[225], g[226], g[227], g[228], g[229], + g[230], g[231], g[232], g[233], g[234], g[235], g[236], g[237], g[238], g[239], + g[240], g[241], g[242], g[243], g[244], g[245], g[246], g[247], g[248], g[249], + g[250], g[251], g[252], g[253], g[254], g[255], g[256], g[257], g[258], g[259], + g[260]) + != 101790) { + return 1; + } + if (fp( + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260) + != 33930) { + return 2; + } + if (sfp( + g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7], g[8], g[9], + g[10], g[11], g[12], g[13], g[14], g[15], g[16], g[17], g[18], g[19], + g[20], g[21], g[22], g[23], g[24], g[25], g[26], g[27], g[28], g[29], + g[30], g[31], g[32], g[33], g[34], g[35], g[36], g[37], g[38], g[39], + g[40], g[41], g[42], g[43], g[44], g[45], g[46], g[47], g[48], g[49], + g[50], g[51], g[52], g[53], g[54], g[55], g[56], g[57], g[58], g[59], + g[60], g[61], g[62], g[63], g[64], g[65], g[66], g[67], g[68], g[69], + g[70], g[71], g[72], g[73], g[74], g[75], g[76], g[77], g[78], g[79], + g[80], g[81], g[82], g[83], g[84], g[85], g[86], g[87], g[88], g[89], + g[90], g[91], g[92], g[93], g[94], g[95], g[96], g[97], g[98], g[99], + g[100], g[101], g[102], g[103], g[104], g[105], g[106], g[107], g[108], g[109], + g[110], g[111], g[112], g[113], g[114], g[115], g[116], g[117], g[118], g[119], + g[120], g[121], g[122], g[123], g[124], g[125], g[126], g[127], g[128], g[129], + g[130], g[131], g[132], g[133], g[134], g[135], g[136], g[137], g[138], g[139], + g[140], g[141], g[142], g[143], g[144], g[145], g[146], g[147], g[148], g[149], + g[150], g[151], g[152], g[153], g[154], g[155], g[156], g[157], g[158], g[159], + g[160], g[161], g[162], g[163], g[164], g[165], g[166], g[167], g[168], g[169], + g[170], g[171], g[172], g[173], g[174], g[175], g[176], g[177], g[178], g[179], + g[180], g[181], g[182], g[183], g[184], g[185], g[186], g[187], g[188], g[189], + g[190], g[191], g[192], g[193], g[194], g[195], g[196], g[197], g[198], g[199], + g[200], g[201], g[202], g[203], g[204], g[205], g[206], g[207], g[208], g[209], + g[210], g[211], g[212], g[213], g[214], g[215], g[216], g[217], g[218], g[219], + g[220], g[221], g[222], g[223], g[224], g[225], g[226], g[227], g[228], g[229], + g[230], g[231], g[232], g[233], g[234], g[235], g[236], g[237], g[238], g[239], + g[240], g[241], g[242], g[243], g[244], g[245], g[246], g[247], g[248], g[249], + g[250], g[251], g[252], g[253], g[254], g[255], g[256], g[257], g[258], g[259], + g[260]) + != 101790) { + return 3; + } + return 0; +} diff --git a/tests/fixtures/c/compound_assign_unsigned_div.c b/tests/fixtures/c/compound_assign_unsigned_div.c new file mode 100644 index 000000000..e1d1da13f --- /dev/null +++ b/tests/fixtures/c/compound_assign_unsigned_div.c @@ -0,0 +1,40 @@ +/* C99 6.5.16.2p3: `E1 op= E2` computes `E1 op E2`, so divide and + remainder run in the 6.3.1.8 common type of both operands -- at + its width and signedness -- and the result converts back to E1's + type. `unsigned x /= -2` divides 0xFFFFFFFF by 0xFFFFFFFE at 32 + bits; `int x /= 2u` divides unsigned. */ +int main(void) { + unsigned q = 0xffffffffu; + q /= -2; + if (q != 1) { + return 1; + } + unsigned q2 = 0xffffffffu; + q2 %= -2; + if (q2 != 1) { + return 2; + } + int d = -2; + d /= 2u; + if (d != 2147483647) { + return 3; + } + int e = -7; + e %= 3; + if (e != -1) { + return 4; + } + /* 64-bit unsigned lvalue: full-width divide, no masking. */ + unsigned long long big = 0xFFFFFFFFFFFFFFFFULL; + big /= 3; + if (big != 6148914691236517205ULL) { + return 5; + } + /* Sub-int unsigned lvalue promotes to signed int: 255 / -2. */ + unsigned char uc = 255; + uc /= -2; + if (uc != 129) { + return 6; + } + return 0; +} diff --git a/tests/fixtures/c/const_expr_unsigned_fold.c b/tests/fixtures/c/const_expr_unsigned_fold.c new file mode 100644 index 000000000..6f0ba6f61 --- /dev/null +++ b/tests/fixtures/c/const_expr_unsigned_fold.c @@ -0,0 +1,44 @@ +/* C99 6.6 + 6.3.1.8: constant expressions fold with the operands' + signedness -- unsigned division, remainder, right shift, and + relational compares on 64-bit unsigned values, and unsigned-int + compares for mixed narrow operands. INT64_MIN / -1 wraps instead + of aborting the compiler; a zero divisor in a not-taken `?:` arm + or short-circuited operand is unevaluated (6.6p4 scopes to the + evaluated expression). */ +static unsigned long long g_div = 0xFFFFFFFFFFFFFFFFULL / 3; +static unsigned long long g_shr = 0xFFFFFFFFFFFFFFFFULL >> 4; +static unsigned long long g_rem = 0xFFFFFFFFFFFFFFFFULL % 7; +static int g_gt = 0xFFFFFFFFFFFFFFFFULL > 2; +static int g_mixed = -1 < 1u; +static long long g_wrap = (-9223372036854775807LL - 1) / -1; +static int arr[0xFFFFFFFFu / 1000000000u]; +static int live[1 ? 3 : 1 / 0]; +static int shortcut = 0 && 1 / 0; + +int main(void) { + if (g_div != 6148914691236517205ULL) { + return 1; + } + if (g_shr != 1152921504606846975ULL) { + return 2; + } + if (g_rem != 1) { + return 3; + } + if (g_gt != 1) { + return 4; + } + if (g_mixed != 0) { + return 5; + } + if (g_wrap != -9223372036854775807LL - 1) { + return 6; + } + if (sizeof(arr) / sizeof(arr[0]) != 4) { + return 7; + } + if (sizeof(live) / sizeof(live[0]) != 3 || shortcut != 0) { + return 8; + } + return 0; +} diff --git a/tests/fixtures/c/data_reloc_one_past_end.c b/tests/fixtures/c/data_reloc_one_past_end.c new file mode 100644 index 000000000..293a3de25 --- /dev/null +++ b/tests/fixtures/c/data_reloc_one_past_end.c @@ -0,0 +1,17 @@ +/* A one-past-the-end address constant (C99 6.5.6p8) coincides with the + following object's start; data compaction must keep it attributed to + the preceding array when bss segregation moves the neighbor. */ +long arr[4] = {1, 2, 3, 4}; +long zeros[8]; +long *const end_p = &arr[4]; + +int main(void) { + long sum = 0; + long *p = arr; + while (p != end_p) { + sum += *p; + p++; + } + sum += zeros[3]; + return (int)sum; +} diff --git a/tests/fixtures/c/decl_specifier_any_order.c b/tests/fixtures/c/decl_specifier_any_order.c new file mode 100644 index 000000000..43ea61c30 --- /dev/null +++ b/tests/fixtures/c/decl_specifier_any_order.c @@ -0,0 +1,42 @@ +/* C99 6.7.2p2: type specifiers may appear in any order, so the + modifier may follow the base keyword: `int long` is `long int`, + `int unsigned` is `unsigned int`, `char unsigned` is `unsigned + char`, `int long long` is `long long int`. */ +struct pair { + long a; + int long b; /* same layout as `long b` */ +}; + +int main(void) { + if (sizeof(int long) != sizeof(long)) { + return 1; + } + if (sizeof(int long long) != sizeof(long long)) { + return 2; + } + int long long big = 0x100000000LL; + if (big >> 32 != 1) { + return 3; + } + int unsigned u = -1; + if (!(u > 0)) { + return 4; + } + char unsigned c = -1; + if (c != 255) { + return 5; + } + long int long llv = -1; /* `long int long` is long long */ + if (sizeof(llv) != 8) { + return 6; + } + if (sizeof(struct pair) != 2 * sizeof(long)) { + return 7; + } + struct pair p; + p.b = -5; + if (p.b >= 0) { + return 8; + } + return 0; +} diff --git a/tests/fixtures/c/fcntl_lock_via_cast_fnptr.c b/tests/fixtures/c/fcntl_lock_via_cast_fnptr.c new file mode 100644 index 000000000..ec357684e --- /dev/null +++ b/tests/fixtures/c/fcntl_lock_via_cast_fnptr.c @@ -0,0 +1,36 @@ +/* fcntl(fd, F_SETLK, &fl) through a sqlite-style dispatch table: the + cast supplies the variadic prototype, so the struct-address tail + must reach libc per the host variadic convention. Verified by the + kernel's return codes. */ +#include +#include +#include +#include + +typedef void (*syscall_ptr)(void); +static syscall_ptr table[1] = { (syscall_ptr)fcntl }; +#define osFcntl ((int (*)(int, int, ...))table[0]) + +int main(void) { + char path[64]; + snprintf(path, sizeof path, "/tmp/badc_fcntl_%d", (int)getpid()); + int fd = open(path, O_RDWR | O_CREAT, 0644); + if (fd < 0) { + return 3; + } + struct flock fl; + memset(&fl, 0, sizeof fl); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + int direct = fcntl(fd, F_SETLK, &fl); + fl.l_type = F_UNLCK; + int unlock = fcntl(fd, F_SETLK, &fl); + fl.l_type = F_WRLCK; + int viaptr = osFcntl(fd, F_SETLK, &fl); + close(fd); + unlink(path); + if (direct != 0 || unlock != 0) { + return 2; + } + return viaptr == 0 ? 0 : 1; +} diff --git a/tests/fixtures/c/float_ternary_promote.c b/tests/fixtures/c/float_ternary_promote.c new file mode 100644 index 000000000..3d3c9bf01 --- /dev/null +++ b/tests/fixtures/c/float_ternary_promote.c @@ -0,0 +1,25 @@ +// C99 6.5.15: a float-typed conditional expression yields one arm's +// value at single precision. The lowering stores each arm through the +// fused StoreLocal / LoadLocal F32 path so the synthetic merge slot +// stays mem2reg-promotable; the value must round-trip exactly at +// 32-bit precision (all constants below are f32-representable). + +static float sel(int c, float a, float b) { + float r = c ? a : b; + return r; +} + +int main(void) { + if (sel(1, 1.5f, -2.5f) != 1.5f) return 1; + if (sel(0, 1.5f, -2.5f) != -2.5f) return 2; + + float x = 3.25f; + float y = (x > 0.0f ? x : -x) + (x < 0.0f ? -x : x); /* 2*|x| */ + if (y != 6.5f) return 3; + + int k = 2; + float z = k == 0 ? 0.0f : k == 1 ? 10.0f : 20.0f; + if (z != 20.0f) return 4; + + return 0; +} diff --git a/tests/fixtures/c/fp_load_folded_disp.c b/tests/fixtures/c/fp_load_folded_disp.c new file mode 100644 index 000000000..89665af9d --- /dev/null +++ b/tests/fixtures/c/fp_load_folded_disp.c @@ -0,0 +1,40 @@ +/* A constant pointer offset folded into a floating load's displacement + must reach the emitted access: the load reads *(base + c), not *base. + The struct places float and double members at nonzero offsets; the + read-modify-write shares one folded address between a load and a + store. */ +struct pack { + long tag; + float f; /* offset 8 */ + double d; /* offset 16 */ + float g[3]; /* offsets 24, 28, 32 */ +}; + +static float read_f(struct pack *p) { return p->f; } +static double read_d(struct pack *p) { return p->d; } +static float read_g2(struct pack *p) { return p->g[2]; } +static void bump_d(struct pack *p) { p->d = p->d + 0.5; } + +int main(void) { + struct pack p; + p.tag = -1; + p.f = 1.25f; + p.d = 2.5; + p.g[0] = 0.0f; + p.g[1] = 0.0f; + p.g[2] = 4.75f; + if (read_f(&p) != 1.25f) { + return 1; + } + if (read_d(&p) != 2.5) { + return 2; + } + if (read_g2(&p) != 4.75f) { + return 3; + } + bump_d(&p); + if (p.d != 3.0) { + return 4; + } + return 0; +} diff --git a/tests/fixtures/c/indirect_call_target_scratch_exhausted.c b/tests/fixtures/c/indirect_call_target_scratch_exhausted.c new file mode 100644 index 000000000..bc668f843 --- /dev/null +++ b/tests/fixtures/c/indirect_call_target_scratch_exhausted.c @@ -0,0 +1,52 @@ +/* An indirect call whose argument sources occupy every caller-saved + target-capture candidate register must not overwrite a live source + with the function pointer: 17 scalar arguments exercise the + 16-byte-stride push path, 16 by-value structs the host-ABI marshal + path. */ +struct pr { + long a; + long b; +}; + +static struct pr g[16]; + +static long sum17(long v1, long v2, long v3, long v4, long v5, long v6, + long v7, long v8, long v9, long v10, long v11, long v12, + long v13, long v14, long v15, long v16, long v17) { + return v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10 + v11 + v12 + + v13 + v14 + v15 + v16 + v17; +} + +static long sum16p(struct pr p0, struct pr p1, struct pr p2, struct pr p3, + struct pr p4, struct pr p5, struct pr p6, struct pr p7, + struct pr p8, struct pr p9, struct pr p10, struct pr p11, + struct pr p12, struct pr p13, struct pr p14, + struct pr p15) { + return p0.a + p0.b + p1.a + p1.b + p2.a + p2.b + p3.a + p3.b + p4.a + + p4.b + p5.a + p5.b + p6.a + p6.b + p7.a + p7.b + p8.a + p8.b + + p9.a + p9.b + p10.a + p10.b + p11.a + p11.b + p12.a + p12.b + + p13.a + p13.b + p14.a + p14.b + p15.a + p15.b; +} + +int main(void) { + long (*fp)(long, long, long, long, long, long, long, long, long, long, + long, long, long, long, long, long, long) = sum17; + long (*sfp)(struct pr, struct pr, struct pr, struct pr, struct pr, + struct pr, struct pr, struct pr, struct pr, struct pr, + struct pr, struct pr, struct pr, struct pr, struct pr, + struct pr) = sum16p; + long i; + for (i = 0; i < 16; i++) { + g[i].a = i; + g[i].b = 2 * i; + } + if (fp(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) != + 153) { + return 1; + } + if (sfp(g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7], g[8], g[9], + g[10], g[11], g[12], g[13], g[14], g[15]) != 360) { + return 2; + } + return 0; +} diff --git a/tests/fixtures/c/inline_multi_block_result_forward.c b/tests/fixtures/c/inline_multi_block_result_forward.c new file mode 100644 index 000000000..7ecbae4ac --- /dev/null +++ b/tests/fixtures/c/inline_multi_block_result_forward.c @@ -0,0 +1,23 @@ +/* The result of an inlined multi-block callee is read in caller blocks + emitted after the splice point; the splice must resolve those forward + references instead of dropping them. */ +static int helper_one(int x) { return x + x; } + +static int helper_two(int x) { + int y; + goto compute; +compute: + y = x << 1; + return y; +} + +int test(int a) { + int r = helper_two(a); + int s = helper_one(a); + if (a > 3) { + return r; + } + return r + s; +} + +int main(void) { return test(5); } diff --git a/tests/fixtures/c/int_literal_boundary_types.c b/tests/fixtures/c/int_literal_boundary_types.c new file mode 100644 index 000000000..5e7f5b05f --- /dev/null +++ b/tests/fixtures/c/int_literal_boundary_types.c @@ -0,0 +1,42 @@ +/* C99 6.4.4.1p5 at the signed-max boundaries: an unsuffixed decimal + constant takes the first of int, long, long long that represents + it, so 2147483648 (2^31) is long, not a wrapped int; a decimal + constant past LLONG_MAX takes unsigned long long (existing gcc / + clang practice). Hex constants at 2^31 / 2^63 take the unsigned + type at the same rank. Octal and binary literals carry the same + u/U/l/L suffixes as decimal and hex. */ +int main(void) { + /* 2147483648 is long (or long long): the negation and subtraction + run at 64 bits instead of wrapping at int width. */ + long long a = -2147483648 - 1; + if (a != -2147483649LL) { + return 1; + } + if (sizeof(2147483648) != sizeof(long long) && sizeof(2147483648) != 8) { + return 2; + } + /* 0x80000000 is unsigned int: -1 converts to 0xFFFFFFFF and + compares above it. */ + if (-1 < 0x80000000) { + return 3; + } + if (sizeof(0x80000000) != 4) { + return 4; + } + /* 2^63: hex and decimal both land at unsigned long long. */ + if (!(0x8000000000000000 > 0x7FFFFFFFFFFFFFFF)) { + return 5; + } + if (9223372036854775808 / 2 != 4611686018427387904) { + return 6; + } + /* Octal / binary suffixes are recorded, not dropped. */ + if (sizeof(01ll) != 8 || sizeof(0777LL) != 8 || sizeof(0b1ull) != 8) { + return 7; + } + /* 010u is unsigned int: the mixed compare runs unsigned. */ + if (-1 < 010u) { + return 8; + } + return 0; +} diff --git a/tests/fixtures/c/ioctl_fionread_pipe.c b/tests/fixtures/c/ioctl_fionread_pipe.c new file mode 100644 index 000000000..a7a13070b --- /dev/null +++ b/tests/fixtures/c/ioctl_fionread_pipe.c @@ -0,0 +1,28 @@ +// POSIX (XSH) declares ioctl variadic and both target libcs read the +// argument via va_arg -- on Darwin arm64 from the stack, so a caller +// compiled against a fixed-arity prototype passes the pointer where +// the callee does not look and FIONREAD faults with EFAULT. A pipe +// holding 5 unread bytes must report 5. + +#include +#include + +int main(void) { + int fds[2]; + int n = 0; + if (pipe(fds) != 0) { + return 1; + } + if (write(fds[1], "hello", 5) != 5) { + return 2; + } + if (ioctl(fds[0], FIONREAD, &n) != 0) { + return 3; + } + if (n != 5) { + return 4; + } + close(fds[0]); + close(fds[1]); + return 0; +} diff --git a/tests/fixtures/c/mixed_sse_int_aggregate_args.c b/tests/fixtures/c/mixed_sse_int_aggregate_args.c new file mode 100644 index 000000000..f4ea52096 --- /dev/null +++ b/tests/fixtures/c/mixed_sse_int_aggregate_args.c @@ -0,0 +1,27 @@ +/* SysV mixed SSE/INTEGER eightbyte aggregates: the integer eightbyte + target GPR may still be another argument's pending source, so the + aggregate loads must join the parallel-move ordering. */ +struct DL { double d; long l; }; +struct LD { long l; double d; }; +struct DD { double a; double b; }; + +static int take3(struct DL s, long x, struct LD t, double f, struct DD u) { + if (s.d != 2.5 || s.l != 7) return 1; + if (x != 4) return 2; + if (t.l != 11 || t.d != 0.5) return 3; + if (f != 1.25) return 4; + if (u.a != 3.5 || u.b != 4.5) return 5; + return 0; +} + +int docall(long x, struct DL *p, struct LD *q, struct DD *r, double f) { + return take3(*p, x, *q, f, *r); +} + +int main(void) { + struct DL s; struct LD t; struct DD u; + s.d = 2.5; s.l = 7; + t.l = 11; t.d = 0.5; + u.a = 3.5; u.b = 4.5; + return docall(4, &s, &t, &u, 1.25); +} diff --git a/tests/fixtures/c/nested_designator_string_member.c b/tests/fixtures/c/nested_designator_string_member.c new file mode 100644 index 000000000..2903dd83e --- /dev/null +++ b/tests/fixtures/c/nested_designator_string_member.c @@ -0,0 +1,31 @@ +// C99 6.7.8p7/p14: a designator chain `.outer.inner = "str"` naming a +// char-array member copies the string's bytes (with zero fill), the +// same as naming the member directly; it must not store the literal's +// address. Checked for a static object (constant staging) and for an +// automatic object whose sibling values force the runtime store path. +// +// Returns 0 only when every check passes; each failure path +// returns a distinct nonzero code. + +struct In { int x; char name[8]; }; +struct Out { struct In in; int y; }; + +struct Out g = { .in.name = "abc", .y = 7, .in.x = 5 }; + +static int str_eq(const char *a, const char *b) { + while (*a && *a == *b) { a++; b++; } + return *a == *b; +} + +int main(int argc, char **argv) { + (void)argv; + if (!str_eq(g.in.name, "abc")) return 1; + if (g.in.name[3] != 0 || g.in.name[7] != 0) return 2; + if (g.y != 7 || g.in.x != 5) return 3; + + struct Out l = { .in.name = "wxyz", .y = argc + 6, .in.x = argc + 4 }; + if (!str_eq(l.in.name, "wxyz")) return 4; + if (l.in.name[4] != 0 || l.in.name[7] != 0) return 5; + if (l.y != argc + 6 || l.in.x != argc + 4) return 6; + return 0; +} diff --git a/tests/fixtures/c/packed_bitfield_repack.c b/tests/fixtures/c/packed_bitfield_repack.c new file mode 100644 index 000000000..363acbccb --- /dev/null +++ b/tests/fixtures/c/packed_bitfield_repack.c @@ -0,0 +1,57 @@ +// A struct with a trailing `__attribute__((packed))` re-lays its +// fields with no inter-member padding. Bitfield members must keep +// their storage: C99 6.7.2.1p11 leaves the addressable unit +// implementation-defined, and the packed layout (matching gcc and +// clang) allocates bitfields at the bit level, placing the next +// non-bitfield member at the following byte boundary. Sizes, +// offsets, and read-back values are checked against clang output. +// +// Returns 0 only when every check passes; each failure path +// returns a distinct nonzero code. + +#include + +struct A { int flags:8; char c; } __attribute__((packed)); +struct B { int a:17; int b:10; char c; } __attribute__((packed)); +struct C { char a:3; char b:7; char c; } __attribute__((packed)); +struct E { char c; int b:16; } __attribute__((packed)); + +struct A ga = { 85, 7 }; + +int main(void) { + if (sizeof(struct A) != 2 || offsetof(struct A, c) != 1) return 1; + if (sizeof(struct B) != 5 || offsetof(struct B, c) != 4) return 2; + if (sizeof(struct C) != 3 || offsetof(struct C, c) != 2) return 3; + if (sizeof(struct E) != 3) return 4; + + // Writing the plain member must not clobber the bitfield's + // storage unit (they overlapped when the repack dropped the + // bitfield's byte). + struct A a; + a.flags = 85; + a.c = 7; + if (a.flags != 85 || a.c != 7) return 5; + + // A run straddling byte boundaries packs contiguously. + struct B b; + b.a = 65000; + b.b = 500; + b.c = 9; + if (b.a != 65000 || b.b != 500 || b.c != 9) return 6; + + struct C c; + c.a = 3; + c.b = 60; + c.c = 4; + if (c.a != 3 || c.b != 60 || c.c != 4) return 7; + + // Trailing bitfield: the access window stays inside the struct. + struct E e; + e.c = 11; + e.b = 30000; + if (e.c != 11 || e.b != 30000) return 8; + + // Static initializer merges into the packed unit. + if (ga.flags != 85 || ga.c != 7) return 9; + return 0; +} diff --git a/tests/fixtures/c/predefined_macros.c b/tests/fixtures/c/predefined_macros.c index f9f2ea3cd..5d5c8416a 100644 --- a/tests/fixtures/c/predefined_macros.c +++ b/tests/fixtures/c/predefined_macros.c @@ -42,12 +42,13 @@ int main() { if (file_str[0] == 0) return 9; // C11 6.10.8.3 conditional-feature macros. badc reports - // __STDC_VERSION__ == 201112L and provides neither variable length - // arrays nor _Complex, so it predefines those two to 1. + // __STDC_VERSION__ == 201112L. It supports C99 6.7.6.2 variable + // length arrays, so __STDC_NO_VLA__ stays undefined; it does not + // provide _Complex, so __STDC_NO_COMPLEX__ is predefined to 1. // __STDC_NO_THREADS__ stays undefined (badc supports the // _Thread_local storage classifier that code gates on this macro), // and __STDC_NO_ATOMICS__ stays undefined ( is provided). -#if !defined(__STDC_NO_VLA__) || (__STDC_NO_VLA__ != 1) +#ifdef __STDC_NO_VLA__ return 10; #endif #if !defined(__STDC_NO_COMPLEX__) || (__STDC_NO_COMPLEX__ != 1) diff --git a/tests/fixtures/c/setenv_overwrite.c b/tests/fixtures/c/setenv_overwrite.c new file mode 100644 index 000000000..0dc374c2e --- /dev/null +++ b/tests/fixtures/c/setenv_overwrite.c @@ -0,0 +1,16 @@ +#include + +// POSIX setenv (IEEE Std 1003.1): overwrite==0 leaves an existing +// binding untouched; overwrite!=0 replaces it. Verified through getenv. +int main(void) { + setenv("BADC_T_SETENV_OW", "first", 1); + setenv("BADC_T_SETENV_OW", "second", 0); /* must not clobber */ + if (getenv("BADC_T_SETENV_OW")[0] != 'f') { + return 1; + } + setenv("BADC_T_SETENV_OW", "third", 1); /* must clobber */ + if (getenv("BADC_T_SETENV_OW")[0] != 't') { + return 2; + } + return 0; +} diff --git a/tests/fixtures/c/setjmp_value_live_across.c b/tests/fixtures/c/setjmp_value_live_across.c new file mode 100644 index 000000000..67488186f --- /dev/null +++ b/tests/fixtures/c/setjmp_value_live_across.c @@ -0,0 +1,24 @@ +/* C99 7.13.2.1p3: a value unmodified since setjmp keeps its value on + the second return. The setjmp site must be a call barrier for the + allocator so the value survives in a callee-saved register or on + the stack (the inline windows-arm64 expansion restores only the + jmp_buf register set). */ +#include +#include + +static jmp_buf b; + +static void h(void) { longjmp(b, 1); } + +int test(int a, int c) { + int x = a * 7 + c; + if (setjmp(b)) { + return x; + } + h(); + return 0; +} + +int main(void) { + return test(5, 7) == 42 ? 0 : 1; +} diff --git a/tests/fixtures/c/shift_result_promoted_type.c b/tests/fixtures/c/shift_result_promoted_type.c new file mode 100644 index 000000000..1baa254c9 --- /dev/null +++ b/tests/fixtures/c/shift_result_promoted_type.c @@ -0,0 +1,29 @@ +/* C99 6.5.7p3: the result of a shift has the promoted type of the + left operand; the count operand does not participate. A signed + 64-bit `>>` must not narrow to int in a surrounding expression. */ +int main(void) { + long long x = -8589934592LL; /* -0x2_0000_0000 */ + long long y = (x >> 1) + 0; + if (y != -4294967296LL) { + return 1; + } + unsigned long long b = 0x8000000000000000ULL; + if ((b >> 63) != 1) { + return 2; + } + unsigned int u = 0x80000000u; + if ((u >> 31) != 1) { + return 3; + } + int neg = -16; + if ((neg >> 2) != -4) { + return 4; + } + /* Promoted sub-int LHS: unsigned char shifts as (zero-extended) + int. */ + unsigned char c = 0x80; + if ((c >> 3) != 0x10) { + return 5; + } + return 0; +} diff --git a/tests/fixtures/c/shm_open_mode_arg.c b/tests/fixtures/c/shm_open_mode_arg.c new file mode 100644 index 000000000..edc7b28ce --- /dev/null +++ b/tests/fixtures/c/shm_open_mode_arg.c @@ -0,0 +1,31 @@ +// Darwin declares shm_open variadic and fetches the mode via va_arg +// (from the stack on arm64); a caller compiled against a fixed-arity +// prototype leaves that slot unwritten and the object is created with +// garbage permission bits. Create with 0600 and read the mode back. + +#include +#include +#include +#include +#include + +int main(void) { + char name[64]; + struct stat st; + int fd; + int rc = 0; + sprintf(name, "/badc_shm_%d", getpid()); + shm_unlink(name); + fd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, 0600); + if (fd < 0) { + return 1; + } + if (fstat(fd, (char *)&st) != 0) { + rc = 2; + } else if ((st.st_mode & 0777) != 0600) { + rc = 3; + } + close(fd); + shm_unlink(name); + return rc; +} diff --git a/tests/fixtures/c/snprintf_truncation_c99.c b/tests/fixtures/c/snprintf_truncation_c99.c new file mode 100644 index 000000000..e97f85b8a --- /dev/null +++ b/tests/fixtures/c/snprintf_truncation_c99.c @@ -0,0 +1,44 @@ +// C99 7.19.6.5p3: on truncation snprintf returns the length the +// output would have had and NUL-terminates what fits (size > 0); +// with size 0 nothing is written. 7.19.6.12p3 gives vsnprintf the +// same contract. msvcrt's _snprintf / _vsnprintf return -1 and omit +// the NUL, so on Windows the standard spellings resolve to the +// conforming wrappers in the auto-linked runtime. + +#include +#include +#include + +static int wrap(char *buf, int size, char *fmt, ...) { + va_list ap; + int n; + va_start(ap, fmt); + n = vsnprintf(buf, size, fmt, ap); + va_end(ap); + return n; +} + +int main(void) { + char buf[8]; + memset(buf, 'A', sizeof(buf)); + if (snprintf(buf, 4, "%d", 123456) != 6) { + return 1; + } + if (strcmp(buf, "123") != 0) { + return 2; + } + if (snprintf(0, 0, "%s", "hello") != 5) { + return 3; + } + memset(buf, 'A', sizeof(buf)); + if (wrap(buf, 4, "%d", 987654) != 6) { + return 4; + } + if (strcmp(buf, "987") != 0) { + return 5; + } + if (snprintf(buf, 8, "%d", 42) != 2 || strcmp(buf, "42") != 0) { + return 6; + } + return 0; +} diff --git a/tests/fixtures/c/strtof_parses_float.c b/tests/fixtures/c/strtof_parses_float.c new file mode 100644 index 000000000..c726fc365 --- /dev/null +++ b/tests/fixtures/c/strtof_parses_float.c @@ -0,0 +1,22 @@ +// C99 7.20.1.3: strtof converts the initial portion of the string and +// sets *endp past the consumed prefix. c5 aliases `float` to `double`, +// so the header binds strtof to the target's double-returning strtod; +// a binding to libc's float-returning strtof leaves the wrong register +// width behind the double-typed prototype. + +#include + +int main(void) { + char *end; + double v = strtof("3.5xyz", &end); + if (v != 3.5) { + return 1; + } + if (*end != 'x') { + return 2; + } + if (strtof("-0.25", 0) != -0.25) { + return 3; + } + return 0; +} diff --git a/tests/fixtures/c/switch_case_label_promoted.c b/tests/fixtures/c/switch_case_label_promoted.c new file mode 100644 index 000000000..fc1df47fa --- /dev/null +++ b/tests/fixtures/c/switch_case_label_promoted.c @@ -0,0 +1,48 @@ +/* C99 6.8.4.2p5: each case constant converts to the promoted type of + the controlling expression. On an int switch `case 0x80000000:` + (unsigned int constant) converts to INT_MIN and must match. */ +int main(void) { + int v = -2147483647 - 1; + int hit = 0; + switch (v) { + case 0x80000000: + hit = 1; + break; + default: + hit = 2; + break; + } + if (hit != 1) { + return 1; + } + /* Unsigned controlling type: a negative label wraps modulo 2^32. */ + unsigned u = 0xfffffffeu; + switch (u) { + case -2: + hit = 3; + break; + default: + hit = 4; + break; + } + if (hit != 3) { + return 2; + } + /* 8-byte controlling type keeps full-width labels. */ + long long w = -4294967296LL; + switch (w) { + case -4294967296LL: + hit = 5; + break; + case 0x80000000: + hit = 6; + break; + default: + hit = 7; + break; + } + if (hit != 5) { + return 3; + } + return 0; +} diff --git a/tests/fixtures/c/sxtw_fold_source_liveness.c b/tests/fixtures/c/sxtw_fold_source_liveness.c new file mode 100644 index 000000000..91b133719 --- /dev/null +++ b/tests/fixtures/c/sxtw_fold_source_liveness.c @@ -0,0 +1,11 @@ +/* The Shl/Shr sign-narrow fold reads the Shl source's register at the + Shr; an intervening definition may reuse that register once the + source's live range ends. The fold must verify the place survives. */ +long long f(long long x, long long b) { + long long t = x << 32; + long long v = x + b; + long long y = t >> 32; + return y + v + b; +} + +int main(void) { return (int)f(2, 7); } diff --git a/tests/fixtures/c/ternary_arith_common_type.c b/tests/fixtures/c/ternary_arith_common_type.c new file mode 100644 index 000000000..1b5807d9e --- /dev/null +++ b/tests/fixtures/c/ternary_arith_common_type.c @@ -0,0 +1,26 @@ +/* C99 6.5.15p5: with two arithmetic arms the conditional's type is + the usual-arithmetic-conversions common type and each arm converts + to it, whichever arm is selected. `c ? 1u : -1` is unsigned int in + both directions, not the else-arm's int. */ +int main(void) { + unsigned r = 0; + long z = (r == 0) ? 1u : -1; + if (z != 1) { + return 1; + } + long w = (r != 0) ? 1u : -1; + if (w != 4294967295L) { + return 2; + } + /* Then-arm conversion: -1 selected against an unsigned else. */ + long v = (r == 0) ? -1 : 1u; + if (v != 4294967295L) { + return 3; + } + /* Rank widening: the int arm widens to long long. */ + long long p = (r == 0) ? -1 : 0LL; + if (p != -1LL) { + return 4; + } + return 0; +} diff --git a/tests/fixtures/c/union_member_unbraced_init.c b/tests/fixtures/c/union_member_unbraced_init.c new file mode 100644 index 000000000..0d35a0c57 --- /dev/null +++ b/tests/fixtures/c/union_member_unbraced_init.c @@ -0,0 +1,43 @@ +// C99 6.7.8p17: with its braces elided, a union member of a struct +// takes a single initializer for its first named member, converted as +// if by assignment. The integer 3 must land as the double 3.0, the +// following value goes to the next struct member, and a union wider +// than 8 bytes must not wrap the stored bytes at offset 8. +// +// Returns 0 only when every check passes; each failure path +// returns a distinct nonzero code. + +union U { double d; char pad[16]; }; +struct S { union U u; int tag; }; +struct S gs = { 3, 42 }; + +union U8 { double d; long l; }; +struct S8 { union U8 u; int tag; } gs8 = { 5, 43 }; + +// The first member may itself be an aggregate; elision continues +// into it (6.7.8p20). +union V { struct { int a; int b; } s; double d; }; +struct W { union V v; int t; } gw = { 1, 2, 9 }; + +struct S garr[2] = { 3, 42, 4, 43 }; + +int main(void) { + if (gs.u.d != 3.0 || gs.tag != 42) return 1; + // Bytes past offset 8 of the 16-byte union stay zero. + for (int i = 8; i < 16; i++) { + if (gs.u.pad[i] != 0) return 2; + } + if (gs8.u.d != 5.0 || gs8.tag != 43) return 3; + if (gw.v.s.a != 1 || gw.v.s.b != 2 || gw.t != 9) return 4; + if (garr[0].u.d != 3.0 || garr[0].tag != 42) return 5; + if (garr[1].u.d != 4.0 || garr[1].tag != 43) return 6; + + // Automatic storage with constant values follows the same path. + struct S l = { 3, 42 }; + if (l.u.d != 3.0 || l.tag != 42) return 7; + + // A braced union member is unaffected. + struct S lb = { { 6 }, 44 }; + if (lb.u.d != 6.0 || lb.tag != 44) return 8; + return 0; +} diff --git a/tests/fixtures/c/va_arg_composite_straddle.c b/tests/fixtures/c/va_arg_composite_straddle.c new file mode 100644 index 000000000..66906cbf2 --- /dev/null +++ b/tests/fixtures/c/va_arg_composite_straddle.c @@ -0,0 +1,28 @@ +#include +#include + +struct S { long x, y; }; + +/* Seven eightbyte-consuming named+leading variadic args leave one GPR + in the save area; the two-eightbyte struct then straddles and must + come from the overflow stack (AAPCS64 B.5), as must the tail. */ +static long take(int n, ...) { + va_list ap; + va_start(ap, n); + for (int i = 0; i < 6; i++) { + (void)va_arg(ap, long); + } + struct S s = va_arg(ap, struct S); + long tail = va_arg(ap, long); + va_end(ap); + if (s.x != 111 || s.y != 222) return 1; + if (tail != 777) return 2; + return 0; +} + +int main(void) { + struct S s; + s.x = 111; + s.y = 222; + return (int)take(1, 2L, 3L, 4L, 5L, 6L, 7L, s, 777L); +} diff --git a/tests/fixtures/c/va_copy_under_pressure.c b/tests/fixtures/c/va_copy_under_pressure.c new file mode 100644 index 000000000..dc07eae21 --- /dev/null +++ b/tests/fixtures/c/va_copy_under_pressure.c @@ -0,0 +1,34 @@ +#include + +/* Enough simultaneously live temporaries that the va_list address + operands spill and rax/rcx/rdx carry live values across va_copy. */ +static long f(long m, ...) { + va_list ap, aq; + long t1 = m * 3; + long t2 = m + 11; + long t3 = m * 7; + long t4 = m - 2; + long t5 = m * 13; + long t6 = m + 29; + long t7 = m * 4; + long t8 = m + 41; + long t9 = m * 9; + long t10 = m + 53; + long t11 = m * 5; + long t12 = m + 61; + long t13 = m * 15; + long t14 = m + 3; + va_start(ap, m); + va_copy(aq, ap); + long a = va_arg(aq, long); + long b = va_arg(aq, long); + va_end(aq); + va_end(ap); + return t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10 + t11 + t12 + t13 + t14 + a + b; +} + +int main(void) { + long got = f(2, 10L, 20L); + long want = 6 + 13 + 14 + 0 + 26 + 31 + 8 + 43 + 18 + 55 + 10 + 63 + 30 + 5 + 10 + 20; + return got == want ? 0 : 1; +} diff --git a/tests/fixtures/c/variable_shift_rcx_loop.c b/tests/fixtures/c/variable_shift_rcx_loop.c new file mode 100644 index 000000000..e1311bfd6 --- /dev/null +++ b/tests/fixtures/c/variable_shift_rcx_loop.c @@ -0,0 +1,15 @@ +/* The x86_64 variable-shift lowering borrows rcx for the count; a + loop-carried value colored into rcx is live across the shift via + the back edge while its pc interval excludes the shift, so the + save must not rely on a pc-interval liveness test. */ +long g(long n, long m, long c, long k) { + long acc = 0; + for (long i = 0; acc < n; i += (m << c)) { + acc = i + k; + } + return k; +} + +int main(void) { + return g(100, 2, 3, 1) == 1 ? 0 : 1; +} diff --git a/tests/fixtures/c/variadic_agg_return_classes.c b/tests/fixtures/c/variadic_agg_return_classes.c new file mode 100644 index 000000000..28834383f --- /dev/null +++ b/tests/fixtures/c/variadic_agg_return_classes.c @@ -0,0 +1,27 @@ +/* A variadic callee returning a <=16-byte aggregate uses the same + eightbyte classification as a non-variadic one (System V AMD64 + 3.2.3): SSE eightbytes in xmm0/xmm1, INTEGER in rax/rdx. */ +struct P { double x, y; }; +struct M { double d; long l; }; + +static struct P mkp(int n, ...) { + struct P p; + p.x = 1.5 * n; + p.y = 2.25; + return p; +} + +static struct M mkm(int n, ...) { + struct M m; + m.d = 0.5; + m.l = n + 41; + return m; +} + +int main(void) { + struct P p = mkp(2); + if (p.x != 3.0 || p.y != 2.25) return 1; + struct M m = mkm(1); + if (m.d != 0.5 || m.l != 42) return 2; + return 0; +} diff --git a/tests/fixtures/c/variadic_cast_fnptr_dispatch.c b/tests/fixtures/c/variadic_cast_fnptr_dispatch.c new file mode 100644 index 000000000..a1f4e9755 --- /dev/null +++ b/tests/fixtures/c/variadic_cast_fnptr_dispatch.c @@ -0,0 +1,23 @@ +/* A call through a cast fn-pointer type uses the cast's prototype + (C99 6.5.2.2p7): the variadic tail must marshal per the host + variadic convention even when the pointer's declared type says + nothing (the sqlite-style syscall dispatch table shape). */ +#include +#include + +typedef void (*fnp)(void); +static fnp table[1] = { (fnp)snprintf }; + +int main(void) { + char buf[32]; + buf[0] = 0; + int n = ((int (*)(char *, unsigned long, const char *, ...))table[0])( + buf, sizeof buf, "%d %s %d", 4, "mid", 9); + if (n != 7) { + return 1; + } + if (strcmp(buf, "4 mid 9") != 0) { + return 2; + } + return 0; +} diff --git a/tests/fixtures/c/variadic_hfa_struct_arg.c b/tests/fixtures/c/variadic_hfa_struct_arg.c new file mode 100644 index 000000000..5a84963f6 --- /dev/null +++ b/tests/fixtures/c/variadic_hfa_struct_arg.c @@ -0,0 +1,24 @@ +/* A variadic HFA composite: Windows aarch64 passes it in the integer + bank (SIMD/FP registers are unavailable to variadic composites). + TODO: the AAPCS64/SysV register-save va_arg reads every aggregate + from the general area; an HFA composite rides the vector area and + needs per-member composition, so this fixture is not yet registered + for the native_elf / native_elf_x64 lanes. */ +#include + +struct P { double x, y; }; + +static double sum(int n, ...) { + va_list ap; + va_start(ap, n); + struct P p = va_arg(ap, struct P); + va_end(ap); + return p.x + p.y; +} + +int main(void) { + struct P p; + p.x = 1.5; + p.y = 2.25; + return sum(1, p) == 3.75 ? 0 : 1; +} diff --git a/tests/fixtures/c/variadic_libc_fnptr_static_init.c b/tests/fixtures/c/variadic_libc_fnptr_static_init.c new file mode 100644 index 000000000..4573f13a1 --- /dev/null +++ b/tests/fixtures/c/variadic_libc_fnptr_static_init.c @@ -0,0 +1,18 @@ +/* A static initializer naming a variadic libc function resolves to the + sys trampoline; the trampoline must forward the variadic tail (stack + region, and al on System V), which only a frameless jump preserves. */ +#include +#include + +typedef int (*psn)(char *, unsigned long, const char *, ...); +psn table[2] = { snprintf, snprintf }; + +int main(void) { + char buf[64]; + buf[0] = 0; + table[1](buf, sizeof buf, "%d %s %d", 42, "mid", 99); + if (strcmp(buf, "42 mid 99") != 0) { + return 1; + } + return 0; +} diff --git a/tests/fixtures/c/vla_basic_sum.c b/tests/fixtures/c/vla_basic_sum.c new file mode 100644 index 000000000..ac09daa8b --- /dev/null +++ b/tests/fixtures/c/vla_basic_sum.c @@ -0,0 +1,24 @@ +/* C99 6.7.6.2 variable-length array: a runtime-sized local array, read + and written elementwise. Returns 0 on success. */ +static int compute(int n) { + int a[n]; + for (int i = 0; i < n; i++) { + a[i] = i * 2; + } + int s = 0; + for (int i = 0; i < n; i++) { + s += a[i]; + } + return s; +} + +int main(void) { + /* 0 + 2 + 4 + 6 + 8 = 20 */ + if (compute(5) != 20) { + return 1; + } + if (compute(1) != 0) { + return 2; + } + return 0; +} diff --git a/tests/fixtures/c/vla_file_scope_rejected.c b/tests/fixtures/c/vla_file_scope_rejected.c new file mode 100644 index 000000000..7deb05926 --- /dev/null +++ b/tests/fixtures/c/vla_file_scope_rejected.c @@ -0,0 +1,5 @@ +/* C99 6.7.6.2p2: a variably-modified type at file scope is a + constraint violation. */ +extern int n; +int g[n]; +int main(void) { return 0; } diff --git a/tests/fixtures/c/vla_initializer_rejected.c b/tests/fixtures/c/vla_initializer_rejected.c new file mode 100644 index 000000000..db7553888 --- /dev/null +++ b/tests/fixtures/c/vla_initializer_rejected.c @@ -0,0 +1,5 @@ +/* C99 6.7.8p3: a variable-length array may not have an initializer. */ +int f(int n) { + int a[n] = {1, 2, 3}; + return a[0]; +} diff --git a/tests/fixtures/c/vla_multidim_rejected.c b/tests/fixtures/c/vla_multidim_rejected.c new file mode 100644 index 000000000..f608ba584 --- /dev/null +++ b/tests/fixtures/c/vla_multidim_rejected.c @@ -0,0 +1,7 @@ +/* Multidimensional VLAs need runtime element strides, which c5's + compile-time stride model cannot represent; rejected cleanly rather + than miscompiled (C99 6.7.6.2). */ +int f(int n, int m) { + int a[n][m]; + return a[0][0]; +} diff --git a/tests/fixtures/c/vla_param_decay.c b/tests/fixtures/c/vla_param_decay.c new file mode 100644 index 000000000..389a3f7e3 --- /dev/null +++ b/tests/fixtures/c/vla_param_decay.c @@ -0,0 +1,17 @@ +/* C99 6.7.6.3p7: a variable-length array parameter is adjusted to a + pointer to the element type; the dimension expression documents the + intent but the parameter is passed as a plain pointer. */ +static int dot(int n, int a[n], int b[n]) { + int s = 0; + for (int i = 0; i < n; i++) { + s += a[i] * b[i]; + } + return s; +} + +int main(void) { + int x[4] = {1, 2, 3, 4}; + int y[4] = {5, 6, 7, 8}; + /* 5 + 12 + 21 + 32 = 70 */ + return dot(4, x, y) == 70 ? 0 : 1; +} diff --git a/tests/fixtures/c/vla_runtime_sizeof.c b/tests/fixtures/c/vla_runtime_sizeof.c new file mode 100644 index 000000000..3cc222bcb --- /dev/null +++ b/tests/fixtures/c/vla_runtime_sizeof.c @@ -0,0 +1,20 @@ +/* C99 6.5.3.4p2: sizeof applied to a variable-length array is a + runtime value, n * sizeof(element). The size is fixed at the + declaration (6.7.6.2p4), so a later change to n does not affect it. */ +int main(void) { + int n = 7; + long a[n]; + unsigned long sz = sizeof(a); + if (sz != (unsigned long)n * sizeof(long)) { + return 1; + } + /* sizeof(a) / sizeof(a[0]) recovers the element count. */ + if (sz / sizeof(a[0]) != (unsigned long)n) { + return 2; + } + n = 100; + if (sizeof(a) != 7 * sizeof(long)) { + return 3; + } + return 0; +} diff --git a/tests/fixtures/c/vla_scope_reclaim_loop.c b/tests/fixtures/c/vla_scope_reclaim_loop.c new file mode 100644 index 000000000..d0990fb8e --- /dev/null +++ b/tests/fixtures/c/vla_scope_reclaim_loop.c @@ -0,0 +1,20 @@ +/* C99 6.2.4p2: a VLA declared in a loop body is reclaimed on each + iteration. The per-frame arena is fixed-size, so without the arena + top being restored per iteration this would exhaust it and trap long + before the loop ends. Self-checks the accumulated value. */ +int main(void) { + long total = 0; + for (int iter = 0; iter < 100000; iter++) { + int n = 64; + int a[n]; + for (int i = 0; i < n; i++) { + a[i] = i; + } + total += a[iter & 63]; + } + long expect = 0; + for (int iter = 0; iter < 100000; iter++) { + expect += (iter & 63); + } + return total == expect ? 0 : 1; +} diff --git a/tests/fixtures/c/vla_size_from_arg.c b/tests/fixtures/c/vla_size_from_arg.c new file mode 100644 index 000000000..33d7359ef --- /dev/null +++ b/tests/fixtures/c/vla_size_from_arg.c @@ -0,0 +1,22 @@ +/* A variable-length array whose dimension is a function argument. */ +static int fill_and_sum(int n) { + char buf[n]; + for (int i = 0; i < n; i++) { + buf[i] = (char)(i + 1); + } + int s = 0; + for (int i = 0; i < n; i++) { + s += buf[i]; + } + return s; +} + +int main(void) { + if (fill_and_sum(10) != 55) { + return 1; + } + if (fill_and_sum(4) != 10) { + return 2; + } + return 0; +} diff --git a/tests/fixtures/c/volatile_param_classes.c b/tests/fixtures/c/volatile_param_classes.c new file mode 100644 index 000000000..b2aa1cddc --- /dev/null +++ b/tests/fixtures/c/volatile_param_classes.c @@ -0,0 +1,36 @@ +/* Volatile-qualified parameters must keep their band classification + (C99 6.7.3, 6.7.5.3): a `volatile double` still arrives in an FP + argument register, a `volatile float` keeps its narrow entry copy, + and the qualifier must not push either onto the integer path. */ +typedef struct Acc { + double sum; + long long cnt; +} Acc; + +static void step(volatile Acc *a, volatile double r) { + volatile double s = a->sum; + a->sum = s + r; +} + +static double half(volatile float f) { + return (double)f * 0.5; +} + +static void bump(Acc *a, double v) { + a->cnt++; + step(a, v); +} + +int main(void) { + Acc a = {0.0, 0}; + bump(&a, 1.5); + bump(&a, 2.5); + bump(&a, 3.5); + if (a.sum != 7.5 || a.cnt != 3) { + return 1; + } + if (half(5.0f) != 2.5) { + return 2; + } + return 0; +} diff --git a/tests/fixtures/c/volatile_ptr_alias_loop.c b/tests/fixtures/c/volatile_ptr_alias_loop.c new file mode 100644 index 000000000..5ced3d794 --- /dev/null +++ b/tests/fixtures/c/volatile_ptr_alias_loop.c @@ -0,0 +1,16 @@ +/* C99 6.7.3p6: a loop whose controlling expression reads a volatile + flag must re-read it on every iteration; the body writes the flag + through a pointer alias, so any cached read diverges. */ +int main(void) { + volatile int flag = 0; + volatile int *p = &flag; + int iters = 0; + while (flag < 3) { + *p = flag + 1; + iters++; + if (iters > 10) { + return 1; + } + } + return iters == 3 ? 0 : 2; +} diff --git a/tests/fixtures/c/volatile_setjmp_longjmp.c b/tests/fixtures/c/volatile_setjmp_longjmp.c new file mode 100644 index 000000000..691a51bf2 --- /dev/null +++ b/tests/fixtures/c/volatile_setjmp_longjmp.c @@ -0,0 +1,16 @@ +/* C99 7.13.2.1p3: after longjmp, a volatile-qualified auto object + modified between setjmp and longjmp keeps its last stored value. + The slot must stay memory-resident (no mem2reg promotion) so the + post-longjmp read observes the store. */ +#include + +static jmp_buf env; + +int main(void) { + volatile int x = 1; + if (setjmp(env) == 0) { + x = 2; + longjmp(env, 1); + } + return x == 2 ? 0 : 1; +} diff --git a/tests/fixtures/c/volatile_unused_read.c b/tests/fixtures/c/volatile_unused_read.c new file mode 100644 index 000000000..fa47203f9 --- /dev/null +++ b/tests/fixtures/c/volatile_unused_read.c @@ -0,0 +1,12 @@ +/* C99 5.1.2.3p2: reading a volatile object is a side effect; an + expression statement consisting of just that read still performs + the access at every optimization level. The values are checked + afterward so the program also exercises the load results. */ +volatile int ready = 5; + +int main(void) { + ready; + volatile int local = 7; + local; + return (ready == 5 && local == 7) ? 0 : 1; +} diff --git a/tests/snapshots/asm/aapcs64_variadic_host_abi.aarch64.asm b/tests/snapshots/asm/aapcs64_variadic_host_abi.aarch64.asm index 7d208c2ba..30bce799a 100644 --- a/tests/snapshots/asm/aapcs64_variadic_host_abi.aarch64.asm +++ b/tests/snapshots/asm/aapcs64_variadic_host_abi.aarch64.asm @@ -70,6 +70,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -149,6 +151,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x10 str w16, [x17, #0x1c] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -238,6 +242,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x10 str w16, [x17, #0x1c] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -258,6 +264,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -343,6 +351,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -372,6 +382,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -458,6 +470,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -477,6 +491,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -496,6 +512,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/aapcs64_variadic_host_abi.x64.asm b/tests/snapshots/asm/aapcs64_variadic_host_abi.x64.asm index b4a1d93c4..51d48992c 100644 --- a/tests/snapshots/asm/aapcs64_variadic_host_abi.x64.asm +++ b/tests/snapshots/asm/aapcs64_variadic_host_abi.x64.asm @@ -233,12 +233,14 @@ Disassembly of section .text: movq %r10, 0x10(%rax) leaq -0x30(%rbp), %rax leaq -0x18(%rbp), %rcx - movq (%rcx), %r10 - movq %r10, (%rax) - movq 0x8(%rcx), %r10 - movq %r10, 0x8(%rax) - movq 0x10(%rcx), %r10 - movq %r10, 0x10(%rax) + pushq %rdx + movq (%rcx), %rdx + movq %rdx, (%rax) + movq 0x8(%rcx), %rdx + movq %rdx, 0x8(%rax) + movq 0x10(%rcx), %rdx + movq %rdx, 0x10(%rax) + popq %rdx movq %rdx, %rax movslq %edx, %rcx movslq -0xf0(%rbp), %rsi @@ -570,3 +572,4 @@ Disassembly of section .text: jmp jmp jmp + addb %al, (%rax) diff --git a/tests/snapshots/asm/add_sub_negative_imm.aarch64.asm b/tests/snapshots/asm/add_sub_negative_imm.aarch64.asm index b77cf180b..7c8ae87b8 100644 --- a/tests/snapshots/asm/add_sub_negative_imm.aarch64.asm +++ b/tests/snapshots/asm/add_sub_negative_imm.aarch64.asm @@ -14,57 +14,66 @@ Disassembly of section .text: mov x29, sp sub sp, sp, #0x20 mov x0, #0xa // =10 - mov x1, #0x3e8 // =1000 - sub x2, x0, #0x5 - sxtw x2, w2 - cmp x2, #0x5 + stur w0, [x29, #-0x8] + mov x0, #0x3e8 // =1000 + stur x0, [x29, #-0x10] + ldursw x0, [x29, #-0x8] + sub x0, x0, #0x5 + sxtw x0, w0 + cmp x0, #0x5 b.eq mov x0, #0x1 // =1 add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 ret - sub x2, x0, #0xa - sxtw x2, w2 - cmp x2, #0x0 + ldursw x0, [x29, #-0x8] + sub x0, x0, #0xa + sxtw x0, w0 + cmp x0, #0x0 b.eq mov x0, #0x2 // =2 add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 ret - add x2, x0, #0x7 - sxtw x2, w2 - cmp x2, #0x11 + ldursw x0, [x29, #-0x8] + add x0, x0, #0x7 + sxtw x0, w0 + cmp x0, #0x11 b.eq mov x0, #0x3 // =3 add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 ret - sub x2, x1, #0x64 - cmp x2, #0x384 + ldur x0, [x29, #-0x10] + sub x0, x0, #0x64 + cmp x0, #0x384 b.eq mov x0, #0x4 // =4 add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 ret - add x1, x1, #0x64 - cmp x1, #0x44c + ldur x0, [x29, #-0x10] + add x0, x0, #0x64 + cmp x0, #0x44c b.eq mov x0, #0x5 // =5 add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 ret - sub x1, x0, #0xfff - sxtw x1, w1 + ldursw x0, [x29, #-0x8] + sub x0, x0, #0xfff + sxtw x0, w0 mov x17, #0xf00b // =61451 movk x17, #0xffff, lsl #16 movk x17, #0xffff, lsl #32 movk x17, #0xffff, lsl #48 - cmp x1, x17 + cmp x0, x17 b.eq mov x0, #0x6 // =6 add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 ret + ldursw x0, [x29, #-0x8] mov x17, #0xf000 // =61440 movk x17, #0xffff, lsl #16 movk x17, #0xffff, lsl #32 @@ -81,18 +90,21 @@ Disassembly of section .text: add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 ret - mov x2, #0x0 // =0 - mov x1, #0x5 // =5 - sxtw x0, w1 + mov x1, #0x0 // =0 + mov x0, #0x5 // =5 + stur w0, [x29, #-0x20] + ldursw x0, [x29, #-0x20] cmp x0, #0x0 b.le b - sxtw x0, w1 - sub x1, x0, #0x1 + ldursw x0, [x29, #-0x20] + sub x0, x0, #0x1 + stur w0, [x29, #-0x20] b - add x2, x2, x1 + ldursw x0, [x29, #-0x20] + add x1, x1, x0 b - sxtw x0, w2 + sxtw x0, w1 cmp x0, #0xf b.eq mov x0, #0x8 // =8 diff --git a/tests/snapshots/asm/add_sub_negative_imm.x64.asm b/tests/snapshots/asm/add_sub_negative_imm.x64.asm index c309e6399..d3ba4d596 100644 --- a/tests/snapshots/asm/add_sub_negative_imm.x64.asm +++ b/tests/snapshots/asm/add_sub_negative_imm.x64.asm @@ -15,53 +15,62 @@ Disassembly of section .text: movq %rsp, %rbp subq $0x20, %rsp movl $0xa, %eax - movl $0x3e8, %ecx # imm = 0x3E8 - leaq -0x5(%rax), %rdx - movslq %edx, %rdx - cmpq $0x5, %rdx + movl %eax, -0x8(%rbp) + movl $0x3e8, %eax # imm = 0x3E8 + movq %rax, -0x10(%rbp) + movslq -0x8(%rbp), %rax + addq $-0x5, %rax + movslq %eax, %rax + cmpq $0x5, %rax je movl $0x1, %eax addq $0x20, %rsp popq %rbp retq - leaq -0xa(%rax), %rdx - movslq %edx, %rdx - testq %rdx, %rdx + movslq -0x8(%rbp), %rax + addq $-0xa, %rax + movslq %eax, %rax + testq %rax, %rax je movl $0x2, %eax addq $0x20, %rsp popq %rbp retq - leaq 0x7(%rax), %rdx - movslq %edx, %rdx - cmpq $0x11, %rdx + movslq -0x8(%rbp), %rax + subq $-0x7, %rax + movslq %eax, %rax + cmpq $0x11, %rax je movl $0x3, %eax addq $0x20, %rsp popq %rbp retq - leaq -0x64(%rcx), %rdx - cmpq $0x384, %rdx # imm = 0x384 + movq -0x10(%rbp), %rax + addq $-0x64, %rax + cmpq $0x384, %rax # imm = 0x384 je movl $0x4, %eax addq $0x20, %rsp popq %rbp retq - subq $-0x64, %rcx - cmpq $0x44c, %rcx # imm = 0x44C + movq -0x10(%rbp), %rax + subq $-0x64, %rax + cmpq $0x44c, %rax # imm = 0x44C je movl $0x5, %eax addq $0x20, %rsp popq %rbp retq - leaq -0xfff(%rax), %rcx - movslq %ecx, %rcx - cmpq $-0xff5, %rcx # imm = 0xF00B + movslq -0x8(%rbp), %rax + addq $-0xfff, %rax # imm = 0xF001 + movslq %eax, %rax + cmpq $-0xff5, %rax # imm = 0xF00B je movl $0x6, %eax addq $0x20, %rsp popq %rbp retq + movslq -0x8(%rbp), %rax addq $-0x1000, %rax # imm = 0xF000 movslq %eax, %rax cmpq $-0xff6, %rax # imm = 0xF00A @@ -70,18 +79,21 @@ Disassembly of section .text: addq $0x20, %rsp popq %rbp retq - xorq %rdx, %rdx - movl $0x5, %ecx - movslq %ecx, %rax + xorq %rcx, %rcx + movl $0x5, %eax + movl %eax, -0x20(%rbp) + movslq -0x20(%rbp), %rax testq %rax, %rax jle jmp - movslq %ecx, %rax - leaq -0x1(%rax), %rcx + movslq -0x20(%rbp), %rax + decq %rax + movl %eax, -0x20(%rbp) jmp - addq %rcx, %rdx + movslq -0x20(%rbp), %rax + addq %rax, %rcx jmp - movslq %edx, %rax + movslq %ecx, %rax cmpq $0xf, %rax je movl $0x8, %eax @@ -92,3 +104,4 @@ Disassembly of section .text: addq $0x20, %rsp popq %rbp retq + addb %al, (%rax) diff --git a/tests/snapshots/asm/add_three_operand_lea.aarch64.asm b/tests/snapshots/asm/add_three_operand_lea.aarch64.asm index 5ce2abccb..a405ebb00 100644 --- a/tests/snapshots/asm/add_three_operand_lea.aarch64.asm +++ b/tests/snapshots/asm/add_three_operand_lea.aarch64.asm @@ -14,18 +14,27 @@ Disassembly of section .text: mov x29, sp sub sp, sp, #0x30 mov x0, #0x3 // =3 - mov x1, #0x4 // =4 - mov x2, #0x5 // =5 - add x3, x0, x1 - cmp x3, #0x7 + stur x0, [x29, #-0x8] + mov x0, #0x4 // =4 + stur x0, [x29, #-0x10] + mov x0, #0x5 // =5 + stur x0, [x29, #-0x18] + ldur x0, [x29, #-0x8] + ldur x1, [x29, #-0x10] + add x0, x0, x1 + cmp x0, #0x7 b.eq mov x0, #0x1 // =1 add sp, sp, #0x30 ldp x29, x30, [sp], #0x10 ret - add x3, x0, x1 - add x0, x0, x2 - add x0, x3, x0 + ldur x0, [x29, #-0x8] + ldur x1, [x29, #-0x10] + add x0, x0, x1 + ldur x1, [x29, #-0x8] + ldur x2, [x29, #-0x18] + add x1, x1, x2 + add x0, x0, x1 cmp x0, #0xf b.eq mov x0, #0x2 // =2 @@ -36,6 +45,9 @@ Disassembly of section .text: movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 + stur x0, [x29, #-0x8] + ldur x0, [x29, #-0x8] + ldur x1, [x29, #-0x10] add x0, x0, x1 mov x17, #0xffff // =65535 movk x17, #0xffff, lsl #16 @@ -49,7 +61,11 @@ Disassembly of section .text: ret mov x0, #0x9400 // =37888 movk x0, #0x7735, lsl #16 - add x0, x0, x0 + stur w0, [x29, #-0x20] + stur w0, [x29, #-0x28] + ldursw x0, [x29, #-0x20] + ldursw x1, [x29, #-0x28] + add x0, x0, x1 sxtw x0, w0 mov x17, #0x2800 // =10240 movk x17, #0xee6b, lsl #16 @@ -65,6 +81,8 @@ Disassembly of section .text: movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0x7fff, lsl #48 + stur x0, [x29, #-0x30] + ldur x0, [x29, #-0x30] add x0, x0, #0x1 mov x17, #-0x8000000000000000 // =-9223372036854775808 cmp x0, x17 diff --git a/tests/snapshots/asm/add_three_operand_lea.x64.asm b/tests/snapshots/asm/add_three_operand_lea.x64.asm index 3e941fcdf..cd09c7828 100644 --- a/tests/snapshots/asm/add_three_operand_lea.x64.asm +++ b/tests/snapshots/asm/add_three_operand_lea.x64.asm @@ -15,18 +15,27 @@ Disassembly of section .text: movq %rsp, %rbp subq $0x30, %rsp movl $0x3, %eax - movl $0x4, %ecx - movl $0x5, %edx - leaq (%rax,%rcx), %rsi - cmpq $0x7, %rsi + movq %rax, -0x8(%rbp) + movl $0x4, %eax + movq %rax, -0x10(%rbp) + movl $0x5, %eax + movq %rax, -0x18(%rbp) + movq -0x8(%rbp), %rax + movq -0x10(%rbp), %rcx + addq %rcx, %rax + cmpq $0x7, %rax je movl $0x1, %eax addq $0x30, %rsp popq %rbp retq - leaq (%rax,%rcx), %rsi - addq %rdx, %rax - addq %rsi, %rax + movq -0x8(%rbp), %rax + movq -0x10(%rbp), %rcx + addq %rcx, %rax + movq -0x8(%rbp), %rcx + movq -0x18(%rbp), %rdx + addq %rdx, %rcx + addq %rcx, %rax cmpq $0xf, %rax je movl $0x2, %eax @@ -34,6 +43,9 @@ Disassembly of section .text: popq %rbp retq movabsq $-0x5, %rax + movq %rax, -0x8(%rbp) + movq -0x8(%rbp), %rax + movq -0x10(%rbp), %rcx addq %rcx, %rax cmpq $-0x1, %rax je @@ -42,7 +54,11 @@ Disassembly of section .text: popq %rbp retq movl $0x77359400, %eax # imm = 0x77359400 - addq %rax, %rax + movl %eax, -0x20(%rbp) + movl %eax, -0x28(%rbp) + movslq -0x20(%rbp), %rax + movslq -0x28(%rbp), %rcx + addq %rcx, %rax movslq %eax, %rax cmpq $-0x1194d800, %rax # imm = 0xEE6B2800 je @@ -51,6 +67,8 @@ Disassembly of section .text: popq %rbp retq movabsq $0x7fffffffffffffff, %rax # imm = 0x7FFFFFFFFFFFFFFF + movq %rax, -0x30(%rbp) + movq -0x30(%rbp), %rax incq %rax movabsq $-0x8000000000000000, %r11 # imm = 0x8000000000000000 cmpq %r11, %rax diff --git a/tests/snapshots/asm/addr_of_intrinsic_math.aarch64.asm b/tests/snapshots/asm/addr_of_intrinsic_math.aarch64.asm index bd95c9314..9c7e1ab0f 100644 --- a/tests/snapshots/asm/addr_of_intrinsic_math.aarch64.asm +++ b/tests/snapshots/asm/addr_of_intrinsic_math.aarch64.asm @@ -32,9 +32,9 @@ Disassembly of section .text: mov x24, #0x400c000000000000 // =4615063718147915776 fmov d16, x24 fneg d0, d16 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -53,8 +53,8 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret mov x0, #0x4030000000000000 // =4625196817309499392 - mov x9, x20 str x0, [sp, #-0x10]! + mov x9, x20 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -77,8 +77,8 @@ Disassembly of section .text: movk x0, #0x9999, lsl #16 movk x0, #0x9999, lsl #32 movk x0, #0x4005, lsl #48 - mov x9, x21 str x0, [sp, #-0x10]! + mov x9, x21 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -101,8 +101,8 @@ Disassembly of section .text: movk x0, #0xcccc, lsl #16 movk x0, #0xcccc, lsl #32 movk x0, #0x4000, lsl #48 - mov x9, x22 str x0, [sp, #-0x10]! + mov x9, x22 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -125,8 +125,8 @@ Disassembly of section .text: movk x0, #0x3333, lsl #16 movk x0, #0x3333, lsl #32 movk x0, #0x4007, lsl #48 - mov x9, x23 str x0, [sp, #-0x10]! + mov x9, x23 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -161,9 +161,9 @@ Disassembly of section .text: mov x20, #0x4022000000000000 // =4621256167635550208 fmov d16, x20 fneg d0, d16 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -185,8 +185,8 @@ Disassembly of section .text: ldr x0, [x0, #0x8] mov x1, #0x400000000000 // =70368744177664 movk x1, #0x4054, lsl #48 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -211,8 +211,8 @@ Disassembly of section .text: movk x1, #0x9999, lsl #16 movk x1, #0x9999, lsl #32 movk x1, #0x4017, lsl #48 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/addr_of_intrinsic_math_float.aarch64.asm b/tests/snapshots/asm/addr_of_intrinsic_math_float.aarch64.asm index 4944046c5..aad4e05a0 100644 --- a/tests/snapshots/asm/addr_of_intrinsic_math_float.aarch64.asm +++ b/tests/snapshots/asm/addr_of_intrinsic_math_float.aarch64.asm @@ -30,9 +30,9 @@ Disassembly of section .text: mov x1, #0x4030000000000000 // =4625196817309499392 fmov d16, x1 fcvt s0, d16 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -58,9 +58,9 @@ Disassembly of section .text: movk x0, #0x4005, lsl #48 fmov d16, x0 fcvt s0, d16 - mov x9, x20 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x20 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -86,9 +86,9 @@ Disassembly of section .text: movk x0, #0x4000, lsl #48 fmov d16, x0 fcvt s0, d16 - mov x9, x21 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x21 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -114,9 +114,9 @@ Disassembly of section .text: movk x0, #0x4007, lsl #48 fmov d16, x0 fcvt s0, d16 - mov x9, x22 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x22 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -142,9 +142,9 @@ Disassembly of section .text: fmov d16, x20 fneg d0, d16 fcvt s0, d0 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -192,9 +192,9 @@ Disassembly of section .text: fcvt s9, d16 sub x0, x29, #0x40 ldr x0, [x0] - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -216,9 +216,9 @@ Disassembly of section .text: ret sub x0, x29, #0x40 ldr x0, [x0, #0x8] - mov x9, x0 fmov x16, d8 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -240,9 +240,9 @@ Disassembly of section .text: ret sub x0, x29, #0x40 ldr x0, [x0, #0x10] - mov x9, x0 fmov x16, d9 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/addr_of_libc_strcmp.aarch64.asm b/tests/snapshots/asm/addr_of_libc_strcmp.aarch64.asm index 69f0fdf2b..cb1b3934c 100644 --- a/tests/snapshots/asm/addr_of_libc_strcmp.aarch64.asm +++ b/tests/snapshots/asm/addr_of_libc_strcmp.aarch64.asm @@ -22,9 +22,9 @@ Disassembly of section .text: add x0, x0, adrp x1, add x1, x1, - mov x9, x20 str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -43,9 +43,9 @@ Disassembly of section .text: add x0, x0, adrp x1, add x1, x1, - mov x9, x20 str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -64,9 +64,9 @@ Disassembly of section .text: add x0, x0, adrp x1, add x1, x1, - mov x9, x20 str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -92,9 +92,9 @@ Disassembly of section .text: add x0, x0, adrp x1, add x1, x1, - mov x9, x20 str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/addr_of_libm_import.aarch64.asm b/tests/snapshots/asm/addr_of_libm_import.aarch64.asm index 7fbebd3dd..dff444c5b 100644 --- a/tests/snapshots/asm/addr_of_libm_import.aarch64.asm +++ b/tests/snapshots/asm/addr_of_libm_import.aarch64.asm @@ -24,8 +24,8 @@ Disassembly of section .text: adrp x21, add x21, x21, mov x22, #0x0 // =0 - mov x9, x0 str x22, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -42,8 +42,8 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret mov x0, #0x0 // =0 - mov x9, x20 str x0, [sp, #-0x10]! + mov x9, x20 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -62,9 +62,9 @@ Disassembly of section .text: ret mov x0, #0x4000000000000000 // =4611686018427387904 mov x1, #0x4024000000000000 // =4621819117588971520 - mov x9, x21 str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x21 ldr d0, [sp] ldr d1, [sp, #0x10] blr x9 @@ -94,8 +94,8 @@ Disassembly of section .text: sub x0, x29, #0x28 mov x20, #0x0 // =0 ldr x0, [x0] - mov x9, x0 str x20, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -114,8 +114,8 @@ Disassembly of section .text: sub x0, x29, #0x28 ldr x0, [x0, #0x8] mov x1, #0x0 // =0 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/anonymous_aggregates.aarch64.asm b/tests/snapshots/asm/anonymous_aggregates.aarch64.asm index 5b80184a4..28e97cff9 100644 --- a/tests/snapshots/asm/anonymous_aggregates.aarch64.asm +++ b/tests/snapshots/asm/anonymous_aggregates.aarch64.asm @@ -138,13 +138,12 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret sub x0, x29, #0x20 - add x0, x0, #0x8 mov x1, #0x851f // =34079 movk x1, #0x51eb, lsl #16 movk x1, #0x1eb8, lsl #32 movk x1, #0x4009, lsl #48 fmov d16, x1 - str d16, [x0] + str d16, [x0, #0x8] sub x0, x29, #0x20 ldrsw x0, [x0] cmp x0, #0x1 diff --git a/tests/snapshots/asm/anonymous_aggregates.x64.asm b/tests/snapshots/asm/anonymous_aggregates.x64.asm index 8debd04c3..83b4498a3 100644 --- a/tests/snapshots/asm/anonymous_aggregates.x64.asm +++ b/tests/snapshots/asm/anonymous_aggregates.x64.asm @@ -122,10 +122,9 @@ Disassembly of section .text: popq %rbp retq leaq -0x20(%rbp), %rax - addq $0x8, %rax movabsq $0x40091eb851eb851f, %rcx # imm = 0x40091EB851EB851F movq %rcx, %xmm14 - movsd %xmm14, (%rax,%riz) + movsd %xmm14, 0x8(%rax,%riz) leaq -0x20(%rbp), %rax movslq (%rax), %rax cmpq $0x1, %rax @@ -317,4 +316,3 @@ Disassembly of section .text: popq %rbp retq addb %al, (%rax) - addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/array_2d_struct_init.aarch64.asm b/tests/snapshots/asm/array_2d_struct_init.aarch64.asm index 81f417eeb..015cb4dde 100644 --- a/tests/snapshots/asm/array_2d_struct_init.aarch64.asm +++ b/tests/snapshots/asm/array_2d_struct_init.aarch64.asm @@ -21,8 +21,7 @@ Disassembly of section .text: fcmp d0, d1 cset x1, ne cbnz x1, - add x1, x0, #0x18 - ldr d0, [x1] + ldr d0, [x0, #0x18] mov x1, #0x4 // =4 scvtf d1, x1 fcmp d0, d1 @@ -31,8 +30,7 @@ Disassembly of section .text: cset x3, ne mov x2, #0x1 // =1 cbnz x3, - add x1, x0, #0x20 - ldr d0, [x1] + ldr d0, [x0, #0x20] mov x1, #0x5 // =5 scvtf d1, x1 fcmp d0, d1 @@ -40,8 +38,7 @@ Disassembly of section .text: cmp x1, #0x0 cset x2, ne cbnz x2, - add x0, x0, #0x38 - ldr d0, [x0] + ldr d0, [x0, #0x38] mov x0, #0x8 // =8 scvtf d1, x0 fcmp d0, d1 @@ -61,8 +58,7 @@ Disassembly of section .text: cbnz x0, adrp x0, add x0, x0, - add x0, x0, #0x78 - ldr d0, [x0] + ldr d0, [x0, #0x78] mov x0, #0x8 // =8 scvtf d1, x0 fcmp d0, d1 @@ -72,8 +68,7 @@ Disassembly of section .text: cbnz x2, adrp x0, add x0, x0, - add x0, x0, #0x50 - ldr d0, [x0] + ldr d0, [x0, #0x50] mov x0, #0x6 // =6 scvtf d1, x0 fcmp d0, d1 @@ -95,8 +90,7 @@ Disassembly of section .text: adrp x0, add x0, x0, mov x1, #0x10 // =16 - add x0, x0, #0x38 - ldr d0, [x0] + ldr d0, [x0, #0x38] scvtf d1, x1 fcmp d0, d1 cset x0, ne @@ -105,8 +99,7 @@ Disassembly of section .text: cbnz x2, adrp x0, add x0, x0, - add x0, x0, #0x10 - ldr d0, [x0] + ldr d0, [x0, #0x10] mov x0, #0xb // =11 scvtf d1, x0 fcmp d0, d1 diff --git a/tests/snapshots/asm/array_2d_struct_init.x64.asm b/tests/snapshots/asm/array_2d_struct_init.x64.asm index f7617676d..8f6592cee 100644 --- a/tests/snapshots/asm/array_2d_struct_init.x64.asm +++ b/tests/snapshots/asm/array_2d_struct_init.x64.asm @@ -26,8 +26,7 @@ Disassembly of section .text: orq %r10, %rcx testq %rcx, %rcx jne - leaq 0x18(%rax), %rcx - movsd (%rcx,%riz), %xmm0 + movsd 0x18(%rax,%riz), %xmm0 movl $0x4, %ecx cvtsi2sd %rcx, %xmm1 ucomisd %xmm1, %xmm0 @@ -42,8 +41,7 @@ Disassembly of section .text: movl $0x1, %edx testq %rsi, %rsi jne - leaq 0x20(%rax), %rcx - movsd (%rcx,%riz), %xmm0 + movsd 0x20(%rax,%riz), %xmm0 movl $0x5, %ecx cvtsi2sd %rcx, %xmm1 ucomisd %xmm1, %xmm0 @@ -57,8 +55,7 @@ Disassembly of section .text: movzbq %dl, %rdx testq %rdx, %rdx jne - addq $0x38, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x38(%rax,%riz), %xmm0 movl $0x8, %eax cvtsi2sd %rax, %xmm1 ucomisd %xmm1, %xmm0 @@ -86,8 +83,7 @@ Disassembly of section .text: testq %rax, %rax jne leaq , %rax - addq $0x78, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x78(%rax,%riz), %xmm0 movl $0x8, %eax cvtsi2sd %rax, %xmm1 ucomisd %xmm1, %xmm0 @@ -102,8 +98,7 @@ Disassembly of section .text: testq %rdx, %rdx jne leaq , %rax - addq $0x50, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x50(%rax,%riz), %xmm0 movl $0x6, %eax cvtsi2sd %rax, %xmm1 ucomisd %xmm1, %xmm0 @@ -133,8 +128,7 @@ Disassembly of section .text: jne leaq , %rax movl $0x10, %ecx - addq $0x38, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x38(%rax,%riz), %xmm0 cvtsi2sd %rcx, %xmm1 ucomisd %xmm1, %xmm0 setne %al @@ -148,8 +142,7 @@ Disassembly of section .text: testq %rdx, %rdx jne leaq , %rax - addq $0x10, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x10(%rax,%riz), %xmm0 movl $0xb, %eax cvtsi2sd %rax, %xmm1 ucomisd %xmm1, %xmm0 @@ -175,4 +168,4 @@ Disassembly of section .text: jmp jmp jmp - addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/atomic_operand_in_working_regs.aarch64.asm b/tests/snapshots/asm/atomic_operand_in_working_regs.aarch64.asm new file mode 100644 index 000000000..c1ab8d686 --- /dev/null +++ b/tests/snapshots/asm/atomic_operand_in_working_regs.aarch64.asm @@ -0,0 +1,113 @@ + +atomic_operand_in_working_regs.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x20 + mov x8, #0x64 // =100 + stur x8, [x29, #-0x8] + adrp x8, + add x8, x8, + sub x9, x29, #0x8 + mov x10, #0x5 // =5 + stp x9, x10, [sp, #-0x20]! + stp x11, x12, [sp, #0x10] + mov x9, x8 + ldr x10, [sp] + ldr x11, [sp, #0x8] + ldr x12, [x10] + ldaxr x16, [x9] + cmp x16, x12 + b.ne + stlxr w17, x11, [x9] + cbnz x17, + mov x16, #0x1 // =1 + b + str x16, [x10] + mov x16, #0x0 // =0 + ldp x11, x12, [sp, #0x10] + ldp x9, x10, [sp], #0x20 + mov x9, x16 + add x10, x0, x1 + stp x9, x10, [sp, #-0x20]! + stp x11, x12, [sp, #0x10] + mov x9, x8 + ldr x10, [sp, #0x8] + ldaxr x16, [x9] + add x11, x16, x10 + stlxr w12, x11, [x9] + cbnz x12, + ldp x11, x12, [sp, #0x10] + ldp x9, x10, [sp], #0x20 + mov x10, x16 + sxtw x9, w9 + cmp x9, #0x0 + b.eq + mov x0, #0x1 // =1 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + ldur x9, [x29, #-0x8] + cmp x9, #0x9 + b.eq + mov x0, #0x2 // =2 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + cmp x10, #0x9 + b.eq + mov x0, #0x3 // =3 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + ldr x8, [x8] + add x9, x0, #0x9 + add x9, x9, x1 + cmp x8, x9 + b.eq + mov x0, #0x4 // =4 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + add x0, x0, x1 + add x0, x0, x2 + add x0, x0, x3 + add x0, x0, x4 + add x0, x0, x5 + add x0, x0, x6 + add x0, x0, x7 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x50 + mov x0, #0x1 // =1 + mov x1, #0x2 // =2 + mov x2, #0x3 // =3 + mov x3, #0x4 // =4 + mov x4, #0x5 // =5 + mov x5, #0x6 // =6 + mov x6, #0x7 // =7 + mov x7, #0x8 // =8 + bl + cmp x0, #0x24 + b.ne + mov x1, #0x0 // =0 + b + sxtw x1, w0 + mov x0, x1 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/atomic_operand_in_working_regs.x64.asm b/tests/snapshots/asm/atomic_operand_in_working_regs.x64.asm new file mode 100644 index 000000000..2c8e49c7d --- /dev/null +++ b/tests/snapshots/asm/atomic_operand_in_working_regs.x64.asm @@ -0,0 +1,158 @@ + +atomic_operand_in_working_regs.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + popq %r10 + subq $0x80, %rsp + movq 0x80(%rsp), %rax + movq %rax, 0x60(%rsp) + movq 0x88(%rsp), %rax + movq %rax, 0x70(%rsp) + pushq %r10 + pushq %rbp + movq %rsp, %rbp + subq $0x40, %rsp + movq %rbx, (%rsp) + movq %r12, 0x8(%rsp) + movq %r13, 0x10(%rsp) + movl $0x64, %eax + movq %rax, -0x8(%rbp) + leaq , %rax + leaq -0x8(%rbp), %rbx + movl $0x5, %r12d + pushq %rax + pushq %rcx + movq %rax, %r11 + movq %r12, %r10 + movq %rbx, %rcx + movq (%rcx), %rax + lock + cmpxchgq %r10, (%r11) + je + movq %rax, (%rcx) + sete %r11b + movzbq %r11b, %r11 + popq %rcx + popq %rax + movq %r11, %rbx + leaq (%rdi,%rsi), %r12 + pushq %rax + movq %rax, %r11 + movq %r12, %r10 + movq %r10, %rax + lock + xaddq %rax, (%r11) + movq %rax, %r10 + popq %rax + movq %r10, %r12 + movslq %ebx, %rbx + testq %rbx, %rbx + je + movl $0x1, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x40, %rsp + popq %rbp + popq %r11 + addq $0x80, %rsp + pushq %r11 + retq + movq -0x8(%rbp), %rbx + cmpq $0x9, %rbx + je + movl $0x2, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x40, %rsp + popq %rbp + popq %r11 + addq $0x80, %rsp + pushq %r11 + retq + cmpq $0x9, %r12 + je + movl $0x3, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x40, %rsp + popq %rbp + popq %r11 + addq $0x80, %rsp + pushq %r11 + retq + movq (%rax), %rax + leaq 0x9(%rdi), %rbx + addq %rsi, %rbx + cmpq %rbx, %rax + je + movl $0x4, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x40, %rsp + popq %rbp + popq %r11 + addq $0x80, %rsp + pushq %r11 + retq + leaq (%rdi,%rsi), %rax + addq %rdx, %rax + addq %rcx, %rax + addq %r8, %rax + addq %r9, %rax + movq 0x70(%rbp), %rcx + addq %rcx, %rax + movq 0x80(%rbp), %rcx + addq %rcx, %rax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x40, %rsp + popq %rbp + popq %r11 + addq $0x80, %rsp + pushq %r11 + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x60, %rsp + movq %rbx, (%rsp) + movl $0x1, %edi + movl $0x2, %esi + movl $0x3, %edx + movl $0x4, %ecx + movl $0x5, %r8d + movl $0x6, %r9d + movl $0x7, %eax + movl $0x8, %ebx + subq $0x10, %rsp + movq %rax, (%rsp) + movq %rbx, 0x8(%rsp) + callq + addq $0x10, %rsp + cmpq $0x24, %rax + jne + xorq %rcx, %rcx + jmp + movslq %eax, %rcx + movq (%rsp), %rbx + movq %rcx, %rax + addq $0x60, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/bitwise_not_mvn.aarch64.asm b/tests/snapshots/asm/bitwise_not_mvn.aarch64.asm index 6d26a7082..d48ea59ba 100644 --- a/tests/snapshots/asm/bitwise_not_mvn.aarch64.asm +++ b/tests/snapshots/asm/bitwise_not_mvn.aarch64.asm @@ -33,47 +33,65 @@ Disassembly of section .text: movk x0, #0x89ab, lsl #16 movk x0, #0x4567, lsl #32 movk x0, #0x123, lsl #48 - mov x1, #0x3210 // =12816 - movk x1, #0x7654, lsl #16 - movk x1, #0xba98, lsl #32 - movk x1, #0xfedc, lsl #48 - mov x2, #0x5555 // =21845 - movk x2, #0xaaaa, lsl #16 - movk x2, #0x5555, lsl #32 - movk x2, #0xaaaa, lsl #48 - mvn x3, x0 - mvn x4, x0 - cmp x3, x4 + stur x0, [x29, #-0x8] + mov x0, #0x3210 // =12816 + movk x0, #0x7654, lsl #16 + movk x0, #0xba98, lsl #32 + movk x0, #0xfedc, lsl #48 + stur x0, [x29, #-0x10] + mov x0, #0x5555 // =21845 + movk x0, #0xaaaa, lsl #16 + movk x0, #0x5555, lsl #32 + movk x0, #0xaaaa, lsl #48 + stur x0, [x29, #-0x18] + ldur x0, [x29, #-0x8] + mvn x0, x0 + ldur x1, [x29, #-0x8] + mvn x1, x1 + cmp x0, x1 b.eq mov x0, #0x1 // =1 add sp, sp, #0x30 ldp x29, x30, [sp], #0x10 ret - mvn x3, x0 - and x3, x3, x1 - mvn x4, x0 - and x4, x4, x1 - cmp x3, x4 + ldur x0, [x29, #-0x8] + ldur x1, [x29, #-0x10] + mvn x0, x0 + and x0, x0, x1 + ldur x1, [x29, #-0x8] + mvn x1, x1 + ldur x2, [x29, #-0x10] + and x1, x1, x2 + cmp x0, x1 b.eq mov x0, #0x2 // =2 add sp, sp, #0x30 ldp x29, x30, [sp], #0x10 ret - and x3, x0, x1 - mvn x4, x0 - and x4, x4, x2 - eor x3, x3, x4 + ldur x0, [x29, #-0x8] + ldur x1, [x29, #-0x10] + ldur x2, [x29, #-0x18] and x1, x0, x1 mvn x0, x0 and x0, x0, x2 eor x0, x1, x0 - cmp x3, x0 + ldur x1, [x29, #-0x8] + ldur x2, [x29, #-0x10] + and x1, x1, x2 + ldur x2, [x29, #-0x8] + mvn x2, x2 + ldur x3, [x29, #-0x18] + and x2, x2, x3 + eor x1, x1, x2 + cmp x0, x1 b.eq mov x0, #0x3 // =3 add sp, sp, #0x30 ldp x29, x30, [sp], #0x10 ret mov x0, #0x0 // =0 + stur x0, [x29, #-0x8] + ldur x0, [x29, #-0x8] mvn x0, x0 mov x17, #0xffff // =65535 movk x17, #0xffff, lsl #16 @@ -89,6 +107,8 @@ Disassembly of section .text: movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 + stur x0, [x29, #-0x8] + ldur x0, [x29, #-0x8] mvn x0, x0 cmp x0, #0x0 b.eq diff --git a/tests/snapshots/asm/bitwise_not_mvn.x64.asm b/tests/snapshots/asm/bitwise_not_mvn.x64.asm index fcf40fa4a..0757f43cc 100644 --- a/tests/snapshots/asm/bitwise_not_mvn.x64.asm +++ b/tests/snapshots/asm/bitwise_not_mvn.x64.asm @@ -35,47 +35,59 @@ Disassembly of section .text: movq %rsp, %rbp subq $0x30, %rsp movabsq $0x123456789abcdef, %rax # imm = 0x123456789ABCDEF - movabsq $-0x123456789abcdf0, %rcx # imm = 0xFEDCBA9876543210 - movabsq $-0x5555aaaa5555aaab, %rdx # imm = 0xAAAA5555AAAA5555 - movq %rax, %rsi - xorq $-0x1, %rsi - movq %rax, %rdi - xorq $-0x1, %rdi - cmpq %rdi, %rsi + movq %rax, -0x8(%rbp) + movabsq $-0x123456789abcdf0, %rax # imm = 0xFEDCBA9876543210 + movq %rax, -0x10(%rbp) + movabsq $-0x5555aaaa5555aaab, %rax # imm = 0xAAAA5555AAAA5555 + movq %rax, -0x18(%rbp) + movq -0x8(%rbp), %rax + xorq $-0x1, %rax + movq -0x8(%rbp), %rcx + xorq $-0x1, %rcx + cmpq %rcx, %rax je movl $0x1, %eax addq $0x30, %rsp popq %rbp retq - movq %rax, %rsi - xorq $-0x1, %rsi - andq %rcx, %rsi - movq %rax, %rdi - xorq $-0x1, %rdi - andq %rcx, %rdi - cmpq %rdi, %rsi + movq -0x8(%rbp), %rax + movq -0x10(%rbp), %rcx + xorq $-0x1, %rax + andq %rcx, %rax + movq -0x8(%rbp), %rcx + xorq $-0x1, %rcx + movq -0x10(%rbp), %rdx + andq %rdx, %rcx + cmpq %rcx, %rax je movl $0x2, %eax addq $0x30, %rsp popq %rbp retq - movq %rax, %rsi - andq %rcx, %rsi - movq %rax, %rdi - xorq $-0x1, %rdi - andq %rdx, %rdi - xorq %rdi, %rsi + movq -0x8(%rbp), %rax + movq -0x10(%rbp), %rcx + movq -0x18(%rbp), %rdx andq %rax, %rcx xorq $-0x1, %rax andq %rdx, %rax xorq %rcx, %rax - cmpq %rax, %rsi + movq -0x8(%rbp), %rcx + movq -0x10(%rbp), %rdx + andq %rdx, %rcx + movq -0x8(%rbp), %rdx + xorq $-0x1, %rdx + movq -0x18(%rbp), %rsi + andq %rsi, %rdx + xorq %rdx, %rcx + cmpq %rcx, %rax je movl $0x3, %eax addq $0x30, %rsp popq %rbp retq xorq %rax, %rax + movq %rax, -0x8(%rbp) + movq -0x8(%rbp), %rax xorq $-0x1, %rax cmpq $-0x1, %rax je @@ -84,6 +96,8 @@ Disassembly of section .text: popq %rbp retq movabsq $-0x1, %rax + movq %rax, -0x8(%rbp) + movq -0x8(%rbp), %rax xorq $-0x1, %rax testq %rax, %rax je @@ -95,4 +109,5 @@ Disassembly of section .text: addq $0x30, %rsp popq %rbp retq + addb %al, (%rax) addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/block_scope_typedef_variadic_fnptr.aarch64.asm b/tests/snapshots/asm/block_scope_typedef_variadic_fnptr.aarch64.asm new file mode 100644 index 000000000..2cff6e648 --- /dev/null +++ b/tests/snapshots/asm/block_scope_typedef_variadic_fnptr.aarch64.asm @@ -0,0 +1,51 @@ + +block_scope_typedef_variadic_fnptr.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x2b0 // =688 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x80 + str x19, [sp] + sub x0, x29, #0x40 + mov x1, #0x0 // =0 + strb w1, [x0] + sub x0, x29, #0x40 + mov x1, #0x40 // =64 + adrp x2, + add x2, x2, + mov x3, #0x7 // =7 + adrp x4, + add x4, x4, + adrp x5, + add x5, x5, + ldr x5, [x5] + mov x9, x5 + blr x9 + sub x0, x29, #0x40 + adrp x1, + add x1, x1, + bl + sxtw x0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x1 // =1 + ldr x19, [sp] + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x19, [sp] + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + +<__c5_sys_snprintf>: + b diff --git a/tests/snapshots/asm/block_scope_typedef_variadic_fnptr.x64.asm b/tests/snapshots/asm/block_scope_typedef_variadic_fnptr.x64.asm new file mode 100644 index 000000000..004f67e9e --- /dev/null +++ b/tests/snapshots/asm/block_scope_typedef_variadic_fnptr.x64.asm @@ -0,0 +1,47 @@ + +block_scope_typedef_variadic_fnptr.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x70, %rsp + leaq -0x40(%rbp), %rax + xorq %rcx, %rcx + movb %cl, (%rax) + leaq -0x40(%rbp), %rdi + movl $0x40, %esi + leaq , %rdx + movl $0x7, %ecx + leaq , %r8 + leaq , %rax + movq (%rax), %rax + movq %rax, %r9 + movb $0x0, %al + callq *%r9 + leaq -0x40(%rbp), %rdi + leaq , %rsi + xorl %eax, %eax + callq + movslq %eax, %rax + testq %rax, %rax + je + movl $0x1, %eax + addq $0x70, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x70, %rsp + popq %rbp + retq + +<__c5_sys_snprintf>: + jmp diff --git a/tests/snapshots/asm/builtin_bit_count.aarch64.asm b/tests/snapshots/asm/builtin_bit_count.aarch64.asm index f5fa3feab..087096912 100644 --- a/tests/snapshots/asm/builtin_bit_count.aarch64.asm +++ b/tests/snapshots/asm/builtin_bit_count.aarch64.asm @@ -947,89 +947,93 @@ Disassembly of section .text: ret mov x0, #0xff // =255 movk x0, #0xff, lsl #16 + stur w0, [x29, #-0x8] + ldur w0, [x29, #-0x8] lsr x1, x0, #1 mov x17, #0x5555 // =21845 movk x17, #0x5555, lsl #16 and x1, x1, x17 - sub x1, x0, x1 + sub x0, x0, x1 mov x17, #0x3333 // =13107 movk x17, #0x3333, lsl #16 - and x2, x1, x17 - lsr x1, x1, #2 + and x1, x0, x17 + lsr x0, x0, #2 mov x17, #0x3333 // =13107 movk x17, #0x3333, lsl #16 - and x1, x1, x17 - add x1, x2, x1 - lsr x2, x1, #4 - add x1, x1, x2 + and x0, x0, x17 + add x0, x1, x0 + lsr x1, x0, #4 + add x0, x0, x1 mov x17, #0xf0f // =3855 movk x17, #0xf0f, lsl #16 - and x1, x1, x17 - lsr x2, x1, #8 - add x1, x1, x2 - lsr x2, x1, #16 - add x1, x1, x2 + and x0, x0, x17 + lsr x1, x0, #8 + add x0, x0, x1 + lsr x1, x0, #16 + add x0, x0, x1 mov x17, #0x7f // =127 - and x1, x1, x17 - mov x2, #0x10 // =16 + and x0, x0, x17 + mov x1, #0x10 // =16 + sxtw x0, w0 sxtw x1, w1 - sxtw x2, w2 - cmp x1, x2 - cset x1, eq - cmp x1, #0x0 + cmp x0, x1 + cset x0, eq + cmp x0, #0x0 b.ne mov x0, #0x15 // =21 add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 ret + ldur w0, [x29, #-0x8] + lsr x1, x0, #1 + orr x0, x0, x1 + lsr x1, x0, #2 + orr x0, x0, x1 + lsr x1, x0, #4 + orr x0, x0, x1 + lsr x1, x0, #8 + orr x0, x0, x1 + lsr x1, x0, #16 + orr x0, x0, x1 + mov w0, w0 lsr x1, x0, #1 - orr x1, x0, x1 - lsr x2, x1, #2 - orr x1, x1, x2 - lsr x2, x1, #4 - orr x1, x1, x2 - lsr x2, x1, #8 - orr x1, x1, x2 - lsr x2, x1, #16 - orr x1, x1, x2 - mov w1, w1 - lsr x2, x1, #1 mov x17, #0x5555 // =21845 movk x17, #0x5555, lsl #16 - and x2, x2, x17 - sub x1, x1, x2 + and x1, x1, x17 + sub x0, x0, x1 mov x17, #0x3333 // =13107 movk x17, #0x3333, lsl #16 - and x2, x1, x17 - lsr x1, x1, #2 + and x1, x0, x17 + lsr x0, x0, #2 mov x17, #0x3333 // =13107 movk x17, #0x3333, lsl #16 - and x1, x1, x17 - add x1, x2, x1 - lsr x2, x1, #4 - add x1, x1, x2 + and x0, x0, x17 + add x0, x1, x0 + lsr x1, x0, #4 + add x0, x0, x1 mov x17, #0xf0f // =3855 movk x17, #0xf0f, lsl #16 - and x1, x1, x17 - lsr x2, x1, #8 - add x1, x1, x2 - lsr x2, x1, #16 - add x1, x1, x2 + and x0, x0, x17 + lsr x1, x0, #8 + add x0, x0, x1 + lsr x1, x0, #16 + add x0, x0, x1 mov x17, #0x7f // =127 - and x1, x1, x17 - mov x2, #0x20 // =32 - sub x1, x2, x1 - mov x2, #0x8 // =8 + and x0, x0, x17 + mov x1, #0x20 // =32 + sub x0, x1, x0 + mov x1, #0x8 // =8 + sxtw x0, w0 sxtw x1, w1 - sxtw x2, w2 - cmp x1, x2 - cset x1, eq - cmp x1, #0x0 + cmp x0, x1 + cset x0, eq + cmp x0, #0x0 b.ne mov x0, #0x16 // =22 add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 ret + ldur w0, [x29, #-0x8] sub x1, x0, #0x1 mvn x0, x0 and x0, x1, x0 @@ -1256,51 +1260,54 @@ Disassembly of section .text: ret mov x0, #0xff // =255 movk x0, #0xff, lsl #16 + stur x0, [x29, #-0x10] + ldur x0, [x29, #-0x10] lsr x1, x0, #1 mov x17, #0x5555 // =21845 movk x17, #0x5555, lsl #16 movk x17, #0x5555, lsl #32 movk x17, #0x5555, lsl #48 and x1, x1, x17 - sub x1, x0, x1 + sub x0, x0, x1 mov x17, #0x3333 // =13107 movk x17, #0x3333, lsl #16 movk x17, #0x3333, lsl #32 movk x17, #0x3333, lsl #48 - and x2, x1, x17 - lsr x1, x1, #2 + and x1, x0, x17 + lsr x0, x0, #2 mov x17, #0x3333 // =13107 movk x17, #0x3333, lsl #16 movk x17, #0x3333, lsl #32 movk x17, #0x3333, lsl #48 - and x1, x1, x17 - add x1, x2, x1 - lsr x2, x1, #4 - add x1, x1, x2 + and x0, x0, x17 + add x0, x1, x0 + lsr x1, x0, #4 + add x0, x0, x1 mov x17, #0xf0f // =3855 movk x17, #0xf0f, lsl #16 movk x17, #0xf0f, lsl #32 movk x17, #0xf0f, lsl #48 - and x1, x1, x17 - lsr x2, x1, #8 - add x1, x1, x2 - lsr x2, x1, #16 - add x1, x1, x2 - lsr x2, x1, #32 - add x1, x1, x2 + and x0, x0, x17 + lsr x1, x0, #8 + add x0, x0, x1 + lsr x1, x0, #16 + add x0, x0, x1 + lsr x1, x0, #32 + add x0, x0, x1 mov x17, #0x7f // =127 - and x1, x1, x17 - mov x2, #0x10 // =16 + and x0, x0, x17 + mov x1, #0x10 // =16 + sxtw x0, w0 sxtw x1, w1 - sxtw x2, w2 - cmp x1, x2 - cset x1, eq - cmp x1, #0x0 + cmp x0, x1 + cset x0, eq + cmp x0, #0x0 b.ne mov x0, #0x1c // =28 add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 ret + ldur x0, [x29, #-0x10] sub x1, x0, #0x1 mvn x0, x0 and x0, x1, x0 diff --git a/tests/snapshots/asm/builtin_bit_count.x64.asm b/tests/snapshots/asm/builtin_bit_count.x64.asm index ab0c9b501..e987812b2 100644 --- a/tests/snapshots/asm/builtin_bit_count.x64.asm +++ b/tests/snapshots/asm/builtin_bit_count.x64.asm @@ -870,92 +870,94 @@ Disassembly of section .text: popq %rbp retq movl $0xff00ff, %eax # imm = 0xFF00FF + movl %eax, -0x8(%rbp) + movl -0x8(%rbp), %eax movq %rax, %rcx shrq $0x1, %rcx andq $0x55555555, %rcx # imm = 0x55555555 - movq %rcx, %r10 + subq %rcx, %rax movq %rax, %rcx - subq %r10, %rcx - movq %rcx, %rdx - andq $0x33333333, %rdx # imm = 0x33333333 - shrq $0x2, %rcx andq $0x33333333, %rcx # imm = 0x33333333 - addq %rdx, %rcx - movq %rcx, %rdx - shrq $0x4, %rdx - addq %rdx, %rcx - andq $0xf0f0f0f, %rcx # imm = 0xF0F0F0F - movq %rcx, %rdx - shrq $0x8, %rdx - addq %rdx, %rcx - movq %rcx, %rdx - shrq $0x10, %rdx - addq %rdx, %rcx - andq $0x7f, %rcx - movl $0x10, %edx + shrq $0x2, %rax + andq $0x33333333, %rax # imm = 0x33333333 + addq %rcx, %rax + movq %rax, %rcx + shrq $0x4, %rcx + addq %rcx, %rax + andq $0xf0f0f0f, %rax # imm = 0xF0F0F0F + movq %rax, %rcx + shrq $0x8, %rcx + addq %rcx, %rax + movq %rax, %rcx + shrq $0x10, %rcx + addq %rcx, %rax + andq $0x7f, %rax + movl $0x10, %ecx + movslq %eax, %rax movslq %ecx, %rcx - movslq %edx, %rdx - cmpq %rdx, %rcx - sete %cl - movzbq %cl, %rcx - testq %rcx, %rcx + cmpq %rcx, %rax + sete %al + movzbq %al, %rax + testq %rax, %rax jne movl $0x15, %eax addq $0x20, %rsp popq %rbp retq + movl -0x8(%rbp), %eax movq %rax, %rcx shrq $0x1, %rcx - orq %rax, %rcx - movq %rcx, %rdx - shrq $0x2, %rdx - orq %rdx, %rcx - movq %rcx, %rdx - shrq $0x4, %rdx - orq %rdx, %rcx - movq %rcx, %rdx - shrq $0x8, %rdx - orq %rdx, %rcx - movq %rcx, %rdx - shrq $0x10, %rdx - orq %rdx, %rcx - movl %ecx, %ecx - movq %rcx, %rdx - shrq $0x1, %rdx - andq $0x55555555, %rdx # imm = 0x55555555 - subq %rdx, %rcx - movq %rcx, %rdx - andq $0x33333333, %rdx # imm = 0x33333333 + orq %rcx, %rax + movq %rax, %rcx shrq $0x2, %rcx + orq %rcx, %rax + movq %rax, %rcx + shrq $0x4, %rcx + orq %rcx, %rax + movq %rax, %rcx + shrq $0x8, %rcx + orq %rcx, %rax + movq %rax, %rcx + shrq $0x10, %rcx + orq %rcx, %rax + movl %eax, %eax + movq %rax, %rcx + shrq $0x1, %rcx + andq $0x55555555, %rcx # imm = 0x55555555 + subq %rcx, %rax + movq %rax, %rcx andq $0x33333333, %rcx # imm = 0x33333333 - addq %rdx, %rcx - movq %rcx, %rdx - shrq $0x4, %rdx - addq %rdx, %rcx - andq $0xf0f0f0f, %rcx # imm = 0xF0F0F0F - movq %rcx, %rdx - shrq $0x8, %rdx - addq %rdx, %rcx - movq %rcx, %rdx - shrq $0x10, %rdx - addq %rdx, %rcx - andq $0x7f, %rcx - movl $0x20, %edx - movq %rcx, %r10 - movq %rdx, %rcx - subq %r10, %rcx - movl $0x8, %edx + shrq $0x2, %rax + andq $0x33333333, %rax # imm = 0x33333333 + addq %rcx, %rax + movq %rax, %rcx + shrq $0x4, %rcx + addq %rcx, %rax + andq $0xf0f0f0f, %rax # imm = 0xF0F0F0F + movq %rax, %rcx + shrq $0x8, %rcx + addq %rcx, %rax + movq %rax, %rcx + shrq $0x10, %rcx + addq %rcx, %rax + andq $0x7f, %rax + movl $0x20, %ecx + movq %rax, %r10 + movq %rcx, %rax + subq %r10, %rax + movl $0x8, %ecx + movslq %eax, %rax movslq %ecx, %rcx - movslq %edx, %rdx - cmpq %rdx, %rcx - sete %cl - movzbq %cl, %rcx - testq %rcx, %rcx + cmpq %rcx, %rax + sete %al + movzbq %al, %rax + testq %rax, %rax jne movl $0x16, %eax addq $0x20, %rsp popq %rbp retq + movl -0x8(%rbp), %eax leaq -0x1(%rax), %rcx xorq $-0x1, %rax andq %rcx, %rax @@ -1146,46 +1148,47 @@ Disassembly of section .text: popq %rbp retq movl $0xff00ff, %eax # imm = 0xFF00FF + movq %rax, -0x10(%rbp) + movq -0x10(%rbp), %rax movq %rax, %rcx shrq $0x1, %rcx movabsq $0x5555555555555555, %r11 # imm = 0x5555555555555555 andq %r11, %rcx - movq %rcx, %r10 - movq %rax, %rcx - subq %r10, %rcx - movabsq $0x3333333333333333, %rdx # imm = 0x3333333333333333 - andq %rcx, %rdx - shrq $0x2, %rcx + subq %rcx, %rax + movabsq $0x3333333333333333, %rcx # imm = 0x3333333333333333 + andq %rax, %rcx + shrq $0x2, %rax movabsq $0x3333333333333333, %r11 # imm = 0x3333333333333333 - andq %r11, %rcx - addq %rdx, %rcx - movq %rcx, %rdx - shrq $0x4, %rdx - addq %rdx, %rcx + andq %r11, %rax + addq %rcx, %rax + movq %rax, %rcx + shrq $0x4, %rcx + addq %rcx, %rax movabsq $0xf0f0f0f0f0f0f0f, %r11 # imm = 0xF0F0F0F0F0F0F0F - andq %r11, %rcx - movq %rcx, %rdx - shrq $0x8, %rdx - addq %rdx, %rcx - movq %rcx, %rdx - shrq $0x10, %rdx - addq %rdx, %rcx - movq %rcx, %rdx - shrq $0x20, %rdx - addq %rdx, %rcx - andq $0x7f, %rcx - movl $0x10, %edx + andq %r11, %rax + movq %rax, %rcx + shrq $0x8, %rcx + addq %rcx, %rax + movq %rax, %rcx + shrq $0x10, %rcx + addq %rcx, %rax + movq %rax, %rcx + shrq $0x20, %rcx + addq %rcx, %rax + andq $0x7f, %rax + movl $0x10, %ecx + movslq %eax, %rax movslq %ecx, %rcx - movslq %edx, %rdx - cmpq %rdx, %rcx - sete %cl - movzbq %cl, %rcx - testq %rcx, %rcx + cmpq %rcx, %rax + sete %al + movzbq %al, %rax + testq %rax, %rax jne movl $0x1c, %eax addq $0x20, %rsp popq %rbp retq + movq -0x10(%rbp), %rax leaq -0x1(%rax), %rcx xorq $-0x1, %rax andq %rcx, %rax diff --git a/tests/snapshots/asm/builtin_bswap_expect.aarch64.asm b/tests/snapshots/asm/builtin_bswap_expect.aarch64.asm index 8a8297ee6..367f9a005 100644 --- a/tests/snapshots/asm/builtin_bswap_expect.aarch64.asm +++ b/tests/snapshots/asm/builtin_bswap_expect.aarch64.asm @@ -68,6 +68,8 @@ Disassembly of section .text: ret mov x0, #0xccdd // =52445 movk x0, #0xaabb, lsl #16 + stur w0, [x29, #-0x8] + ldur w0, [x29, #-0x8] mov x17, #0xff // =255 and x1, x0, x17 lsl x1, x1, #24 diff --git a/tests/snapshots/asm/builtin_bswap_expect.x64.asm b/tests/snapshots/asm/builtin_bswap_expect.x64.asm index b39218345..498a282dd 100644 --- a/tests/snapshots/asm/builtin_bswap_expect.x64.asm +++ b/tests/snapshots/asm/builtin_bswap_expect.x64.asm @@ -59,6 +59,8 @@ Disassembly of section .text: popq %rbp retq movl $0xaabbccdd, %eax # imm = 0xAABBCCDD + movl %eax, -0x8(%rbp) + movl -0x8(%rbp), %eax movq %rax, %rcx andq $0xff, %rcx shlq $0x18, %rcx @@ -105,4 +107,3 @@ Disassembly of section .text: addq $0x10, %rsp popq %rbp retq - addb %al, (%rax) diff --git a/tests/snapshots/asm/c11_atomic_specifier.aarch64.asm b/tests/snapshots/asm/c11_atomic_specifier.aarch64.asm index fb52d410b..b5455bdb1 100644 --- a/tests/snapshots/asm/c11_atomic_specifier.aarch64.asm +++ b/tests/snapshots/asm/c11_atomic_specifier.aarch64.asm @@ -89,12 +89,13 @@ Disassembly of section .text: stur w0, [x29, #-0x30] mov x0, #0x63 // =99 mov x1, #0xd // =13 - ldursw x2, [x29, #-0x30] + sturh w1, [x29, #-0x40] + ldursw x1, [x29, #-0x30] mov x17, #0xfff9 // =65529 movk x17, #0xffff, lsl #16 movk x17, #0xffff, lsl #32 movk x17, #0xffff, lsl #48 - cmp x2, x17 + cmp x1, x17 b.eq mov x0, #0x7 // =7 add sp, sp, #0x50 @@ -106,7 +107,8 @@ Disassembly of section .text: add sp, sp, #0x50 ldp x29, x30, [sp], #0x10 ret - cmp x1, #0xd + ldursh x0, [x29, #-0x40] + cmp x0, #0xd b.eq mov x0, #0x9 // =9 add sp, sp, #0x50 diff --git a/tests/snapshots/asm/c11_atomic_specifier.x64.asm b/tests/snapshots/asm/c11_atomic_specifier.x64.asm index 99bf6b633..5363dbf32 100644 --- a/tests/snapshots/asm/c11_atomic_specifier.x64.asm +++ b/tests/snapshots/asm/c11_atomic_specifier.x64.asm @@ -75,8 +75,9 @@ Disassembly of section .text: movl %eax, -0x30(%rbp) movl $0x63, %eax movl $0xd, %ecx - movslq -0x30(%rbp), %rdx - cmpq $-0x7, %rdx + movw %cx, -0x40(%rbp) + movslq -0x30(%rbp), %rcx + cmpq $-0x7, %rcx je movl $0x7, %eax addq $0x50, %rsp @@ -88,7 +89,8 @@ Disassembly of section .text: addq $0x50, %rsp popq %rbp retq - cmpq $0xd, %rcx + movswq -0x40(%rbp), %rax + cmpq $0xd, %rax je movl $0x9, %eax addq $0x50, %rsp @@ -108,4 +110,3 @@ Disassembly of section .text: addq $0x50, %rsp popq %rbp retq - addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/call_indirect_target_scratch_collision.aarch64.asm b/tests/snapshots/asm/call_indirect_target_scratch_collision.aarch64.asm index fb26a5adc..f80c2f024 100644 --- a/tests/snapshots/asm/call_indirect_target_scratch_collision.aarch64.asm +++ b/tests/snapshots/asm/call_indirect_target_scratch_collision.aarch64.asm @@ -25,12 +25,12 @@ Disassembly of section .text: ldr x5, [x0] mov x17, #0xffff // =65535 and x3, x3, x17 - mov x9, x5 str x4, [sp, #-0x10]! str x3, [sp, #-0x10]! str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x5 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] diff --git a/tests/snapshots/asm/call_sp_adjust_imm12_overflow.aarch64.asm b/tests/snapshots/asm/call_sp_adjust_imm12_overflow.aarch64.asm new file mode 100644 index 000000000..d01f17e8b --- /dev/null +++ b/tests/snapshots/asm/call_sp_adjust_imm12_overflow.aarch64.asm @@ -0,0 +1,9673 @@ + +call_sp_adjust_imm12_overflow.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x1, lsl #12 // =0x1000 + sub sp, sp, #0x60 + sub x16, x29, #0x10 + str x0, [x16] + str x1, [x16, #0x8] + sub x16, x29, #0x20 + str x2, [x16] + str x3, [x16, #0x8] + sub x16, x29, #0x30 + str x4, [x16] + str x5, [x16, #0x8] + sub x16, x29, #0x40 + str x6, [x16] + str x7, [x16, #0x8] + sub x16, x29, #0x50 + ldr x17, [x29, #0x1060] + str x17, [x16] + ldr x17, [x29, #0x1068] + str x17, [x16, #0x8] + sub x16, x29, #0x60 + ldr x17, [x29, #0x1070] + str x17, [x16] + ldr x17, [x29, #0x1078] + str x17, [x16, #0x8] + sub x16, x29, #0x70 + ldr x17, [x29, #0x1080] + str x17, [x16] + ldr x17, [x29, #0x1088] + str x17, [x16, #0x8] + sub x16, x29, #0x80 + ldr x17, [x29, #0x1090] + str x17, [x16] + ldr x17, [x29, #0x1098] + str x17, [x16, #0x8] + sub x16, x29, #0x90 + ldr x17, [x29, #0x10a0] + str x17, [x16] + ldr x17, [x29, #0x10a8] + str x17, [x16, #0x8] + sub x16, x29, #0xa0 + ldr x17, [x29, #0x10b0] + str x17, [x16] + ldr x17, [x29, #0x10b8] + str x17, [x16, #0x8] + sub x16, x29, #0xb0 + ldr x17, [x29, #0x10c0] + str x17, [x16] + ldr x17, [x29, #0x10c8] + str x17, [x16, #0x8] + sub x16, x29, #0xc0 + ldr x17, [x29, #0x10d0] + str x17, [x16] + ldr x17, [x29, #0x10d8] + str x17, [x16, #0x8] + sub x16, x29, #0xd0 + ldr x17, [x29, #0x10e0] + str x17, [x16] + ldr x17, [x29, #0x10e8] + str x17, [x16, #0x8] + sub x16, x29, #0xe0 + ldr x17, [x29, #0x10f0] + str x17, [x16] + ldr x17, [x29, #0x10f8] + str x17, [x16, #0x8] + sub x16, x29, #0xf0 + ldr x17, [x29, #0x1100] + str x17, [x16] + ldr x17, [x29, #0x1108] + str x17, [x16, #0x8] + sub x16, x29, #0x100 + ldr x17, [x29, #0x1110] + str x17, [x16] + ldr x17, [x29, #0x1118] + str x17, [x16, #0x8] + sub x16, x29, #0x110 + ldr x17, [x29, #0x1120] + str x17, [x16] + ldr x17, [x29, #0x1128] + str x17, [x16, #0x8] + sub x16, x29, #0x120 + ldr x17, [x29, #0x1130] + str x17, [x16] + ldr x17, [x29, #0x1138] + str x17, [x16, #0x8] + sub x16, x29, #0x130 + ldr x17, [x29, #0x1140] + str x17, [x16] + ldr x17, [x29, #0x1148] + str x17, [x16, #0x8] + sub x16, x29, #0x140 + ldr x17, [x29, #0x1150] + str x17, [x16] + ldr x17, [x29, #0x1158] + str x17, [x16, #0x8] + sub x16, x29, #0x150 + ldr x17, [x29, #0x1160] + str x17, [x16] + ldr x17, [x29, #0x1168] + str x17, [x16, #0x8] + sub x16, x29, #0x160 + ldr x17, [x29, #0x1170] + str x17, [x16] + ldr x17, [x29, #0x1178] + str x17, [x16, #0x8] + sub x16, x29, #0x170 + ldr x17, [x29, #0x1180] + str x17, [x16] + ldr x17, [x29, #0x1188] + str x17, [x16, #0x8] + sub x16, x29, #0x180 + ldr x17, [x29, #0x1190] + str x17, [x16] + ldr x17, [x29, #0x1198] + str x17, [x16, #0x8] + sub x16, x29, #0x190 + ldr x17, [x29, #0x11a0] + str x17, [x16] + ldr x17, [x29, #0x11a8] + str x17, [x16, #0x8] + sub x16, x29, #0x1a0 + ldr x17, [x29, #0x11b0] + str x17, [x16] + ldr x17, [x29, #0x11b8] + str x17, [x16, #0x8] + sub x16, x29, #0x1b0 + ldr x17, [x29, #0x11c0] + str x17, [x16] + ldr x17, [x29, #0x11c8] + str x17, [x16, #0x8] + sub x16, x29, #0x1c0 + ldr x17, [x29, #0x11d0] + str x17, [x16] + ldr x17, [x29, #0x11d8] + str x17, [x16, #0x8] + sub x16, x29, #0x1d0 + ldr x17, [x29, #0x11e0] + str x17, [x16] + ldr x17, [x29, #0x11e8] + str x17, [x16, #0x8] + sub x16, x29, #0x1e0 + ldr x17, [x29, #0x11f0] + str x17, [x16] + ldr x17, [x29, #0x11f8] + str x17, [x16, #0x8] + sub x16, x29, #0x1f0 + ldr x17, [x29, #0x1200] + str x17, [x16] + ldr x17, [x29, #0x1208] + str x17, [x16, #0x8] + sub x16, x29, #0x200 + ldr x17, [x29, #0x1210] + str x17, [x16] + ldr x17, [x29, #0x1218] + str x17, [x16, #0x8] + sub x16, x29, #0x210 + ldr x17, [x29, #0x1220] + str x17, [x16] + ldr x17, [x29, #0x1228] + str x17, [x16, #0x8] + sub x16, x29, #0x220 + ldr x17, [x29, #0x1230] + str x17, [x16] + ldr x17, [x29, #0x1238] + str x17, [x16, #0x8] + sub x16, x29, #0x230 + ldr x17, [x29, #0x1240] + str x17, [x16] + ldr x17, [x29, #0x1248] + str x17, [x16, #0x8] + sub x16, x29, #0x240 + ldr x17, [x29, #0x1250] + str x17, [x16] + ldr x17, [x29, #0x1258] + str x17, [x16, #0x8] + sub x16, x29, #0x250 + ldr x17, [x29, #0x1260] + str x17, [x16] + ldr x17, [x29, #0x1268] + str x17, [x16, #0x8] + sub x16, x29, #0x260 + ldr x17, [x29, #0x1270] + str x17, [x16] + ldr x17, [x29, #0x1278] + str x17, [x16, #0x8] + sub x16, x29, #0x270 + ldr x17, [x29, #0x1280] + str x17, [x16] + ldr x17, [x29, #0x1288] + str x17, [x16, #0x8] + sub x16, x29, #0x280 + ldr x17, [x29, #0x1290] + str x17, [x16] + ldr x17, [x29, #0x1298] + str x17, [x16, #0x8] + sub x16, x29, #0x290 + ldr x17, [x29, #0x12a0] + str x17, [x16] + ldr x17, [x29, #0x12a8] + str x17, [x16, #0x8] + sub x16, x29, #0x2a0 + ldr x17, [x29, #0x12b0] + str x17, [x16] + ldr x17, [x29, #0x12b8] + str x17, [x16, #0x8] + sub x16, x29, #0x2b0 + ldr x17, [x29, #0x12c0] + str x17, [x16] + ldr x17, [x29, #0x12c8] + str x17, [x16, #0x8] + sub x16, x29, #0x2c0 + ldr x17, [x29, #0x12d0] + str x17, [x16] + ldr x17, [x29, #0x12d8] + str x17, [x16, #0x8] + sub x16, x29, #0x2d0 + ldr x17, [x29, #0x12e0] + str x17, [x16] + ldr x17, [x29, #0x12e8] + str x17, [x16, #0x8] + sub x16, x29, #0x2e0 + ldr x17, [x29, #0x12f0] + str x17, [x16] + ldr x17, [x29, #0x12f8] + str x17, [x16, #0x8] + sub x16, x29, #0x2f0 + ldr x17, [x29, #0x1300] + str x17, [x16] + ldr x17, [x29, #0x1308] + str x17, [x16, #0x8] + sub x16, x29, #0x300 + ldr x17, [x29, #0x1310] + str x17, [x16] + ldr x17, [x29, #0x1318] + str x17, [x16, #0x8] + sub x16, x29, #0x310 + ldr x17, [x29, #0x1320] + str x17, [x16] + ldr x17, [x29, #0x1328] + str x17, [x16, #0x8] + sub x16, x29, #0x320 + ldr x17, [x29, #0x1330] + str x17, [x16] + ldr x17, [x29, #0x1338] + str x17, [x16, #0x8] + sub x16, x29, #0x330 + ldr x17, [x29, #0x1340] + str x17, [x16] + ldr x17, [x29, #0x1348] + str x17, [x16, #0x8] + sub x16, x29, #0x340 + ldr x17, [x29, #0x1350] + str x17, [x16] + ldr x17, [x29, #0x1358] + str x17, [x16, #0x8] + sub x16, x29, #0x350 + ldr x17, [x29, #0x1360] + str x17, [x16] + ldr x17, [x29, #0x1368] + str x17, [x16, #0x8] + sub x16, x29, #0x360 + ldr x17, [x29, #0x1370] + str x17, [x16] + ldr x17, [x29, #0x1378] + str x17, [x16, #0x8] + sub x16, x29, #0x370 + ldr x17, [x29, #0x1380] + str x17, [x16] + ldr x17, [x29, #0x1388] + str x17, [x16, #0x8] + sub x16, x29, #0x380 + ldr x17, [x29, #0x1390] + str x17, [x16] + ldr x17, [x29, #0x1398] + str x17, [x16, #0x8] + sub x16, x29, #0x390 + ldr x17, [x29, #0x13a0] + str x17, [x16] + ldr x17, [x29, #0x13a8] + str x17, [x16, #0x8] + sub x16, x29, #0x3a0 + ldr x17, [x29, #0x13b0] + str x17, [x16] + ldr x17, [x29, #0x13b8] + str x17, [x16, #0x8] + sub x16, x29, #0x3b0 + ldr x17, [x29, #0x13c0] + str x17, [x16] + ldr x17, [x29, #0x13c8] + str x17, [x16, #0x8] + sub x16, x29, #0x3c0 + ldr x17, [x29, #0x13d0] + str x17, [x16] + ldr x17, [x29, #0x13d8] + str x17, [x16, #0x8] + sub x16, x29, #0x3d0 + ldr x17, [x29, #0x13e0] + str x17, [x16] + ldr x17, [x29, #0x13e8] + str x17, [x16, #0x8] + sub x16, x29, #0x3e0 + ldr x17, [x29, #0x13f0] + str x17, [x16] + ldr x17, [x29, #0x13f8] + str x17, [x16, #0x8] + sub x16, x29, #0x3f0 + ldr x17, [x29, #0x1400] + str x17, [x16] + ldr x17, [x29, #0x1408] + str x17, [x16, #0x8] + sub x16, x29, #0x400 + ldr x17, [x29, #0x1410] + str x17, [x16] + ldr x17, [x29, #0x1418] + str x17, [x16, #0x8] + sub x16, x29, #0x410 + ldr x17, [x29, #0x1420] + str x17, [x16] + ldr x17, [x29, #0x1428] + str x17, [x16, #0x8] + sub x16, x29, #0x420 + ldr x17, [x29, #0x1430] + str x17, [x16] + ldr x17, [x29, #0x1438] + str x17, [x16, #0x8] + sub x16, x29, #0x430 + ldr x17, [x29, #0x1440] + str x17, [x16] + ldr x17, [x29, #0x1448] + str x17, [x16, #0x8] + sub x16, x29, #0x440 + ldr x17, [x29, #0x1450] + str x17, [x16] + ldr x17, [x29, #0x1458] + str x17, [x16, #0x8] + sub x16, x29, #0x450 + ldr x17, [x29, #0x1460] + str x17, [x16] + ldr x17, [x29, #0x1468] + str x17, [x16, #0x8] + sub x16, x29, #0x460 + ldr x17, [x29, #0x1470] + str x17, [x16] + ldr x17, [x29, #0x1478] + str x17, [x16, #0x8] + sub x16, x29, #0x470 + ldr x17, [x29, #0x1480] + str x17, [x16] + ldr x17, [x29, #0x1488] + str x17, [x16, #0x8] + sub x16, x29, #0x480 + ldr x17, [x29, #0x1490] + str x17, [x16] + ldr x17, [x29, #0x1498] + str x17, [x16, #0x8] + sub x16, x29, #0x490 + ldr x17, [x29, #0x14a0] + str x17, [x16] + ldr x17, [x29, #0x14a8] + str x17, [x16, #0x8] + sub x16, x29, #0x4a0 + ldr x17, [x29, #0x14b0] + str x17, [x16] + ldr x17, [x29, #0x14b8] + str x17, [x16, #0x8] + sub x16, x29, #0x4b0 + ldr x17, [x29, #0x14c0] + str x17, [x16] + ldr x17, [x29, #0x14c8] + str x17, [x16, #0x8] + sub x16, x29, #0x4c0 + ldr x17, [x29, #0x14d0] + str x17, [x16] + ldr x17, [x29, #0x14d8] + str x17, [x16, #0x8] + sub x16, x29, #0x4d0 + ldr x17, [x29, #0x14e0] + str x17, [x16] + ldr x17, [x29, #0x14e8] + str x17, [x16, #0x8] + sub x16, x29, #0x4e0 + ldr x17, [x29, #0x14f0] + str x17, [x16] + ldr x17, [x29, #0x14f8] + str x17, [x16, #0x8] + sub x16, x29, #0x4f0 + ldr x17, [x29, #0x1500] + str x17, [x16] + ldr x17, [x29, #0x1508] + str x17, [x16, #0x8] + sub x16, x29, #0x500 + ldr x17, [x29, #0x1510] + str x17, [x16] + ldr x17, [x29, #0x1518] + str x17, [x16, #0x8] + sub x16, x29, #0x510 + ldr x17, [x29, #0x1520] + str x17, [x16] + ldr x17, [x29, #0x1528] + str x17, [x16, #0x8] + sub x16, x29, #0x520 + ldr x17, [x29, #0x1530] + str x17, [x16] + ldr x17, [x29, #0x1538] + str x17, [x16, #0x8] + sub x16, x29, #0x530 + ldr x17, [x29, #0x1540] + str x17, [x16] + ldr x17, [x29, #0x1548] + str x17, [x16, #0x8] + sub x16, x29, #0x540 + ldr x17, [x29, #0x1550] + str x17, [x16] + ldr x17, [x29, #0x1558] + str x17, [x16, #0x8] + sub x16, x29, #0x550 + ldr x17, [x29, #0x1560] + str x17, [x16] + ldr x17, [x29, #0x1568] + str x17, [x16, #0x8] + sub x16, x29, #0x560 + ldr x17, [x29, #0x1570] + str x17, [x16] + ldr x17, [x29, #0x1578] + str x17, [x16, #0x8] + sub x16, x29, #0x570 + ldr x17, [x29, #0x1580] + str x17, [x16] + ldr x17, [x29, #0x1588] + str x17, [x16, #0x8] + sub x16, x29, #0x580 + ldr x17, [x29, #0x1590] + str x17, [x16] + ldr x17, [x29, #0x1598] + str x17, [x16, #0x8] + sub x16, x29, #0x590 + ldr x17, [x29, #0x15a0] + str x17, [x16] + ldr x17, [x29, #0x15a8] + str x17, [x16, #0x8] + sub x16, x29, #0x5a0 + ldr x17, [x29, #0x15b0] + str x17, [x16] + ldr x17, [x29, #0x15b8] + str x17, [x16, #0x8] + sub x16, x29, #0x5b0 + ldr x17, [x29, #0x15c0] + str x17, [x16] + ldr x17, [x29, #0x15c8] + str x17, [x16, #0x8] + sub x16, x29, #0x5c0 + ldr x17, [x29, #0x15d0] + str x17, [x16] + ldr x17, [x29, #0x15d8] + str x17, [x16, #0x8] + sub x16, x29, #0x5d0 + ldr x17, [x29, #0x15e0] + str x17, [x16] + ldr x17, [x29, #0x15e8] + str x17, [x16, #0x8] + sub x16, x29, #0x5e0 + ldr x17, [x29, #0x15f0] + str x17, [x16] + ldr x17, [x29, #0x15f8] + str x17, [x16, #0x8] + sub x16, x29, #0x5f0 + ldr x17, [x29, #0x1600] + str x17, [x16] + ldr x17, [x29, #0x1608] + str x17, [x16, #0x8] + sub x16, x29, #0x600 + ldr x17, [x29, #0x1610] + str x17, [x16] + ldr x17, [x29, #0x1618] + str x17, [x16, #0x8] + sub x16, x29, #0x610 + ldr x17, [x29, #0x1620] + str x17, [x16] + ldr x17, [x29, #0x1628] + str x17, [x16, #0x8] + sub x16, x29, #0x620 + ldr x17, [x29, #0x1630] + str x17, [x16] + ldr x17, [x29, #0x1638] + str x17, [x16, #0x8] + sub x16, x29, #0x630 + ldr x17, [x29, #0x1640] + str x17, [x16] + ldr x17, [x29, #0x1648] + str x17, [x16, #0x8] + sub x16, x29, #0x640 + ldr x17, [x29, #0x1650] + str x17, [x16] + ldr x17, [x29, #0x1658] + str x17, [x16, #0x8] + sub x16, x29, #0x650 + ldr x17, [x29, #0x1660] + str x17, [x16] + ldr x17, [x29, #0x1668] + str x17, [x16, #0x8] + sub x16, x29, #0x660 + ldr x17, [x29, #0x1670] + str x17, [x16] + ldr x17, [x29, #0x1678] + str x17, [x16, #0x8] + sub x16, x29, #0x670 + ldr x17, [x29, #0x1680] + str x17, [x16] + ldr x17, [x29, #0x1688] + str x17, [x16, #0x8] + sub x16, x29, #0x680 + ldr x17, [x29, #0x1690] + str x17, [x16] + ldr x17, [x29, #0x1698] + str x17, [x16, #0x8] + sub x16, x29, #0x690 + ldr x17, [x29, #0x16a0] + str x17, [x16] + ldr x17, [x29, #0x16a8] + str x17, [x16, #0x8] + sub x16, x29, #0x6a0 + ldr x17, [x29, #0x16b0] + str x17, [x16] + ldr x17, [x29, #0x16b8] + str x17, [x16, #0x8] + sub x16, x29, #0x6b0 + ldr x17, [x29, #0x16c0] + str x17, [x16] + ldr x17, [x29, #0x16c8] + str x17, [x16, #0x8] + sub x16, x29, #0x6c0 + ldr x17, [x29, #0x16d0] + str x17, [x16] + ldr x17, [x29, #0x16d8] + str x17, [x16, #0x8] + sub x16, x29, #0x6d0 + ldr x17, [x29, #0x16e0] + str x17, [x16] + ldr x17, [x29, #0x16e8] + str x17, [x16, #0x8] + sub x16, x29, #0x6e0 + ldr x17, [x29, #0x16f0] + str x17, [x16] + ldr x17, [x29, #0x16f8] + str x17, [x16, #0x8] + sub x16, x29, #0x6f0 + ldr x17, [x29, #0x1700] + str x17, [x16] + ldr x17, [x29, #0x1708] + str x17, [x16, #0x8] + sub x16, x29, #0x700 + ldr x17, [x29, #0x1710] + str x17, [x16] + ldr x17, [x29, #0x1718] + str x17, [x16, #0x8] + sub x16, x29, #0x710 + ldr x17, [x29, #0x1720] + str x17, [x16] + ldr x17, [x29, #0x1728] + str x17, [x16, #0x8] + sub x16, x29, #0x720 + ldr x17, [x29, #0x1730] + str x17, [x16] + ldr x17, [x29, #0x1738] + str x17, [x16, #0x8] + sub x16, x29, #0x730 + ldr x17, [x29, #0x1740] + str x17, [x16] + ldr x17, [x29, #0x1748] + str x17, [x16, #0x8] + sub x16, x29, #0x740 + ldr x17, [x29, #0x1750] + str x17, [x16] + ldr x17, [x29, #0x1758] + str x17, [x16, #0x8] + sub x16, x29, #0x750 + ldr x17, [x29, #0x1760] + str x17, [x16] + ldr x17, [x29, #0x1768] + str x17, [x16, #0x8] + sub x16, x29, #0x760 + ldr x17, [x29, #0x1770] + str x17, [x16] + ldr x17, [x29, #0x1778] + str x17, [x16, #0x8] + sub x16, x29, #0x770 + ldr x17, [x29, #0x1780] + str x17, [x16] + ldr x17, [x29, #0x1788] + str x17, [x16, #0x8] + sub x16, x29, #0x780 + ldr x17, [x29, #0x1790] + str x17, [x16] + ldr x17, [x29, #0x1798] + str x17, [x16, #0x8] + sub x16, x29, #0x790 + ldr x17, [x29, #0x17a0] + str x17, [x16] + ldr x17, [x29, #0x17a8] + str x17, [x16, #0x8] + sub x16, x29, #0x7a0 + ldr x17, [x29, #0x17b0] + str x17, [x16] + ldr x17, [x29, #0x17b8] + str x17, [x16, #0x8] + sub x16, x29, #0x7b0 + ldr x17, [x29, #0x17c0] + str x17, [x16] + ldr x17, [x29, #0x17c8] + str x17, [x16, #0x8] + sub x16, x29, #0x7c0 + ldr x17, [x29, #0x17d0] + str x17, [x16] + ldr x17, [x29, #0x17d8] + str x17, [x16, #0x8] + sub x16, x29, #0x7d0 + ldr x17, [x29, #0x17e0] + str x17, [x16] + ldr x17, [x29, #0x17e8] + str x17, [x16, #0x8] + sub x16, x29, #0x7e0 + ldr x17, [x29, #0x17f0] + str x17, [x16] + ldr x17, [x29, #0x17f8] + str x17, [x16, #0x8] + sub x16, x29, #0x7f0 + ldr x17, [x29, #0x1800] + str x17, [x16] + ldr x17, [x29, #0x1808] + str x17, [x16, #0x8] + sub x16, x29, #0x800 + ldr x17, [x29, #0x1810] + str x17, [x16] + ldr x17, [x29, #0x1818] + str x17, [x16, #0x8] + sub x16, x29, #0x810 + ldr x17, [x29, #0x1820] + str x17, [x16] + ldr x17, [x29, #0x1828] + str x17, [x16, #0x8] + sub x16, x29, #0x820 + ldr x17, [x29, #0x1830] + str x17, [x16] + ldr x17, [x29, #0x1838] + str x17, [x16, #0x8] + sub x16, x29, #0x830 + ldr x17, [x29, #0x1840] + str x17, [x16] + ldr x17, [x29, #0x1848] + str x17, [x16, #0x8] + sub x16, x29, #0x840 + ldr x17, [x29, #0x1850] + str x17, [x16] + ldr x17, [x29, #0x1858] + str x17, [x16, #0x8] + sub x16, x29, #0x850 + ldr x17, [x29, #0x1860] + str x17, [x16] + ldr x17, [x29, #0x1868] + str x17, [x16, #0x8] + sub x16, x29, #0x860 + ldr x17, [x29, #0x1870] + str x17, [x16] + ldr x17, [x29, #0x1878] + str x17, [x16, #0x8] + sub x16, x29, #0x870 + ldr x17, [x29, #0x1880] + str x17, [x16] + ldr x17, [x29, #0x1888] + str x17, [x16, #0x8] + sub x16, x29, #0x880 + ldr x17, [x29, #0x1890] + str x17, [x16] + ldr x17, [x29, #0x1898] + str x17, [x16, #0x8] + sub x16, x29, #0x890 + ldr x17, [x29, #0x18a0] + str x17, [x16] + ldr x17, [x29, #0x18a8] + str x17, [x16, #0x8] + sub x16, x29, #0x8a0 + ldr x17, [x29, #0x18b0] + str x17, [x16] + ldr x17, [x29, #0x18b8] + str x17, [x16, #0x8] + sub x16, x29, #0x8b0 + ldr x17, [x29, #0x18c0] + str x17, [x16] + ldr x17, [x29, #0x18c8] + str x17, [x16, #0x8] + sub x16, x29, #0x8c0 + ldr x17, [x29, #0x18d0] + str x17, [x16] + ldr x17, [x29, #0x18d8] + str x17, [x16, #0x8] + sub x16, x29, #0x8d0 + ldr x17, [x29, #0x18e0] + str x17, [x16] + ldr x17, [x29, #0x18e8] + str x17, [x16, #0x8] + sub x16, x29, #0x8e0 + ldr x17, [x29, #0x18f0] + str x17, [x16] + ldr x17, [x29, #0x18f8] + str x17, [x16, #0x8] + sub x16, x29, #0x8f0 + ldr x17, [x29, #0x1900] + str x17, [x16] + ldr x17, [x29, #0x1908] + str x17, [x16, #0x8] + sub x16, x29, #0x900 + ldr x17, [x29, #0x1910] + str x17, [x16] + ldr x17, [x29, #0x1918] + str x17, [x16, #0x8] + sub x16, x29, #0x910 + ldr x17, [x29, #0x1920] + str x17, [x16] + ldr x17, [x29, #0x1928] + str x17, [x16, #0x8] + sub x16, x29, #0x920 + ldr x17, [x29, #0x1930] + str x17, [x16] + ldr x17, [x29, #0x1938] + str x17, [x16, #0x8] + sub x16, x29, #0x930 + ldr x17, [x29, #0x1940] + str x17, [x16] + ldr x17, [x29, #0x1948] + str x17, [x16, #0x8] + sub x16, x29, #0x940 + ldr x17, [x29, #0x1950] + str x17, [x16] + ldr x17, [x29, #0x1958] + str x17, [x16, #0x8] + sub x16, x29, #0x950 + ldr x17, [x29, #0x1960] + str x17, [x16] + ldr x17, [x29, #0x1968] + str x17, [x16, #0x8] + sub x16, x29, #0x960 + ldr x17, [x29, #0x1970] + str x17, [x16] + ldr x17, [x29, #0x1978] + str x17, [x16, #0x8] + sub x16, x29, #0x970 + ldr x17, [x29, #0x1980] + str x17, [x16] + ldr x17, [x29, #0x1988] + str x17, [x16, #0x8] + sub x16, x29, #0x980 + ldr x17, [x29, #0x1990] + str x17, [x16] + ldr x17, [x29, #0x1998] + str x17, [x16, #0x8] + sub x16, x29, #0x990 + ldr x17, [x29, #0x19a0] + str x17, [x16] + ldr x17, [x29, #0x19a8] + str x17, [x16, #0x8] + sub x16, x29, #0x9a0 + ldr x17, [x29, #0x19b0] + str x17, [x16] + ldr x17, [x29, #0x19b8] + str x17, [x16, #0x8] + sub x16, x29, #0x9b0 + ldr x17, [x29, #0x19c0] + str x17, [x16] + ldr x17, [x29, #0x19c8] + str x17, [x16, #0x8] + sub x16, x29, #0x9c0 + ldr x17, [x29, #0x19d0] + str x17, [x16] + ldr x17, [x29, #0x19d8] + str x17, [x16, #0x8] + sub x16, x29, #0x9d0 + ldr x17, [x29, #0x19e0] + str x17, [x16] + ldr x17, [x29, #0x19e8] + str x17, [x16, #0x8] + sub x16, x29, #0x9e0 + ldr x17, [x29, #0x19f0] + str x17, [x16] + ldr x17, [x29, #0x19f8] + str x17, [x16, #0x8] + sub x16, x29, #0x9f0 + ldr x17, [x29, #0x1a00] + str x17, [x16] + ldr x17, [x29, #0x1a08] + str x17, [x16, #0x8] + sub x16, x29, #0xa00 + ldr x17, [x29, #0x1a10] + str x17, [x16] + ldr x17, [x29, #0x1a18] + str x17, [x16, #0x8] + sub x16, x29, #0xa10 + ldr x17, [x29, #0x1a20] + str x17, [x16] + ldr x17, [x29, #0x1a28] + str x17, [x16, #0x8] + sub x16, x29, #0xa20 + ldr x17, [x29, #0x1a30] + str x17, [x16] + ldr x17, [x29, #0x1a38] + str x17, [x16, #0x8] + sub x16, x29, #0xa30 + ldr x17, [x29, #0x1a40] + str x17, [x16] + ldr x17, [x29, #0x1a48] + str x17, [x16, #0x8] + sub x16, x29, #0xa40 + ldr x17, [x29, #0x1a50] + str x17, [x16] + ldr x17, [x29, #0x1a58] + str x17, [x16, #0x8] + sub x16, x29, #0xa50 + ldr x17, [x29, #0x1a60] + str x17, [x16] + ldr x17, [x29, #0x1a68] + str x17, [x16, #0x8] + sub x16, x29, #0xa60 + ldr x17, [x29, #0x1a70] + str x17, [x16] + ldr x17, [x29, #0x1a78] + str x17, [x16, #0x8] + sub x16, x29, #0xa70 + ldr x17, [x29, #0x1a80] + str x17, [x16] + ldr x17, [x29, #0x1a88] + str x17, [x16, #0x8] + sub x16, x29, #0xa80 + ldr x17, [x29, #0x1a90] + str x17, [x16] + ldr x17, [x29, #0x1a98] + str x17, [x16, #0x8] + sub x16, x29, #0xa90 + ldr x17, [x29, #0x1aa0] + str x17, [x16] + ldr x17, [x29, #0x1aa8] + str x17, [x16, #0x8] + sub x16, x29, #0xaa0 + ldr x17, [x29, #0x1ab0] + str x17, [x16] + ldr x17, [x29, #0x1ab8] + str x17, [x16, #0x8] + sub x16, x29, #0xab0 + ldr x17, [x29, #0x1ac0] + str x17, [x16] + ldr x17, [x29, #0x1ac8] + str x17, [x16, #0x8] + sub x16, x29, #0xac0 + ldr x17, [x29, #0x1ad0] + str x17, [x16] + ldr x17, [x29, #0x1ad8] + str x17, [x16, #0x8] + sub x16, x29, #0xad0 + ldr x17, [x29, #0x1ae0] + str x17, [x16] + ldr x17, [x29, #0x1ae8] + str x17, [x16, #0x8] + sub x16, x29, #0xae0 + ldr x17, [x29, #0x1af0] + str x17, [x16] + ldr x17, [x29, #0x1af8] + str x17, [x16, #0x8] + sub x16, x29, #0xaf0 + ldr x17, [x29, #0x1b00] + str x17, [x16] + ldr x17, [x29, #0x1b08] + str x17, [x16, #0x8] + sub x16, x29, #0xb00 + ldr x17, [x29, #0x1b10] + str x17, [x16] + ldr x17, [x29, #0x1b18] + str x17, [x16, #0x8] + sub x16, x29, #0xb10 + ldr x17, [x29, #0x1b20] + str x17, [x16] + ldr x17, [x29, #0x1b28] + str x17, [x16, #0x8] + sub x16, x29, #0xb20 + ldr x17, [x29, #0x1b30] + str x17, [x16] + ldr x17, [x29, #0x1b38] + str x17, [x16, #0x8] + sub x16, x29, #0xb30 + ldr x17, [x29, #0x1b40] + str x17, [x16] + ldr x17, [x29, #0x1b48] + str x17, [x16, #0x8] + sub x16, x29, #0xb40 + ldr x17, [x29, #0x1b50] + str x17, [x16] + ldr x17, [x29, #0x1b58] + str x17, [x16, #0x8] + sub x16, x29, #0xb50 + ldr x17, [x29, #0x1b60] + str x17, [x16] + ldr x17, [x29, #0x1b68] + str x17, [x16, #0x8] + sub x16, x29, #0xb60 + ldr x17, [x29, #0x1b70] + str x17, [x16] + ldr x17, [x29, #0x1b78] + str x17, [x16, #0x8] + sub x16, x29, #0xb70 + ldr x17, [x29, #0x1b80] + str x17, [x16] + ldr x17, [x29, #0x1b88] + str x17, [x16, #0x8] + sub x16, x29, #0xb80 + ldr x17, [x29, #0x1b90] + str x17, [x16] + ldr x17, [x29, #0x1b98] + str x17, [x16, #0x8] + sub x16, x29, #0xb90 + ldr x17, [x29, #0x1ba0] + str x17, [x16] + ldr x17, [x29, #0x1ba8] + str x17, [x16, #0x8] + sub x16, x29, #0xba0 + ldr x17, [x29, #0x1bb0] + str x17, [x16] + ldr x17, [x29, #0x1bb8] + str x17, [x16, #0x8] + sub x16, x29, #0xbb0 + ldr x17, [x29, #0x1bc0] + str x17, [x16] + ldr x17, [x29, #0x1bc8] + str x17, [x16, #0x8] + sub x16, x29, #0xbc0 + ldr x17, [x29, #0x1bd0] + str x17, [x16] + ldr x17, [x29, #0x1bd8] + str x17, [x16, #0x8] + sub x16, x29, #0xbd0 + ldr x17, [x29, #0x1be0] + str x17, [x16] + ldr x17, [x29, #0x1be8] + str x17, [x16, #0x8] + sub x16, x29, #0xbe0 + ldr x17, [x29, #0x1bf0] + str x17, [x16] + ldr x17, [x29, #0x1bf8] + str x17, [x16, #0x8] + sub x16, x29, #0xbf0 + ldr x17, [x29, #0x1c00] + str x17, [x16] + ldr x17, [x29, #0x1c08] + str x17, [x16, #0x8] + sub x16, x29, #0xc00 + ldr x17, [x29, #0x1c10] + str x17, [x16] + ldr x17, [x29, #0x1c18] + str x17, [x16, #0x8] + sub x16, x29, #0xc10 + ldr x17, [x29, #0x1c20] + str x17, [x16] + ldr x17, [x29, #0x1c28] + str x17, [x16, #0x8] + sub x16, x29, #0xc20 + ldr x17, [x29, #0x1c30] + str x17, [x16] + ldr x17, [x29, #0x1c38] + str x17, [x16, #0x8] + sub x16, x29, #0xc30 + ldr x17, [x29, #0x1c40] + str x17, [x16] + ldr x17, [x29, #0x1c48] + str x17, [x16, #0x8] + sub x16, x29, #0xc40 + ldr x17, [x29, #0x1c50] + str x17, [x16] + ldr x17, [x29, #0x1c58] + str x17, [x16, #0x8] + sub x16, x29, #0xc50 + ldr x17, [x29, #0x1c60] + str x17, [x16] + ldr x17, [x29, #0x1c68] + str x17, [x16, #0x8] + sub x16, x29, #0xc60 + ldr x17, [x29, #0x1c70] + str x17, [x16] + ldr x17, [x29, #0x1c78] + str x17, [x16, #0x8] + sub x16, x29, #0xc70 + ldr x17, [x29, #0x1c80] + str x17, [x16] + ldr x17, [x29, #0x1c88] + str x17, [x16, #0x8] + sub x16, x29, #0xc80 + ldr x17, [x29, #0x1c90] + str x17, [x16] + ldr x17, [x29, #0x1c98] + str x17, [x16, #0x8] + sub x16, x29, #0xc90 + ldr x17, [x29, #0x1ca0] + str x17, [x16] + ldr x17, [x29, #0x1ca8] + str x17, [x16, #0x8] + sub x16, x29, #0xca0 + ldr x17, [x29, #0x1cb0] + str x17, [x16] + ldr x17, [x29, #0x1cb8] + str x17, [x16, #0x8] + sub x16, x29, #0xcb0 + ldr x17, [x29, #0x1cc0] + str x17, [x16] + ldr x17, [x29, #0x1cc8] + str x17, [x16, #0x8] + sub x16, x29, #0xcc0 + ldr x17, [x29, #0x1cd0] + str x17, [x16] + ldr x17, [x29, #0x1cd8] + str x17, [x16, #0x8] + sub x16, x29, #0xcd0 + ldr x17, [x29, #0x1ce0] + str x17, [x16] + ldr x17, [x29, #0x1ce8] + str x17, [x16, #0x8] + sub x16, x29, #0xce0 + ldr x17, [x29, #0x1cf0] + str x17, [x16] + ldr x17, [x29, #0x1cf8] + str x17, [x16, #0x8] + sub x16, x29, #0xcf0 + ldr x17, [x29, #0x1d00] + str x17, [x16] + ldr x17, [x29, #0x1d08] + str x17, [x16, #0x8] + sub x16, x29, #0xd00 + ldr x17, [x29, #0x1d10] + str x17, [x16] + ldr x17, [x29, #0x1d18] + str x17, [x16, #0x8] + sub x16, x29, #0xd10 + ldr x17, [x29, #0x1d20] + str x17, [x16] + ldr x17, [x29, #0x1d28] + str x17, [x16, #0x8] + sub x16, x29, #0xd20 + ldr x17, [x29, #0x1d30] + str x17, [x16] + ldr x17, [x29, #0x1d38] + str x17, [x16, #0x8] + sub x16, x29, #0xd30 + ldr x17, [x29, #0x1d40] + str x17, [x16] + ldr x17, [x29, #0x1d48] + str x17, [x16, #0x8] + sub x16, x29, #0xd40 + ldr x17, [x29, #0x1d50] + str x17, [x16] + ldr x17, [x29, #0x1d58] + str x17, [x16, #0x8] + sub x16, x29, #0xd50 + ldr x17, [x29, #0x1d60] + str x17, [x16] + ldr x17, [x29, #0x1d68] + str x17, [x16, #0x8] + sub x16, x29, #0xd60 + ldr x17, [x29, #0x1d70] + str x17, [x16] + ldr x17, [x29, #0x1d78] + str x17, [x16, #0x8] + sub x16, x29, #0xd70 + ldr x17, [x29, #0x1d80] + str x17, [x16] + ldr x17, [x29, #0x1d88] + str x17, [x16, #0x8] + sub x16, x29, #0xd80 + ldr x17, [x29, #0x1d90] + str x17, [x16] + ldr x17, [x29, #0x1d98] + str x17, [x16, #0x8] + sub x16, x29, #0xd90 + ldr x17, [x29, #0x1da0] + str x17, [x16] + ldr x17, [x29, #0x1da8] + str x17, [x16, #0x8] + sub x16, x29, #0xda0 + ldr x17, [x29, #0x1db0] + str x17, [x16] + ldr x17, [x29, #0x1db8] + str x17, [x16, #0x8] + sub x16, x29, #0xdb0 + ldr x17, [x29, #0x1dc0] + str x17, [x16] + ldr x17, [x29, #0x1dc8] + str x17, [x16, #0x8] + sub x16, x29, #0xdc0 + ldr x17, [x29, #0x1dd0] + str x17, [x16] + ldr x17, [x29, #0x1dd8] + str x17, [x16, #0x8] + sub x16, x29, #0xdd0 + ldr x17, [x29, #0x1de0] + str x17, [x16] + ldr x17, [x29, #0x1de8] + str x17, [x16, #0x8] + sub x16, x29, #0xde0 + ldr x17, [x29, #0x1df0] + str x17, [x16] + ldr x17, [x29, #0x1df8] + str x17, [x16, #0x8] + sub x16, x29, #0xdf0 + ldr x17, [x29, #0x1e00] + str x17, [x16] + ldr x17, [x29, #0x1e08] + str x17, [x16, #0x8] + sub x16, x29, #0xe00 + ldr x17, [x29, #0x1e10] + str x17, [x16] + ldr x17, [x29, #0x1e18] + str x17, [x16, #0x8] + sub x16, x29, #0xe10 + ldr x17, [x29, #0x1e20] + str x17, [x16] + ldr x17, [x29, #0x1e28] + str x17, [x16, #0x8] + sub x16, x29, #0xe20 + ldr x17, [x29, #0x1e30] + str x17, [x16] + ldr x17, [x29, #0x1e38] + str x17, [x16, #0x8] + sub x16, x29, #0xe30 + ldr x17, [x29, #0x1e40] + str x17, [x16] + ldr x17, [x29, #0x1e48] + str x17, [x16, #0x8] + sub x16, x29, #0xe40 + ldr x17, [x29, #0x1e50] + str x17, [x16] + ldr x17, [x29, #0x1e58] + str x17, [x16, #0x8] + sub x16, x29, #0xe50 + ldr x17, [x29, #0x1e60] + str x17, [x16] + ldr x17, [x29, #0x1e68] + str x17, [x16, #0x8] + sub x16, x29, #0xe60 + ldr x17, [x29, #0x1e70] + str x17, [x16] + ldr x17, [x29, #0x1e78] + str x17, [x16, #0x8] + sub x16, x29, #0xe70 + ldr x17, [x29, #0x1e80] + str x17, [x16] + ldr x17, [x29, #0x1e88] + str x17, [x16, #0x8] + sub x16, x29, #0xe80 + ldr x17, [x29, #0x1e90] + str x17, [x16] + ldr x17, [x29, #0x1e98] + str x17, [x16, #0x8] + sub x16, x29, #0xe90 + ldr x17, [x29, #0x1ea0] + str x17, [x16] + ldr x17, [x29, #0x1ea8] + str x17, [x16, #0x8] + sub x16, x29, #0xea0 + ldr x17, [x29, #0x1eb0] + str x17, [x16] + ldr x17, [x29, #0x1eb8] + str x17, [x16, #0x8] + sub x16, x29, #0xeb0 + ldr x17, [x29, #0x1ec0] + str x17, [x16] + ldr x17, [x29, #0x1ec8] + str x17, [x16, #0x8] + sub x16, x29, #0xec0 + ldr x17, [x29, #0x1ed0] + str x17, [x16] + ldr x17, [x29, #0x1ed8] + str x17, [x16, #0x8] + sub x16, x29, #0xed0 + ldr x17, [x29, #0x1ee0] + str x17, [x16] + ldr x17, [x29, #0x1ee8] + str x17, [x16, #0x8] + sub x16, x29, #0xee0 + ldr x17, [x29, #0x1ef0] + str x17, [x16] + ldr x17, [x29, #0x1ef8] + str x17, [x16, #0x8] + sub x16, x29, #0xef0 + ldr x17, [x29, #0x1f00] + str x17, [x16] + ldr x17, [x29, #0x1f08] + str x17, [x16, #0x8] + sub x16, x29, #0xf00 + ldr x17, [x29, #0x1f10] + str x17, [x16] + ldr x17, [x29, #0x1f18] + str x17, [x16, #0x8] + sub x16, x29, #0xf10 + ldr x17, [x29, #0x1f20] + str x17, [x16] + ldr x17, [x29, #0x1f28] + str x17, [x16, #0x8] + sub x16, x29, #0xf20 + ldr x17, [x29, #0x1f30] + str x17, [x16] + ldr x17, [x29, #0x1f38] + str x17, [x16, #0x8] + sub x16, x29, #0xf30 + ldr x17, [x29, #0x1f40] + str x17, [x16] + ldr x17, [x29, #0x1f48] + str x17, [x16, #0x8] + sub x16, x29, #0xf40 + ldr x17, [x29, #0x1f50] + str x17, [x16] + ldr x17, [x29, #0x1f58] + str x17, [x16, #0x8] + sub x16, x29, #0xf50 + ldr x17, [x29, #0x1f60] + str x17, [x16] + ldr x17, [x29, #0x1f68] + str x17, [x16, #0x8] + sub x16, x29, #0xf60 + ldr x17, [x29, #0x1f70] + str x17, [x16] + ldr x17, [x29, #0x1f78] + str x17, [x16, #0x8] + sub x16, x29, #0xf70 + ldr x17, [x29, #0x1f80] + str x17, [x16] + ldr x17, [x29, #0x1f88] + str x17, [x16, #0x8] + sub x16, x29, #0xf80 + ldr x17, [x29, #0x1f90] + str x17, [x16] + ldr x17, [x29, #0x1f98] + str x17, [x16, #0x8] + sub x16, x29, #0xf90 + ldr x17, [x29, #0x1fa0] + str x17, [x16] + ldr x17, [x29, #0x1fa8] + str x17, [x16, #0x8] + sub x16, x29, #0xfa0 + ldr x17, [x29, #0x1fb0] + str x17, [x16] + ldr x17, [x29, #0x1fb8] + str x17, [x16, #0x8] + sub x16, x29, #0xfb0 + ldr x17, [x29, #0x1fc0] + str x17, [x16] + ldr x17, [x29, #0x1fc8] + str x17, [x16, #0x8] + sub x16, x29, #0xfc0 + ldr x17, [x29, #0x1fd0] + str x17, [x16] + ldr x17, [x29, #0x1fd8] + str x17, [x16, #0x8] + sub x16, x29, #0xfd0 + ldr x17, [x29, #0x1fe0] + str x17, [x16] + ldr x17, [x29, #0x1fe8] + str x17, [x16, #0x8] + sub x16, x29, #0xfe0 + ldr x17, [x29, #0x1ff0] + str x17, [x16] + ldr x17, [x29, #0x1ff8] + str x17, [x16, #0x8] + sub x16, x29, #0xff0 + ldr x17, [x29, #0x2000] + str x17, [x16] + ldr x17, [x29, #0x2008] + str x17, [x16, #0x8] + sub x16, x29, #0x1, lsl #12 // =0x1000 + ldr x17, [x29, #0x2010] + str x17, [x16] + ldr x17, [x29, #0x2018] + str x17, [x16, #0x8] + sub x16, x29, #0x1, lsl #12 // =0x1000 + sub x16, x16, #0x10 + ldr x17, [x29, #0x2020] + str x17, [x16] + ldr x17, [x29, #0x2028] + str x17, [x16, #0x8] + sub x16, x29, #0x1, lsl #12 // =0x1000 + sub x16, x16, #0x20 + ldr x17, [x29, #0x2030] + str x17, [x16] + ldr x17, [x29, #0x2038] + str x17, [x16, #0x8] + sub x16, x29, #0x1, lsl #12 // =0x1000 + sub x16, x16, #0x30 + ldr x17, [x29, #0x2040] + str x17, [x16] + ldr x17, [x29, #0x2048] + str x17, [x16, #0x8] + sub x16, x29, #0x1, lsl #12 // =0x1000 + sub x16, x16, #0x40 + ldr x17, [x29, #0x2050] + str x17, [x16] + ldr x17, [x29, #0x2058] + str x17, [x16, #0x8] + sub x16, x29, #0x1, lsl #12 // =0x1000 + sub x16, x16, #0x50 + ldr x17, [x29, #0x2060] + str x17, [x16] + ldr x17, [x29, #0x2068] + str x17, [x16, #0x8] + mov x0, #0x0 // =0 + sub x1, x29, #0x10 + ldr x1, [x1] + sub x2, x29, #0x10 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x20 + ldr x1, [x1] + sub x2, x29, #0x20 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x30 + ldr x1, [x1] + sub x2, x29, #0x30 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x40 + ldr x1, [x1] + sub x2, x29, #0x40 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x50 + ldr x1, [x1] + sub x2, x29, #0x50 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x60 + ldr x1, [x1] + sub x2, x29, #0x60 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x70 + ldr x1, [x1] + sub x2, x29, #0x70 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x80 + ldr x1, [x1] + sub x2, x29, #0x80 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x90 + ldr x1, [x1] + sub x2, x29, #0x90 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa0 + ldr x1, [x1] + sub x2, x29, #0xa0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb0 + ldr x1, [x1] + sub x2, x29, #0xb0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc0 + ldr x1, [x1] + sub x2, x29, #0xc0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd0 + ldr x1, [x1] + sub x2, x29, #0xd0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe0 + ldr x1, [x1] + sub x2, x29, #0xe0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf0 + ldr x1, [x1] + sub x2, x29, #0xf0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x100 + ldr x1, [x1] + sub x2, x29, #0x100 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x110 + ldr x1, [x1] + sub x2, x29, #0x110 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x120 + ldr x1, [x1] + sub x2, x29, #0x120 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x130 + ldr x1, [x1] + sub x2, x29, #0x130 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x140 + ldr x1, [x1] + sub x2, x29, #0x140 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x150 + ldr x1, [x1] + sub x2, x29, #0x150 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x160 + ldr x1, [x1] + sub x2, x29, #0x160 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x170 + ldr x1, [x1] + sub x2, x29, #0x170 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x180 + ldr x1, [x1] + sub x2, x29, #0x180 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x190 + ldr x1, [x1] + sub x2, x29, #0x190 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1a0 + ldr x1, [x1] + sub x2, x29, #0x1a0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1b0 + ldr x1, [x1] + sub x2, x29, #0x1b0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1c0 + ldr x1, [x1] + sub x2, x29, #0x1c0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1d0 + ldr x1, [x1] + sub x2, x29, #0x1d0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1e0 + ldr x1, [x1] + sub x2, x29, #0x1e0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1f0 + ldr x1, [x1] + sub x2, x29, #0x1f0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x200 + ldr x1, [x1] + sub x2, x29, #0x200 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x210 + ldr x1, [x1] + sub x2, x29, #0x210 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x220 + ldr x1, [x1] + sub x2, x29, #0x220 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x230 + ldr x1, [x1] + sub x2, x29, #0x230 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x240 + ldr x1, [x1] + sub x2, x29, #0x240 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x250 + ldr x1, [x1] + sub x2, x29, #0x250 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x260 + ldr x1, [x1] + sub x2, x29, #0x260 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x270 + ldr x1, [x1] + sub x2, x29, #0x270 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x280 + ldr x1, [x1] + sub x2, x29, #0x280 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x290 + ldr x1, [x1] + sub x2, x29, #0x290 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x2a0 + ldr x1, [x1] + sub x2, x29, #0x2a0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x2b0 + ldr x1, [x1] + sub x2, x29, #0x2b0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x2c0 + ldr x1, [x1] + sub x2, x29, #0x2c0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x2d0 + ldr x1, [x1] + sub x2, x29, #0x2d0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x2e0 + ldr x1, [x1] + sub x2, x29, #0x2e0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x2f0 + ldr x1, [x1] + sub x2, x29, #0x2f0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x300 + ldr x1, [x1] + sub x2, x29, #0x300 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x310 + ldr x1, [x1] + sub x2, x29, #0x310 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x320 + ldr x1, [x1] + sub x2, x29, #0x320 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x330 + ldr x1, [x1] + sub x2, x29, #0x330 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x340 + ldr x1, [x1] + sub x2, x29, #0x340 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x350 + ldr x1, [x1] + sub x2, x29, #0x350 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x360 + ldr x1, [x1] + sub x2, x29, #0x360 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x370 + ldr x1, [x1] + sub x2, x29, #0x370 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x380 + ldr x1, [x1] + sub x2, x29, #0x380 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x390 + ldr x1, [x1] + sub x2, x29, #0x390 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x3a0 + ldr x1, [x1] + sub x2, x29, #0x3a0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x3b0 + ldr x1, [x1] + sub x2, x29, #0x3b0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x3c0 + ldr x1, [x1] + sub x2, x29, #0x3c0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x3d0 + ldr x1, [x1] + sub x2, x29, #0x3d0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x3e0 + ldr x1, [x1] + sub x2, x29, #0x3e0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x3f0 + ldr x1, [x1] + sub x2, x29, #0x3f0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x400 + ldr x1, [x1] + sub x2, x29, #0x400 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x410 + ldr x1, [x1] + sub x2, x29, #0x410 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x420 + ldr x1, [x1] + sub x2, x29, #0x420 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x430 + ldr x1, [x1] + sub x2, x29, #0x430 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x440 + ldr x1, [x1] + sub x2, x29, #0x440 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x450 + ldr x1, [x1] + sub x2, x29, #0x450 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x460 + ldr x1, [x1] + sub x2, x29, #0x460 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x470 + ldr x1, [x1] + sub x2, x29, #0x470 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x480 + ldr x1, [x1] + sub x2, x29, #0x480 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x490 + ldr x1, [x1] + sub x2, x29, #0x490 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x4a0 + ldr x1, [x1] + sub x2, x29, #0x4a0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x4b0 + ldr x1, [x1] + sub x2, x29, #0x4b0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x4c0 + ldr x1, [x1] + sub x2, x29, #0x4c0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x4d0 + ldr x1, [x1] + sub x2, x29, #0x4d0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x4e0 + ldr x1, [x1] + sub x2, x29, #0x4e0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x4f0 + ldr x1, [x1] + sub x2, x29, #0x4f0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x500 + ldr x1, [x1] + sub x2, x29, #0x500 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x510 + ldr x1, [x1] + sub x2, x29, #0x510 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x520 + ldr x1, [x1] + sub x2, x29, #0x520 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x530 + ldr x1, [x1] + sub x2, x29, #0x530 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x540 + ldr x1, [x1] + sub x2, x29, #0x540 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x550 + ldr x1, [x1] + sub x2, x29, #0x550 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x560 + ldr x1, [x1] + sub x2, x29, #0x560 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x570 + ldr x1, [x1] + sub x2, x29, #0x570 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x580 + ldr x1, [x1] + sub x2, x29, #0x580 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x590 + ldr x1, [x1] + sub x2, x29, #0x590 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x5a0 + ldr x1, [x1] + sub x2, x29, #0x5a0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x5b0 + ldr x1, [x1] + sub x2, x29, #0x5b0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x5c0 + ldr x1, [x1] + sub x2, x29, #0x5c0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x5d0 + ldr x1, [x1] + sub x2, x29, #0x5d0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x5e0 + ldr x1, [x1] + sub x2, x29, #0x5e0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x5f0 + ldr x1, [x1] + sub x2, x29, #0x5f0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x600 + ldr x1, [x1] + sub x2, x29, #0x600 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x610 + ldr x1, [x1] + sub x2, x29, #0x610 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x620 + ldr x1, [x1] + sub x2, x29, #0x620 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x630 + ldr x1, [x1] + sub x2, x29, #0x630 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x640 + ldr x1, [x1] + sub x2, x29, #0x640 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x650 + ldr x1, [x1] + sub x2, x29, #0x650 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x660 + ldr x1, [x1] + sub x2, x29, #0x660 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x670 + ldr x1, [x1] + sub x2, x29, #0x670 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x680 + ldr x1, [x1] + sub x2, x29, #0x680 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x690 + ldr x1, [x1] + sub x2, x29, #0x690 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x6a0 + ldr x1, [x1] + sub x2, x29, #0x6a0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x6b0 + ldr x1, [x1] + sub x2, x29, #0x6b0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x6c0 + ldr x1, [x1] + sub x2, x29, #0x6c0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x6d0 + ldr x1, [x1] + sub x2, x29, #0x6d0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x6e0 + ldr x1, [x1] + sub x2, x29, #0x6e0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x6f0 + ldr x1, [x1] + sub x2, x29, #0x6f0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x700 + ldr x1, [x1] + sub x2, x29, #0x700 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x710 + ldr x1, [x1] + sub x2, x29, #0x710 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x720 + ldr x1, [x1] + sub x2, x29, #0x720 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x730 + ldr x1, [x1] + sub x2, x29, #0x730 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x740 + ldr x1, [x1] + sub x2, x29, #0x740 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x750 + ldr x1, [x1] + sub x2, x29, #0x750 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x760 + ldr x1, [x1] + sub x2, x29, #0x760 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x770 + ldr x1, [x1] + sub x2, x29, #0x770 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x780 + ldr x1, [x1] + sub x2, x29, #0x780 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x790 + ldr x1, [x1] + sub x2, x29, #0x790 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x7a0 + ldr x1, [x1] + sub x2, x29, #0x7a0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x7b0 + ldr x1, [x1] + sub x2, x29, #0x7b0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x7c0 + ldr x1, [x1] + sub x2, x29, #0x7c0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x7d0 + ldr x1, [x1] + sub x2, x29, #0x7d0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x7e0 + ldr x1, [x1] + sub x2, x29, #0x7e0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x7f0 + ldr x1, [x1] + sub x2, x29, #0x7f0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x800 + ldr x1, [x1] + sub x2, x29, #0x800 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x810 + ldr x1, [x1] + sub x2, x29, #0x810 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x820 + ldr x1, [x1] + sub x2, x29, #0x820 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x830 + ldr x1, [x1] + sub x2, x29, #0x830 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x840 + ldr x1, [x1] + sub x2, x29, #0x840 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x850 + ldr x1, [x1] + sub x2, x29, #0x850 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x860 + ldr x1, [x1] + sub x2, x29, #0x860 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x870 + ldr x1, [x1] + sub x2, x29, #0x870 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x880 + ldr x1, [x1] + sub x2, x29, #0x880 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x890 + ldr x1, [x1] + sub x2, x29, #0x890 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x8a0 + ldr x1, [x1] + sub x2, x29, #0x8a0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x8b0 + ldr x1, [x1] + sub x2, x29, #0x8b0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x8c0 + ldr x1, [x1] + sub x2, x29, #0x8c0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x8d0 + ldr x1, [x1] + sub x2, x29, #0x8d0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x8e0 + ldr x1, [x1] + sub x2, x29, #0x8e0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x8f0 + ldr x1, [x1] + sub x2, x29, #0x8f0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x900 + ldr x1, [x1] + sub x2, x29, #0x900 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x910 + ldr x1, [x1] + sub x2, x29, #0x910 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x920 + ldr x1, [x1] + sub x2, x29, #0x920 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x930 + ldr x1, [x1] + sub x2, x29, #0x930 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x940 + ldr x1, [x1] + sub x2, x29, #0x940 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x950 + ldr x1, [x1] + sub x2, x29, #0x950 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x960 + ldr x1, [x1] + sub x2, x29, #0x960 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x970 + ldr x1, [x1] + sub x2, x29, #0x970 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x980 + ldr x1, [x1] + sub x2, x29, #0x980 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x990 + ldr x1, [x1] + sub x2, x29, #0x990 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x9a0 + ldr x1, [x1] + sub x2, x29, #0x9a0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x9b0 + ldr x1, [x1] + sub x2, x29, #0x9b0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x9c0 + ldr x1, [x1] + sub x2, x29, #0x9c0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x9d0 + ldr x1, [x1] + sub x2, x29, #0x9d0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x9e0 + ldr x1, [x1] + sub x2, x29, #0x9e0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x9f0 + ldr x1, [x1] + sub x2, x29, #0x9f0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa00 + ldr x1, [x1] + sub x2, x29, #0xa00 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa10 + ldr x1, [x1] + sub x2, x29, #0xa10 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa20 + ldr x1, [x1] + sub x2, x29, #0xa20 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa30 + ldr x1, [x1] + sub x2, x29, #0xa30 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa40 + ldr x1, [x1] + sub x2, x29, #0xa40 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa50 + ldr x1, [x1] + sub x2, x29, #0xa50 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa60 + ldr x1, [x1] + sub x2, x29, #0xa60 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa70 + ldr x1, [x1] + sub x2, x29, #0xa70 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa80 + ldr x1, [x1] + sub x2, x29, #0xa80 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xa90 + ldr x1, [x1] + sub x2, x29, #0xa90 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xaa0 + ldr x1, [x1] + sub x2, x29, #0xaa0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xab0 + ldr x1, [x1] + sub x2, x29, #0xab0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xac0 + ldr x1, [x1] + sub x2, x29, #0xac0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xad0 + ldr x1, [x1] + sub x2, x29, #0xad0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xae0 + ldr x1, [x1] + sub x2, x29, #0xae0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xaf0 + ldr x1, [x1] + sub x2, x29, #0xaf0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb00 + ldr x1, [x1] + sub x2, x29, #0xb00 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb10 + ldr x1, [x1] + sub x2, x29, #0xb10 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb20 + ldr x1, [x1] + sub x2, x29, #0xb20 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb30 + ldr x1, [x1] + sub x2, x29, #0xb30 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb40 + ldr x1, [x1] + sub x2, x29, #0xb40 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb50 + ldr x1, [x1] + sub x2, x29, #0xb50 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb60 + ldr x1, [x1] + sub x2, x29, #0xb60 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb70 + ldr x1, [x1] + sub x2, x29, #0xb70 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb80 + ldr x1, [x1] + sub x2, x29, #0xb80 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xb90 + ldr x1, [x1] + sub x2, x29, #0xb90 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xba0 + ldr x1, [x1] + sub x2, x29, #0xba0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xbb0 + ldr x1, [x1] + sub x2, x29, #0xbb0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xbc0 + ldr x1, [x1] + sub x2, x29, #0xbc0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xbd0 + ldr x1, [x1] + sub x2, x29, #0xbd0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xbe0 + ldr x1, [x1] + sub x2, x29, #0xbe0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xbf0 + ldr x1, [x1] + sub x2, x29, #0xbf0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc00 + ldr x1, [x1] + sub x2, x29, #0xc00 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc10 + ldr x1, [x1] + sub x2, x29, #0xc10 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc20 + ldr x1, [x1] + sub x2, x29, #0xc20 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc30 + ldr x1, [x1] + sub x2, x29, #0xc30 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc40 + ldr x1, [x1] + sub x2, x29, #0xc40 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc50 + ldr x1, [x1] + sub x2, x29, #0xc50 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc60 + ldr x1, [x1] + sub x2, x29, #0xc60 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc70 + ldr x1, [x1] + sub x2, x29, #0xc70 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc80 + ldr x1, [x1] + sub x2, x29, #0xc80 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xc90 + ldr x1, [x1] + sub x2, x29, #0xc90 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xca0 + ldr x1, [x1] + sub x2, x29, #0xca0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xcb0 + ldr x1, [x1] + sub x2, x29, #0xcb0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xcc0 + ldr x1, [x1] + sub x2, x29, #0xcc0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xcd0 + ldr x1, [x1] + sub x2, x29, #0xcd0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xce0 + ldr x1, [x1] + sub x2, x29, #0xce0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xcf0 + ldr x1, [x1] + sub x2, x29, #0xcf0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd00 + ldr x1, [x1] + sub x2, x29, #0xd00 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd10 + ldr x1, [x1] + sub x2, x29, #0xd10 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd20 + ldr x1, [x1] + sub x2, x29, #0xd20 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd30 + ldr x1, [x1] + sub x2, x29, #0xd30 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd40 + ldr x1, [x1] + sub x2, x29, #0xd40 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd50 + ldr x1, [x1] + sub x2, x29, #0xd50 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd60 + ldr x1, [x1] + sub x2, x29, #0xd60 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd70 + ldr x1, [x1] + sub x2, x29, #0xd70 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd80 + ldr x1, [x1] + sub x2, x29, #0xd80 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xd90 + ldr x1, [x1] + sub x2, x29, #0xd90 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xda0 + ldr x1, [x1] + sub x2, x29, #0xda0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xdb0 + ldr x1, [x1] + sub x2, x29, #0xdb0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xdc0 + ldr x1, [x1] + sub x2, x29, #0xdc0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xdd0 + ldr x1, [x1] + sub x2, x29, #0xdd0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xde0 + ldr x1, [x1] + sub x2, x29, #0xde0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xdf0 + ldr x1, [x1] + sub x2, x29, #0xdf0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe00 + ldr x1, [x1] + sub x2, x29, #0xe00 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe10 + ldr x1, [x1] + sub x2, x29, #0xe10 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe20 + ldr x1, [x1] + sub x2, x29, #0xe20 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe30 + ldr x1, [x1] + sub x2, x29, #0xe30 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe40 + ldr x1, [x1] + sub x2, x29, #0xe40 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe50 + ldr x1, [x1] + sub x2, x29, #0xe50 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe60 + ldr x1, [x1] + sub x2, x29, #0xe60 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe70 + ldr x1, [x1] + sub x2, x29, #0xe70 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe80 + ldr x1, [x1] + sub x2, x29, #0xe80 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xe90 + ldr x1, [x1] + sub x2, x29, #0xe90 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xea0 + ldr x1, [x1] + sub x2, x29, #0xea0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xeb0 + ldr x1, [x1] + sub x2, x29, #0xeb0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xec0 + ldr x1, [x1] + sub x2, x29, #0xec0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xed0 + ldr x1, [x1] + sub x2, x29, #0xed0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xee0 + ldr x1, [x1] + sub x2, x29, #0xee0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xef0 + ldr x1, [x1] + sub x2, x29, #0xef0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf00 + ldr x1, [x1] + sub x2, x29, #0xf00 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf10 + ldr x1, [x1] + sub x2, x29, #0xf10 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf20 + ldr x1, [x1] + sub x2, x29, #0xf20 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf30 + ldr x1, [x1] + sub x2, x29, #0xf30 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf40 + ldr x1, [x1] + sub x2, x29, #0xf40 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf50 + ldr x1, [x1] + sub x2, x29, #0xf50 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf60 + ldr x1, [x1] + sub x2, x29, #0xf60 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf70 + ldr x1, [x1] + sub x2, x29, #0xf70 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf80 + ldr x1, [x1] + sub x2, x29, #0xf80 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xf90 + ldr x1, [x1] + sub x2, x29, #0xf90 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xfa0 + ldr x1, [x1] + sub x2, x29, #0xfa0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xfb0 + ldr x1, [x1] + sub x2, x29, #0xfb0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xfc0 + ldr x1, [x1] + sub x2, x29, #0xfc0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xfd0 + ldr x1, [x1] + sub x2, x29, #0xfd0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xfe0 + ldr x1, [x1] + sub x2, x29, #0xfe0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0xff0 + ldr x1, [x1] + sub x2, x29, #0xff0 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1, lsl #12 // =0x1000 + ldr x1, [x1] + sub x2, x29, #0x1, lsl #12 // =0x1000 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1, lsl #12 // =0x1000 + sub x1, x1, #0x10 + ldr x1, [x1] + sub x2, x29, #0x1, lsl #12 // =0x1000 + sub x2, x2, #0x10 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1, lsl #12 // =0x1000 + sub x1, x1, #0x20 + ldr x1, [x1] + sub x2, x29, #0x1, lsl #12 // =0x1000 + sub x2, x2, #0x20 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1, lsl #12 // =0x1000 + sub x1, x1, #0x30 + ldr x1, [x1] + sub x2, x29, #0x1, lsl #12 // =0x1000 + sub x2, x2, #0x30 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1, lsl #12 // =0x1000 + sub x1, x1, #0x40 + ldr x1, [x1] + sub x2, x29, #0x1, lsl #12 // =0x1000 + sub x2, x2, #0x40 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + sub x1, x29, #0x1, lsl #12 // =0x1000 + sub x1, x1, #0x50 + ldr x1, [x1] + sub x2, x29, #0x1, lsl #12 // =0x1000 + sub x2, x2, #0x50 + ldr x2, [x2, #0x8] + add x1, x1, x2 + add x0, x0, x1 + add sp, sp, #0x1, lsl #12 // =0x1000 + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x1, lsl #12 // =0x1000 + add sp, sp, #0x50 + ret + +: + sub sp, sp, #0xfc0 + ldr x16, [sp, #0xfc0] + str x16, [sp] + ldr x16, [sp, #0xfc8] + str x16, [sp, #0x10] + ldr x16, [sp, #0xfd0] + str x16, [sp, #0x20] + ldr x16, [sp, #0xfd8] + str x16, [sp, #0x30] + ldr x16, [sp, #0xfe0] + str x16, [sp, #0x40] + ldr x16, [sp, #0xfe8] + str x16, [sp, #0x50] + ldr x16, [sp, #0xff0] + str x16, [sp, #0x60] + ldr x16, [sp, #0xff8] + str x16, [sp, #0x70] + ldr x16, [sp, #0x1000] + str x16, [sp, #0x80] + ldr x16, [sp, #0x1008] + str x16, [sp, #0x90] + ldr x16, [sp, #0x1010] + str x16, [sp, #0xa0] + ldr x16, [sp, #0x1018] + str x16, [sp, #0xb0] + ldr x16, [sp, #0x1020] + str x16, [sp, #0xc0] + ldr x16, [sp, #0x1028] + str x16, [sp, #0xd0] + ldr x16, [sp, #0x1030] + str x16, [sp, #0xe0] + ldr x16, [sp, #0x1038] + str x16, [sp, #0xf0] + ldr x16, [sp, #0x1040] + str x16, [sp, #0x100] + ldr x16, [sp, #0x1048] + str x16, [sp, #0x110] + ldr x16, [sp, #0x1050] + str x16, [sp, #0x120] + ldr x16, [sp, #0x1058] + str x16, [sp, #0x130] + ldr x16, [sp, #0x1060] + str x16, [sp, #0x140] + ldr x16, [sp, #0x1068] + str x16, [sp, #0x150] + ldr x16, [sp, #0x1070] + str x16, [sp, #0x160] + ldr x16, [sp, #0x1078] + str x16, [sp, #0x170] + ldr x16, [sp, #0x1080] + str x16, [sp, #0x180] + ldr x16, [sp, #0x1088] + str x16, [sp, #0x190] + ldr x16, [sp, #0x1090] + str x16, [sp, #0x1a0] + ldr x16, [sp, #0x1098] + str x16, [sp, #0x1b0] + ldr x16, [sp, #0x10a0] + str x16, [sp, #0x1c0] + ldr x16, [sp, #0x10a8] + str x16, [sp, #0x1d0] + ldr x16, [sp, #0x10b0] + str x16, [sp, #0x1e0] + ldr x16, [sp, #0x10b8] + str x16, [sp, #0x1f0] + ldr x16, [sp, #0x10c0] + str x16, [sp, #0x200] + ldr x16, [sp, #0x10c8] + str x16, [sp, #0x210] + ldr x16, [sp, #0x10d0] + str x16, [sp, #0x220] + ldr x16, [sp, #0x10d8] + str x16, [sp, #0x230] + ldr x16, [sp, #0x10e0] + str x16, [sp, #0x240] + ldr x16, [sp, #0x10e8] + str x16, [sp, #0x250] + ldr x16, [sp, #0x10f0] + str x16, [sp, #0x260] + ldr x16, [sp, #0x10f8] + str x16, [sp, #0x270] + ldr x16, [sp, #0x1100] + str x16, [sp, #0x280] + ldr x16, [sp, #0x1108] + str x16, [sp, #0x290] + ldr x16, [sp, #0x1110] + str x16, [sp, #0x2a0] + ldr x16, [sp, #0x1118] + str x16, [sp, #0x2b0] + ldr x16, [sp, #0x1120] + str x16, [sp, #0x2c0] + ldr x16, [sp, #0x1128] + str x16, [sp, #0x2d0] + ldr x16, [sp, #0x1130] + str x16, [sp, #0x2e0] + ldr x16, [sp, #0x1138] + str x16, [sp, #0x2f0] + ldr x16, [sp, #0x1140] + str x16, [sp, #0x300] + ldr x16, [sp, #0x1148] + str x16, [sp, #0x310] + ldr x16, [sp, #0x1150] + str x16, [sp, #0x320] + ldr x16, [sp, #0x1158] + str x16, [sp, #0x330] + ldr x16, [sp, #0x1160] + str x16, [sp, #0x340] + ldr x16, [sp, #0x1168] + str x16, [sp, #0x350] + ldr x16, [sp, #0x1170] + str x16, [sp, #0x360] + ldr x16, [sp, #0x1178] + str x16, [sp, #0x370] + ldr x16, [sp, #0x1180] + str x16, [sp, #0x380] + ldr x16, [sp, #0x1188] + str x16, [sp, #0x390] + ldr x16, [sp, #0x1190] + str x16, [sp, #0x3a0] + ldr x16, [sp, #0x1198] + str x16, [sp, #0x3b0] + ldr x16, [sp, #0x11a0] + str x16, [sp, #0x3c0] + ldr x16, [sp, #0x11a8] + str x16, [sp, #0x3d0] + ldr x16, [sp, #0x11b0] + str x16, [sp, #0x3e0] + ldr x16, [sp, #0x11b8] + str x16, [sp, #0x3f0] + ldr x16, [sp, #0x11c0] + str x16, [sp, #0x400] + ldr x16, [sp, #0x11c8] + str x16, [sp, #0x410] + ldr x16, [sp, #0x11d0] + str x16, [sp, #0x420] + ldr x16, [sp, #0x11d8] + str x16, [sp, #0x430] + ldr x16, [sp, #0x11e0] + str x16, [sp, #0x440] + ldr x16, [sp, #0x11e8] + str x16, [sp, #0x450] + ldr x16, [sp, #0x11f0] + str x16, [sp, #0x460] + ldr x16, [sp, #0x11f8] + str x16, [sp, #0x470] + ldr x16, [sp, #0x1200] + str x16, [sp, #0x480] + ldr x16, [sp, #0x1208] + str x16, [sp, #0x490] + ldr x16, [sp, #0x1210] + str x16, [sp, #0x4a0] + ldr x16, [sp, #0x1218] + str x16, [sp, #0x4b0] + ldr x16, [sp, #0x1220] + str x16, [sp, #0x4c0] + ldr x16, [sp, #0x1228] + str x16, [sp, #0x4d0] + ldr x16, [sp, #0x1230] + str x16, [sp, #0x4e0] + ldr x16, [sp, #0x1238] + str x16, [sp, #0x4f0] + ldr x16, [sp, #0x1240] + str x16, [sp, #0x500] + ldr x16, [sp, #0x1248] + str x16, [sp, #0x510] + ldr x16, [sp, #0x1250] + str x16, [sp, #0x520] + ldr x16, [sp, #0x1258] + str x16, [sp, #0x530] + ldr x16, [sp, #0x1260] + str x16, [sp, #0x540] + ldr x16, [sp, #0x1268] + str x16, [sp, #0x550] + ldr x16, [sp, #0x1270] + str x16, [sp, #0x560] + ldr x16, [sp, #0x1278] + str x16, [sp, #0x570] + ldr x16, [sp, #0x1280] + str x16, [sp, #0x580] + ldr x16, [sp, #0x1288] + str x16, [sp, #0x590] + ldr x16, [sp, #0x1290] + str x16, [sp, #0x5a0] + ldr x16, [sp, #0x1298] + str x16, [sp, #0x5b0] + ldr x16, [sp, #0x12a0] + str x16, [sp, #0x5c0] + ldr x16, [sp, #0x12a8] + str x16, [sp, #0x5d0] + ldr x16, [sp, #0x12b0] + str x16, [sp, #0x5e0] + ldr x16, [sp, #0x12b8] + str x16, [sp, #0x5f0] + ldr x16, [sp, #0x12c0] + str x16, [sp, #0x600] + ldr x16, [sp, #0x12c8] + str x16, [sp, #0x610] + ldr x16, [sp, #0x12d0] + str x16, [sp, #0x620] + ldr x16, [sp, #0x12d8] + str x16, [sp, #0x630] + ldr x16, [sp, #0x12e0] + str x16, [sp, #0x640] + ldr x16, [sp, #0x12e8] + str x16, [sp, #0x650] + ldr x16, [sp, #0x12f0] + str x16, [sp, #0x660] + ldr x16, [sp, #0x12f8] + str x16, [sp, #0x670] + ldr x16, [sp, #0x1300] + str x16, [sp, #0x680] + ldr x16, [sp, #0x1308] + str x16, [sp, #0x690] + ldr x16, [sp, #0x1310] + str x16, [sp, #0x6a0] + ldr x16, [sp, #0x1318] + str x16, [sp, #0x6b0] + ldr x16, [sp, #0x1320] + str x16, [sp, #0x6c0] + ldr x16, [sp, #0x1328] + str x16, [sp, #0x6d0] + ldr x16, [sp, #0x1330] + str x16, [sp, #0x6e0] + ldr x16, [sp, #0x1338] + str x16, [sp, #0x6f0] + ldr x16, [sp, #0x1340] + str x16, [sp, #0x700] + ldr x16, [sp, #0x1348] + str x16, [sp, #0x710] + ldr x16, [sp, #0x1350] + str x16, [sp, #0x720] + ldr x16, [sp, #0x1358] + str x16, [sp, #0x730] + ldr x16, [sp, #0x1360] + str x16, [sp, #0x740] + ldr x16, [sp, #0x1368] + str x16, [sp, #0x750] + ldr x16, [sp, #0x1370] + str x16, [sp, #0x760] + ldr x16, [sp, #0x1378] + str x16, [sp, #0x770] + ldr x16, [sp, #0x1380] + str x16, [sp, #0x780] + ldr x16, [sp, #0x1388] + str x16, [sp, #0x790] + ldr x16, [sp, #0x1390] + str x16, [sp, #0x7a0] + ldr x16, [sp, #0x1398] + str x16, [sp, #0x7b0] + ldr x16, [sp, #0x13a0] + str x16, [sp, #0x7c0] + ldr x16, [sp, #0x13a8] + str x16, [sp, #0x7d0] + ldr x16, [sp, #0x13b0] + str x16, [sp, #0x7e0] + ldr x16, [sp, #0x13b8] + str x16, [sp, #0x7f0] + ldr x16, [sp, #0x13c0] + str x16, [sp, #0x800] + ldr x16, [sp, #0x13c8] + str x16, [sp, #0x810] + ldr x16, [sp, #0x13d0] + str x16, [sp, #0x820] + ldr x16, [sp, #0x13d8] + str x16, [sp, #0x830] + ldr x16, [sp, #0x13e0] + str x16, [sp, #0x840] + ldr x16, [sp, #0x13e8] + str x16, [sp, #0x850] + ldr x16, [sp, #0x13f0] + str x16, [sp, #0x860] + ldr x16, [sp, #0x13f8] + str x16, [sp, #0x870] + ldr x16, [sp, #0x1400] + str x16, [sp, #0x880] + ldr x16, [sp, #0x1408] + str x16, [sp, #0x890] + ldr x16, [sp, #0x1410] + str x16, [sp, #0x8a0] + ldr x16, [sp, #0x1418] + str x16, [sp, #0x8b0] + ldr x16, [sp, #0x1420] + str x16, [sp, #0x8c0] + ldr x16, [sp, #0x1428] + str x16, [sp, #0x8d0] + ldr x16, [sp, #0x1430] + str x16, [sp, #0x8e0] + ldr x16, [sp, #0x1438] + str x16, [sp, #0x8f0] + ldr x16, [sp, #0x1440] + str x16, [sp, #0x900] + ldr x16, [sp, #0x1448] + str x16, [sp, #0x910] + ldr x16, [sp, #0x1450] + str x16, [sp, #0x920] + ldr x16, [sp, #0x1458] + str x16, [sp, #0x930] + ldr x16, [sp, #0x1460] + str x16, [sp, #0x940] + ldr x16, [sp, #0x1468] + str x16, [sp, #0x950] + ldr x16, [sp, #0x1470] + str x16, [sp, #0x960] + ldr x16, [sp, #0x1478] + str x16, [sp, #0x970] + ldr x16, [sp, #0x1480] + str x16, [sp, #0x980] + ldr x16, [sp, #0x1488] + str x16, [sp, #0x990] + ldr x16, [sp, #0x1490] + str x16, [sp, #0x9a0] + ldr x16, [sp, #0x1498] + str x16, [sp, #0x9b0] + ldr x16, [sp, #0x14a0] + str x16, [sp, #0x9c0] + ldr x16, [sp, #0x14a8] + str x16, [sp, #0x9d0] + ldr x16, [sp, #0x14b0] + str x16, [sp, #0x9e0] + ldr x16, [sp, #0x14b8] + str x16, [sp, #0x9f0] + ldr x16, [sp, #0x14c0] + str x16, [sp, #0xa00] + ldr x16, [sp, #0x14c8] + str x16, [sp, #0xa10] + ldr x16, [sp, #0x14d0] + str x16, [sp, #0xa20] + ldr x16, [sp, #0x14d8] + str x16, [sp, #0xa30] + ldr x16, [sp, #0x14e0] + str x16, [sp, #0xa40] + ldr x16, [sp, #0x14e8] + str x16, [sp, #0xa50] + ldr x16, [sp, #0x14f0] + str x16, [sp, #0xa60] + ldr x16, [sp, #0x14f8] + str x16, [sp, #0xa70] + ldr x16, [sp, #0x1500] + str x16, [sp, #0xa80] + ldr x16, [sp, #0x1508] + str x16, [sp, #0xa90] + ldr x16, [sp, #0x1510] + str x16, [sp, #0xaa0] + ldr x16, [sp, #0x1518] + str x16, [sp, #0xab0] + ldr x16, [sp, #0x1520] + str x16, [sp, #0xac0] + ldr x16, [sp, #0x1528] + str x16, [sp, #0xad0] + ldr x16, [sp, #0x1530] + str x16, [sp, #0xae0] + ldr x16, [sp, #0x1538] + str x16, [sp, #0xaf0] + ldr x16, [sp, #0x1540] + str x16, [sp, #0xb00] + ldr x16, [sp, #0x1548] + str x16, [sp, #0xb10] + ldr x16, [sp, #0x1550] + str x16, [sp, #0xb20] + ldr x16, [sp, #0x1558] + str x16, [sp, #0xb30] + ldr x16, [sp, #0x1560] + str x16, [sp, #0xb40] + ldr x16, [sp, #0x1568] + str x16, [sp, #0xb50] + ldr x16, [sp, #0x1570] + str x16, [sp, #0xb60] + ldr x16, [sp, #0x1578] + str x16, [sp, #0xb70] + ldr x16, [sp, #0x1580] + str x16, [sp, #0xb80] + ldr x16, [sp, #0x1588] + str x16, [sp, #0xb90] + ldr x16, [sp, #0x1590] + str x16, [sp, #0xba0] + ldr x16, [sp, #0x1598] + str x16, [sp, #0xbb0] + ldr x16, [sp, #0x15a0] + str x16, [sp, #0xbc0] + ldr x16, [sp, #0x15a8] + str x16, [sp, #0xbd0] + ldr x16, [sp, #0x15b0] + str x16, [sp, #0xbe0] + ldr x16, [sp, #0x15b8] + str x16, [sp, #0xbf0] + ldr x16, [sp, #0x15c0] + str x16, [sp, #0xc00] + ldr x16, [sp, #0x15c8] + str x16, [sp, #0xc10] + ldr x16, [sp, #0x15d0] + str x16, [sp, #0xc20] + ldr x16, [sp, #0x15d8] + str x16, [sp, #0xc30] + ldr x16, [sp, #0x15e0] + str x16, [sp, #0xc40] + ldr x16, [sp, #0x15e8] + str x16, [sp, #0xc50] + ldr x16, [sp, #0x15f0] + str x16, [sp, #0xc60] + ldr x16, [sp, #0x15f8] + str x16, [sp, #0xc70] + ldr x16, [sp, #0x1600] + str x16, [sp, #0xc80] + ldr x16, [sp, #0x1608] + str x16, [sp, #0xc90] + ldr x16, [sp, #0x1610] + str x16, [sp, #0xca0] + ldr x16, [sp, #0x1618] + str x16, [sp, #0xcb0] + ldr x16, [sp, #0x1620] + str x16, [sp, #0xcc0] + ldr x16, [sp, #0x1628] + str x16, [sp, #0xcd0] + ldr x16, [sp, #0x1630] + str x16, [sp, #0xce0] + ldr x16, [sp, #0x1638] + str x16, [sp, #0xcf0] + ldr x16, [sp, #0x1640] + str x16, [sp, #0xd00] + ldr x16, [sp, #0x1648] + str x16, [sp, #0xd10] + ldr x16, [sp, #0x1650] + str x16, [sp, #0xd20] + ldr x16, [sp, #0x1658] + str x16, [sp, #0xd30] + ldr x16, [sp, #0x1660] + str x16, [sp, #0xd40] + ldr x16, [sp, #0x1668] + str x16, [sp, #0xd50] + ldr x16, [sp, #0x1670] + str x16, [sp, #0xd60] + ldr x16, [sp, #0x1678] + str x16, [sp, #0xd70] + ldr x16, [sp, #0x1680] + str x16, [sp, #0xd80] + ldr x16, [sp, #0x1688] + str x16, [sp, #0xd90] + ldr x16, [sp, #0x1690] + str x16, [sp, #0xda0] + ldr x16, [sp, #0x1698] + str x16, [sp, #0xdb0] + ldr x16, [sp, #0x16a0] + str x16, [sp, #0xdc0] + ldr x16, [sp, #0x16a8] + str x16, [sp, #0xdd0] + ldr x16, [sp, #0x16b0] + str x16, [sp, #0xde0] + ldr x16, [sp, #0x16b8] + str x16, [sp, #0xdf0] + ldr x16, [sp, #0x16c0] + str x16, [sp, #0xe00] + ldr x16, [sp, #0x16c8] + str x16, [sp, #0xe10] + ldr x16, [sp, #0x16d0] + str x16, [sp, #0xe20] + ldr x16, [sp, #0x16d8] + str x16, [sp, #0xe30] + ldr x16, [sp, #0x16e0] + str x16, [sp, #0xe40] + ldr x16, [sp, #0x16e8] + str x16, [sp, #0xe50] + ldr x16, [sp, #0x16f0] + str x16, [sp, #0xe60] + ldr x16, [sp, #0x16f8] + str x16, [sp, #0xe70] + ldr x16, [sp, #0x1700] + str x16, [sp, #0xe80] + ldr x16, [sp, #0x1708] + str x16, [sp, #0xe90] + ldr x16, [sp, #0x1710] + str x16, [sp, #0xea0] + ldr x16, [sp, #0x1718] + str x16, [sp, #0xeb0] + ldr x16, [sp, #0x1720] + str x16, [sp, #0xec0] + ldr x16, [sp, #0x1728] + str x16, [sp, #0xed0] + ldr x16, [sp, #0x1730] + str x16, [sp, #0xee0] + ldr x16, [sp, #0x1738] + str x16, [sp, #0xef0] + ldr x16, [sp, #0x1740] + str x16, [sp, #0xf00] + ldr x16, [sp, #0x1748] + str x16, [sp, #0xf10] + ldr x16, [sp, #0x1750] + str x16, [sp, #0xf20] + ldr x16, [sp, #0x1758] + str x16, [sp, #0xf30] + ldr x16, [sp, #0x1760] + str x16, [sp, #0xf40] + ldr x16, [sp, #0x1768] + str x16, [sp, #0xf50] + ldr x16, [sp, #0x1770] + str x16, [sp, #0xf60] + ldr x16, [sp, #0x1778] + str x16, [sp, #0xf70] + ldr x16, [sp, #0x1780] + str x16, [sp, #0xf80] + ldr x16, [sp, #0x1788] + str x16, [sp, #0xf90] + ldr x16, [sp, #0x1790] + str x16, [sp, #0xfa0] + ldr x16, [sp, #0x1798] + str x16, [sp, #0xfb0] + sub sp, sp, #0x80 + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + mov x8, #0x0 // =0 + add x0, x8, x0 + add x0, x0, x1 + add x0, x0, x2 + add x0, x0, x3 + add x0, x0, x4 + add x0, x0, x5 + add x0, x0, x6 + add x0, x0, x7 + ldur x1, [x29, #0x90] + add x0, x0, x1 + ldur x1, [x29, #0xa0] + add x0, x0, x1 + ldur x1, [x29, #0xb0] + add x0, x0, x1 + ldur x1, [x29, #0xc0] + add x0, x0, x1 + ldur x1, [x29, #0xd0] + add x0, x0, x1 + ldur x1, [x29, #0xe0] + add x0, x0, x1 + ldur x1, [x29, #0xf0] + add x0, x0, x1 + add x16, x29, #0x100 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x110 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x120 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x130 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x140 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x150 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x160 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x170 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x180 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x190 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1a0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1b0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1c0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1d0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1e0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1f0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x200 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x210 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x220 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x230 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x240 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x250 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x260 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x270 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x280 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x290 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x2a0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x2b0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x2c0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x2d0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x2e0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x2f0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x300 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x310 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x320 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x330 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x340 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x350 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x360 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x370 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x380 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x390 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x3a0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x3b0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x3c0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x3d0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x3e0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x3f0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x400 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x410 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x420 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x430 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x440 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x450 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x460 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x470 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x480 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x490 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x4a0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x4b0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x4c0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x4d0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x4e0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x4f0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x500 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x510 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x520 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x530 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x540 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x550 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x560 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x570 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x580 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x590 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x5a0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x5b0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x5c0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x5d0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x5e0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x5f0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x600 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x610 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x620 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x630 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x640 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x650 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x660 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x670 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x680 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x690 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x6a0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x6b0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x6c0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x6d0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x6e0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x6f0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x700 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x710 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x720 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x730 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x740 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x750 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x760 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x770 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x780 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x790 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x7a0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x7b0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x7c0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x7d0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x7e0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x7f0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x800 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x810 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x820 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x830 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x840 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x850 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x860 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x870 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x880 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x890 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x8a0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x8b0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x8c0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x8d0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x8e0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x8f0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x900 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x910 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x920 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x930 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x940 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x950 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x960 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x970 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x980 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x990 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x9a0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x9b0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x9c0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x9d0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x9e0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x9f0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xa00 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xa10 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xa20 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xa30 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xa40 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xa50 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xa60 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xa70 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xa80 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xa90 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xaa0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xab0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xac0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xad0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xae0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xaf0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xb00 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xb10 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xb20 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xb30 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xb40 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xb50 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xb60 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xb70 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xb80 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xb90 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xba0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xbb0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xbc0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xbd0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xbe0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xbf0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xc00 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xc10 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xc20 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xc30 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xc40 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xc50 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xc60 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xc70 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xc80 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xc90 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xca0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xcb0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xcc0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xcd0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xce0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xcf0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xd00 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xd10 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xd20 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xd30 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xd40 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xd50 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xd60 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xd70 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xd80 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xd90 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xda0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xdb0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xdc0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xdd0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xde0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xdf0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xe00 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xe10 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xe20 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xe30 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xe40 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xe50 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xe60 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xe70 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xe80 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xe90 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xea0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xeb0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xec0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xed0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xee0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xef0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xf00 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xf10 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xf20 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xf30 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xf40 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xf50 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xf60 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xf70 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xf80 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xf90 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xfa0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xfb0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xfc0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xfd0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xfe0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0xff0 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1, lsl #12 // =0x1000 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1, lsl #12 // =0x1000 + add x16, x16, #0x10 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1, lsl #12 // =0x1000 + add x16, x16, #0x20 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1, lsl #12 // =0x1000 + add x16, x16, #0x30 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x1, lsl #12 // =0x1000 + add x16, x16, #0x40 + ldr x1, [x16] + add x0, x0, x1 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x1, lsl #12 // =0x1000 + add sp, sp, #0x40 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x1, lsl #12 // =0x1000 + sub sp, sp, #0x10 + str x20, [sp] + str x21, [sp, #0x8] + str x22, [sp, #0x10] + str x23, [sp, #0x18] + str x24, [sp, #0x20] + str x25, [sp, #0x28] + str x26, [sp, #0x30] + str x27, [sp, #0x38] + str x28, [sp, #0x40] + str x19, [sp, #0x50] + adrp x20, + add x20, x20, #0x370 + adrp x21, + add x21, x21, + mov x1, #0x0 // =0 + cmp x1, #0x105 + b.ge + b + add x1, x1, #0x1 + b + adrp x0, + add x0, x0, + lsl x2, x1, #4 + add x2, x0, x2 + str x1, [x2] + lsl x2, x1, #4 + add x0, x0, x2 + lsl x2, x1, #1 + str x2, [x0, #0x8] + b + adrp x0, + add x0, x0, + add x1, x0, #0x10 + add x2, x0, #0x20 + add x3, x0, #0x30 + add x4, x0, #0x40 + add x5, x0, #0x50 + add x6, x0, #0x60 + add x7, x0, #0x70 + add x8, x0, #0x80 + add x9, x0, #0x90 + add x10, x0, #0xa0 + add x11, x0, #0xb0 + add x12, x0, #0xc0 + add x13, x0, #0xd0 + add x14, x0, #0xe0 + add x15, x0, #0xf0 + add x22, x0, #0x100 + add x23, x0, #0x110 + add x24, x0, #0x120 + add x25, x0, #0x130 + add x26, x0, #0x140 + add x27, x0, #0x150 + add x28, x0, #0x160 + add x16, x0, #0x170 + str x16, [sp, #0x7c8] + add x16, x0, #0x180 + str x16, [sp, #0x7c0] + add x16, x0, #0x190 + str x16, [sp, #0x7b8] + add x16, x0, #0x1a0 + str x16, [sp, #0x7b0] + add x16, x0, #0x1b0 + str x16, [sp, #0x7a8] + add x16, x0, #0x1c0 + str x16, [sp, #0x7a0] + add x16, x0, #0x1d0 + str x16, [sp, #0x798] + add x16, x0, #0x1e0 + str x16, [sp, #0x790] + add x16, x0, #0x1f0 + str x16, [sp, #0x788] + add x16, x0, #0x200 + str x16, [sp, #0x780] + add x16, x0, #0x210 + str x16, [sp, #0x778] + add x16, x0, #0x220 + str x16, [sp, #0x770] + add x16, x0, #0x230 + str x16, [sp, #0x768] + add x16, x0, #0x240 + str x16, [sp, #0x760] + add x16, x0, #0x250 + str x16, [sp, #0x758] + add x16, x0, #0x260 + str x16, [sp, #0x750] + add x16, x0, #0x270 + str x16, [sp, #0x748] + add x16, x0, #0x280 + str x16, [sp, #0x740] + add x16, x0, #0x290 + str x16, [sp, #0x738] + add x16, x0, #0x2a0 + str x16, [sp, #0x730] + add x16, x0, #0x2b0 + str x16, [sp, #0x728] + add x16, x0, #0x2c0 + str x16, [sp, #0x720] + add x16, x0, #0x2d0 + str x16, [sp, #0x718] + add x16, x0, #0x2e0 + str x16, [sp, #0x710] + add x16, x0, #0x2f0 + str x16, [sp, #0x708] + add x16, x0, #0x300 + str x16, [sp, #0x700] + add x16, x0, #0x310 + str x16, [sp, #0x6f8] + add x16, x0, #0x320 + str x16, [sp, #0x6f0] + add x16, x0, #0x330 + str x16, [sp, #0x6e8] + add x16, x0, #0x340 + str x16, [sp, #0x6e0] + add x16, x0, #0x350 + str x16, [sp, #0x6d8] + add x16, x0, #0x360 + str x16, [sp, #0x6d0] + add x16, x0, #0x370 + str x16, [sp, #0x6c8] + add x16, x0, #0x380 + str x16, [sp, #0x6c0] + add x16, x0, #0x390 + str x16, [sp, #0x6b8] + add x16, x0, #0x3a0 + str x16, [sp, #0x6b0] + add x16, x0, #0x3b0 + str x16, [sp, #0x6a8] + add x16, x0, #0x3c0 + str x16, [sp, #0x6a0] + add x16, x0, #0x3d0 + str x16, [sp, #0x698] + add x16, x0, #0x3e0 + str x16, [sp, #0x690] + add x16, x0, #0x3f0 + str x16, [sp, #0x688] + add x16, x0, #0x400 + str x16, [sp, #0x680] + add x16, x0, #0x410 + str x16, [sp, #0x678] + add x16, x0, #0x420 + str x16, [sp, #0x670] + add x16, x0, #0x430 + str x16, [sp, #0x668] + add x16, x0, #0x440 + str x16, [sp, #0x660] + add x16, x0, #0x450 + str x16, [sp, #0x658] + add x16, x0, #0x460 + str x16, [sp, #0x650] + add x16, x0, #0x470 + str x16, [sp, #0x648] + add x16, x0, #0x480 + str x16, [sp, #0x640] + add x16, x0, #0x490 + str x16, [sp, #0x638] + add x16, x0, #0x4a0 + str x16, [sp, #0x630] + add x16, x0, #0x4b0 + str x16, [sp, #0x628] + add x16, x0, #0x4c0 + str x16, [sp, #0x620] + add x16, x0, #0x4d0 + str x16, [sp, #0x618] + add x16, x0, #0x4e0 + str x16, [sp, #0x610] + add x16, x0, #0x4f0 + str x16, [sp, #0x608] + add x16, x0, #0x500 + str x16, [sp, #0x600] + add x16, x0, #0x510 + str x16, [sp, #0x5f8] + add x16, x0, #0x520 + str x16, [sp, #0x5f0] + add x16, x0, #0x530 + str x16, [sp, #0x5e8] + add x16, x0, #0x540 + str x16, [sp, #0x5e0] + add x16, x0, #0x550 + str x16, [sp, #0x5d8] + add x16, x0, #0x560 + str x16, [sp, #0x5d0] + add x16, x0, #0x570 + str x16, [sp, #0x5c8] + add x16, x0, #0x580 + str x16, [sp, #0x5c0] + add x16, x0, #0x590 + str x16, [sp, #0x5b8] + add x16, x0, #0x5a0 + str x16, [sp, #0x5b0] + add x16, x0, #0x5b0 + str x16, [sp, #0x5a8] + add x16, x0, #0x5c0 + str x16, [sp, #0x5a0] + add x16, x0, #0x5d0 + str x16, [sp, #0x598] + add x16, x0, #0x5e0 + str x16, [sp, #0x590] + add x16, x0, #0x5f0 + str x16, [sp, #0x588] + add x16, x0, #0x600 + str x16, [sp, #0x580] + add x16, x0, #0x610 + str x16, [sp, #0x578] + add x16, x0, #0x620 + str x16, [sp, #0x570] + add x16, x0, #0x630 + str x16, [sp, #0x568] + add x16, x0, #0x640 + str x16, [sp, #0x560] + add x16, x0, #0x650 + str x16, [sp, #0x558] + add x16, x0, #0x660 + str x16, [sp, #0x550] + add x16, x0, #0x670 + str x16, [sp, #0x548] + add x16, x0, #0x680 + str x16, [sp, #0x540] + add x16, x0, #0x690 + str x16, [sp, #0x538] + add x16, x0, #0x6a0 + str x16, [sp, #0x530] + add x16, x0, #0x6b0 + str x16, [sp, #0x528] + add x16, x0, #0x6c0 + str x16, [sp, #0x520] + add x16, x0, #0x6d0 + str x16, [sp, #0x518] + add x16, x0, #0x6e0 + str x16, [sp, #0x510] + add x16, x0, #0x6f0 + str x16, [sp, #0x508] + add x16, x0, #0x700 + str x16, [sp, #0x500] + add x16, x0, #0x710 + str x16, [sp, #0x4f8] + add x16, x0, #0x720 + str x16, [sp, #0x4f0] + add x16, x0, #0x730 + str x16, [sp, #0x4e8] + add x16, x0, #0x740 + str x16, [sp, #0x4e0] + add x16, x0, #0x750 + str x16, [sp, #0x4d8] + add x16, x0, #0x760 + str x16, [sp, #0x4d0] + add x16, x0, #0x770 + str x16, [sp, #0x4c8] + add x16, x0, #0x780 + str x16, [sp, #0x4c0] + add x16, x0, #0x790 + str x16, [sp, #0x4b8] + add x16, x0, #0x7a0 + str x16, [sp, #0x4b0] + add x16, x0, #0x7b0 + str x16, [sp, #0x4a8] + add x16, x0, #0x7c0 + str x16, [sp, #0x4a0] + add x16, x0, #0x7d0 + str x16, [sp, #0x498] + add x16, x0, #0x7e0 + str x16, [sp, #0x490] + add x16, x0, #0x7f0 + str x16, [sp, #0x488] + add x16, x0, #0x800 + str x16, [sp, #0x480] + add x16, x0, #0x810 + str x16, [sp, #0x478] + add x16, x0, #0x820 + str x16, [sp, #0x470] + add x16, x0, #0x830 + str x16, [sp, #0x468] + add x16, x0, #0x840 + str x16, [sp, #0x460] + add x16, x0, #0x850 + str x16, [sp, #0x458] + add x16, x0, #0x860 + str x16, [sp, #0x450] + add x16, x0, #0x870 + str x16, [sp, #0x448] + add x16, x0, #0x880 + str x16, [sp, #0x440] + add x16, x0, #0x890 + str x16, [sp, #0x438] + add x16, x0, #0x8a0 + str x16, [sp, #0x430] + add x16, x0, #0x8b0 + str x16, [sp, #0x428] + add x16, x0, #0x8c0 + str x16, [sp, #0x420] + add x16, x0, #0x8d0 + str x16, [sp, #0x418] + add x16, x0, #0x8e0 + str x16, [sp, #0x410] + add x16, x0, #0x8f0 + str x16, [sp, #0x408] + add x16, x0, #0x900 + str x16, [sp, #0x400] + add x16, x0, #0x910 + str x16, [sp, #0x3f8] + add x16, x0, #0x920 + str x16, [sp, #0x3f0] + add x16, x0, #0x930 + str x16, [sp, #0x3e8] + add x16, x0, #0x940 + str x16, [sp, #0x3e0] + add x16, x0, #0x950 + str x16, [sp, #0x3d8] + add x16, x0, #0x960 + str x16, [sp, #0x3d0] + add x16, x0, #0x970 + str x16, [sp, #0x3c8] + add x16, x0, #0x980 + str x16, [sp, #0x3c0] + add x16, x0, #0x990 + str x16, [sp, #0x3b8] + add x16, x0, #0x9a0 + str x16, [sp, #0x3b0] + add x16, x0, #0x9b0 + str x16, [sp, #0x3a8] + add x16, x0, #0x9c0 + str x16, [sp, #0x3a0] + add x16, x0, #0x9d0 + str x16, [sp, #0x398] + add x16, x0, #0x9e0 + str x16, [sp, #0x390] + add x16, x0, #0x9f0 + str x16, [sp, #0x388] + add x16, x0, #0xa00 + str x16, [sp, #0x380] + add x16, x0, #0xa10 + str x16, [sp, #0x378] + add x16, x0, #0xa20 + str x16, [sp, #0x370] + add x16, x0, #0xa30 + str x16, [sp, #0x368] + add x16, x0, #0xa40 + str x16, [sp, #0x360] + add x16, x0, #0xa50 + str x16, [sp, #0x358] + add x16, x0, #0xa60 + str x16, [sp, #0x350] + add x16, x0, #0xa70 + str x16, [sp, #0x348] + add x16, x0, #0xa80 + str x16, [sp, #0x340] + add x16, x0, #0xa90 + str x16, [sp, #0x338] + add x16, x0, #0xaa0 + str x16, [sp, #0x330] + add x16, x0, #0xab0 + str x16, [sp, #0x328] + add x16, x0, #0xac0 + str x16, [sp, #0x320] + add x16, x0, #0xad0 + str x16, [sp, #0x318] + add x16, x0, #0xae0 + str x16, [sp, #0x310] + add x16, x0, #0xaf0 + str x16, [sp, #0x308] + add x16, x0, #0xb00 + str x16, [sp, #0x300] + add x16, x0, #0xb10 + str x16, [sp, #0x2f8] + add x16, x0, #0xb20 + str x16, [sp, #0x2f0] + add x16, x0, #0xb30 + str x16, [sp, #0x2e8] + add x16, x0, #0xb40 + str x16, [sp, #0x2e0] + add x16, x0, #0xb50 + str x16, [sp, #0x2d8] + add x16, x0, #0xb60 + str x16, [sp, #0x2d0] + add x16, x0, #0xb70 + str x16, [sp, #0x2c8] + add x16, x0, #0xb80 + str x16, [sp, #0x2c0] + add x16, x0, #0xb90 + str x16, [sp, #0x2b8] + add x16, x0, #0xba0 + str x16, [sp, #0x2b0] + add x16, x0, #0xbb0 + str x16, [sp, #0x2a8] + add x16, x0, #0xbc0 + str x16, [sp, #0x2a0] + add x16, x0, #0xbd0 + str x16, [sp, #0x298] + add x16, x0, #0xbe0 + str x16, [sp, #0x290] + add x16, x0, #0xbf0 + str x16, [sp, #0x288] + add x16, x0, #0xc00 + str x16, [sp, #0x280] + add x16, x0, #0xc10 + str x16, [sp, #0x278] + add x16, x0, #0xc20 + str x16, [sp, #0x270] + add x16, x0, #0xc30 + str x16, [sp, #0x268] + add x16, x0, #0xc40 + str x16, [sp, #0x260] + add x16, x0, #0xc50 + str x16, [sp, #0x258] + add x16, x0, #0xc60 + str x16, [sp, #0x250] + add x16, x0, #0xc70 + str x16, [sp, #0x248] + add x16, x0, #0xc80 + str x16, [sp, #0x240] + add x16, x0, #0xc90 + str x16, [sp, #0x238] + add x16, x0, #0xca0 + str x16, [sp, #0x230] + add x16, x0, #0xcb0 + str x16, [sp, #0x228] + add x16, x0, #0xcc0 + str x16, [sp, #0x220] + add x16, x0, #0xcd0 + str x16, [sp, #0x218] + add x16, x0, #0xce0 + str x16, [sp, #0x210] + add x16, x0, #0xcf0 + str x16, [sp, #0x208] + add x16, x0, #0xd00 + str x16, [sp, #0x200] + add x16, x0, #0xd10 + str x16, [sp, #0x1f8] + add x16, x0, #0xd20 + str x16, [sp, #0x1f0] + add x16, x0, #0xd30 + str x16, [sp, #0x1e8] + add x16, x0, #0xd40 + str x16, [sp, #0x1e0] + add x16, x0, #0xd50 + str x16, [sp, #0x1d8] + add x16, x0, #0xd60 + str x16, [sp, #0x1d0] + add x16, x0, #0xd70 + str x16, [sp, #0x1c8] + add x16, x0, #0xd80 + str x16, [sp, #0x1c0] + add x16, x0, #0xd90 + str x16, [sp, #0x1b8] + add x16, x0, #0xda0 + str x16, [sp, #0x1b0] + add x16, x0, #0xdb0 + str x16, [sp, #0x1a8] + add x16, x0, #0xdc0 + str x16, [sp, #0x1a0] + add x16, x0, #0xdd0 + str x16, [sp, #0x198] + add x16, x0, #0xde0 + str x16, [sp, #0x190] + add x16, x0, #0xdf0 + str x16, [sp, #0x188] + add x16, x0, #0xe00 + str x16, [sp, #0x180] + add x16, x0, #0xe10 + str x16, [sp, #0x178] + add x16, x0, #0xe20 + str x16, [sp, #0x170] + add x16, x0, #0xe30 + str x16, [sp, #0x168] + add x16, x0, #0xe40 + str x16, [sp, #0x160] + add x16, x0, #0xe50 + str x16, [sp, #0x158] + add x16, x0, #0xe60 + str x16, [sp, #0x150] + add x16, x0, #0xe70 + str x16, [sp, #0x148] + add x16, x0, #0xe80 + str x16, [sp, #0x140] + add x16, x0, #0xe90 + str x16, [sp, #0x138] + add x16, x0, #0xea0 + str x16, [sp, #0x130] + add x16, x0, #0xeb0 + str x16, [sp, #0x128] + add x16, x0, #0xec0 + str x16, [sp, #0x120] + add x16, x0, #0xed0 + str x16, [sp, #0x118] + add x16, x0, #0xee0 + str x16, [sp, #0x110] + add x16, x0, #0xef0 + str x16, [sp, #0x108] + add x16, x0, #0xf00 + str x16, [sp, #0x100] + add x16, x0, #0xf10 + str x16, [sp, #0xf8] + add x16, x0, #0xf20 + str x16, [sp, #0xf0] + add x16, x0, #0xf30 + str x16, [sp, #0xe8] + add x16, x0, #0xf40 + str x16, [sp, #0xe0] + add x16, x0, #0xf50 + str x16, [sp, #0xd8] + add x16, x0, #0xf60 + str x16, [sp, #0xd0] + add x16, x0, #0xf70 + str x16, [sp, #0xc8] + add x16, x0, #0xf80 + str x16, [sp, #0xc0] + add x16, x0, #0xf90 + str x16, [sp, #0xb8] + add x16, x0, #0xfa0 + str x16, [sp, #0xb0] + add x16, x0, #0xfb0 + str x16, [sp, #0xa8] + add x16, x0, #0xfc0 + str x16, [sp, #0xa0] + add x16, x0, #0xfd0 + str x16, [sp, #0x98] + add x16, x0, #0xfe0 + str x16, [sp, #0x90] + add x16, x0, #0xff0 + str x16, [sp, #0x88] + mov x17, #0x1000 // =4096 + add x16, x0, x17 + str x16, [sp, #0x80] + mov x17, #0x1010 // =4112 + add x16, x0, x17 + str x16, [sp, #0x78] + mov x17, #0x1020 // =4128 + add x16, x0, x17 + str x16, [sp, #0x70] + mov x17, #0x1030 // =4144 + add x16, x0, x17 + str x16, [sp, #0x68] + mov x17, #0x1040 // =4160 + add x16, x0, x17 + str x16, [sp, #0x60] + sub sp, sp, #0x1, lsl #12 // =0x1000 + sub sp, sp, #0x10 + mov x16, x4 + ldr x17, [x16] + str x17, [sp] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8] + mov x16, x5 + ldr x17, [x16] + str x17, [sp, #0x10] + ldr x17, [x16, #0x8] + str x17, [sp, #0x18] + mov x16, x6 + ldr x17, [x16] + str x17, [sp, #0x20] + ldr x17, [x16, #0x8] + str x17, [sp, #0x28] + mov x16, x7 + ldr x17, [x16] + str x17, [sp, #0x30] + ldr x17, [x16, #0x8] + str x17, [sp, #0x38] + mov x16, x8 + ldr x17, [x16] + str x17, [sp, #0x40] + ldr x17, [x16, #0x8] + str x17, [sp, #0x48] + mov x16, x9 + ldr x17, [x16] + str x17, [sp, #0x50] + ldr x17, [x16, #0x8] + str x17, [sp, #0x58] + mov x16, x10 + ldr x17, [x16] + str x17, [sp, #0x60] + ldr x17, [x16, #0x8] + str x17, [sp, #0x68] + mov x16, x11 + ldr x17, [x16] + str x17, [sp, #0x70] + ldr x17, [x16, #0x8] + str x17, [sp, #0x78] + mov x16, x12 + ldr x17, [x16] + str x17, [sp, #0x80] + ldr x17, [x16, #0x8] + str x17, [sp, #0x88] + mov x16, x13 + ldr x17, [x16] + str x17, [sp, #0x90] + ldr x17, [x16, #0x8] + str x17, [sp, #0x98] + mov x16, x14 + ldr x17, [x16] + str x17, [sp, #0xa0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa8] + mov x16, x15 + ldr x17, [x16] + str x17, [sp, #0xb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb8] + mov x16, x22 + ldr x17, [x16] + str x17, [sp, #0xc0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc8] + mov x16, x23 + ldr x17, [x16] + str x17, [sp, #0xd0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd8] + mov x16, x24 + ldr x17, [x16] + str x17, [sp, #0xe0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe8] + mov x16, x25 + ldr x17, [x16] + str x17, [sp, #0xf0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf8] + mov x16, x26 + ldr x17, [x16] + str x17, [sp, #0x100] + ldr x17, [x16, #0x8] + str x17, [sp, #0x108] + mov x16, x27 + ldr x17, [x16] + str x17, [sp, #0x110] + ldr x17, [x16, #0x8] + str x17, [sp, #0x118] + mov x16, x28 + ldr x17, [x16] + str x17, [sp, #0x120] + ldr x17, [x16, #0x8] + str x17, [sp, #0x128] + ldr x16, [sp, #0x17d8] + ldr x17, [x16] + str x17, [sp, #0x130] + ldr x17, [x16, #0x8] + str x17, [sp, #0x138] + ldr x16, [sp, #0x17d0] + ldr x17, [x16] + str x17, [sp, #0x140] + ldr x17, [x16, #0x8] + str x17, [sp, #0x148] + ldr x16, [sp, #0x17c8] + ldr x17, [x16] + str x17, [sp, #0x150] + ldr x17, [x16, #0x8] + str x17, [sp, #0x158] + ldr x16, [sp, #0x17c0] + ldr x17, [x16] + str x17, [sp, #0x160] + ldr x17, [x16, #0x8] + str x17, [sp, #0x168] + ldr x16, [sp, #0x17b8] + ldr x17, [x16] + str x17, [sp, #0x170] + ldr x17, [x16, #0x8] + str x17, [sp, #0x178] + ldr x16, [sp, #0x17b0] + ldr x17, [x16] + str x17, [sp, #0x180] + ldr x17, [x16, #0x8] + str x17, [sp, #0x188] + ldr x16, [sp, #0x17a8] + ldr x17, [x16] + str x17, [sp, #0x190] + ldr x17, [x16, #0x8] + str x17, [sp, #0x198] + ldr x16, [sp, #0x17a0] + ldr x17, [x16] + str x17, [sp, #0x1a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1a8] + ldr x16, [sp, #0x1798] + ldr x17, [x16] + str x17, [sp, #0x1b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1b8] + ldr x16, [sp, #0x1790] + ldr x17, [x16] + str x17, [sp, #0x1c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1c8] + ldr x16, [sp, #0x1788] + ldr x17, [x16] + str x17, [sp, #0x1d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1d8] + ldr x16, [sp, #0x1780] + ldr x17, [x16] + str x17, [sp, #0x1e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1e8] + ldr x16, [sp, #0x1778] + ldr x17, [x16] + str x17, [sp, #0x1f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1f8] + ldr x16, [sp, #0x1770] + ldr x17, [x16] + str x17, [sp, #0x200] + ldr x17, [x16, #0x8] + str x17, [sp, #0x208] + ldr x16, [sp, #0x1768] + ldr x17, [x16] + str x17, [sp, #0x210] + ldr x17, [x16, #0x8] + str x17, [sp, #0x218] + ldr x16, [sp, #0x1760] + ldr x17, [x16] + str x17, [sp, #0x220] + ldr x17, [x16, #0x8] + str x17, [sp, #0x228] + ldr x16, [sp, #0x1758] + ldr x17, [x16] + str x17, [sp, #0x230] + ldr x17, [x16, #0x8] + str x17, [sp, #0x238] + ldr x16, [sp, #0x1750] + ldr x17, [x16] + str x17, [sp, #0x240] + ldr x17, [x16, #0x8] + str x17, [sp, #0x248] + ldr x16, [sp, #0x1748] + ldr x17, [x16] + str x17, [sp, #0x250] + ldr x17, [x16, #0x8] + str x17, [sp, #0x258] + ldr x16, [sp, #0x1740] + ldr x17, [x16] + str x17, [sp, #0x260] + ldr x17, [x16, #0x8] + str x17, [sp, #0x268] + ldr x16, [sp, #0x1738] + ldr x17, [x16] + str x17, [sp, #0x270] + ldr x17, [x16, #0x8] + str x17, [sp, #0x278] + ldr x16, [sp, #0x1730] + ldr x17, [x16] + str x17, [sp, #0x280] + ldr x17, [x16, #0x8] + str x17, [sp, #0x288] + ldr x16, [sp, #0x1728] + ldr x17, [x16] + str x17, [sp, #0x290] + ldr x17, [x16, #0x8] + str x17, [sp, #0x298] + ldr x16, [sp, #0x1720] + ldr x17, [x16] + str x17, [sp, #0x2a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2a8] + ldr x16, [sp, #0x1718] + ldr x17, [x16] + str x17, [sp, #0x2b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2b8] + ldr x16, [sp, #0x1710] + ldr x17, [x16] + str x17, [sp, #0x2c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2c8] + ldr x16, [sp, #0x1708] + ldr x17, [x16] + str x17, [sp, #0x2d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2d8] + ldr x16, [sp, #0x1700] + ldr x17, [x16] + str x17, [sp, #0x2e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2e8] + ldr x16, [sp, #0x16f8] + ldr x17, [x16] + str x17, [sp, #0x2f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2f8] + ldr x16, [sp, #0x16f0] + ldr x17, [x16] + str x17, [sp, #0x300] + ldr x17, [x16, #0x8] + str x17, [sp, #0x308] + ldr x16, [sp, #0x16e8] + ldr x17, [x16] + str x17, [sp, #0x310] + ldr x17, [x16, #0x8] + str x17, [sp, #0x318] + ldr x16, [sp, #0x16e0] + ldr x17, [x16] + str x17, [sp, #0x320] + ldr x17, [x16, #0x8] + str x17, [sp, #0x328] + ldr x16, [sp, #0x16d8] + ldr x17, [x16] + str x17, [sp, #0x330] + ldr x17, [x16, #0x8] + str x17, [sp, #0x338] + ldr x16, [sp, #0x16d0] + ldr x17, [x16] + str x17, [sp, #0x340] + ldr x17, [x16, #0x8] + str x17, [sp, #0x348] + ldr x16, [sp, #0x16c8] + ldr x17, [x16] + str x17, [sp, #0x350] + ldr x17, [x16, #0x8] + str x17, [sp, #0x358] + ldr x16, [sp, #0x16c0] + ldr x17, [x16] + str x17, [sp, #0x360] + ldr x17, [x16, #0x8] + str x17, [sp, #0x368] + ldr x16, [sp, #0x16b8] + ldr x17, [x16] + str x17, [sp, #0x370] + ldr x17, [x16, #0x8] + str x17, [sp, #0x378] + ldr x16, [sp, #0x16b0] + ldr x17, [x16] + str x17, [sp, #0x380] + ldr x17, [x16, #0x8] + str x17, [sp, #0x388] + ldr x16, [sp, #0x16a8] + ldr x17, [x16] + str x17, [sp, #0x390] + ldr x17, [x16, #0x8] + str x17, [sp, #0x398] + ldr x16, [sp, #0x16a0] + ldr x17, [x16] + str x17, [sp, #0x3a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3a8] + ldr x16, [sp, #0x1698] + ldr x17, [x16] + str x17, [sp, #0x3b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3b8] + ldr x16, [sp, #0x1690] + ldr x17, [x16] + str x17, [sp, #0x3c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3c8] + ldr x16, [sp, #0x1688] + ldr x17, [x16] + str x17, [sp, #0x3d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3d8] + ldr x16, [sp, #0x1680] + ldr x17, [x16] + str x17, [sp, #0x3e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3e8] + ldr x16, [sp, #0x1678] + ldr x17, [x16] + str x17, [sp, #0x3f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3f8] + ldr x16, [sp, #0x1670] + ldr x17, [x16] + str x17, [sp, #0x400] + ldr x17, [x16, #0x8] + str x17, [sp, #0x408] + ldr x16, [sp, #0x1668] + ldr x17, [x16] + str x17, [sp, #0x410] + ldr x17, [x16, #0x8] + str x17, [sp, #0x418] + ldr x16, [sp, #0x1660] + ldr x17, [x16] + str x17, [sp, #0x420] + ldr x17, [x16, #0x8] + str x17, [sp, #0x428] + ldr x16, [sp, #0x1658] + ldr x17, [x16] + str x17, [sp, #0x430] + ldr x17, [x16, #0x8] + str x17, [sp, #0x438] + ldr x16, [sp, #0x1650] + ldr x17, [x16] + str x17, [sp, #0x440] + ldr x17, [x16, #0x8] + str x17, [sp, #0x448] + ldr x16, [sp, #0x1648] + ldr x17, [x16] + str x17, [sp, #0x450] + ldr x17, [x16, #0x8] + str x17, [sp, #0x458] + ldr x16, [sp, #0x1640] + ldr x17, [x16] + str x17, [sp, #0x460] + ldr x17, [x16, #0x8] + str x17, [sp, #0x468] + ldr x16, [sp, #0x1638] + ldr x17, [x16] + str x17, [sp, #0x470] + ldr x17, [x16, #0x8] + str x17, [sp, #0x478] + ldr x16, [sp, #0x1630] + ldr x17, [x16] + str x17, [sp, #0x480] + ldr x17, [x16, #0x8] + str x17, [sp, #0x488] + ldr x16, [sp, #0x1628] + ldr x17, [x16] + str x17, [sp, #0x490] + ldr x17, [x16, #0x8] + str x17, [sp, #0x498] + ldr x16, [sp, #0x1620] + ldr x17, [x16] + str x17, [sp, #0x4a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4a8] + ldr x16, [sp, #0x1618] + ldr x17, [x16] + str x17, [sp, #0x4b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4b8] + ldr x16, [sp, #0x1610] + ldr x17, [x16] + str x17, [sp, #0x4c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4c8] + ldr x16, [sp, #0x1608] + ldr x17, [x16] + str x17, [sp, #0x4d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4d8] + ldr x16, [sp, #0x1600] + ldr x17, [x16] + str x17, [sp, #0x4e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4e8] + ldr x16, [sp, #0x15f8] + ldr x17, [x16] + str x17, [sp, #0x4f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4f8] + ldr x16, [sp, #0x15f0] + ldr x17, [x16] + str x17, [sp, #0x500] + ldr x17, [x16, #0x8] + str x17, [sp, #0x508] + ldr x16, [sp, #0x15e8] + ldr x17, [x16] + str x17, [sp, #0x510] + ldr x17, [x16, #0x8] + str x17, [sp, #0x518] + ldr x16, [sp, #0x15e0] + ldr x17, [x16] + str x17, [sp, #0x520] + ldr x17, [x16, #0x8] + str x17, [sp, #0x528] + ldr x16, [sp, #0x15d8] + ldr x17, [x16] + str x17, [sp, #0x530] + ldr x17, [x16, #0x8] + str x17, [sp, #0x538] + ldr x16, [sp, #0x15d0] + ldr x17, [x16] + str x17, [sp, #0x540] + ldr x17, [x16, #0x8] + str x17, [sp, #0x548] + ldr x16, [sp, #0x15c8] + ldr x17, [x16] + str x17, [sp, #0x550] + ldr x17, [x16, #0x8] + str x17, [sp, #0x558] + ldr x16, [sp, #0x15c0] + ldr x17, [x16] + str x17, [sp, #0x560] + ldr x17, [x16, #0x8] + str x17, [sp, #0x568] + ldr x16, [sp, #0x15b8] + ldr x17, [x16] + str x17, [sp, #0x570] + ldr x17, [x16, #0x8] + str x17, [sp, #0x578] + ldr x16, [sp, #0x15b0] + ldr x17, [x16] + str x17, [sp, #0x580] + ldr x17, [x16, #0x8] + str x17, [sp, #0x588] + ldr x16, [sp, #0x15a8] + ldr x17, [x16] + str x17, [sp, #0x590] + ldr x17, [x16, #0x8] + str x17, [sp, #0x598] + ldr x16, [sp, #0x15a0] + ldr x17, [x16] + str x17, [sp, #0x5a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5a8] + ldr x16, [sp, #0x1598] + ldr x17, [x16] + str x17, [sp, #0x5b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5b8] + ldr x16, [sp, #0x1590] + ldr x17, [x16] + str x17, [sp, #0x5c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5c8] + ldr x16, [sp, #0x1588] + ldr x17, [x16] + str x17, [sp, #0x5d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5d8] + ldr x16, [sp, #0x1580] + ldr x17, [x16] + str x17, [sp, #0x5e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5e8] + ldr x16, [sp, #0x1578] + ldr x17, [x16] + str x17, [sp, #0x5f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5f8] + ldr x16, [sp, #0x1570] + ldr x17, [x16] + str x17, [sp, #0x600] + ldr x17, [x16, #0x8] + str x17, [sp, #0x608] + ldr x16, [sp, #0x1568] + ldr x17, [x16] + str x17, [sp, #0x610] + ldr x17, [x16, #0x8] + str x17, [sp, #0x618] + ldr x16, [sp, #0x1560] + ldr x17, [x16] + str x17, [sp, #0x620] + ldr x17, [x16, #0x8] + str x17, [sp, #0x628] + ldr x16, [sp, #0x1558] + ldr x17, [x16] + str x17, [sp, #0x630] + ldr x17, [x16, #0x8] + str x17, [sp, #0x638] + ldr x16, [sp, #0x1550] + ldr x17, [x16] + str x17, [sp, #0x640] + ldr x17, [x16, #0x8] + str x17, [sp, #0x648] + ldr x16, [sp, #0x1548] + ldr x17, [x16] + str x17, [sp, #0x650] + ldr x17, [x16, #0x8] + str x17, [sp, #0x658] + ldr x16, [sp, #0x1540] + ldr x17, [x16] + str x17, [sp, #0x660] + ldr x17, [x16, #0x8] + str x17, [sp, #0x668] + ldr x16, [sp, #0x1538] + ldr x17, [x16] + str x17, [sp, #0x670] + ldr x17, [x16, #0x8] + str x17, [sp, #0x678] + ldr x16, [sp, #0x1530] + ldr x17, [x16] + str x17, [sp, #0x680] + ldr x17, [x16, #0x8] + str x17, [sp, #0x688] + ldr x16, [sp, #0x1528] + ldr x17, [x16] + str x17, [sp, #0x690] + ldr x17, [x16, #0x8] + str x17, [sp, #0x698] + ldr x16, [sp, #0x1520] + ldr x17, [x16] + str x17, [sp, #0x6a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6a8] + ldr x16, [sp, #0x1518] + ldr x17, [x16] + str x17, [sp, #0x6b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6b8] + ldr x16, [sp, #0x1510] + ldr x17, [x16] + str x17, [sp, #0x6c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6c8] + ldr x16, [sp, #0x1508] + ldr x17, [x16] + str x17, [sp, #0x6d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6d8] + ldr x16, [sp, #0x1500] + ldr x17, [x16] + str x17, [sp, #0x6e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6e8] + ldr x16, [sp, #0x14f8] + ldr x17, [x16] + str x17, [sp, #0x6f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6f8] + ldr x16, [sp, #0x14f0] + ldr x17, [x16] + str x17, [sp, #0x700] + ldr x17, [x16, #0x8] + str x17, [sp, #0x708] + ldr x16, [sp, #0x14e8] + ldr x17, [x16] + str x17, [sp, #0x710] + ldr x17, [x16, #0x8] + str x17, [sp, #0x718] + ldr x16, [sp, #0x14e0] + ldr x17, [x16] + str x17, [sp, #0x720] + ldr x17, [x16, #0x8] + str x17, [sp, #0x728] + ldr x16, [sp, #0x14d8] + ldr x17, [x16] + str x17, [sp, #0x730] + ldr x17, [x16, #0x8] + str x17, [sp, #0x738] + ldr x16, [sp, #0x14d0] + ldr x17, [x16] + str x17, [sp, #0x740] + ldr x17, [x16, #0x8] + str x17, [sp, #0x748] + ldr x16, [sp, #0x14c8] + ldr x17, [x16] + str x17, [sp, #0x750] + ldr x17, [x16, #0x8] + str x17, [sp, #0x758] + ldr x16, [sp, #0x14c0] + ldr x17, [x16] + str x17, [sp, #0x760] + ldr x17, [x16, #0x8] + str x17, [sp, #0x768] + ldr x16, [sp, #0x14b8] + ldr x17, [x16] + str x17, [sp, #0x770] + ldr x17, [x16, #0x8] + str x17, [sp, #0x778] + ldr x16, [sp, #0x14b0] + ldr x17, [x16] + str x17, [sp, #0x780] + ldr x17, [x16, #0x8] + str x17, [sp, #0x788] + ldr x16, [sp, #0x14a8] + ldr x17, [x16] + str x17, [sp, #0x790] + ldr x17, [x16, #0x8] + str x17, [sp, #0x798] + ldr x16, [sp, #0x14a0] + ldr x17, [x16] + str x17, [sp, #0x7a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7a8] + ldr x16, [sp, #0x1498] + ldr x17, [x16] + str x17, [sp, #0x7b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7b8] + ldr x16, [sp, #0x1490] + ldr x17, [x16] + str x17, [sp, #0x7c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7c8] + ldr x16, [sp, #0x1488] + ldr x17, [x16] + str x17, [sp, #0x7d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7d8] + ldr x16, [sp, #0x1480] + ldr x17, [x16] + str x17, [sp, #0x7e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7e8] + ldr x16, [sp, #0x1478] + ldr x17, [x16] + str x17, [sp, #0x7f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7f8] + ldr x16, [sp, #0x1470] + ldr x17, [x16] + str x17, [sp, #0x800] + ldr x17, [x16, #0x8] + str x17, [sp, #0x808] + ldr x16, [sp, #0x1468] + ldr x17, [x16] + str x17, [sp, #0x810] + ldr x17, [x16, #0x8] + str x17, [sp, #0x818] + ldr x16, [sp, #0x1460] + ldr x17, [x16] + str x17, [sp, #0x820] + ldr x17, [x16, #0x8] + str x17, [sp, #0x828] + ldr x16, [sp, #0x1458] + ldr x17, [x16] + str x17, [sp, #0x830] + ldr x17, [x16, #0x8] + str x17, [sp, #0x838] + ldr x16, [sp, #0x1450] + ldr x17, [x16] + str x17, [sp, #0x840] + ldr x17, [x16, #0x8] + str x17, [sp, #0x848] + ldr x16, [sp, #0x1448] + ldr x17, [x16] + str x17, [sp, #0x850] + ldr x17, [x16, #0x8] + str x17, [sp, #0x858] + ldr x16, [sp, #0x1440] + ldr x17, [x16] + str x17, [sp, #0x860] + ldr x17, [x16, #0x8] + str x17, [sp, #0x868] + ldr x16, [sp, #0x1438] + ldr x17, [x16] + str x17, [sp, #0x870] + ldr x17, [x16, #0x8] + str x17, [sp, #0x878] + ldr x16, [sp, #0x1430] + ldr x17, [x16] + str x17, [sp, #0x880] + ldr x17, [x16, #0x8] + str x17, [sp, #0x888] + ldr x16, [sp, #0x1428] + ldr x17, [x16] + str x17, [sp, #0x890] + ldr x17, [x16, #0x8] + str x17, [sp, #0x898] + ldr x16, [sp, #0x1420] + ldr x17, [x16] + str x17, [sp, #0x8a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8a8] + ldr x16, [sp, #0x1418] + ldr x17, [x16] + str x17, [sp, #0x8b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8b8] + ldr x16, [sp, #0x1410] + ldr x17, [x16] + str x17, [sp, #0x8c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8c8] + ldr x16, [sp, #0x1408] + ldr x17, [x16] + str x17, [sp, #0x8d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8d8] + ldr x16, [sp, #0x1400] + ldr x17, [x16] + str x17, [sp, #0x8e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8e8] + ldr x16, [sp, #0x13f8] + ldr x17, [x16] + str x17, [sp, #0x8f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8f8] + ldr x16, [sp, #0x13f0] + ldr x17, [x16] + str x17, [sp, #0x900] + ldr x17, [x16, #0x8] + str x17, [sp, #0x908] + ldr x16, [sp, #0x13e8] + ldr x17, [x16] + str x17, [sp, #0x910] + ldr x17, [x16, #0x8] + str x17, [sp, #0x918] + ldr x16, [sp, #0x13e0] + ldr x17, [x16] + str x17, [sp, #0x920] + ldr x17, [x16, #0x8] + str x17, [sp, #0x928] + ldr x16, [sp, #0x13d8] + ldr x17, [x16] + str x17, [sp, #0x930] + ldr x17, [x16, #0x8] + str x17, [sp, #0x938] + ldr x16, [sp, #0x13d0] + ldr x17, [x16] + str x17, [sp, #0x940] + ldr x17, [x16, #0x8] + str x17, [sp, #0x948] + ldr x16, [sp, #0x13c8] + ldr x17, [x16] + str x17, [sp, #0x950] + ldr x17, [x16, #0x8] + str x17, [sp, #0x958] + ldr x16, [sp, #0x13c0] + ldr x17, [x16] + str x17, [sp, #0x960] + ldr x17, [x16, #0x8] + str x17, [sp, #0x968] + ldr x16, [sp, #0x13b8] + ldr x17, [x16] + str x17, [sp, #0x970] + ldr x17, [x16, #0x8] + str x17, [sp, #0x978] + ldr x16, [sp, #0x13b0] + ldr x17, [x16] + str x17, [sp, #0x980] + ldr x17, [x16, #0x8] + str x17, [sp, #0x988] + ldr x16, [sp, #0x13a8] + ldr x17, [x16] + str x17, [sp, #0x990] + ldr x17, [x16, #0x8] + str x17, [sp, #0x998] + ldr x16, [sp, #0x13a0] + ldr x17, [x16] + str x17, [sp, #0x9a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9a8] + ldr x16, [sp, #0x1398] + ldr x17, [x16] + str x17, [sp, #0x9b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9b8] + ldr x16, [sp, #0x1390] + ldr x17, [x16] + str x17, [sp, #0x9c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9c8] + ldr x16, [sp, #0x1388] + ldr x17, [x16] + str x17, [sp, #0x9d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9d8] + ldr x16, [sp, #0x1380] + ldr x17, [x16] + str x17, [sp, #0x9e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9e8] + ldr x16, [sp, #0x1378] + ldr x17, [x16] + str x17, [sp, #0x9f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9f8] + ldr x16, [sp, #0x1370] + ldr x17, [x16] + str x17, [sp, #0xa00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa08] + ldr x16, [sp, #0x1368] + ldr x17, [x16] + str x17, [sp, #0xa10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa18] + ldr x16, [sp, #0x1360] + ldr x17, [x16] + str x17, [sp, #0xa20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa28] + ldr x16, [sp, #0x1358] + ldr x17, [x16] + str x17, [sp, #0xa30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa38] + ldr x16, [sp, #0x1350] + ldr x17, [x16] + str x17, [sp, #0xa40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa48] + ldr x16, [sp, #0x1348] + ldr x17, [x16] + str x17, [sp, #0xa50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa58] + ldr x16, [sp, #0x1340] + ldr x17, [x16] + str x17, [sp, #0xa60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa68] + ldr x16, [sp, #0x1338] + ldr x17, [x16] + str x17, [sp, #0xa70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa78] + ldr x16, [sp, #0x1330] + ldr x17, [x16] + str x17, [sp, #0xa80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa88] + ldr x16, [sp, #0x1328] + ldr x17, [x16] + str x17, [sp, #0xa90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa98] + ldr x16, [sp, #0x1320] + ldr x17, [x16] + str x17, [sp, #0xaa0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xaa8] + ldr x16, [sp, #0x1318] + ldr x17, [x16] + str x17, [sp, #0xab0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xab8] + ldr x16, [sp, #0x1310] + ldr x17, [x16] + str x17, [sp, #0xac0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xac8] + ldr x16, [sp, #0x1308] + ldr x17, [x16] + str x17, [sp, #0xad0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xad8] + ldr x16, [sp, #0x1300] + ldr x17, [x16] + str x17, [sp, #0xae0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xae8] + ldr x16, [sp, #0x12f8] + ldr x17, [x16] + str x17, [sp, #0xaf0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xaf8] + ldr x16, [sp, #0x12f0] + ldr x17, [x16] + str x17, [sp, #0xb00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb08] + ldr x16, [sp, #0x12e8] + ldr x17, [x16] + str x17, [sp, #0xb10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb18] + ldr x16, [sp, #0x12e0] + ldr x17, [x16] + str x17, [sp, #0xb20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb28] + ldr x16, [sp, #0x12d8] + ldr x17, [x16] + str x17, [sp, #0xb30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb38] + ldr x16, [sp, #0x12d0] + ldr x17, [x16] + str x17, [sp, #0xb40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb48] + ldr x16, [sp, #0x12c8] + ldr x17, [x16] + str x17, [sp, #0xb50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb58] + ldr x16, [sp, #0x12c0] + ldr x17, [x16] + str x17, [sp, #0xb60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb68] + ldr x16, [sp, #0x12b8] + ldr x17, [x16] + str x17, [sp, #0xb70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb78] + ldr x16, [sp, #0x12b0] + ldr x17, [x16] + str x17, [sp, #0xb80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb88] + ldr x16, [sp, #0x12a8] + ldr x17, [x16] + str x17, [sp, #0xb90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb98] + ldr x16, [sp, #0x12a0] + ldr x17, [x16] + str x17, [sp, #0xba0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xba8] + ldr x16, [sp, #0x1298] + ldr x17, [x16] + str x17, [sp, #0xbb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xbb8] + ldr x16, [sp, #0x1290] + ldr x17, [x16] + str x17, [sp, #0xbc0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xbc8] + ldr x16, [sp, #0x1288] + ldr x17, [x16] + str x17, [sp, #0xbd0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xbd8] + ldr x16, [sp, #0x1280] + ldr x17, [x16] + str x17, [sp, #0xbe0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xbe8] + ldr x16, [sp, #0x1278] + ldr x17, [x16] + str x17, [sp, #0xbf0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xbf8] + ldr x16, [sp, #0x1270] + ldr x17, [x16] + str x17, [sp, #0xc00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc08] + ldr x16, [sp, #0x1268] + ldr x17, [x16] + str x17, [sp, #0xc10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc18] + ldr x16, [sp, #0x1260] + ldr x17, [x16] + str x17, [sp, #0xc20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc28] + ldr x16, [sp, #0x1258] + ldr x17, [x16] + str x17, [sp, #0xc30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc38] + ldr x16, [sp, #0x1250] + ldr x17, [x16] + str x17, [sp, #0xc40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc48] + ldr x16, [sp, #0x1248] + ldr x17, [x16] + str x17, [sp, #0xc50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc58] + ldr x16, [sp, #0x1240] + ldr x17, [x16] + str x17, [sp, #0xc60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc68] + ldr x16, [sp, #0x1238] + ldr x17, [x16] + str x17, [sp, #0xc70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc78] + ldr x16, [sp, #0x1230] + ldr x17, [x16] + str x17, [sp, #0xc80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc88] + ldr x16, [sp, #0x1228] + ldr x17, [x16] + str x17, [sp, #0xc90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc98] + ldr x16, [sp, #0x1220] + ldr x17, [x16] + str x17, [sp, #0xca0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xca8] + ldr x16, [sp, #0x1218] + ldr x17, [x16] + str x17, [sp, #0xcb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xcb8] + ldr x16, [sp, #0x1210] + ldr x17, [x16] + str x17, [sp, #0xcc0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xcc8] + ldr x16, [sp, #0x1208] + ldr x17, [x16] + str x17, [sp, #0xcd0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xcd8] + ldr x16, [sp, #0x1200] + ldr x17, [x16] + str x17, [sp, #0xce0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xce8] + ldr x16, [sp, #0x11f8] + ldr x17, [x16] + str x17, [sp, #0xcf0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xcf8] + ldr x16, [sp, #0x11f0] + ldr x17, [x16] + str x17, [sp, #0xd00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd08] + ldr x16, [sp, #0x11e8] + ldr x17, [x16] + str x17, [sp, #0xd10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd18] + ldr x16, [sp, #0x11e0] + ldr x17, [x16] + str x17, [sp, #0xd20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd28] + ldr x16, [sp, #0x11d8] + ldr x17, [x16] + str x17, [sp, #0xd30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd38] + ldr x16, [sp, #0x11d0] + ldr x17, [x16] + str x17, [sp, #0xd40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd48] + ldr x16, [sp, #0x11c8] + ldr x17, [x16] + str x17, [sp, #0xd50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd58] + ldr x16, [sp, #0x11c0] + ldr x17, [x16] + str x17, [sp, #0xd60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd68] + ldr x16, [sp, #0x11b8] + ldr x17, [x16] + str x17, [sp, #0xd70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd78] + ldr x16, [sp, #0x11b0] + ldr x17, [x16] + str x17, [sp, #0xd80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd88] + ldr x16, [sp, #0x11a8] + ldr x17, [x16] + str x17, [sp, #0xd90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd98] + ldr x16, [sp, #0x11a0] + ldr x17, [x16] + str x17, [sp, #0xda0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xda8] + ldr x16, [sp, #0x1198] + ldr x17, [x16] + str x17, [sp, #0xdb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xdb8] + ldr x16, [sp, #0x1190] + ldr x17, [x16] + str x17, [sp, #0xdc0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xdc8] + ldr x16, [sp, #0x1188] + ldr x17, [x16] + str x17, [sp, #0xdd0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xdd8] + ldr x16, [sp, #0x1180] + ldr x17, [x16] + str x17, [sp, #0xde0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xde8] + ldr x16, [sp, #0x1178] + ldr x17, [x16] + str x17, [sp, #0xdf0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xdf8] + ldr x16, [sp, #0x1170] + ldr x17, [x16] + str x17, [sp, #0xe00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe08] + ldr x16, [sp, #0x1168] + ldr x17, [x16] + str x17, [sp, #0xe10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe18] + ldr x16, [sp, #0x1160] + ldr x17, [x16] + str x17, [sp, #0xe20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe28] + ldr x16, [sp, #0x1158] + ldr x17, [x16] + str x17, [sp, #0xe30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe38] + ldr x16, [sp, #0x1150] + ldr x17, [x16] + str x17, [sp, #0xe40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe48] + ldr x16, [sp, #0x1148] + ldr x17, [x16] + str x17, [sp, #0xe50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe58] + ldr x16, [sp, #0x1140] + ldr x17, [x16] + str x17, [sp, #0xe60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe68] + ldr x16, [sp, #0x1138] + ldr x17, [x16] + str x17, [sp, #0xe70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe78] + ldr x16, [sp, #0x1130] + ldr x17, [x16] + str x17, [sp, #0xe80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe88] + ldr x16, [sp, #0x1128] + ldr x17, [x16] + str x17, [sp, #0xe90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe98] + ldr x16, [sp, #0x1120] + ldr x17, [x16] + str x17, [sp, #0xea0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xea8] + ldr x16, [sp, #0x1118] + ldr x17, [x16] + str x17, [sp, #0xeb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xeb8] + ldr x16, [sp, #0x1110] + ldr x17, [x16] + str x17, [sp, #0xec0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xec8] + ldr x16, [sp, #0x1108] + ldr x17, [x16] + str x17, [sp, #0xed0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xed8] + ldr x16, [sp, #0x1100] + ldr x17, [x16] + str x17, [sp, #0xee0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xee8] + ldr x16, [sp, #0x10f8] + ldr x17, [x16] + str x17, [sp, #0xef0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xef8] + ldr x16, [sp, #0x10f0] + ldr x17, [x16] + str x17, [sp, #0xf00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf08] + ldr x16, [sp, #0x10e8] + ldr x17, [x16] + str x17, [sp, #0xf10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf18] + ldr x16, [sp, #0x10e0] + ldr x17, [x16] + str x17, [sp, #0xf20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf28] + ldr x16, [sp, #0x10d8] + ldr x17, [x16] + str x17, [sp, #0xf30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf38] + ldr x16, [sp, #0x10d0] + ldr x17, [x16] + str x17, [sp, #0xf40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf48] + ldr x16, [sp, #0x10c8] + ldr x17, [x16] + str x17, [sp, #0xf50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf58] + ldr x16, [sp, #0x10c0] + ldr x17, [x16] + str x17, [sp, #0xf60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf68] + ldr x16, [sp, #0x10b8] + ldr x17, [x16] + str x17, [sp, #0xf70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf78] + ldr x16, [sp, #0x10b0] + ldr x17, [x16] + str x17, [sp, #0xf80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf88] + ldr x16, [sp, #0x10a8] + ldr x17, [x16] + str x17, [sp, #0xf90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf98] + ldr x16, [sp, #0x10a0] + ldr x17, [x16] + str x17, [sp, #0xfa0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xfa8] + ldr x16, [sp, #0x1098] + ldr x17, [x16] + str x17, [sp, #0xfb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xfb8] + ldr x16, [sp, #0x1090] + ldr x17, [x16] + str x17, [sp, #0xfc0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xfc8] + ldr x16, [sp, #0x1088] + ldr x17, [x16] + str x17, [sp, #0xfd0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xfd8] + ldr x16, [sp, #0x1080] + ldr x17, [x16] + str x17, [sp, #0xfe0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xfe8] + ldr x16, [sp, #0x1078] + ldr x17, [x16] + str x17, [sp, #0xff0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xff8] + ldr x16, [sp, #0x1070] + ldr x17, [x16] + str x17, [sp, #0x1000] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1008] + mov x4, x2 + mov x6, x3 + mov x2, x1 + ldr x1, [x0, #0x8] + ldr x0, [x0] + ldr x3, [x2, #0x8] + ldr x2, [x2] + ldr x5, [x4, #0x8] + ldr x4, [x4] + ldr x7, [x6, #0x8] + ldr x6, [x6] + bl + add sp, sp, #0x1, lsl #12 // =0x1000 + add sp, sp, #0x10 + mov x17, #0x8d9e // =36254 + movk x17, #0x1, lsl #16 + cmp x0, x17 + b.eq + mov x0, #0x1 // =1 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x23, [sp, #0x18] + ldr x24, [sp, #0x20] + ldr x25, [sp, #0x28] + ldr x26, [sp, #0x30] + ldr x27, [sp, #0x38] + ldr x28, [sp, #0x40] + ldr x19, [sp, #0x50] + add sp, sp, #0x1, lsl #12 // =0x1000 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x1 // =1 + mov x1, #0x2 // =2 + mov x2, #0x3 // =3 + mov x3, #0x4 // =4 + mov x4, #0x5 // =5 + mov x5, #0x6 // =6 + mov x6, #0x7 // =7 + mov x7, #0x8 // =8 + mov x8, #0x9 // =9 + mov x9, #0xa // =10 + mov x10, #0xb // =11 + mov x11, #0xc // =12 + mov x12, #0xd // =13 + mov x13, #0xe // =14 + mov x14, #0xf // =15 + mov x15, #0x10 // =16 + mov x22, #0x11 // =17 + mov x23, #0x12 // =18 + mov x24, #0x13 // =19 + mov x25, #0x14 // =20 + mov x26, #0x15 // =21 + mov x27, #0x16 // =22 + mov x28, #0x17 // =23 + mov x16, #0x18 // =24 + str x16, [sp, #0x7c8] + mov x16, #0x19 // =25 + str x16, [sp, #0x7c0] + mov x16, #0x1a // =26 + str x16, [sp, #0x7b8] + mov x16, #0x1b // =27 + str x16, [sp, #0x7b0] + mov x16, #0x1c // =28 + str x16, [sp, #0x7a8] + mov x16, #0x1d // =29 + str x16, [sp, #0x7a0] + mov x16, #0x1e // =30 + str x16, [sp, #0x798] + mov x16, #0x1f // =31 + str x16, [sp, #0x790] + mov x16, #0x20 // =32 + str x16, [sp, #0x788] + mov x16, #0x21 // =33 + str x16, [sp, #0x780] + mov x16, #0x22 // =34 + str x16, [sp, #0x778] + mov x16, #0x23 // =35 + str x16, [sp, #0x770] + mov x16, #0x24 // =36 + str x16, [sp, #0x768] + mov x16, #0x25 // =37 + str x16, [sp, #0x760] + mov x16, #0x26 // =38 + str x16, [sp, #0x758] + mov x16, #0x27 // =39 + str x16, [sp, #0x750] + mov x16, #0x28 // =40 + str x16, [sp, #0x748] + mov x16, #0x29 // =41 + str x16, [sp, #0x740] + mov x16, #0x2a // =42 + str x16, [sp, #0x738] + mov x16, #0x2b // =43 + str x16, [sp, #0x730] + mov x16, #0x2c // =44 + str x16, [sp, #0x728] + mov x16, #0x2d // =45 + str x16, [sp, #0x720] + mov x16, #0x2e // =46 + str x16, [sp, #0x718] + mov x16, #0x2f // =47 + str x16, [sp, #0x710] + mov x16, #0x30 // =48 + str x16, [sp, #0x708] + mov x16, #0x31 // =49 + str x16, [sp, #0x700] + mov x16, #0x32 // =50 + str x16, [sp, #0x6f8] + mov x16, #0x33 // =51 + str x16, [sp, #0x6f0] + mov x16, #0x34 // =52 + str x16, [sp, #0x6e8] + mov x16, #0x35 // =53 + str x16, [sp, #0x6e0] + mov x16, #0x36 // =54 + str x16, [sp, #0x6d8] + mov x16, #0x37 // =55 + str x16, [sp, #0x6d0] + mov x16, #0x38 // =56 + str x16, [sp, #0x6c8] + mov x16, #0x39 // =57 + str x16, [sp, #0x6c0] + mov x16, #0x3a // =58 + str x16, [sp, #0x6b8] + mov x16, #0x3b // =59 + str x16, [sp, #0x6b0] + mov x16, #0x3c // =60 + str x16, [sp, #0x6a8] + mov x16, #0x3d // =61 + str x16, [sp, #0x6a0] + mov x16, #0x3e // =62 + str x16, [sp, #0x698] + mov x16, #0x3f // =63 + str x16, [sp, #0x690] + mov x16, #0x40 // =64 + str x16, [sp, #0x688] + mov x16, #0x41 // =65 + str x16, [sp, #0x680] + mov x16, #0x42 // =66 + str x16, [sp, #0x678] + mov x16, #0x43 // =67 + str x16, [sp, #0x670] + mov x16, #0x44 // =68 + str x16, [sp, #0x668] + mov x16, #0x45 // =69 + str x16, [sp, #0x660] + mov x16, #0x46 // =70 + str x16, [sp, #0x658] + mov x16, #0x47 // =71 + str x16, [sp, #0x650] + mov x16, #0x48 // =72 + str x16, [sp, #0x648] + mov x16, #0x49 // =73 + str x16, [sp, #0x640] + mov x16, #0x4a // =74 + str x16, [sp, #0x638] + mov x16, #0x4b // =75 + str x16, [sp, #0x630] + mov x16, #0x4c // =76 + str x16, [sp, #0x628] + mov x16, #0x4d // =77 + str x16, [sp, #0x620] + mov x16, #0x4e // =78 + str x16, [sp, #0x618] + mov x16, #0x4f // =79 + str x16, [sp, #0x610] + mov x16, #0x50 // =80 + str x16, [sp, #0x608] + mov x16, #0x51 // =81 + str x16, [sp, #0x600] + mov x16, #0x52 // =82 + str x16, [sp, #0x5f8] + mov x16, #0x53 // =83 + str x16, [sp, #0x5f0] + mov x16, #0x54 // =84 + str x16, [sp, #0x5e8] + mov x16, #0x55 // =85 + str x16, [sp, #0x5e0] + mov x16, #0x56 // =86 + str x16, [sp, #0x5d8] + mov x16, #0x57 // =87 + str x16, [sp, #0x5d0] + mov x16, #0x58 // =88 + str x16, [sp, #0x5c8] + mov x16, #0x59 // =89 + str x16, [sp, #0x5c0] + mov x16, #0x5a // =90 + str x16, [sp, #0x5b8] + mov x16, #0x5b // =91 + str x16, [sp, #0x5b0] + mov x16, #0x5c // =92 + str x16, [sp, #0x5a8] + mov x16, #0x5d // =93 + str x16, [sp, #0x5a0] + mov x16, #0x5e // =94 + str x16, [sp, #0x598] + mov x16, #0x5f // =95 + str x16, [sp, #0x590] + mov x16, #0x60 // =96 + str x16, [sp, #0x588] + mov x16, #0x61 // =97 + str x16, [sp, #0x580] + mov x16, #0x62 // =98 + str x16, [sp, #0x578] + mov x16, #0x63 // =99 + str x16, [sp, #0x570] + mov x16, #0x64 // =100 + str x16, [sp, #0x568] + mov x16, #0x65 // =101 + str x16, [sp, #0x560] + mov x16, #0x66 // =102 + str x16, [sp, #0x558] + mov x16, #0x67 // =103 + str x16, [sp, #0x550] + mov x16, #0x68 // =104 + str x16, [sp, #0x548] + mov x16, #0x69 // =105 + str x16, [sp, #0x540] + mov x16, #0x6a // =106 + str x16, [sp, #0x538] + mov x16, #0x6b // =107 + str x16, [sp, #0x530] + mov x16, #0x6c // =108 + str x16, [sp, #0x528] + mov x16, #0x6d // =109 + str x16, [sp, #0x520] + mov x16, #0x6e // =110 + str x16, [sp, #0x518] + mov x16, #0x6f // =111 + str x16, [sp, #0x510] + mov x16, #0x70 // =112 + str x16, [sp, #0x508] + mov x16, #0x71 // =113 + str x16, [sp, #0x500] + mov x16, #0x72 // =114 + str x16, [sp, #0x4f8] + mov x16, #0x73 // =115 + str x16, [sp, #0x4f0] + mov x16, #0x74 // =116 + str x16, [sp, #0x4e8] + mov x16, #0x75 // =117 + str x16, [sp, #0x4e0] + mov x16, #0x76 // =118 + str x16, [sp, #0x4d8] + mov x16, #0x77 // =119 + str x16, [sp, #0x4d0] + mov x16, #0x78 // =120 + str x16, [sp, #0x4c8] + mov x16, #0x79 // =121 + str x16, [sp, #0x4c0] + mov x16, #0x7a // =122 + str x16, [sp, #0x4b8] + mov x16, #0x7b // =123 + str x16, [sp, #0x4b0] + mov x16, #0x7c // =124 + str x16, [sp, #0x4a8] + mov x16, #0x7d // =125 + str x16, [sp, #0x4a0] + mov x16, #0x7e // =126 + str x16, [sp, #0x498] + mov x16, #0x7f // =127 + str x16, [sp, #0x490] + mov x16, #0x80 // =128 + str x16, [sp, #0x488] + mov x16, #0x81 // =129 + str x16, [sp, #0x480] + mov x16, #0x82 // =130 + str x16, [sp, #0x478] + mov x16, #0x83 // =131 + str x16, [sp, #0x470] + mov x16, #0x84 // =132 + str x16, [sp, #0x468] + mov x16, #0x85 // =133 + str x16, [sp, #0x460] + mov x16, #0x86 // =134 + str x16, [sp, #0x458] + mov x16, #0x87 // =135 + str x16, [sp, #0x450] + mov x16, #0x88 // =136 + str x16, [sp, #0x448] + mov x16, #0x89 // =137 + str x16, [sp, #0x440] + mov x16, #0x8a // =138 + str x16, [sp, #0x438] + mov x16, #0x8b // =139 + str x16, [sp, #0x430] + mov x16, #0x8c // =140 + str x16, [sp, #0x428] + mov x16, #0x8d // =141 + str x16, [sp, #0x420] + mov x16, #0x8e // =142 + str x16, [sp, #0x418] + mov x16, #0x8f // =143 + str x16, [sp, #0x410] + mov x16, #0x90 // =144 + str x16, [sp, #0x408] + mov x16, #0x91 // =145 + str x16, [sp, #0x400] + mov x16, #0x92 // =146 + str x16, [sp, #0x3f8] + mov x16, #0x93 // =147 + str x16, [sp, #0x3f0] + mov x16, #0x94 // =148 + str x16, [sp, #0x3e8] + mov x16, #0x95 // =149 + str x16, [sp, #0x3e0] + mov x16, #0x96 // =150 + str x16, [sp, #0x3d8] + mov x16, #0x97 // =151 + str x16, [sp, #0x3d0] + mov x16, #0x98 // =152 + str x16, [sp, #0x3c8] + mov x16, #0x99 // =153 + str x16, [sp, #0x3c0] + mov x16, #0x9a // =154 + str x16, [sp, #0x3b8] + mov x16, #0x9b // =155 + str x16, [sp, #0x3b0] + mov x16, #0x9c // =156 + str x16, [sp, #0x3a8] + mov x16, #0x9d // =157 + str x16, [sp, #0x3a0] + mov x16, #0x9e // =158 + str x16, [sp, #0x398] + mov x16, #0x9f // =159 + str x16, [sp, #0x390] + mov x16, #0xa0 // =160 + str x16, [sp, #0x388] + mov x16, #0xa1 // =161 + str x16, [sp, #0x380] + mov x16, #0xa2 // =162 + str x16, [sp, #0x378] + mov x16, #0xa3 // =163 + str x16, [sp, #0x370] + mov x16, #0xa4 // =164 + str x16, [sp, #0x368] + mov x16, #0xa5 // =165 + str x16, [sp, #0x360] + mov x16, #0xa6 // =166 + str x16, [sp, #0x358] + mov x16, #0xa7 // =167 + str x16, [sp, #0x350] + mov x16, #0xa8 // =168 + str x16, [sp, #0x348] + mov x16, #0xa9 // =169 + str x16, [sp, #0x340] + mov x16, #0xaa // =170 + str x16, [sp, #0x338] + mov x16, #0xab // =171 + str x16, [sp, #0x330] + mov x16, #0xac // =172 + str x16, [sp, #0x328] + mov x16, #0xad // =173 + str x16, [sp, #0x320] + mov x16, #0xae // =174 + str x16, [sp, #0x318] + mov x16, #0xaf // =175 + str x16, [sp, #0x310] + mov x16, #0xb0 // =176 + str x16, [sp, #0x308] + mov x16, #0xb1 // =177 + str x16, [sp, #0x300] + mov x16, #0xb2 // =178 + str x16, [sp, #0x2f8] + mov x16, #0xb3 // =179 + str x16, [sp, #0x2f0] + mov x16, #0xb4 // =180 + str x16, [sp, #0x2e8] + mov x16, #0xb5 // =181 + str x16, [sp, #0x2e0] + mov x16, #0xb6 // =182 + str x16, [sp, #0x2d8] + mov x16, #0xb7 // =183 + str x16, [sp, #0x2d0] + mov x16, #0xb8 // =184 + str x16, [sp, #0x2c8] + mov x16, #0xb9 // =185 + str x16, [sp, #0x2c0] + mov x16, #0xba // =186 + str x16, [sp, #0x2b8] + mov x16, #0xbb // =187 + str x16, [sp, #0x2b0] + mov x16, #0xbc // =188 + str x16, [sp, #0x2a8] + mov x16, #0xbd // =189 + str x16, [sp, #0x2a0] + mov x16, #0xbe // =190 + str x16, [sp, #0x298] + mov x16, #0xbf // =191 + str x16, [sp, #0x290] + mov x16, #0xc0 // =192 + str x16, [sp, #0x288] + mov x16, #0xc1 // =193 + str x16, [sp, #0x280] + mov x16, #0xc2 // =194 + str x16, [sp, #0x278] + mov x16, #0xc3 // =195 + str x16, [sp, #0x270] + mov x16, #0xc4 // =196 + str x16, [sp, #0x268] + mov x16, #0xc5 // =197 + str x16, [sp, #0x260] + mov x16, #0xc6 // =198 + str x16, [sp, #0x258] + mov x16, #0xc7 // =199 + str x16, [sp, #0x250] + mov x16, #0xc8 // =200 + str x16, [sp, #0x248] + mov x16, #0xc9 // =201 + str x16, [sp, #0x240] + mov x16, #0xca // =202 + str x16, [sp, #0x238] + mov x16, #0xcb // =203 + str x16, [sp, #0x230] + mov x16, #0xcc // =204 + str x16, [sp, #0x228] + mov x16, #0xcd // =205 + str x16, [sp, #0x220] + mov x16, #0xce // =206 + str x16, [sp, #0x218] + mov x16, #0xcf // =207 + str x16, [sp, #0x210] + mov x16, #0xd0 // =208 + str x16, [sp, #0x208] + mov x16, #0xd1 // =209 + str x16, [sp, #0x200] + mov x16, #0xd2 // =210 + str x16, [sp, #0x1f8] + mov x16, #0xd3 // =211 + str x16, [sp, #0x1f0] + mov x16, #0xd4 // =212 + str x16, [sp, #0x1e8] + mov x16, #0xd5 // =213 + str x16, [sp, #0x1e0] + mov x16, #0xd6 // =214 + str x16, [sp, #0x1d8] + mov x16, #0xd7 // =215 + str x16, [sp, #0x1d0] + mov x16, #0xd8 // =216 + str x16, [sp, #0x1c8] + mov x16, #0xd9 // =217 + str x16, [sp, #0x1c0] + mov x16, #0xda // =218 + str x16, [sp, #0x1b8] + mov x16, #0xdb // =219 + str x16, [sp, #0x1b0] + mov x16, #0xdc // =220 + str x16, [sp, #0x1a8] + mov x16, #0xdd // =221 + str x16, [sp, #0x1a0] + mov x16, #0xde // =222 + str x16, [sp, #0x198] + mov x16, #0xdf // =223 + str x16, [sp, #0x190] + mov x16, #0xe0 // =224 + str x16, [sp, #0x188] + mov x16, #0xe1 // =225 + str x16, [sp, #0x180] + mov x16, #0xe2 // =226 + str x16, [sp, #0x178] + mov x16, #0xe3 // =227 + str x16, [sp, #0x170] + mov x16, #0xe4 // =228 + str x16, [sp, #0x168] + mov x16, #0xe5 // =229 + str x16, [sp, #0x160] + mov x16, #0xe6 // =230 + str x16, [sp, #0x158] + mov x16, #0xe7 // =231 + str x16, [sp, #0x150] + mov x16, #0xe8 // =232 + str x16, [sp, #0x148] + mov x16, #0xe9 // =233 + str x16, [sp, #0x140] + mov x16, #0xea // =234 + str x16, [sp, #0x138] + mov x16, #0xeb // =235 + str x16, [sp, #0x130] + mov x16, #0xec // =236 + str x16, [sp, #0x128] + mov x16, #0xed // =237 + str x16, [sp, #0x120] + mov x16, #0xee // =238 + str x16, [sp, #0x118] + mov x16, #0xef // =239 + str x16, [sp, #0x110] + mov x16, #0xf0 // =240 + str x16, [sp, #0x108] + mov x16, #0xf1 // =241 + str x16, [sp, #0x100] + mov x16, #0xf2 // =242 + str x16, [sp, #0xf8] + mov x16, #0xf3 // =243 + str x16, [sp, #0xf0] + mov x16, #0xf4 // =244 + str x16, [sp, #0xe8] + mov x16, #0xf5 // =245 + str x16, [sp, #0xe0] + mov x16, #0xf6 // =246 + str x16, [sp, #0xd8] + mov x16, #0xf7 // =247 + str x16, [sp, #0xd0] + mov x16, #0xf8 // =248 + str x16, [sp, #0xc8] + mov x16, #0xf9 // =249 + str x16, [sp, #0xc0] + mov x16, #0xfa // =250 + str x16, [sp, #0xb8] + mov x16, #0xfb // =251 + str x16, [sp, #0xb0] + mov x16, #0xfc // =252 + str x16, [sp, #0xa8] + mov x16, #0xfd // =253 + str x16, [sp, #0xa0] + mov x16, #0xfe // =254 + str x16, [sp, #0x98] + mov x16, #0xff // =255 + str x16, [sp, #0x90] + mov x16, #0x100 // =256 + str x16, [sp, #0x88] + mov x16, #0x101 // =257 + str x16, [sp, #0x80] + mov x16, #0x102 // =258 + str x16, [sp, #0x78] + mov x16, #0x103 // =259 + str x16, [sp, #0x70] + mov x16, #0x104 // =260 + str x16, [sp, #0x68] + ldr x16, [sp, #0x68] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x80] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x98] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xb0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xc8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xe0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xf8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x110] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x128] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x140] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x158] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x170] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x188] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1a0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1b8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1d0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1e8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x200] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x218] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x230] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x248] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x260] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x278] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x290] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x2a8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x2c0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x2d8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x2f0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x308] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x320] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x338] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x350] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x368] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x380] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x398] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x3b0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x3c8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x3e0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x3f8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x410] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x428] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x440] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x458] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x470] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x488] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x4a0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x4b8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x4d0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x4e8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x500] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x518] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x530] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x548] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x560] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x578] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x590] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x5a8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x5c0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x5d8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x5f0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x608] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x620] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x638] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x650] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x668] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x680] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x698] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x6b0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x6c8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x6e0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x6f8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x710] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x728] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x740] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x758] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x770] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x788] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x7a0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x7b8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x7d0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x7e8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x800] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x818] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x830] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x848] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x860] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x878] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x890] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x8a8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x8c0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x8d8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x8f0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x908] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x920] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x938] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x950] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x968] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x980] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x998] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x9b0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x9c8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x9e0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x9f8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xa10] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xa28] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xa40] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xa58] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xa70] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xa88] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xaa0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xab8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xad0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xae8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xb00] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xb18] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xb30] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xb48] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xb60] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xb78] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xb90] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xba8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xbc0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xbd8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xbf0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xc08] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xc20] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xc38] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xc50] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xc68] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xc80] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xc98] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xcb0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xcc8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xce0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xcf8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xd10] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xd28] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xd40] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xd58] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xd70] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xd88] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xda0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xdb8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xdd0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xde8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xe00] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xe18] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xe30] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xe48] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xe60] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xe78] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xe90] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xea8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xec0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xed8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xef0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xf08] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xf20] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xf38] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xf50] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xf68] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xf80] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xf98] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xfb0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xfc8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xfe0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0xff8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1010] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1028] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1040] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1058] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1070] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1088] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x10a0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x10b8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x10d0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x10e8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1100] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1118] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1130] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1148] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1160] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1178] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1190] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x11a8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x11c0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x11d8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x11f0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1208] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1220] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1238] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1250] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1268] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1280] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1298] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x12b0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x12c8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x12e0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x12f8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1310] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1328] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1340] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1358] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1370] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1388] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x13a0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x13b8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x13d0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x13e8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1400] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1418] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1430] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1448] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1460] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1478] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1490] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x14a8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x14c0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x14d8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x14f0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1508] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1520] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1538] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1550] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1568] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1580] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1598] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x15b0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x15c8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x15e0] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x15f8] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1610] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1628] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1640] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1658] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1670] + str x16, [sp, #-0x10]! + ldr x16, [sp, #0x1688] + str x16, [sp, #-0x10]! + str x28, [sp, #-0x10]! + str x27, [sp, #-0x10]! + str x26, [sp, #-0x10]! + str x25, [sp, #-0x10]! + str x24, [sp, #-0x10]! + str x23, [sp, #-0x10]! + str x22, [sp, #-0x10]! + str x15, [sp, #-0x10]! + str x14, [sp, #-0x10]! + str x13, [sp, #-0x10]! + str x12, [sp, #-0x10]! + str x11, [sp, #-0x10]! + str x10, [sp, #-0x10]! + str x9, [sp, #-0x10]! + str x8, [sp, #-0x10]! + str x7, [sp, #-0x10]! + str x6, [sp, #-0x10]! + str x5, [sp, #-0x10]! + str x4, [sp, #-0x10]! + str x3, [sp, #-0x10]! + str x2, [sp, #-0x10]! + str x1, [sp, #-0x10]! + str x0, [sp, #-0x10]! + mov x9, x20 + sub sp, sp, #0x7e0 + ldr x0, [sp, #0x7e0] + ldr x1, [sp, #0x7f0] + ldr x2, [sp, #0x800] + ldr x3, [sp, #0x810] + ldr x4, [sp, #0x820] + ldr x5, [sp, #0x830] + ldr x6, [sp, #0x840] + ldr x7, [sp, #0x850] + ldr x16, [sp, #0x860] + str x16, [sp] + ldr x16, [sp, #0x870] + str x16, [sp, #0x8] + ldr x16, [sp, #0x880] + str x16, [sp, #0x10] + ldr x16, [sp, #0x890] + str x16, [sp, #0x18] + ldr x16, [sp, #0x8a0] + str x16, [sp, #0x20] + ldr x16, [sp, #0x8b0] + str x16, [sp, #0x28] + ldr x16, [sp, #0x8c0] + str x16, [sp, #0x30] + ldr x16, [sp, #0x8d0] + str x16, [sp, #0x38] + ldr x16, [sp, #0x8e0] + str x16, [sp, #0x40] + ldr x16, [sp, #0x8f0] + str x16, [sp, #0x48] + ldr x16, [sp, #0x900] + str x16, [sp, #0x50] + ldr x16, [sp, #0x910] + str x16, [sp, #0x58] + ldr x16, [sp, #0x920] + str x16, [sp, #0x60] + ldr x16, [sp, #0x930] + str x16, [sp, #0x68] + ldr x16, [sp, #0x940] + str x16, [sp, #0x70] + ldr x16, [sp, #0x950] + str x16, [sp, #0x78] + ldr x16, [sp, #0x960] + str x16, [sp, #0x80] + ldr x16, [sp, #0x970] + str x16, [sp, #0x88] + ldr x16, [sp, #0x980] + str x16, [sp, #0x90] + ldr x16, [sp, #0x990] + str x16, [sp, #0x98] + ldr x16, [sp, #0x9a0] + str x16, [sp, #0xa0] + ldr x16, [sp, #0x9b0] + str x16, [sp, #0xa8] + ldr x16, [sp, #0x9c0] + str x16, [sp, #0xb0] + ldr x16, [sp, #0x9d0] + str x16, [sp, #0xb8] + ldr x16, [sp, #0x9e0] + str x16, [sp, #0xc0] + ldr x16, [sp, #0x9f0] + str x16, [sp, #0xc8] + ldr x16, [sp, #0xa00] + str x16, [sp, #0xd0] + ldr x16, [sp, #0xa10] + str x16, [sp, #0xd8] + ldr x16, [sp, #0xa20] + str x16, [sp, #0xe0] + ldr x16, [sp, #0xa30] + str x16, [sp, #0xe8] + ldr x16, [sp, #0xa40] + str x16, [sp, #0xf0] + ldr x16, [sp, #0xa50] + str x16, [sp, #0xf8] + ldr x16, [sp, #0xa60] + str x16, [sp, #0x100] + ldr x16, [sp, #0xa70] + str x16, [sp, #0x108] + ldr x16, [sp, #0xa80] + str x16, [sp, #0x110] + ldr x16, [sp, #0xa90] + str x16, [sp, #0x118] + ldr x16, [sp, #0xaa0] + str x16, [sp, #0x120] + ldr x16, [sp, #0xab0] + str x16, [sp, #0x128] + ldr x16, [sp, #0xac0] + str x16, [sp, #0x130] + ldr x16, [sp, #0xad0] + str x16, [sp, #0x138] + ldr x16, [sp, #0xae0] + str x16, [sp, #0x140] + ldr x16, [sp, #0xaf0] + str x16, [sp, #0x148] + ldr x16, [sp, #0xb00] + str x16, [sp, #0x150] + ldr x16, [sp, #0xb10] + str x16, [sp, #0x158] + ldr x16, [sp, #0xb20] + str x16, [sp, #0x160] + ldr x16, [sp, #0xb30] + str x16, [sp, #0x168] + ldr x16, [sp, #0xb40] + str x16, [sp, #0x170] + ldr x16, [sp, #0xb50] + str x16, [sp, #0x178] + ldr x16, [sp, #0xb60] + str x16, [sp, #0x180] + ldr x16, [sp, #0xb70] + str x16, [sp, #0x188] + ldr x16, [sp, #0xb80] + str x16, [sp, #0x190] + ldr x16, [sp, #0xb90] + str x16, [sp, #0x198] + ldr x16, [sp, #0xba0] + str x16, [sp, #0x1a0] + ldr x16, [sp, #0xbb0] + str x16, [sp, #0x1a8] + ldr x16, [sp, #0xbc0] + str x16, [sp, #0x1b0] + ldr x16, [sp, #0xbd0] + str x16, [sp, #0x1b8] + ldr x16, [sp, #0xbe0] + str x16, [sp, #0x1c0] + ldr x16, [sp, #0xbf0] + str x16, [sp, #0x1c8] + ldr x16, [sp, #0xc00] + str x16, [sp, #0x1d0] + ldr x16, [sp, #0xc10] + str x16, [sp, #0x1d8] + ldr x16, [sp, #0xc20] + str x16, [sp, #0x1e0] + ldr x16, [sp, #0xc30] + str x16, [sp, #0x1e8] + ldr x16, [sp, #0xc40] + str x16, [sp, #0x1f0] + ldr x16, [sp, #0xc50] + str x16, [sp, #0x1f8] + ldr x16, [sp, #0xc60] + str x16, [sp, #0x200] + ldr x16, [sp, #0xc70] + str x16, [sp, #0x208] + ldr x16, [sp, #0xc80] + str x16, [sp, #0x210] + ldr x16, [sp, #0xc90] + str x16, [sp, #0x218] + ldr x16, [sp, #0xca0] + str x16, [sp, #0x220] + ldr x16, [sp, #0xcb0] + str x16, [sp, #0x228] + ldr x16, [sp, #0xcc0] + str x16, [sp, #0x230] + ldr x16, [sp, #0xcd0] + str x16, [sp, #0x238] + ldr x16, [sp, #0xce0] + str x16, [sp, #0x240] + ldr x16, [sp, #0xcf0] + str x16, [sp, #0x248] + ldr x16, [sp, #0xd00] + str x16, [sp, #0x250] + ldr x16, [sp, #0xd10] + str x16, [sp, #0x258] + ldr x16, [sp, #0xd20] + str x16, [sp, #0x260] + ldr x16, [sp, #0xd30] + str x16, [sp, #0x268] + ldr x16, [sp, #0xd40] + str x16, [sp, #0x270] + ldr x16, [sp, #0xd50] + str x16, [sp, #0x278] + ldr x16, [sp, #0xd60] + str x16, [sp, #0x280] + ldr x16, [sp, #0xd70] + str x16, [sp, #0x288] + ldr x16, [sp, #0xd80] + str x16, [sp, #0x290] + ldr x16, [sp, #0xd90] + str x16, [sp, #0x298] + ldr x16, [sp, #0xda0] + str x16, [sp, #0x2a0] + ldr x16, [sp, #0xdb0] + str x16, [sp, #0x2a8] + ldr x16, [sp, #0xdc0] + str x16, [sp, #0x2b0] + ldr x16, [sp, #0xdd0] + str x16, [sp, #0x2b8] + ldr x16, [sp, #0xde0] + str x16, [sp, #0x2c0] + ldr x16, [sp, #0xdf0] + str x16, [sp, #0x2c8] + ldr x16, [sp, #0xe00] + str x16, [sp, #0x2d0] + ldr x16, [sp, #0xe10] + str x16, [sp, #0x2d8] + ldr x16, [sp, #0xe20] + str x16, [sp, #0x2e0] + ldr x16, [sp, #0xe30] + str x16, [sp, #0x2e8] + ldr x16, [sp, #0xe40] + str x16, [sp, #0x2f0] + ldr x16, [sp, #0xe50] + str x16, [sp, #0x2f8] + ldr x16, [sp, #0xe60] + str x16, [sp, #0x300] + ldr x16, [sp, #0xe70] + str x16, [sp, #0x308] + ldr x16, [sp, #0xe80] + str x16, [sp, #0x310] + ldr x16, [sp, #0xe90] + str x16, [sp, #0x318] + ldr x16, [sp, #0xea0] + str x16, [sp, #0x320] + ldr x16, [sp, #0xeb0] + str x16, [sp, #0x328] + ldr x16, [sp, #0xec0] + str x16, [sp, #0x330] + ldr x16, [sp, #0xed0] + str x16, [sp, #0x338] + ldr x16, [sp, #0xee0] + str x16, [sp, #0x340] + ldr x16, [sp, #0xef0] + str x16, [sp, #0x348] + ldr x16, [sp, #0xf00] + str x16, [sp, #0x350] + ldr x16, [sp, #0xf10] + str x16, [sp, #0x358] + ldr x16, [sp, #0xf20] + str x16, [sp, #0x360] + ldr x16, [sp, #0xf30] + str x16, [sp, #0x368] + ldr x16, [sp, #0xf40] + str x16, [sp, #0x370] + ldr x16, [sp, #0xf50] + str x16, [sp, #0x378] + ldr x16, [sp, #0xf60] + str x16, [sp, #0x380] + ldr x16, [sp, #0xf70] + str x16, [sp, #0x388] + ldr x16, [sp, #0xf80] + str x16, [sp, #0x390] + ldr x16, [sp, #0xf90] + str x16, [sp, #0x398] + ldr x16, [sp, #0xfa0] + str x16, [sp, #0x3a0] + ldr x16, [sp, #0xfb0] + str x16, [sp, #0x3a8] + ldr x16, [sp, #0xfc0] + str x16, [sp, #0x3b0] + ldr x16, [sp, #0xfd0] + str x16, [sp, #0x3b8] + ldr x16, [sp, #0xfe0] + str x16, [sp, #0x3c0] + ldr x16, [sp, #0xff0] + str x16, [sp, #0x3c8] + ldr x16, [sp, #0x1000] + str x16, [sp, #0x3d0] + ldr x16, [sp, #0x1010] + str x16, [sp, #0x3d8] + ldr x16, [sp, #0x1020] + str x16, [sp, #0x3e0] + ldr x16, [sp, #0x1030] + str x16, [sp, #0x3e8] + ldr x16, [sp, #0x1040] + str x16, [sp, #0x3f0] + ldr x16, [sp, #0x1050] + str x16, [sp, #0x3f8] + ldr x16, [sp, #0x1060] + str x16, [sp, #0x400] + ldr x16, [sp, #0x1070] + str x16, [sp, #0x408] + ldr x16, [sp, #0x1080] + str x16, [sp, #0x410] + ldr x16, [sp, #0x1090] + str x16, [sp, #0x418] + ldr x16, [sp, #0x10a0] + str x16, [sp, #0x420] + ldr x16, [sp, #0x10b0] + str x16, [sp, #0x428] + ldr x16, [sp, #0x10c0] + str x16, [sp, #0x430] + ldr x16, [sp, #0x10d0] + str x16, [sp, #0x438] + ldr x16, [sp, #0x10e0] + str x16, [sp, #0x440] + ldr x16, [sp, #0x10f0] + str x16, [sp, #0x448] + ldr x16, [sp, #0x1100] + str x16, [sp, #0x450] + ldr x16, [sp, #0x1110] + str x16, [sp, #0x458] + ldr x16, [sp, #0x1120] + str x16, [sp, #0x460] + ldr x16, [sp, #0x1130] + str x16, [sp, #0x468] + ldr x16, [sp, #0x1140] + str x16, [sp, #0x470] + ldr x16, [sp, #0x1150] + str x16, [sp, #0x478] + ldr x16, [sp, #0x1160] + str x16, [sp, #0x480] + ldr x16, [sp, #0x1170] + str x16, [sp, #0x488] + ldr x16, [sp, #0x1180] + str x16, [sp, #0x490] + ldr x16, [sp, #0x1190] + str x16, [sp, #0x498] + ldr x16, [sp, #0x11a0] + str x16, [sp, #0x4a0] + ldr x16, [sp, #0x11b0] + str x16, [sp, #0x4a8] + ldr x16, [sp, #0x11c0] + str x16, [sp, #0x4b0] + ldr x16, [sp, #0x11d0] + str x16, [sp, #0x4b8] + ldr x16, [sp, #0x11e0] + str x16, [sp, #0x4c0] + ldr x16, [sp, #0x11f0] + str x16, [sp, #0x4c8] + ldr x16, [sp, #0x1200] + str x16, [sp, #0x4d0] + ldr x16, [sp, #0x1210] + str x16, [sp, #0x4d8] + ldr x16, [sp, #0x1220] + str x16, [sp, #0x4e0] + ldr x16, [sp, #0x1230] + str x16, [sp, #0x4e8] + ldr x16, [sp, #0x1240] + str x16, [sp, #0x4f0] + ldr x16, [sp, #0x1250] + str x16, [sp, #0x4f8] + ldr x16, [sp, #0x1260] + str x16, [sp, #0x500] + ldr x16, [sp, #0x1270] + str x16, [sp, #0x508] + ldr x16, [sp, #0x1280] + str x16, [sp, #0x510] + ldr x16, [sp, #0x1290] + str x16, [sp, #0x518] + ldr x16, [sp, #0x12a0] + str x16, [sp, #0x520] + ldr x16, [sp, #0x12b0] + str x16, [sp, #0x528] + ldr x16, [sp, #0x12c0] + str x16, [sp, #0x530] + ldr x16, [sp, #0x12d0] + str x16, [sp, #0x538] + ldr x16, [sp, #0x12e0] + str x16, [sp, #0x540] + ldr x16, [sp, #0x12f0] + str x16, [sp, #0x548] + ldr x16, [sp, #0x1300] + str x16, [sp, #0x550] + ldr x16, [sp, #0x1310] + str x16, [sp, #0x558] + ldr x16, [sp, #0x1320] + str x16, [sp, #0x560] + ldr x16, [sp, #0x1330] + str x16, [sp, #0x568] + ldr x16, [sp, #0x1340] + str x16, [sp, #0x570] + ldr x16, [sp, #0x1350] + str x16, [sp, #0x578] + ldr x16, [sp, #0x1360] + str x16, [sp, #0x580] + ldr x16, [sp, #0x1370] + str x16, [sp, #0x588] + ldr x16, [sp, #0x1380] + str x16, [sp, #0x590] + ldr x16, [sp, #0x1390] + str x16, [sp, #0x598] + ldr x16, [sp, #0x13a0] + str x16, [sp, #0x5a0] + ldr x16, [sp, #0x13b0] + str x16, [sp, #0x5a8] + ldr x16, [sp, #0x13c0] + str x16, [sp, #0x5b0] + ldr x16, [sp, #0x13d0] + str x16, [sp, #0x5b8] + ldr x16, [sp, #0x13e0] + str x16, [sp, #0x5c0] + ldr x16, [sp, #0x13f0] + str x16, [sp, #0x5c8] + ldr x16, [sp, #0x1400] + str x16, [sp, #0x5d0] + ldr x16, [sp, #0x1410] + str x16, [sp, #0x5d8] + ldr x16, [sp, #0x1420] + str x16, [sp, #0x5e0] + ldr x16, [sp, #0x1430] + str x16, [sp, #0x5e8] + ldr x16, [sp, #0x1440] + str x16, [sp, #0x5f0] + ldr x16, [sp, #0x1450] + str x16, [sp, #0x5f8] + ldr x16, [sp, #0x1460] + str x16, [sp, #0x600] + ldr x16, [sp, #0x1470] + str x16, [sp, #0x608] + ldr x16, [sp, #0x1480] + str x16, [sp, #0x610] + ldr x16, [sp, #0x1490] + str x16, [sp, #0x618] + ldr x16, [sp, #0x14a0] + str x16, [sp, #0x620] + ldr x16, [sp, #0x14b0] + str x16, [sp, #0x628] + ldr x16, [sp, #0x14c0] + str x16, [sp, #0x630] + ldr x16, [sp, #0x14d0] + str x16, [sp, #0x638] + ldr x16, [sp, #0x14e0] + str x16, [sp, #0x640] + ldr x16, [sp, #0x14f0] + str x16, [sp, #0x648] + ldr x16, [sp, #0x1500] + str x16, [sp, #0x650] + ldr x16, [sp, #0x1510] + str x16, [sp, #0x658] + ldr x16, [sp, #0x1520] + str x16, [sp, #0x660] + ldr x16, [sp, #0x1530] + str x16, [sp, #0x668] + ldr x16, [sp, #0x1540] + str x16, [sp, #0x670] + ldr x16, [sp, #0x1550] + str x16, [sp, #0x678] + ldr x16, [sp, #0x1560] + str x16, [sp, #0x680] + ldr x16, [sp, #0x1570] + str x16, [sp, #0x688] + ldr x16, [sp, #0x1580] + str x16, [sp, #0x690] + ldr x16, [sp, #0x1590] + str x16, [sp, #0x698] + ldr x16, [sp, #0x15a0] + str x16, [sp, #0x6a0] + ldr x16, [sp, #0x15b0] + str x16, [sp, #0x6a8] + ldr x16, [sp, #0x15c0] + str x16, [sp, #0x6b0] + ldr x16, [sp, #0x15d0] + str x16, [sp, #0x6b8] + ldr x16, [sp, #0x15e0] + str x16, [sp, #0x6c0] + ldr x16, [sp, #0x15f0] + str x16, [sp, #0x6c8] + ldr x16, [sp, #0x1600] + str x16, [sp, #0x6d0] + ldr x16, [sp, #0x1610] + str x16, [sp, #0x6d8] + ldr x16, [sp, #0x1620] + str x16, [sp, #0x6e0] + ldr x16, [sp, #0x1630] + str x16, [sp, #0x6e8] + ldr x16, [sp, #0x1640] + str x16, [sp, #0x6f0] + ldr x16, [sp, #0x1650] + str x16, [sp, #0x6f8] + ldr x16, [sp, #0x1660] + str x16, [sp, #0x700] + ldr x16, [sp, #0x1670] + str x16, [sp, #0x708] + ldr x16, [sp, #0x1680] + str x16, [sp, #0x710] + ldr x16, [sp, #0x1690] + str x16, [sp, #0x718] + ldr x16, [sp, #0x16a0] + str x16, [sp, #0x720] + ldr x16, [sp, #0x16b0] + str x16, [sp, #0x728] + ldr x16, [sp, #0x16c0] + str x16, [sp, #0x730] + ldr x16, [sp, #0x16d0] + str x16, [sp, #0x738] + ldr x16, [sp, #0x16e0] + str x16, [sp, #0x740] + ldr x16, [sp, #0x16f0] + str x16, [sp, #0x748] + ldr x16, [sp, #0x1700] + str x16, [sp, #0x750] + ldr x16, [sp, #0x1710] + str x16, [sp, #0x758] + ldr x16, [sp, #0x1720] + str x16, [sp, #0x760] + ldr x16, [sp, #0x1730] + str x16, [sp, #0x768] + ldr x16, [sp, #0x1740] + str x16, [sp, #0x770] + ldr x16, [sp, #0x1750] + str x16, [sp, #0x778] + ldr x16, [sp, #0x1760] + str x16, [sp, #0x780] + ldr x16, [sp, #0x1770] + str x16, [sp, #0x788] + ldr x16, [sp, #0x1780] + str x16, [sp, #0x790] + ldr x16, [sp, #0x1790] + str x16, [sp, #0x798] + ldr x16, [sp, #0x17a0] + str x16, [sp, #0x7a0] + ldr x16, [sp, #0x17b0] + str x16, [sp, #0x7a8] + ldr x16, [sp, #0x17c0] + str x16, [sp, #0x7b0] + ldr x16, [sp, #0x17d0] + str x16, [sp, #0x7b8] + ldr x16, [sp, #0x17e0] + str x16, [sp, #0x7c0] + ldr x16, [sp, #0x17f0] + str x16, [sp, #0x7c8] + ldr x16, [sp, #0x1800] + str x16, [sp, #0x7d0] + ldr x16, [sp, #0x1810] + str x16, [sp, #0x7d8] + blr x9 + add sp, sp, #0x7e0 + add sp, sp, #0x1, lsl #12 // =0x1000 + add sp, sp, #0x40 + mov x17, #0x848a // =33930 + cmp x0, x17 + b.eq + mov x0, #0x2 // =2 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x23, [sp, #0x18] + ldr x24, [sp, #0x20] + ldr x25, [sp, #0x28] + ldr x26, [sp, #0x30] + ldr x27, [sp, #0x38] + ldr x28, [sp, #0x40] + ldr x19, [sp, #0x50] + add sp, sp, #0x1, lsl #12 // =0x1000 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + add x1, x0, #0x10 + add x2, x0, #0x20 + add x3, x0, #0x30 + add x4, x0, #0x40 + add x5, x0, #0x50 + add x6, x0, #0x60 + add x7, x0, #0x70 + add x8, x0, #0x80 + add x9, x0, #0x90 + add x10, x0, #0xa0 + add x11, x0, #0xb0 + add x12, x0, #0xc0 + add x13, x0, #0xd0 + add x14, x0, #0xe0 + add x15, x0, #0xf0 + add x20, x0, #0x100 + add x22, x0, #0x110 + add x23, x0, #0x120 + add x24, x0, #0x130 + add x25, x0, #0x140 + add x26, x0, #0x150 + add x27, x0, #0x160 + add x28, x0, #0x170 + add x16, x0, #0x180 + str x16, [sp, #0x7c8] + add x16, x0, #0x190 + str x16, [sp, #0x7c0] + add x16, x0, #0x1a0 + str x16, [sp, #0x7b8] + add x16, x0, #0x1b0 + str x16, [sp, #0x7b0] + add x16, x0, #0x1c0 + str x16, [sp, #0x7a8] + add x16, x0, #0x1d0 + str x16, [sp, #0x7a0] + add x16, x0, #0x1e0 + str x16, [sp, #0x798] + add x16, x0, #0x1f0 + str x16, [sp, #0x790] + add x16, x0, #0x200 + str x16, [sp, #0x788] + add x16, x0, #0x210 + str x16, [sp, #0x780] + add x16, x0, #0x220 + str x16, [sp, #0x778] + add x16, x0, #0x230 + str x16, [sp, #0x770] + add x16, x0, #0x240 + str x16, [sp, #0x768] + add x16, x0, #0x250 + str x16, [sp, #0x760] + add x16, x0, #0x260 + str x16, [sp, #0x758] + add x16, x0, #0x270 + str x16, [sp, #0x750] + add x16, x0, #0x280 + str x16, [sp, #0x748] + add x16, x0, #0x290 + str x16, [sp, #0x740] + add x16, x0, #0x2a0 + str x16, [sp, #0x738] + add x16, x0, #0x2b0 + str x16, [sp, #0x730] + add x16, x0, #0x2c0 + str x16, [sp, #0x728] + add x16, x0, #0x2d0 + str x16, [sp, #0x720] + add x16, x0, #0x2e0 + str x16, [sp, #0x718] + add x16, x0, #0x2f0 + str x16, [sp, #0x710] + add x16, x0, #0x300 + str x16, [sp, #0x708] + add x16, x0, #0x310 + str x16, [sp, #0x700] + add x16, x0, #0x320 + str x16, [sp, #0x6f8] + add x16, x0, #0x330 + str x16, [sp, #0x6f0] + add x16, x0, #0x340 + str x16, [sp, #0x6e8] + add x16, x0, #0x350 + str x16, [sp, #0x6e0] + add x16, x0, #0x360 + str x16, [sp, #0x6d8] + add x16, x0, #0x370 + str x16, [sp, #0x6d0] + add x16, x0, #0x380 + str x16, [sp, #0x6c8] + add x16, x0, #0x390 + str x16, [sp, #0x6c0] + add x16, x0, #0x3a0 + str x16, [sp, #0x6b8] + add x16, x0, #0x3b0 + str x16, [sp, #0x6b0] + add x16, x0, #0x3c0 + str x16, [sp, #0x6a8] + add x16, x0, #0x3d0 + str x16, [sp, #0x6a0] + add x16, x0, #0x3e0 + str x16, [sp, #0x698] + add x16, x0, #0x3f0 + str x16, [sp, #0x690] + add x16, x0, #0x400 + str x16, [sp, #0x688] + add x16, x0, #0x410 + str x16, [sp, #0x680] + add x16, x0, #0x420 + str x16, [sp, #0x678] + add x16, x0, #0x430 + str x16, [sp, #0x670] + add x16, x0, #0x440 + str x16, [sp, #0x668] + add x16, x0, #0x450 + str x16, [sp, #0x660] + add x16, x0, #0x460 + str x16, [sp, #0x658] + add x16, x0, #0x470 + str x16, [sp, #0x650] + add x16, x0, #0x480 + str x16, [sp, #0x648] + add x16, x0, #0x490 + str x16, [sp, #0x640] + add x16, x0, #0x4a0 + str x16, [sp, #0x638] + add x16, x0, #0x4b0 + str x16, [sp, #0x630] + add x16, x0, #0x4c0 + str x16, [sp, #0x628] + add x16, x0, #0x4d0 + str x16, [sp, #0x620] + add x16, x0, #0x4e0 + str x16, [sp, #0x618] + add x16, x0, #0x4f0 + str x16, [sp, #0x610] + add x16, x0, #0x500 + str x16, [sp, #0x608] + add x16, x0, #0x510 + str x16, [sp, #0x600] + add x16, x0, #0x520 + str x16, [sp, #0x5f8] + add x16, x0, #0x530 + str x16, [sp, #0x5f0] + add x16, x0, #0x540 + str x16, [sp, #0x5e8] + add x16, x0, #0x550 + str x16, [sp, #0x5e0] + add x16, x0, #0x560 + str x16, [sp, #0x5d8] + add x16, x0, #0x570 + str x16, [sp, #0x5d0] + add x16, x0, #0x580 + str x16, [sp, #0x5c8] + add x16, x0, #0x590 + str x16, [sp, #0x5c0] + add x16, x0, #0x5a0 + str x16, [sp, #0x5b8] + add x16, x0, #0x5b0 + str x16, [sp, #0x5b0] + add x16, x0, #0x5c0 + str x16, [sp, #0x5a8] + add x16, x0, #0x5d0 + str x16, [sp, #0x5a0] + add x16, x0, #0x5e0 + str x16, [sp, #0x598] + add x16, x0, #0x5f0 + str x16, [sp, #0x590] + add x16, x0, #0x600 + str x16, [sp, #0x588] + add x16, x0, #0x610 + str x16, [sp, #0x580] + add x16, x0, #0x620 + str x16, [sp, #0x578] + add x16, x0, #0x630 + str x16, [sp, #0x570] + add x16, x0, #0x640 + str x16, [sp, #0x568] + add x16, x0, #0x650 + str x16, [sp, #0x560] + add x16, x0, #0x660 + str x16, [sp, #0x558] + add x16, x0, #0x670 + str x16, [sp, #0x550] + add x16, x0, #0x680 + str x16, [sp, #0x548] + add x16, x0, #0x690 + str x16, [sp, #0x540] + add x16, x0, #0x6a0 + str x16, [sp, #0x538] + add x16, x0, #0x6b0 + str x16, [sp, #0x530] + add x16, x0, #0x6c0 + str x16, [sp, #0x528] + add x16, x0, #0x6d0 + str x16, [sp, #0x520] + add x16, x0, #0x6e0 + str x16, [sp, #0x518] + add x16, x0, #0x6f0 + str x16, [sp, #0x510] + add x16, x0, #0x700 + str x16, [sp, #0x508] + add x16, x0, #0x710 + str x16, [sp, #0x500] + add x16, x0, #0x720 + str x16, [sp, #0x4f8] + add x16, x0, #0x730 + str x16, [sp, #0x4f0] + add x16, x0, #0x740 + str x16, [sp, #0x4e8] + add x16, x0, #0x750 + str x16, [sp, #0x4e0] + add x16, x0, #0x760 + str x16, [sp, #0x4d8] + add x16, x0, #0x770 + str x16, [sp, #0x4d0] + add x16, x0, #0x780 + str x16, [sp, #0x4c8] + add x16, x0, #0x790 + str x16, [sp, #0x4c0] + add x16, x0, #0x7a0 + str x16, [sp, #0x4b8] + add x16, x0, #0x7b0 + str x16, [sp, #0x4b0] + add x16, x0, #0x7c0 + str x16, [sp, #0x4a8] + add x16, x0, #0x7d0 + str x16, [sp, #0x4a0] + add x16, x0, #0x7e0 + str x16, [sp, #0x498] + add x16, x0, #0x7f0 + str x16, [sp, #0x490] + add x16, x0, #0x800 + str x16, [sp, #0x488] + add x16, x0, #0x810 + str x16, [sp, #0x480] + add x16, x0, #0x820 + str x16, [sp, #0x478] + add x16, x0, #0x830 + str x16, [sp, #0x470] + add x16, x0, #0x840 + str x16, [sp, #0x468] + add x16, x0, #0x850 + str x16, [sp, #0x460] + add x16, x0, #0x860 + str x16, [sp, #0x458] + add x16, x0, #0x870 + str x16, [sp, #0x450] + add x16, x0, #0x880 + str x16, [sp, #0x448] + add x16, x0, #0x890 + str x16, [sp, #0x440] + add x16, x0, #0x8a0 + str x16, [sp, #0x438] + add x16, x0, #0x8b0 + str x16, [sp, #0x430] + add x16, x0, #0x8c0 + str x16, [sp, #0x428] + add x16, x0, #0x8d0 + str x16, [sp, #0x420] + add x16, x0, #0x8e0 + str x16, [sp, #0x418] + add x16, x0, #0x8f0 + str x16, [sp, #0x410] + add x16, x0, #0x900 + str x16, [sp, #0x408] + add x16, x0, #0x910 + str x16, [sp, #0x400] + add x16, x0, #0x920 + str x16, [sp, #0x3f8] + add x16, x0, #0x930 + str x16, [sp, #0x3f0] + add x16, x0, #0x940 + str x16, [sp, #0x3e8] + add x16, x0, #0x950 + str x16, [sp, #0x3e0] + add x16, x0, #0x960 + str x16, [sp, #0x3d8] + add x16, x0, #0x970 + str x16, [sp, #0x3d0] + add x16, x0, #0x980 + str x16, [sp, #0x3c8] + add x16, x0, #0x990 + str x16, [sp, #0x3c0] + add x16, x0, #0x9a0 + str x16, [sp, #0x3b8] + add x16, x0, #0x9b0 + str x16, [sp, #0x3b0] + add x16, x0, #0x9c0 + str x16, [sp, #0x3a8] + add x16, x0, #0x9d0 + str x16, [sp, #0x3a0] + add x16, x0, #0x9e0 + str x16, [sp, #0x398] + add x16, x0, #0x9f0 + str x16, [sp, #0x390] + add x16, x0, #0xa00 + str x16, [sp, #0x388] + add x16, x0, #0xa10 + str x16, [sp, #0x380] + add x16, x0, #0xa20 + str x16, [sp, #0x378] + add x16, x0, #0xa30 + str x16, [sp, #0x370] + add x16, x0, #0xa40 + str x16, [sp, #0x368] + add x16, x0, #0xa50 + str x16, [sp, #0x360] + add x16, x0, #0xa60 + str x16, [sp, #0x358] + add x16, x0, #0xa70 + str x16, [sp, #0x350] + add x16, x0, #0xa80 + str x16, [sp, #0x348] + add x16, x0, #0xa90 + str x16, [sp, #0x340] + add x16, x0, #0xaa0 + str x16, [sp, #0x338] + add x16, x0, #0xab0 + str x16, [sp, #0x330] + add x16, x0, #0xac0 + str x16, [sp, #0x328] + add x16, x0, #0xad0 + str x16, [sp, #0x320] + add x16, x0, #0xae0 + str x16, [sp, #0x318] + add x16, x0, #0xaf0 + str x16, [sp, #0x310] + add x16, x0, #0xb00 + str x16, [sp, #0x308] + add x16, x0, #0xb10 + str x16, [sp, #0x300] + add x16, x0, #0xb20 + str x16, [sp, #0x2f8] + add x16, x0, #0xb30 + str x16, [sp, #0x2f0] + add x16, x0, #0xb40 + str x16, [sp, #0x2e8] + add x16, x0, #0xb50 + str x16, [sp, #0x2e0] + add x16, x0, #0xb60 + str x16, [sp, #0x2d8] + add x16, x0, #0xb70 + str x16, [sp, #0x2d0] + add x16, x0, #0xb80 + str x16, [sp, #0x2c8] + add x16, x0, #0xb90 + str x16, [sp, #0x2c0] + add x16, x0, #0xba0 + str x16, [sp, #0x2b8] + add x16, x0, #0xbb0 + str x16, [sp, #0x2b0] + add x16, x0, #0xbc0 + str x16, [sp, #0x2a8] + add x16, x0, #0xbd0 + str x16, [sp, #0x2a0] + add x16, x0, #0xbe0 + str x16, [sp, #0x298] + add x16, x0, #0xbf0 + str x16, [sp, #0x290] + add x16, x0, #0xc00 + str x16, [sp, #0x288] + add x16, x0, #0xc10 + str x16, [sp, #0x280] + add x16, x0, #0xc20 + str x16, [sp, #0x278] + add x16, x0, #0xc30 + str x16, [sp, #0x270] + add x16, x0, #0xc40 + str x16, [sp, #0x268] + add x16, x0, #0xc50 + str x16, [sp, #0x260] + add x16, x0, #0xc60 + str x16, [sp, #0x258] + add x16, x0, #0xc70 + str x16, [sp, #0x250] + add x16, x0, #0xc80 + str x16, [sp, #0x248] + add x16, x0, #0xc90 + str x16, [sp, #0x240] + add x16, x0, #0xca0 + str x16, [sp, #0x238] + add x16, x0, #0xcb0 + str x16, [sp, #0x230] + add x16, x0, #0xcc0 + str x16, [sp, #0x228] + add x16, x0, #0xcd0 + str x16, [sp, #0x220] + add x16, x0, #0xce0 + str x16, [sp, #0x218] + add x16, x0, #0xcf0 + str x16, [sp, #0x210] + add x16, x0, #0xd00 + str x16, [sp, #0x208] + add x16, x0, #0xd10 + str x16, [sp, #0x200] + add x16, x0, #0xd20 + str x16, [sp, #0x1f8] + add x16, x0, #0xd30 + str x16, [sp, #0x1f0] + add x16, x0, #0xd40 + str x16, [sp, #0x1e8] + add x16, x0, #0xd50 + str x16, [sp, #0x1e0] + add x16, x0, #0xd60 + str x16, [sp, #0x1d8] + add x16, x0, #0xd70 + str x16, [sp, #0x1d0] + add x16, x0, #0xd80 + str x16, [sp, #0x1c8] + add x16, x0, #0xd90 + str x16, [sp, #0x1c0] + add x16, x0, #0xda0 + str x16, [sp, #0x1b8] + add x16, x0, #0xdb0 + str x16, [sp, #0x1b0] + add x16, x0, #0xdc0 + str x16, [sp, #0x1a8] + add x16, x0, #0xdd0 + str x16, [sp, #0x1a0] + add x16, x0, #0xde0 + str x16, [sp, #0x198] + add x16, x0, #0xdf0 + str x16, [sp, #0x190] + add x16, x0, #0xe00 + str x16, [sp, #0x188] + add x16, x0, #0xe10 + str x16, [sp, #0x180] + add x16, x0, #0xe20 + str x16, [sp, #0x178] + add x16, x0, #0xe30 + str x16, [sp, #0x170] + add x16, x0, #0xe40 + str x16, [sp, #0x168] + add x16, x0, #0xe50 + str x16, [sp, #0x160] + add x16, x0, #0xe60 + str x16, [sp, #0x158] + add x16, x0, #0xe70 + str x16, [sp, #0x150] + add x16, x0, #0xe80 + str x16, [sp, #0x148] + add x16, x0, #0xe90 + str x16, [sp, #0x140] + add x16, x0, #0xea0 + str x16, [sp, #0x138] + add x16, x0, #0xeb0 + str x16, [sp, #0x130] + add x16, x0, #0xec0 + str x16, [sp, #0x128] + add x16, x0, #0xed0 + str x16, [sp, #0x120] + add x16, x0, #0xee0 + str x16, [sp, #0x118] + add x16, x0, #0xef0 + str x16, [sp, #0x110] + add x16, x0, #0xf00 + str x16, [sp, #0x108] + add x16, x0, #0xf10 + str x16, [sp, #0x100] + add x16, x0, #0xf20 + str x16, [sp, #0xf8] + add x16, x0, #0xf30 + str x16, [sp, #0xf0] + add x16, x0, #0xf40 + str x16, [sp, #0xe8] + add x16, x0, #0xf50 + str x16, [sp, #0xe0] + add x16, x0, #0xf60 + str x16, [sp, #0xd8] + add x16, x0, #0xf70 + str x16, [sp, #0xd0] + add x16, x0, #0xf80 + str x16, [sp, #0xc8] + add x16, x0, #0xf90 + str x16, [sp, #0xc0] + add x16, x0, #0xfa0 + str x16, [sp, #0xb8] + add x16, x0, #0xfb0 + str x16, [sp, #0xb0] + add x16, x0, #0xfc0 + str x16, [sp, #0xa8] + add x16, x0, #0xfd0 + str x16, [sp, #0xa0] + add x16, x0, #0xfe0 + str x16, [sp, #0x98] + add x16, x0, #0xff0 + str x16, [sp, #0x90] + mov x17, #0x1000 // =4096 + add x16, x0, x17 + str x16, [sp, #0x88] + mov x17, #0x1010 // =4112 + add x16, x0, x17 + str x16, [sp, #0x80] + mov x17, #0x1020 // =4128 + add x16, x0, x17 + str x16, [sp, #0x78] + mov x17, #0x1030 // =4144 + add x16, x0, x17 + str x16, [sp, #0x70] + mov x17, #0x1040 // =4160 + add x16, x0, x17 + str x16, [sp, #0x68] + mov x16, x21 + sub sp, sp, #0x1, lsl #12 // =0x1000 + sub sp, sp, #0x20 + str x16, [sp, #0x1010] + mov x16, x4 + ldr x17, [x16] + str x17, [sp] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8] + mov x16, x5 + ldr x17, [x16] + str x17, [sp, #0x10] + ldr x17, [x16, #0x8] + str x17, [sp, #0x18] + mov x16, x6 + ldr x17, [x16] + str x17, [sp, #0x20] + ldr x17, [x16, #0x8] + str x17, [sp, #0x28] + mov x16, x7 + ldr x17, [x16] + str x17, [sp, #0x30] + ldr x17, [x16, #0x8] + str x17, [sp, #0x38] + mov x16, x8 + ldr x17, [x16] + str x17, [sp, #0x40] + ldr x17, [x16, #0x8] + str x17, [sp, #0x48] + mov x16, x9 + ldr x17, [x16] + str x17, [sp, #0x50] + ldr x17, [x16, #0x8] + str x17, [sp, #0x58] + mov x16, x10 + ldr x17, [x16] + str x17, [sp, #0x60] + ldr x17, [x16, #0x8] + str x17, [sp, #0x68] + mov x16, x11 + ldr x17, [x16] + str x17, [sp, #0x70] + ldr x17, [x16, #0x8] + str x17, [sp, #0x78] + mov x16, x12 + ldr x17, [x16] + str x17, [sp, #0x80] + ldr x17, [x16, #0x8] + str x17, [sp, #0x88] + mov x16, x13 + ldr x17, [x16] + str x17, [sp, #0x90] + ldr x17, [x16, #0x8] + str x17, [sp, #0x98] + mov x16, x14 + ldr x17, [x16] + str x17, [sp, #0xa0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa8] + mov x16, x15 + ldr x17, [x16] + str x17, [sp, #0xb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb8] + mov x16, x20 + ldr x17, [x16] + str x17, [sp, #0xc0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc8] + mov x16, x22 + ldr x17, [x16] + str x17, [sp, #0xd0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd8] + mov x16, x23 + ldr x17, [x16] + str x17, [sp, #0xe0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe8] + mov x16, x24 + ldr x17, [x16] + str x17, [sp, #0xf0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf8] + mov x16, x25 + ldr x17, [x16] + str x17, [sp, #0x100] + ldr x17, [x16, #0x8] + str x17, [sp, #0x108] + mov x16, x26 + ldr x17, [x16] + str x17, [sp, #0x110] + ldr x17, [x16, #0x8] + str x17, [sp, #0x118] + mov x16, x27 + ldr x17, [x16] + str x17, [sp, #0x120] + ldr x17, [x16, #0x8] + str x17, [sp, #0x128] + mov x16, x28 + ldr x17, [x16] + str x17, [sp, #0x130] + ldr x17, [x16, #0x8] + str x17, [sp, #0x138] + ldr x16, [sp, #0x17e8] + ldr x17, [x16] + str x17, [sp, #0x140] + ldr x17, [x16, #0x8] + str x17, [sp, #0x148] + ldr x16, [sp, #0x17e0] + ldr x17, [x16] + str x17, [sp, #0x150] + ldr x17, [x16, #0x8] + str x17, [sp, #0x158] + ldr x16, [sp, #0x17d8] + ldr x17, [x16] + str x17, [sp, #0x160] + ldr x17, [x16, #0x8] + str x17, [sp, #0x168] + ldr x16, [sp, #0x17d0] + ldr x17, [x16] + str x17, [sp, #0x170] + ldr x17, [x16, #0x8] + str x17, [sp, #0x178] + ldr x16, [sp, #0x17c8] + ldr x17, [x16] + str x17, [sp, #0x180] + ldr x17, [x16, #0x8] + str x17, [sp, #0x188] + ldr x16, [sp, #0x17c0] + ldr x17, [x16] + str x17, [sp, #0x190] + ldr x17, [x16, #0x8] + str x17, [sp, #0x198] + ldr x16, [sp, #0x17b8] + ldr x17, [x16] + str x17, [sp, #0x1a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1a8] + ldr x16, [sp, #0x17b0] + ldr x17, [x16] + str x17, [sp, #0x1b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1b8] + ldr x16, [sp, #0x17a8] + ldr x17, [x16] + str x17, [sp, #0x1c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1c8] + ldr x16, [sp, #0x17a0] + ldr x17, [x16] + str x17, [sp, #0x1d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1d8] + ldr x16, [sp, #0x1798] + ldr x17, [x16] + str x17, [sp, #0x1e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1e8] + ldr x16, [sp, #0x1790] + ldr x17, [x16] + str x17, [sp, #0x1f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1f8] + ldr x16, [sp, #0x1788] + ldr x17, [x16] + str x17, [sp, #0x200] + ldr x17, [x16, #0x8] + str x17, [sp, #0x208] + ldr x16, [sp, #0x1780] + ldr x17, [x16] + str x17, [sp, #0x210] + ldr x17, [x16, #0x8] + str x17, [sp, #0x218] + ldr x16, [sp, #0x1778] + ldr x17, [x16] + str x17, [sp, #0x220] + ldr x17, [x16, #0x8] + str x17, [sp, #0x228] + ldr x16, [sp, #0x1770] + ldr x17, [x16] + str x17, [sp, #0x230] + ldr x17, [x16, #0x8] + str x17, [sp, #0x238] + ldr x16, [sp, #0x1768] + ldr x17, [x16] + str x17, [sp, #0x240] + ldr x17, [x16, #0x8] + str x17, [sp, #0x248] + ldr x16, [sp, #0x1760] + ldr x17, [x16] + str x17, [sp, #0x250] + ldr x17, [x16, #0x8] + str x17, [sp, #0x258] + ldr x16, [sp, #0x1758] + ldr x17, [x16] + str x17, [sp, #0x260] + ldr x17, [x16, #0x8] + str x17, [sp, #0x268] + ldr x16, [sp, #0x1750] + ldr x17, [x16] + str x17, [sp, #0x270] + ldr x17, [x16, #0x8] + str x17, [sp, #0x278] + ldr x16, [sp, #0x1748] + ldr x17, [x16] + str x17, [sp, #0x280] + ldr x17, [x16, #0x8] + str x17, [sp, #0x288] + ldr x16, [sp, #0x1740] + ldr x17, [x16] + str x17, [sp, #0x290] + ldr x17, [x16, #0x8] + str x17, [sp, #0x298] + ldr x16, [sp, #0x1738] + ldr x17, [x16] + str x17, [sp, #0x2a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2a8] + ldr x16, [sp, #0x1730] + ldr x17, [x16] + str x17, [sp, #0x2b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2b8] + ldr x16, [sp, #0x1728] + ldr x17, [x16] + str x17, [sp, #0x2c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2c8] + ldr x16, [sp, #0x1720] + ldr x17, [x16] + str x17, [sp, #0x2d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2d8] + ldr x16, [sp, #0x1718] + ldr x17, [x16] + str x17, [sp, #0x2e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2e8] + ldr x16, [sp, #0x1710] + ldr x17, [x16] + str x17, [sp, #0x2f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x2f8] + ldr x16, [sp, #0x1708] + ldr x17, [x16] + str x17, [sp, #0x300] + ldr x17, [x16, #0x8] + str x17, [sp, #0x308] + ldr x16, [sp, #0x1700] + ldr x17, [x16] + str x17, [sp, #0x310] + ldr x17, [x16, #0x8] + str x17, [sp, #0x318] + ldr x16, [sp, #0x16f8] + ldr x17, [x16] + str x17, [sp, #0x320] + ldr x17, [x16, #0x8] + str x17, [sp, #0x328] + ldr x16, [sp, #0x16f0] + ldr x17, [x16] + str x17, [sp, #0x330] + ldr x17, [x16, #0x8] + str x17, [sp, #0x338] + ldr x16, [sp, #0x16e8] + ldr x17, [x16] + str x17, [sp, #0x340] + ldr x17, [x16, #0x8] + str x17, [sp, #0x348] + ldr x16, [sp, #0x16e0] + ldr x17, [x16] + str x17, [sp, #0x350] + ldr x17, [x16, #0x8] + str x17, [sp, #0x358] + ldr x16, [sp, #0x16d8] + ldr x17, [x16] + str x17, [sp, #0x360] + ldr x17, [x16, #0x8] + str x17, [sp, #0x368] + ldr x16, [sp, #0x16d0] + ldr x17, [x16] + str x17, [sp, #0x370] + ldr x17, [x16, #0x8] + str x17, [sp, #0x378] + ldr x16, [sp, #0x16c8] + ldr x17, [x16] + str x17, [sp, #0x380] + ldr x17, [x16, #0x8] + str x17, [sp, #0x388] + ldr x16, [sp, #0x16c0] + ldr x17, [x16] + str x17, [sp, #0x390] + ldr x17, [x16, #0x8] + str x17, [sp, #0x398] + ldr x16, [sp, #0x16b8] + ldr x17, [x16] + str x17, [sp, #0x3a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3a8] + ldr x16, [sp, #0x16b0] + ldr x17, [x16] + str x17, [sp, #0x3b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3b8] + ldr x16, [sp, #0x16a8] + ldr x17, [x16] + str x17, [sp, #0x3c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3c8] + ldr x16, [sp, #0x16a0] + ldr x17, [x16] + str x17, [sp, #0x3d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3d8] + ldr x16, [sp, #0x1698] + ldr x17, [x16] + str x17, [sp, #0x3e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3e8] + ldr x16, [sp, #0x1690] + ldr x17, [x16] + str x17, [sp, #0x3f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x3f8] + ldr x16, [sp, #0x1688] + ldr x17, [x16] + str x17, [sp, #0x400] + ldr x17, [x16, #0x8] + str x17, [sp, #0x408] + ldr x16, [sp, #0x1680] + ldr x17, [x16] + str x17, [sp, #0x410] + ldr x17, [x16, #0x8] + str x17, [sp, #0x418] + ldr x16, [sp, #0x1678] + ldr x17, [x16] + str x17, [sp, #0x420] + ldr x17, [x16, #0x8] + str x17, [sp, #0x428] + ldr x16, [sp, #0x1670] + ldr x17, [x16] + str x17, [sp, #0x430] + ldr x17, [x16, #0x8] + str x17, [sp, #0x438] + ldr x16, [sp, #0x1668] + ldr x17, [x16] + str x17, [sp, #0x440] + ldr x17, [x16, #0x8] + str x17, [sp, #0x448] + ldr x16, [sp, #0x1660] + ldr x17, [x16] + str x17, [sp, #0x450] + ldr x17, [x16, #0x8] + str x17, [sp, #0x458] + ldr x16, [sp, #0x1658] + ldr x17, [x16] + str x17, [sp, #0x460] + ldr x17, [x16, #0x8] + str x17, [sp, #0x468] + ldr x16, [sp, #0x1650] + ldr x17, [x16] + str x17, [sp, #0x470] + ldr x17, [x16, #0x8] + str x17, [sp, #0x478] + ldr x16, [sp, #0x1648] + ldr x17, [x16] + str x17, [sp, #0x480] + ldr x17, [x16, #0x8] + str x17, [sp, #0x488] + ldr x16, [sp, #0x1640] + ldr x17, [x16] + str x17, [sp, #0x490] + ldr x17, [x16, #0x8] + str x17, [sp, #0x498] + ldr x16, [sp, #0x1638] + ldr x17, [x16] + str x17, [sp, #0x4a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4a8] + ldr x16, [sp, #0x1630] + ldr x17, [x16] + str x17, [sp, #0x4b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4b8] + ldr x16, [sp, #0x1628] + ldr x17, [x16] + str x17, [sp, #0x4c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4c8] + ldr x16, [sp, #0x1620] + ldr x17, [x16] + str x17, [sp, #0x4d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4d8] + ldr x16, [sp, #0x1618] + ldr x17, [x16] + str x17, [sp, #0x4e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4e8] + ldr x16, [sp, #0x1610] + ldr x17, [x16] + str x17, [sp, #0x4f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x4f8] + ldr x16, [sp, #0x1608] + ldr x17, [x16] + str x17, [sp, #0x500] + ldr x17, [x16, #0x8] + str x17, [sp, #0x508] + ldr x16, [sp, #0x1600] + ldr x17, [x16] + str x17, [sp, #0x510] + ldr x17, [x16, #0x8] + str x17, [sp, #0x518] + ldr x16, [sp, #0x15f8] + ldr x17, [x16] + str x17, [sp, #0x520] + ldr x17, [x16, #0x8] + str x17, [sp, #0x528] + ldr x16, [sp, #0x15f0] + ldr x17, [x16] + str x17, [sp, #0x530] + ldr x17, [x16, #0x8] + str x17, [sp, #0x538] + ldr x16, [sp, #0x15e8] + ldr x17, [x16] + str x17, [sp, #0x540] + ldr x17, [x16, #0x8] + str x17, [sp, #0x548] + ldr x16, [sp, #0x15e0] + ldr x17, [x16] + str x17, [sp, #0x550] + ldr x17, [x16, #0x8] + str x17, [sp, #0x558] + ldr x16, [sp, #0x15d8] + ldr x17, [x16] + str x17, [sp, #0x560] + ldr x17, [x16, #0x8] + str x17, [sp, #0x568] + ldr x16, [sp, #0x15d0] + ldr x17, [x16] + str x17, [sp, #0x570] + ldr x17, [x16, #0x8] + str x17, [sp, #0x578] + ldr x16, [sp, #0x15c8] + ldr x17, [x16] + str x17, [sp, #0x580] + ldr x17, [x16, #0x8] + str x17, [sp, #0x588] + ldr x16, [sp, #0x15c0] + ldr x17, [x16] + str x17, [sp, #0x590] + ldr x17, [x16, #0x8] + str x17, [sp, #0x598] + ldr x16, [sp, #0x15b8] + ldr x17, [x16] + str x17, [sp, #0x5a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5a8] + ldr x16, [sp, #0x15b0] + ldr x17, [x16] + str x17, [sp, #0x5b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5b8] + ldr x16, [sp, #0x15a8] + ldr x17, [x16] + str x17, [sp, #0x5c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5c8] + ldr x16, [sp, #0x15a0] + ldr x17, [x16] + str x17, [sp, #0x5d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5d8] + ldr x16, [sp, #0x1598] + ldr x17, [x16] + str x17, [sp, #0x5e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5e8] + ldr x16, [sp, #0x1590] + ldr x17, [x16] + str x17, [sp, #0x5f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x5f8] + ldr x16, [sp, #0x1588] + ldr x17, [x16] + str x17, [sp, #0x600] + ldr x17, [x16, #0x8] + str x17, [sp, #0x608] + ldr x16, [sp, #0x1580] + ldr x17, [x16] + str x17, [sp, #0x610] + ldr x17, [x16, #0x8] + str x17, [sp, #0x618] + ldr x16, [sp, #0x1578] + ldr x17, [x16] + str x17, [sp, #0x620] + ldr x17, [x16, #0x8] + str x17, [sp, #0x628] + ldr x16, [sp, #0x1570] + ldr x17, [x16] + str x17, [sp, #0x630] + ldr x17, [x16, #0x8] + str x17, [sp, #0x638] + ldr x16, [sp, #0x1568] + ldr x17, [x16] + str x17, [sp, #0x640] + ldr x17, [x16, #0x8] + str x17, [sp, #0x648] + ldr x16, [sp, #0x1560] + ldr x17, [x16] + str x17, [sp, #0x650] + ldr x17, [x16, #0x8] + str x17, [sp, #0x658] + ldr x16, [sp, #0x1558] + ldr x17, [x16] + str x17, [sp, #0x660] + ldr x17, [x16, #0x8] + str x17, [sp, #0x668] + ldr x16, [sp, #0x1550] + ldr x17, [x16] + str x17, [sp, #0x670] + ldr x17, [x16, #0x8] + str x17, [sp, #0x678] + ldr x16, [sp, #0x1548] + ldr x17, [x16] + str x17, [sp, #0x680] + ldr x17, [x16, #0x8] + str x17, [sp, #0x688] + ldr x16, [sp, #0x1540] + ldr x17, [x16] + str x17, [sp, #0x690] + ldr x17, [x16, #0x8] + str x17, [sp, #0x698] + ldr x16, [sp, #0x1538] + ldr x17, [x16] + str x17, [sp, #0x6a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6a8] + ldr x16, [sp, #0x1530] + ldr x17, [x16] + str x17, [sp, #0x6b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6b8] + ldr x16, [sp, #0x1528] + ldr x17, [x16] + str x17, [sp, #0x6c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6c8] + ldr x16, [sp, #0x1520] + ldr x17, [x16] + str x17, [sp, #0x6d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6d8] + ldr x16, [sp, #0x1518] + ldr x17, [x16] + str x17, [sp, #0x6e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6e8] + ldr x16, [sp, #0x1510] + ldr x17, [x16] + str x17, [sp, #0x6f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x6f8] + ldr x16, [sp, #0x1508] + ldr x17, [x16] + str x17, [sp, #0x700] + ldr x17, [x16, #0x8] + str x17, [sp, #0x708] + ldr x16, [sp, #0x1500] + ldr x17, [x16] + str x17, [sp, #0x710] + ldr x17, [x16, #0x8] + str x17, [sp, #0x718] + ldr x16, [sp, #0x14f8] + ldr x17, [x16] + str x17, [sp, #0x720] + ldr x17, [x16, #0x8] + str x17, [sp, #0x728] + ldr x16, [sp, #0x14f0] + ldr x17, [x16] + str x17, [sp, #0x730] + ldr x17, [x16, #0x8] + str x17, [sp, #0x738] + ldr x16, [sp, #0x14e8] + ldr x17, [x16] + str x17, [sp, #0x740] + ldr x17, [x16, #0x8] + str x17, [sp, #0x748] + ldr x16, [sp, #0x14e0] + ldr x17, [x16] + str x17, [sp, #0x750] + ldr x17, [x16, #0x8] + str x17, [sp, #0x758] + ldr x16, [sp, #0x14d8] + ldr x17, [x16] + str x17, [sp, #0x760] + ldr x17, [x16, #0x8] + str x17, [sp, #0x768] + ldr x16, [sp, #0x14d0] + ldr x17, [x16] + str x17, [sp, #0x770] + ldr x17, [x16, #0x8] + str x17, [sp, #0x778] + ldr x16, [sp, #0x14c8] + ldr x17, [x16] + str x17, [sp, #0x780] + ldr x17, [x16, #0x8] + str x17, [sp, #0x788] + ldr x16, [sp, #0x14c0] + ldr x17, [x16] + str x17, [sp, #0x790] + ldr x17, [x16, #0x8] + str x17, [sp, #0x798] + ldr x16, [sp, #0x14b8] + ldr x17, [x16] + str x17, [sp, #0x7a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7a8] + ldr x16, [sp, #0x14b0] + ldr x17, [x16] + str x17, [sp, #0x7b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7b8] + ldr x16, [sp, #0x14a8] + ldr x17, [x16] + str x17, [sp, #0x7c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7c8] + ldr x16, [sp, #0x14a0] + ldr x17, [x16] + str x17, [sp, #0x7d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7d8] + ldr x16, [sp, #0x1498] + ldr x17, [x16] + str x17, [sp, #0x7e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7e8] + ldr x16, [sp, #0x1490] + ldr x17, [x16] + str x17, [sp, #0x7f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x7f8] + ldr x16, [sp, #0x1488] + ldr x17, [x16] + str x17, [sp, #0x800] + ldr x17, [x16, #0x8] + str x17, [sp, #0x808] + ldr x16, [sp, #0x1480] + ldr x17, [x16] + str x17, [sp, #0x810] + ldr x17, [x16, #0x8] + str x17, [sp, #0x818] + ldr x16, [sp, #0x1478] + ldr x17, [x16] + str x17, [sp, #0x820] + ldr x17, [x16, #0x8] + str x17, [sp, #0x828] + ldr x16, [sp, #0x1470] + ldr x17, [x16] + str x17, [sp, #0x830] + ldr x17, [x16, #0x8] + str x17, [sp, #0x838] + ldr x16, [sp, #0x1468] + ldr x17, [x16] + str x17, [sp, #0x840] + ldr x17, [x16, #0x8] + str x17, [sp, #0x848] + ldr x16, [sp, #0x1460] + ldr x17, [x16] + str x17, [sp, #0x850] + ldr x17, [x16, #0x8] + str x17, [sp, #0x858] + ldr x16, [sp, #0x1458] + ldr x17, [x16] + str x17, [sp, #0x860] + ldr x17, [x16, #0x8] + str x17, [sp, #0x868] + ldr x16, [sp, #0x1450] + ldr x17, [x16] + str x17, [sp, #0x870] + ldr x17, [x16, #0x8] + str x17, [sp, #0x878] + ldr x16, [sp, #0x1448] + ldr x17, [x16] + str x17, [sp, #0x880] + ldr x17, [x16, #0x8] + str x17, [sp, #0x888] + ldr x16, [sp, #0x1440] + ldr x17, [x16] + str x17, [sp, #0x890] + ldr x17, [x16, #0x8] + str x17, [sp, #0x898] + ldr x16, [sp, #0x1438] + ldr x17, [x16] + str x17, [sp, #0x8a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8a8] + ldr x16, [sp, #0x1430] + ldr x17, [x16] + str x17, [sp, #0x8b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8b8] + ldr x16, [sp, #0x1428] + ldr x17, [x16] + str x17, [sp, #0x8c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8c8] + ldr x16, [sp, #0x1420] + ldr x17, [x16] + str x17, [sp, #0x8d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8d8] + ldr x16, [sp, #0x1418] + ldr x17, [x16] + str x17, [sp, #0x8e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8e8] + ldr x16, [sp, #0x1410] + ldr x17, [x16] + str x17, [sp, #0x8f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8f8] + ldr x16, [sp, #0x1408] + ldr x17, [x16] + str x17, [sp, #0x900] + ldr x17, [x16, #0x8] + str x17, [sp, #0x908] + ldr x16, [sp, #0x1400] + ldr x17, [x16] + str x17, [sp, #0x910] + ldr x17, [x16, #0x8] + str x17, [sp, #0x918] + ldr x16, [sp, #0x13f8] + ldr x17, [x16] + str x17, [sp, #0x920] + ldr x17, [x16, #0x8] + str x17, [sp, #0x928] + ldr x16, [sp, #0x13f0] + ldr x17, [x16] + str x17, [sp, #0x930] + ldr x17, [x16, #0x8] + str x17, [sp, #0x938] + ldr x16, [sp, #0x13e8] + ldr x17, [x16] + str x17, [sp, #0x940] + ldr x17, [x16, #0x8] + str x17, [sp, #0x948] + ldr x16, [sp, #0x13e0] + ldr x17, [x16] + str x17, [sp, #0x950] + ldr x17, [x16, #0x8] + str x17, [sp, #0x958] + ldr x16, [sp, #0x13d8] + ldr x17, [x16] + str x17, [sp, #0x960] + ldr x17, [x16, #0x8] + str x17, [sp, #0x968] + ldr x16, [sp, #0x13d0] + ldr x17, [x16] + str x17, [sp, #0x970] + ldr x17, [x16, #0x8] + str x17, [sp, #0x978] + ldr x16, [sp, #0x13c8] + ldr x17, [x16] + str x17, [sp, #0x980] + ldr x17, [x16, #0x8] + str x17, [sp, #0x988] + ldr x16, [sp, #0x13c0] + ldr x17, [x16] + str x17, [sp, #0x990] + ldr x17, [x16, #0x8] + str x17, [sp, #0x998] + ldr x16, [sp, #0x13b8] + ldr x17, [x16] + str x17, [sp, #0x9a0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9a8] + ldr x16, [sp, #0x13b0] + ldr x17, [x16] + str x17, [sp, #0x9b0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9b8] + ldr x16, [sp, #0x13a8] + ldr x17, [x16] + str x17, [sp, #0x9c0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9c8] + ldr x16, [sp, #0x13a0] + ldr x17, [x16] + str x17, [sp, #0x9d0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9d8] + ldr x16, [sp, #0x1398] + ldr x17, [x16] + str x17, [sp, #0x9e0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9e8] + ldr x16, [sp, #0x1390] + ldr x17, [x16] + str x17, [sp, #0x9f0] + ldr x17, [x16, #0x8] + str x17, [sp, #0x9f8] + ldr x16, [sp, #0x1388] + ldr x17, [x16] + str x17, [sp, #0xa00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa08] + ldr x16, [sp, #0x1380] + ldr x17, [x16] + str x17, [sp, #0xa10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa18] + ldr x16, [sp, #0x1378] + ldr x17, [x16] + str x17, [sp, #0xa20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa28] + ldr x16, [sp, #0x1370] + ldr x17, [x16] + str x17, [sp, #0xa30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa38] + ldr x16, [sp, #0x1368] + ldr x17, [x16] + str x17, [sp, #0xa40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa48] + ldr x16, [sp, #0x1360] + ldr x17, [x16] + str x17, [sp, #0xa50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa58] + ldr x16, [sp, #0x1358] + ldr x17, [x16] + str x17, [sp, #0xa60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa68] + ldr x16, [sp, #0x1350] + ldr x17, [x16] + str x17, [sp, #0xa70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa78] + ldr x16, [sp, #0x1348] + ldr x17, [x16] + str x17, [sp, #0xa80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa88] + ldr x16, [sp, #0x1340] + ldr x17, [x16] + str x17, [sp, #0xa90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa98] + ldr x16, [sp, #0x1338] + ldr x17, [x16] + str x17, [sp, #0xaa0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xaa8] + ldr x16, [sp, #0x1330] + ldr x17, [x16] + str x17, [sp, #0xab0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xab8] + ldr x16, [sp, #0x1328] + ldr x17, [x16] + str x17, [sp, #0xac0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xac8] + ldr x16, [sp, #0x1320] + ldr x17, [x16] + str x17, [sp, #0xad0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xad8] + ldr x16, [sp, #0x1318] + ldr x17, [x16] + str x17, [sp, #0xae0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xae8] + ldr x16, [sp, #0x1310] + ldr x17, [x16] + str x17, [sp, #0xaf0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xaf8] + ldr x16, [sp, #0x1308] + ldr x17, [x16] + str x17, [sp, #0xb00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb08] + ldr x16, [sp, #0x1300] + ldr x17, [x16] + str x17, [sp, #0xb10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb18] + ldr x16, [sp, #0x12f8] + ldr x17, [x16] + str x17, [sp, #0xb20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb28] + ldr x16, [sp, #0x12f0] + ldr x17, [x16] + str x17, [sp, #0xb30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb38] + ldr x16, [sp, #0x12e8] + ldr x17, [x16] + str x17, [sp, #0xb40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb48] + ldr x16, [sp, #0x12e0] + ldr x17, [x16] + str x17, [sp, #0xb50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb58] + ldr x16, [sp, #0x12d8] + ldr x17, [x16] + str x17, [sp, #0xb60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb68] + ldr x16, [sp, #0x12d0] + ldr x17, [x16] + str x17, [sp, #0xb70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb78] + ldr x16, [sp, #0x12c8] + ldr x17, [x16] + str x17, [sp, #0xb80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb88] + ldr x16, [sp, #0x12c0] + ldr x17, [x16] + str x17, [sp, #0xb90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb98] + ldr x16, [sp, #0x12b8] + ldr x17, [x16] + str x17, [sp, #0xba0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xba8] + ldr x16, [sp, #0x12b0] + ldr x17, [x16] + str x17, [sp, #0xbb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xbb8] + ldr x16, [sp, #0x12a8] + ldr x17, [x16] + str x17, [sp, #0xbc0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xbc8] + ldr x16, [sp, #0x12a0] + ldr x17, [x16] + str x17, [sp, #0xbd0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xbd8] + ldr x16, [sp, #0x1298] + ldr x17, [x16] + str x17, [sp, #0xbe0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xbe8] + ldr x16, [sp, #0x1290] + ldr x17, [x16] + str x17, [sp, #0xbf0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xbf8] + ldr x16, [sp, #0x1288] + ldr x17, [x16] + str x17, [sp, #0xc00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc08] + ldr x16, [sp, #0x1280] + ldr x17, [x16] + str x17, [sp, #0xc10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc18] + ldr x16, [sp, #0x1278] + ldr x17, [x16] + str x17, [sp, #0xc20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc28] + ldr x16, [sp, #0x1270] + ldr x17, [x16] + str x17, [sp, #0xc30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc38] + ldr x16, [sp, #0x1268] + ldr x17, [x16] + str x17, [sp, #0xc40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc48] + ldr x16, [sp, #0x1260] + ldr x17, [x16] + str x17, [sp, #0xc50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc58] + ldr x16, [sp, #0x1258] + ldr x17, [x16] + str x17, [sp, #0xc60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc68] + ldr x16, [sp, #0x1250] + ldr x17, [x16] + str x17, [sp, #0xc70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc78] + ldr x16, [sp, #0x1248] + ldr x17, [x16] + str x17, [sp, #0xc80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc88] + ldr x16, [sp, #0x1240] + ldr x17, [x16] + str x17, [sp, #0xc90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xc98] + ldr x16, [sp, #0x1238] + ldr x17, [x16] + str x17, [sp, #0xca0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xca8] + ldr x16, [sp, #0x1230] + ldr x17, [x16] + str x17, [sp, #0xcb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xcb8] + ldr x16, [sp, #0x1228] + ldr x17, [x16] + str x17, [sp, #0xcc0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xcc8] + ldr x16, [sp, #0x1220] + ldr x17, [x16] + str x17, [sp, #0xcd0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xcd8] + ldr x16, [sp, #0x1218] + ldr x17, [x16] + str x17, [sp, #0xce0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xce8] + ldr x16, [sp, #0x1210] + ldr x17, [x16] + str x17, [sp, #0xcf0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xcf8] + ldr x16, [sp, #0x1208] + ldr x17, [x16] + str x17, [sp, #0xd00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd08] + ldr x16, [sp, #0x1200] + ldr x17, [x16] + str x17, [sp, #0xd10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd18] + ldr x16, [sp, #0x11f8] + ldr x17, [x16] + str x17, [sp, #0xd20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd28] + ldr x16, [sp, #0x11f0] + ldr x17, [x16] + str x17, [sp, #0xd30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd38] + ldr x16, [sp, #0x11e8] + ldr x17, [x16] + str x17, [sp, #0xd40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd48] + ldr x16, [sp, #0x11e0] + ldr x17, [x16] + str x17, [sp, #0xd50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd58] + ldr x16, [sp, #0x11d8] + ldr x17, [x16] + str x17, [sp, #0xd60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd68] + ldr x16, [sp, #0x11d0] + ldr x17, [x16] + str x17, [sp, #0xd70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd78] + ldr x16, [sp, #0x11c8] + ldr x17, [x16] + str x17, [sp, #0xd80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd88] + ldr x16, [sp, #0x11c0] + ldr x17, [x16] + str x17, [sp, #0xd90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xd98] + ldr x16, [sp, #0x11b8] + ldr x17, [x16] + str x17, [sp, #0xda0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xda8] + ldr x16, [sp, #0x11b0] + ldr x17, [x16] + str x17, [sp, #0xdb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xdb8] + ldr x16, [sp, #0x11a8] + ldr x17, [x16] + str x17, [sp, #0xdc0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xdc8] + ldr x16, [sp, #0x11a0] + ldr x17, [x16] + str x17, [sp, #0xdd0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xdd8] + ldr x16, [sp, #0x1198] + ldr x17, [x16] + str x17, [sp, #0xde0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xde8] + ldr x16, [sp, #0x1190] + ldr x17, [x16] + str x17, [sp, #0xdf0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xdf8] + ldr x16, [sp, #0x1188] + ldr x17, [x16] + str x17, [sp, #0xe00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe08] + ldr x16, [sp, #0x1180] + ldr x17, [x16] + str x17, [sp, #0xe10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe18] + ldr x16, [sp, #0x1178] + ldr x17, [x16] + str x17, [sp, #0xe20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe28] + ldr x16, [sp, #0x1170] + ldr x17, [x16] + str x17, [sp, #0xe30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe38] + ldr x16, [sp, #0x1168] + ldr x17, [x16] + str x17, [sp, #0xe40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe48] + ldr x16, [sp, #0x1160] + ldr x17, [x16] + str x17, [sp, #0xe50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe58] + ldr x16, [sp, #0x1158] + ldr x17, [x16] + str x17, [sp, #0xe60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe68] + ldr x16, [sp, #0x1150] + ldr x17, [x16] + str x17, [sp, #0xe70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe78] + ldr x16, [sp, #0x1148] + ldr x17, [x16] + str x17, [sp, #0xe80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe88] + ldr x16, [sp, #0x1140] + ldr x17, [x16] + str x17, [sp, #0xe90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xe98] + ldr x16, [sp, #0x1138] + ldr x17, [x16] + str x17, [sp, #0xea0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xea8] + ldr x16, [sp, #0x1130] + ldr x17, [x16] + str x17, [sp, #0xeb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xeb8] + ldr x16, [sp, #0x1128] + ldr x17, [x16] + str x17, [sp, #0xec0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xec8] + ldr x16, [sp, #0x1120] + ldr x17, [x16] + str x17, [sp, #0xed0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xed8] + ldr x16, [sp, #0x1118] + ldr x17, [x16] + str x17, [sp, #0xee0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xee8] + ldr x16, [sp, #0x1110] + ldr x17, [x16] + str x17, [sp, #0xef0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xef8] + ldr x16, [sp, #0x1108] + ldr x17, [x16] + str x17, [sp, #0xf00] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf08] + ldr x16, [sp, #0x1100] + ldr x17, [x16] + str x17, [sp, #0xf10] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf18] + ldr x16, [sp, #0x10f8] + ldr x17, [x16] + str x17, [sp, #0xf20] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf28] + ldr x16, [sp, #0x10f0] + ldr x17, [x16] + str x17, [sp, #0xf30] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf38] + ldr x16, [sp, #0x10e8] + ldr x17, [x16] + str x17, [sp, #0xf40] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf48] + ldr x16, [sp, #0x10e0] + ldr x17, [x16] + str x17, [sp, #0xf50] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf58] + ldr x16, [sp, #0x10d8] + ldr x17, [x16] + str x17, [sp, #0xf60] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf68] + ldr x16, [sp, #0x10d0] + ldr x17, [x16] + str x17, [sp, #0xf70] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf78] + ldr x16, [sp, #0x10c8] + ldr x17, [x16] + str x17, [sp, #0xf80] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf88] + ldr x16, [sp, #0x10c0] + ldr x17, [x16] + str x17, [sp, #0xf90] + ldr x17, [x16, #0x8] + str x17, [sp, #0xf98] + ldr x16, [sp, #0x10b8] + ldr x17, [x16] + str x17, [sp, #0xfa0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xfa8] + ldr x16, [sp, #0x10b0] + ldr x17, [x16] + str x17, [sp, #0xfb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xfb8] + ldr x16, [sp, #0x10a8] + ldr x17, [x16] + str x17, [sp, #0xfc0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xfc8] + ldr x16, [sp, #0x10a0] + ldr x17, [x16] + str x17, [sp, #0xfd0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xfd8] + ldr x16, [sp, #0x1098] + ldr x17, [x16] + str x17, [sp, #0xfe0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xfe8] + ldr x16, [sp, #0x1090] + ldr x17, [x16] + str x17, [sp, #0xff0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xff8] + ldr x16, [sp, #0x1088] + ldr x17, [x16] + str x17, [sp, #0x1000] + ldr x17, [x16, #0x8] + str x17, [sp, #0x1008] + mov x4, x2 + mov x6, x3 + mov x2, x1 + ldr x1, [x0, #0x8] + ldr x0, [x0] + ldr x3, [x2, #0x8] + ldr x2, [x2] + ldr x5, [x4, #0x8] + ldr x4, [x4] + ldr x7, [x6, #0x8] + ldr x6, [x6] + ldr x9, [sp, #0x1010] + blr x9 + add sp, sp, #0x1, lsl #12 // =0x1000 + add sp, sp, #0x20 + mov x17, #0x8d9e // =36254 + movk x17, #0x1, lsl #16 + cmp x0, x17 + b.eq + mov x0, #0x3 // =3 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x23, [sp, #0x18] + ldr x24, [sp, #0x20] + ldr x25, [sp, #0x28] + ldr x26, [sp, #0x30] + ldr x27, [sp, #0x38] + ldr x28, [sp, #0x40] + ldr x19, [sp, #0x50] + add sp, sp, #0x1, lsl #12 // =0x1000 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x23, [sp, #0x18] + ldr x24, [sp, #0x20] + ldr x25, [sp, #0x28] + ldr x26, [sp, #0x30] + ldr x27, [sp, #0x38] + ldr x28, [sp, #0x40] + ldr x19, [sp, #0x50] + add sp, sp, #0x1, lsl #12 // =0x1000 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/call_sp_adjust_imm12_overflow.x64.asm b/tests/snapshots/asm/call_sp_adjust_imm12_overflow.x64.asm new file mode 100644 index 000000000..1136e11f4 --- /dev/null +++ b/tests/snapshots/asm/call_sp_adjust_imm12_overflow.x64.asm @@ -0,0 +1,8393 @@ + +call_sp_adjust_imm12_overflow.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + popq %r10 + subq $0x1050, %rsp # imm = 0x1050 + pushq %r10 + pushq %rbp + movq %rsp, %rbp + subq $0x1060, %rsp # imm = 0x1060 + movq %rdi, -0x10(%rbp) + movq %rsi, -0x8(%rbp) + movq %rdx, -0x20(%rbp) + movq %rcx, -0x18(%rbp) + movq %r8, -0x30(%rbp) + movq %r9, -0x28(%rbp) + movq 0x1060(%rbp), %r10 + movq %r10, -0x40(%rbp) + movq 0x1068(%rbp), %r10 + movq %r10, -0x38(%rbp) + movq 0x1070(%rbp), %r10 + movq %r10, -0x50(%rbp) + movq 0x1078(%rbp), %r10 + movq %r10, -0x48(%rbp) + movq 0x1080(%rbp), %r10 + movq %r10, -0x60(%rbp) + movq 0x1088(%rbp), %r10 + movq %r10, -0x58(%rbp) + movq 0x1090(%rbp), %r10 + movq %r10, -0x70(%rbp) + movq 0x1098(%rbp), %r10 + movq %r10, -0x68(%rbp) + movq 0x10a0(%rbp), %r10 + movq %r10, -0x80(%rbp) + movq 0x10a8(%rbp), %r10 + movq %r10, -0x78(%rbp) + movq 0x10b0(%rbp), %r10 + movq %r10, -0x90(%rbp) + movq 0x10b8(%rbp), %r10 + movq %r10, -0x88(%rbp) + movq 0x10c0(%rbp), %r10 + movq %r10, -0xa0(%rbp) + movq 0x10c8(%rbp), %r10 + movq %r10, -0x98(%rbp) + movq 0x10d0(%rbp), %r10 + movq %r10, -0xb0(%rbp) + movq 0x10d8(%rbp), %r10 + movq %r10, -0xa8(%rbp) + movq 0x10e0(%rbp), %r10 + movq %r10, -0xc0(%rbp) + movq 0x10e8(%rbp), %r10 + movq %r10, -0xb8(%rbp) + movq 0x10f0(%rbp), %r10 + movq %r10, -0xd0(%rbp) + movq 0x10f8(%rbp), %r10 + movq %r10, -0xc8(%rbp) + movq 0x1100(%rbp), %r10 + movq %r10, -0xe0(%rbp) + movq 0x1108(%rbp), %r10 + movq %r10, -0xd8(%rbp) + movq 0x1110(%rbp), %r10 + movq %r10, -0xf0(%rbp) + movq 0x1118(%rbp), %r10 + movq %r10, -0xe8(%rbp) + movq 0x1120(%rbp), %r10 + movq %r10, -0x100(%rbp) + movq 0x1128(%rbp), %r10 + movq %r10, -0xf8(%rbp) + movq 0x1130(%rbp), %r10 + movq %r10, -0x110(%rbp) + movq 0x1138(%rbp), %r10 + movq %r10, -0x108(%rbp) + movq 0x1140(%rbp), %r10 + movq %r10, -0x120(%rbp) + movq 0x1148(%rbp), %r10 + movq %r10, -0x118(%rbp) + movq 0x1150(%rbp), %r10 + movq %r10, -0x130(%rbp) + movq 0x1158(%rbp), %r10 + movq %r10, -0x128(%rbp) + movq 0x1160(%rbp), %r10 + movq %r10, -0x140(%rbp) + movq 0x1168(%rbp), %r10 + movq %r10, -0x138(%rbp) + movq 0x1170(%rbp), %r10 + movq %r10, -0x150(%rbp) + movq 0x1178(%rbp), %r10 + movq %r10, -0x148(%rbp) + movq 0x1180(%rbp), %r10 + movq %r10, -0x160(%rbp) + movq 0x1188(%rbp), %r10 + movq %r10, -0x158(%rbp) + movq 0x1190(%rbp), %r10 + movq %r10, -0x170(%rbp) + movq 0x1198(%rbp), %r10 + movq %r10, -0x168(%rbp) + movq 0x11a0(%rbp), %r10 + movq %r10, -0x180(%rbp) + movq 0x11a8(%rbp), %r10 + movq %r10, -0x178(%rbp) + movq 0x11b0(%rbp), %r10 + movq %r10, -0x190(%rbp) + movq 0x11b8(%rbp), %r10 + movq %r10, -0x188(%rbp) + movq 0x11c0(%rbp), %r10 + movq %r10, -0x1a0(%rbp) + movq 0x11c8(%rbp), %r10 + movq %r10, -0x198(%rbp) + movq 0x11d0(%rbp), %r10 + movq %r10, -0x1b0(%rbp) + movq 0x11d8(%rbp), %r10 + movq %r10, -0x1a8(%rbp) + movq 0x11e0(%rbp), %r10 + movq %r10, -0x1c0(%rbp) + movq 0x11e8(%rbp), %r10 + movq %r10, -0x1b8(%rbp) + movq 0x11f0(%rbp), %r10 + movq %r10, -0x1d0(%rbp) + movq 0x11f8(%rbp), %r10 + movq %r10, -0x1c8(%rbp) + movq 0x1200(%rbp), %r10 + movq %r10, -0x1e0(%rbp) + movq 0x1208(%rbp), %r10 + movq %r10, -0x1d8(%rbp) + movq 0x1210(%rbp), %r10 + movq %r10, -0x1f0(%rbp) + movq 0x1218(%rbp), %r10 + movq %r10, -0x1e8(%rbp) + movq 0x1220(%rbp), %r10 + movq %r10, -0x200(%rbp) + movq 0x1228(%rbp), %r10 + movq %r10, -0x1f8(%rbp) + movq 0x1230(%rbp), %r10 + movq %r10, -0x210(%rbp) + movq 0x1238(%rbp), %r10 + movq %r10, -0x208(%rbp) + movq 0x1240(%rbp), %r10 + movq %r10, -0x220(%rbp) + movq 0x1248(%rbp), %r10 + movq %r10, -0x218(%rbp) + movq 0x1250(%rbp), %r10 + movq %r10, -0x230(%rbp) + movq 0x1258(%rbp), %r10 + movq %r10, -0x228(%rbp) + movq 0x1260(%rbp), %r10 + movq %r10, -0x240(%rbp) + movq 0x1268(%rbp), %r10 + movq %r10, -0x238(%rbp) + movq 0x1270(%rbp), %r10 + movq %r10, -0x250(%rbp) + movq 0x1278(%rbp), %r10 + movq %r10, -0x248(%rbp) + movq 0x1280(%rbp), %r10 + movq %r10, -0x260(%rbp) + movq 0x1288(%rbp), %r10 + movq %r10, -0x258(%rbp) + movq 0x1290(%rbp), %r10 + movq %r10, -0x270(%rbp) + movq 0x1298(%rbp), %r10 + movq %r10, -0x268(%rbp) + movq 0x12a0(%rbp), %r10 + movq %r10, -0x280(%rbp) + movq 0x12a8(%rbp), %r10 + movq %r10, -0x278(%rbp) + movq 0x12b0(%rbp), %r10 + movq %r10, -0x290(%rbp) + movq 0x12b8(%rbp), %r10 + movq %r10, -0x288(%rbp) + movq 0x12c0(%rbp), %r10 + movq %r10, -0x2a0(%rbp) + movq 0x12c8(%rbp), %r10 + movq %r10, -0x298(%rbp) + movq 0x12d0(%rbp), %r10 + movq %r10, -0x2b0(%rbp) + movq 0x12d8(%rbp), %r10 + movq %r10, -0x2a8(%rbp) + movq 0x12e0(%rbp), %r10 + movq %r10, -0x2c0(%rbp) + movq 0x12e8(%rbp), %r10 + movq %r10, -0x2b8(%rbp) + movq 0x12f0(%rbp), %r10 + movq %r10, -0x2d0(%rbp) + movq 0x12f8(%rbp), %r10 + movq %r10, -0x2c8(%rbp) + movq 0x1300(%rbp), %r10 + movq %r10, -0x2e0(%rbp) + movq 0x1308(%rbp), %r10 + movq %r10, -0x2d8(%rbp) + movq 0x1310(%rbp), %r10 + movq %r10, -0x2f0(%rbp) + movq 0x1318(%rbp), %r10 + movq %r10, -0x2e8(%rbp) + movq 0x1320(%rbp), %r10 + movq %r10, -0x300(%rbp) + movq 0x1328(%rbp), %r10 + movq %r10, -0x2f8(%rbp) + movq 0x1330(%rbp), %r10 + movq %r10, -0x310(%rbp) + movq 0x1338(%rbp), %r10 + movq %r10, -0x308(%rbp) + movq 0x1340(%rbp), %r10 + movq %r10, -0x320(%rbp) + movq 0x1348(%rbp), %r10 + movq %r10, -0x318(%rbp) + movq 0x1350(%rbp), %r10 + movq %r10, -0x330(%rbp) + movq 0x1358(%rbp), %r10 + movq %r10, -0x328(%rbp) + movq 0x1360(%rbp), %r10 + movq %r10, -0x340(%rbp) + movq 0x1368(%rbp), %r10 + movq %r10, -0x338(%rbp) + movq 0x1370(%rbp), %r10 + movq %r10, -0x350(%rbp) + movq 0x1378(%rbp), %r10 + movq %r10, -0x348(%rbp) + movq 0x1380(%rbp), %r10 + movq %r10, -0x360(%rbp) + movq 0x1388(%rbp), %r10 + movq %r10, -0x358(%rbp) + movq 0x1390(%rbp), %r10 + movq %r10, -0x370(%rbp) + movq 0x1398(%rbp), %r10 + movq %r10, -0x368(%rbp) + movq 0x13a0(%rbp), %r10 + movq %r10, -0x380(%rbp) + movq 0x13a8(%rbp), %r10 + movq %r10, -0x378(%rbp) + movq 0x13b0(%rbp), %r10 + movq %r10, -0x390(%rbp) + movq 0x13b8(%rbp), %r10 + movq %r10, -0x388(%rbp) + movq 0x13c0(%rbp), %r10 + movq %r10, -0x3a0(%rbp) + movq 0x13c8(%rbp), %r10 + movq %r10, -0x398(%rbp) + movq 0x13d0(%rbp), %r10 + movq %r10, -0x3b0(%rbp) + movq 0x13d8(%rbp), %r10 + movq %r10, -0x3a8(%rbp) + movq 0x13e0(%rbp), %r10 + movq %r10, -0x3c0(%rbp) + movq 0x13e8(%rbp), %r10 + movq %r10, -0x3b8(%rbp) + movq 0x13f0(%rbp), %r10 + movq %r10, -0x3d0(%rbp) + movq 0x13f8(%rbp), %r10 + movq %r10, -0x3c8(%rbp) + movq 0x1400(%rbp), %r10 + movq %r10, -0x3e0(%rbp) + movq 0x1408(%rbp), %r10 + movq %r10, -0x3d8(%rbp) + movq 0x1410(%rbp), %r10 + movq %r10, -0x3f0(%rbp) + movq 0x1418(%rbp), %r10 + movq %r10, -0x3e8(%rbp) + movq 0x1420(%rbp), %r10 + movq %r10, -0x400(%rbp) + movq 0x1428(%rbp), %r10 + movq %r10, -0x3f8(%rbp) + movq 0x1430(%rbp), %r10 + movq %r10, -0x410(%rbp) + movq 0x1438(%rbp), %r10 + movq %r10, -0x408(%rbp) + movq 0x1440(%rbp), %r10 + movq %r10, -0x420(%rbp) + movq 0x1448(%rbp), %r10 + movq %r10, -0x418(%rbp) + movq 0x1450(%rbp), %r10 + movq %r10, -0x430(%rbp) + movq 0x1458(%rbp), %r10 + movq %r10, -0x428(%rbp) + movq 0x1460(%rbp), %r10 + movq %r10, -0x440(%rbp) + movq 0x1468(%rbp), %r10 + movq %r10, -0x438(%rbp) + movq 0x1470(%rbp), %r10 + movq %r10, -0x450(%rbp) + movq 0x1478(%rbp), %r10 + movq %r10, -0x448(%rbp) + movq 0x1480(%rbp), %r10 + movq %r10, -0x460(%rbp) + movq 0x1488(%rbp), %r10 + movq %r10, -0x458(%rbp) + movq 0x1490(%rbp), %r10 + movq %r10, -0x470(%rbp) + movq 0x1498(%rbp), %r10 + movq %r10, -0x468(%rbp) + movq 0x14a0(%rbp), %r10 + movq %r10, -0x480(%rbp) + movq 0x14a8(%rbp), %r10 + movq %r10, -0x478(%rbp) + movq 0x14b0(%rbp), %r10 + movq %r10, -0x490(%rbp) + movq 0x14b8(%rbp), %r10 + movq %r10, -0x488(%rbp) + movq 0x14c0(%rbp), %r10 + movq %r10, -0x4a0(%rbp) + movq 0x14c8(%rbp), %r10 + movq %r10, -0x498(%rbp) + movq 0x14d0(%rbp), %r10 + movq %r10, -0x4b0(%rbp) + movq 0x14d8(%rbp), %r10 + movq %r10, -0x4a8(%rbp) + movq 0x14e0(%rbp), %r10 + movq %r10, -0x4c0(%rbp) + movq 0x14e8(%rbp), %r10 + movq %r10, -0x4b8(%rbp) + movq 0x14f0(%rbp), %r10 + movq %r10, -0x4d0(%rbp) + movq 0x14f8(%rbp), %r10 + movq %r10, -0x4c8(%rbp) + movq 0x1500(%rbp), %r10 + movq %r10, -0x4e0(%rbp) + movq 0x1508(%rbp), %r10 + movq %r10, -0x4d8(%rbp) + movq 0x1510(%rbp), %r10 + movq %r10, -0x4f0(%rbp) + movq 0x1518(%rbp), %r10 + movq %r10, -0x4e8(%rbp) + movq 0x1520(%rbp), %r10 + movq %r10, -0x500(%rbp) + movq 0x1528(%rbp), %r10 + movq %r10, -0x4f8(%rbp) + movq 0x1530(%rbp), %r10 + movq %r10, -0x510(%rbp) + movq 0x1538(%rbp), %r10 + movq %r10, -0x508(%rbp) + movq 0x1540(%rbp), %r10 + movq %r10, -0x520(%rbp) + movq 0x1548(%rbp), %r10 + movq %r10, -0x518(%rbp) + movq 0x1550(%rbp), %r10 + movq %r10, -0x530(%rbp) + movq 0x1558(%rbp), %r10 + movq %r10, -0x528(%rbp) + movq 0x1560(%rbp), %r10 + movq %r10, -0x540(%rbp) + movq 0x1568(%rbp), %r10 + movq %r10, -0x538(%rbp) + movq 0x1570(%rbp), %r10 + movq %r10, -0x550(%rbp) + movq 0x1578(%rbp), %r10 + movq %r10, -0x548(%rbp) + movq 0x1580(%rbp), %r10 + movq %r10, -0x560(%rbp) + movq 0x1588(%rbp), %r10 + movq %r10, -0x558(%rbp) + movq 0x1590(%rbp), %r10 + movq %r10, -0x570(%rbp) + movq 0x1598(%rbp), %r10 + movq %r10, -0x568(%rbp) + movq 0x15a0(%rbp), %r10 + movq %r10, -0x580(%rbp) + movq 0x15a8(%rbp), %r10 + movq %r10, -0x578(%rbp) + movq 0x15b0(%rbp), %r10 + movq %r10, -0x590(%rbp) + movq 0x15b8(%rbp), %r10 + movq %r10, -0x588(%rbp) + movq 0x15c0(%rbp), %r10 + movq %r10, -0x5a0(%rbp) + movq 0x15c8(%rbp), %r10 + movq %r10, -0x598(%rbp) + movq 0x15d0(%rbp), %r10 + movq %r10, -0x5b0(%rbp) + movq 0x15d8(%rbp), %r10 + movq %r10, -0x5a8(%rbp) + movq 0x15e0(%rbp), %r10 + movq %r10, -0x5c0(%rbp) + movq 0x15e8(%rbp), %r10 + movq %r10, -0x5b8(%rbp) + movq 0x15f0(%rbp), %r10 + movq %r10, -0x5d0(%rbp) + movq 0x15f8(%rbp), %r10 + movq %r10, -0x5c8(%rbp) + movq 0x1600(%rbp), %r10 + movq %r10, -0x5e0(%rbp) + movq 0x1608(%rbp), %r10 + movq %r10, -0x5d8(%rbp) + movq 0x1610(%rbp), %r10 + movq %r10, -0x5f0(%rbp) + movq 0x1618(%rbp), %r10 + movq %r10, -0x5e8(%rbp) + movq 0x1620(%rbp), %r10 + movq %r10, -0x600(%rbp) + movq 0x1628(%rbp), %r10 + movq %r10, -0x5f8(%rbp) + movq 0x1630(%rbp), %r10 + movq %r10, -0x610(%rbp) + movq 0x1638(%rbp), %r10 + movq %r10, -0x608(%rbp) + movq 0x1640(%rbp), %r10 + movq %r10, -0x620(%rbp) + movq 0x1648(%rbp), %r10 + movq %r10, -0x618(%rbp) + movq 0x1650(%rbp), %r10 + movq %r10, -0x630(%rbp) + movq 0x1658(%rbp), %r10 + movq %r10, -0x628(%rbp) + movq 0x1660(%rbp), %r10 + movq %r10, -0x640(%rbp) + movq 0x1668(%rbp), %r10 + movq %r10, -0x638(%rbp) + movq 0x1670(%rbp), %r10 + movq %r10, -0x650(%rbp) + movq 0x1678(%rbp), %r10 + movq %r10, -0x648(%rbp) + movq 0x1680(%rbp), %r10 + movq %r10, -0x660(%rbp) + movq 0x1688(%rbp), %r10 + movq %r10, -0x658(%rbp) + movq 0x1690(%rbp), %r10 + movq %r10, -0x670(%rbp) + movq 0x1698(%rbp), %r10 + movq %r10, -0x668(%rbp) + movq 0x16a0(%rbp), %r10 + movq %r10, -0x680(%rbp) + movq 0x16a8(%rbp), %r10 + movq %r10, -0x678(%rbp) + movq 0x16b0(%rbp), %r10 + movq %r10, -0x690(%rbp) + movq 0x16b8(%rbp), %r10 + movq %r10, -0x688(%rbp) + movq 0x16c0(%rbp), %r10 + movq %r10, -0x6a0(%rbp) + movq 0x16c8(%rbp), %r10 + movq %r10, -0x698(%rbp) + movq 0x16d0(%rbp), %r10 + movq %r10, -0x6b0(%rbp) + movq 0x16d8(%rbp), %r10 + movq %r10, -0x6a8(%rbp) + movq 0x16e0(%rbp), %r10 + movq %r10, -0x6c0(%rbp) + movq 0x16e8(%rbp), %r10 + movq %r10, -0x6b8(%rbp) + movq 0x16f0(%rbp), %r10 + movq %r10, -0x6d0(%rbp) + movq 0x16f8(%rbp), %r10 + movq %r10, -0x6c8(%rbp) + movq 0x1700(%rbp), %r10 + movq %r10, -0x6e0(%rbp) + movq 0x1708(%rbp), %r10 + movq %r10, -0x6d8(%rbp) + movq 0x1710(%rbp), %r10 + movq %r10, -0x6f0(%rbp) + movq 0x1718(%rbp), %r10 + movq %r10, -0x6e8(%rbp) + movq 0x1720(%rbp), %r10 + movq %r10, -0x700(%rbp) + movq 0x1728(%rbp), %r10 + movq %r10, -0x6f8(%rbp) + movq 0x1730(%rbp), %r10 + movq %r10, -0x710(%rbp) + movq 0x1738(%rbp), %r10 + movq %r10, -0x708(%rbp) + movq 0x1740(%rbp), %r10 + movq %r10, -0x720(%rbp) + movq 0x1748(%rbp), %r10 + movq %r10, -0x718(%rbp) + movq 0x1750(%rbp), %r10 + movq %r10, -0x730(%rbp) + movq 0x1758(%rbp), %r10 + movq %r10, -0x728(%rbp) + movq 0x1760(%rbp), %r10 + movq %r10, -0x740(%rbp) + movq 0x1768(%rbp), %r10 + movq %r10, -0x738(%rbp) + movq 0x1770(%rbp), %r10 + movq %r10, -0x750(%rbp) + movq 0x1778(%rbp), %r10 + movq %r10, -0x748(%rbp) + movq 0x1780(%rbp), %r10 + movq %r10, -0x760(%rbp) + movq 0x1788(%rbp), %r10 + movq %r10, -0x758(%rbp) + movq 0x1790(%rbp), %r10 + movq %r10, -0x770(%rbp) + movq 0x1798(%rbp), %r10 + movq %r10, -0x768(%rbp) + movq 0x17a0(%rbp), %r10 + movq %r10, -0x780(%rbp) + movq 0x17a8(%rbp), %r10 + movq %r10, -0x778(%rbp) + movq 0x17b0(%rbp), %r10 + movq %r10, -0x790(%rbp) + movq 0x17b8(%rbp), %r10 + movq %r10, -0x788(%rbp) + movq 0x17c0(%rbp), %r10 + movq %r10, -0x7a0(%rbp) + movq 0x17c8(%rbp), %r10 + movq %r10, -0x798(%rbp) + movq 0x17d0(%rbp), %r10 + movq %r10, -0x7b0(%rbp) + movq 0x17d8(%rbp), %r10 + movq %r10, -0x7a8(%rbp) + movq 0x17e0(%rbp), %r10 + movq %r10, -0x7c0(%rbp) + movq 0x17e8(%rbp), %r10 + movq %r10, -0x7b8(%rbp) + movq 0x17f0(%rbp), %r10 + movq %r10, -0x7d0(%rbp) + movq 0x17f8(%rbp), %r10 + movq %r10, -0x7c8(%rbp) + movq 0x1800(%rbp), %r10 + movq %r10, -0x7e0(%rbp) + movq 0x1808(%rbp), %r10 + movq %r10, -0x7d8(%rbp) + movq 0x1810(%rbp), %r10 + movq %r10, -0x7f0(%rbp) + movq 0x1818(%rbp), %r10 + movq %r10, -0x7e8(%rbp) + movq 0x1820(%rbp), %r10 + movq %r10, -0x800(%rbp) + movq 0x1828(%rbp), %r10 + movq %r10, -0x7f8(%rbp) + movq 0x1830(%rbp), %r10 + movq %r10, -0x810(%rbp) + movq 0x1838(%rbp), %r10 + movq %r10, -0x808(%rbp) + movq 0x1840(%rbp), %r10 + movq %r10, -0x820(%rbp) + movq 0x1848(%rbp), %r10 + movq %r10, -0x818(%rbp) + movq 0x1850(%rbp), %r10 + movq %r10, -0x830(%rbp) + movq 0x1858(%rbp), %r10 + movq %r10, -0x828(%rbp) + movq 0x1860(%rbp), %r10 + movq %r10, -0x840(%rbp) + movq 0x1868(%rbp), %r10 + movq %r10, -0x838(%rbp) + movq 0x1870(%rbp), %r10 + movq %r10, -0x850(%rbp) + movq 0x1878(%rbp), %r10 + movq %r10, -0x848(%rbp) + movq 0x1880(%rbp), %r10 + movq %r10, -0x860(%rbp) + movq 0x1888(%rbp), %r10 + movq %r10, -0x858(%rbp) + movq 0x1890(%rbp), %r10 + movq %r10, -0x870(%rbp) + movq 0x1898(%rbp), %r10 + movq %r10, -0x868(%rbp) + movq 0x18a0(%rbp), %r10 + movq %r10, -0x880(%rbp) + movq 0x18a8(%rbp), %r10 + movq %r10, -0x878(%rbp) + movq 0x18b0(%rbp), %r10 + movq %r10, -0x890(%rbp) + movq 0x18b8(%rbp), %r10 + movq %r10, -0x888(%rbp) + movq 0x18c0(%rbp), %r10 + movq %r10, -0x8a0(%rbp) + movq 0x18c8(%rbp), %r10 + movq %r10, -0x898(%rbp) + movq 0x18d0(%rbp), %r10 + movq %r10, -0x8b0(%rbp) + movq 0x18d8(%rbp), %r10 + movq %r10, -0x8a8(%rbp) + movq 0x18e0(%rbp), %r10 + movq %r10, -0x8c0(%rbp) + movq 0x18e8(%rbp), %r10 + movq %r10, -0x8b8(%rbp) + movq 0x18f0(%rbp), %r10 + movq %r10, -0x8d0(%rbp) + movq 0x18f8(%rbp), %r10 + movq %r10, -0x8c8(%rbp) + movq 0x1900(%rbp), %r10 + movq %r10, -0x8e0(%rbp) + movq 0x1908(%rbp), %r10 + movq %r10, -0x8d8(%rbp) + movq 0x1910(%rbp), %r10 + movq %r10, -0x8f0(%rbp) + movq 0x1918(%rbp), %r10 + movq %r10, -0x8e8(%rbp) + movq 0x1920(%rbp), %r10 + movq %r10, -0x900(%rbp) + movq 0x1928(%rbp), %r10 + movq %r10, -0x8f8(%rbp) + movq 0x1930(%rbp), %r10 + movq %r10, -0x910(%rbp) + movq 0x1938(%rbp), %r10 + movq %r10, -0x908(%rbp) + movq 0x1940(%rbp), %r10 + movq %r10, -0x920(%rbp) + movq 0x1948(%rbp), %r10 + movq %r10, -0x918(%rbp) + movq 0x1950(%rbp), %r10 + movq %r10, -0x930(%rbp) + movq 0x1958(%rbp), %r10 + movq %r10, -0x928(%rbp) + movq 0x1960(%rbp), %r10 + movq %r10, -0x940(%rbp) + movq 0x1968(%rbp), %r10 + movq %r10, -0x938(%rbp) + movq 0x1970(%rbp), %r10 + movq %r10, -0x950(%rbp) + movq 0x1978(%rbp), %r10 + movq %r10, -0x948(%rbp) + movq 0x1980(%rbp), %r10 + movq %r10, -0x960(%rbp) + movq 0x1988(%rbp), %r10 + movq %r10, -0x958(%rbp) + movq 0x1990(%rbp), %r10 + movq %r10, -0x970(%rbp) + movq 0x1998(%rbp), %r10 + movq %r10, -0x968(%rbp) + movq 0x19a0(%rbp), %r10 + movq %r10, -0x980(%rbp) + movq 0x19a8(%rbp), %r10 + movq %r10, -0x978(%rbp) + movq 0x19b0(%rbp), %r10 + movq %r10, -0x990(%rbp) + movq 0x19b8(%rbp), %r10 + movq %r10, -0x988(%rbp) + movq 0x19c0(%rbp), %r10 + movq %r10, -0x9a0(%rbp) + movq 0x19c8(%rbp), %r10 + movq %r10, -0x998(%rbp) + movq 0x19d0(%rbp), %r10 + movq %r10, -0x9b0(%rbp) + movq 0x19d8(%rbp), %r10 + movq %r10, -0x9a8(%rbp) + movq 0x19e0(%rbp), %r10 + movq %r10, -0x9c0(%rbp) + movq 0x19e8(%rbp), %r10 + movq %r10, -0x9b8(%rbp) + movq 0x19f0(%rbp), %r10 + movq %r10, -0x9d0(%rbp) + movq 0x19f8(%rbp), %r10 + movq %r10, -0x9c8(%rbp) + movq 0x1a00(%rbp), %r10 + movq %r10, -0x9e0(%rbp) + movq 0x1a08(%rbp), %r10 + movq %r10, -0x9d8(%rbp) + movq 0x1a10(%rbp), %r10 + movq %r10, -0x9f0(%rbp) + movq 0x1a18(%rbp), %r10 + movq %r10, -0x9e8(%rbp) + movq 0x1a20(%rbp), %r10 + movq %r10, -0xa00(%rbp) + movq 0x1a28(%rbp), %r10 + movq %r10, -0x9f8(%rbp) + movq 0x1a30(%rbp), %r10 + movq %r10, -0xa10(%rbp) + movq 0x1a38(%rbp), %r10 + movq %r10, -0xa08(%rbp) + movq 0x1a40(%rbp), %r10 + movq %r10, -0xa20(%rbp) + movq 0x1a48(%rbp), %r10 + movq %r10, -0xa18(%rbp) + movq 0x1a50(%rbp), %r10 + movq %r10, -0xa30(%rbp) + movq 0x1a58(%rbp), %r10 + movq %r10, -0xa28(%rbp) + movq 0x1a60(%rbp), %r10 + movq %r10, -0xa40(%rbp) + movq 0x1a68(%rbp), %r10 + movq %r10, -0xa38(%rbp) + movq 0x1a70(%rbp), %r10 + movq %r10, -0xa50(%rbp) + movq 0x1a78(%rbp), %r10 + movq %r10, -0xa48(%rbp) + movq 0x1a80(%rbp), %r10 + movq %r10, -0xa60(%rbp) + movq 0x1a88(%rbp), %r10 + movq %r10, -0xa58(%rbp) + movq 0x1a90(%rbp), %r10 + movq %r10, -0xa70(%rbp) + movq 0x1a98(%rbp), %r10 + movq %r10, -0xa68(%rbp) + movq 0x1aa0(%rbp), %r10 + movq %r10, -0xa80(%rbp) + movq 0x1aa8(%rbp), %r10 + movq %r10, -0xa78(%rbp) + movq 0x1ab0(%rbp), %r10 + movq %r10, -0xa90(%rbp) + movq 0x1ab8(%rbp), %r10 + movq %r10, -0xa88(%rbp) + movq 0x1ac0(%rbp), %r10 + movq %r10, -0xaa0(%rbp) + movq 0x1ac8(%rbp), %r10 + movq %r10, -0xa98(%rbp) + movq 0x1ad0(%rbp), %r10 + movq %r10, -0xab0(%rbp) + movq 0x1ad8(%rbp), %r10 + movq %r10, -0xaa8(%rbp) + movq 0x1ae0(%rbp), %r10 + movq %r10, -0xac0(%rbp) + movq 0x1ae8(%rbp), %r10 + movq %r10, -0xab8(%rbp) + movq 0x1af0(%rbp), %r10 + movq %r10, -0xad0(%rbp) + movq 0x1af8(%rbp), %r10 + movq %r10, -0xac8(%rbp) + movq 0x1b00(%rbp), %r10 + movq %r10, -0xae0(%rbp) + movq 0x1b08(%rbp), %r10 + movq %r10, -0xad8(%rbp) + movq 0x1b10(%rbp), %r10 + movq %r10, -0xaf0(%rbp) + movq 0x1b18(%rbp), %r10 + movq %r10, -0xae8(%rbp) + movq 0x1b20(%rbp), %r10 + movq %r10, -0xb00(%rbp) + movq 0x1b28(%rbp), %r10 + movq %r10, -0xaf8(%rbp) + movq 0x1b30(%rbp), %r10 + movq %r10, -0xb10(%rbp) + movq 0x1b38(%rbp), %r10 + movq %r10, -0xb08(%rbp) + movq 0x1b40(%rbp), %r10 + movq %r10, -0xb20(%rbp) + movq 0x1b48(%rbp), %r10 + movq %r10, -0xb18(%rbp) + movq 0x1b50(%rbp), %r10 + movq %r10, -0xb30(%rbp) + movq 0x1b58(%rbp), %r10 + movq %r10, -0xb28(%rbp) + movq 0x1b60(%rbp), %r10 + movq %r10, -0xb40(%rbp) + movq 0x1b68(%rbp), %r10 + movq %r10, -0xb38(%rbp) + movq 0x1b70(%rbp), %r10 + movq %r10, -0xb50(%rbp) + movq 0x1b78(%rbp), %r10 + movq %r10, -0xb48(%rbp) + movq 0x1b80(%rbp), %r10 + movq %r10, -0xb60(%rbp) + movq 0x1b88(%rbp), %r10 + movq %r10, -0xb58(%rbp) + movq 0x1b90(%rbp), %r10 + movq %r10, -0xb70(%rbp) + movq 0x1b98(%rbp), %r10 + movq %r10, -0xb68(%rbp) + movq 0x1ba0(%rbp), %r10 + movq %r10, -0xb80(%rbp) + movq 0x1ba8(%rbp), %r10 + movq %r10, -0xb78(%rbp) + movq 0x1bb0(%rbp), %r10 + movq %r10, -0xb90(%rbp) + movq 0x1bb8(%rbp), %r10 + movq %r10, -0xb88(%rbp) + movq 0x1bc0(%rbp), %r10 + movq %r10, -0xba0(%rbp) + movq 0x1bc8(%rbp), %r10 + movq %r10, -0xb98(%rbp) + movq 0x1bd0(%rbp), %r10 + movq %r10, -0xbb0(%rbp) + movq 0x1bd8(%rbp), %r10 + movq %r10, -0xba8(%rbp) + movq 0x1be0(%rbp), %r10 + movq %r10, -0xbc0(%rbp) + movq 0x1be8(%rbp), %r10 + movq %r10, -0xbb8(%rbp) + movq 0x1bf0(%rbp), %r10 + movq %r10, -0xbd0(%rbp) + movq 0x1bf8(%rbp), %r10 + movq %r10, -0xbc8(%rbp) + movq 0x1c00(%rbp), %r10 + movq %r10, -0xbe0(%rbp) + movq 0x1c08(%rbp), %r10 + movq %r10, -0xbd8(%rbp) + movq 0x1c10(%rbp), %r10 + movq %r10, -0xbf0(%rbp) + movq 0x1c18(%rbp), %r10 + movq %r10, -0xbe8(%rbp) + movq 0x1c20(%rbp), %r10 + movq %r10, -0xc00(%rbp) + movq 0x1c28(%rbp), %r10 + movq %r10, -0xbf8(%rbp) + movq 0x1c30(%rbp), %r10 + movq %r10, -0xc10(%rbp) + movq 0x1c38(%rbp), %r10 + movq %r10, -0xc08(%rbp) + movq 0x1c40(%rbp), %r10 + movq %r10, -0xc20(%rbp) + movq 0x1c48(%rbp), %r10 + movq %r10, -0xc18(%rbp) + movq 0x1c50(%rbp), %r10 + movq %r10, -0xc30(%rbp) + movq 0x1c58(%rbp), %r10 + movq %r10, -0xc28(%rbp) + movq 0x1c60(%rbp), %r10 + movq %r10, -0xc40(%rbp) + movq 0x1c68(%rbp), %r10 + movq %r10, -0xc38(%rbp) + movq 0x1c70(%rbp), %r10 + movq %r10, -0xc50(%rbp) + movq 0x1c78(%rbp), %r10 + movq %r10, -0xc48(%rbp) + movq 0x1c80(%rbp), %r10 + movq %r10, -0xc60(%rbp) + movq 0x1c88(%rbp), %r10 + movq %r10, -0xc58(%rbp) + movq 0x1c90(%rbp), %r10 + movq %r10, -0xc70(%rbp) + movq 0x1c98(%rbp), %r10 + movq %r10, -0xc68(%rbp) + movq 0x1ca0(%rbp), %r10 + movq %r10, -0xc80(%rbp) + movq 0x1ca8(%rbp), %r10 + movq %r10, -0xc78(%rbp) + movq 0x1cb0(%rbp), %r10 + movq %r10, -0xc90(%rbp) + movq 0x1cb8(%rbp), %r10 + movq %r10, -0xc88(%rbp) + movq 0x1cc0(%rbp), %r10 + movq %r10, -0xca0(%rbp) + movq 0x1cc8(%rbp), %r10 + movq %r10, -0xc98(%rbp) + movq 0x1cd0(%rbp), %r10 + movq %r10, -0xcb0(%rbp) + movq 0x1cd8(%rbp), %r10 + movq %r10, -0xca8(%rbp) + movq 0x1ce0(%rbp), %r10 + movq %r10, -0xcc0(%rbp) + movq 0x1ce8(%rbp), %r10 + movq %r10, -0xcb8(%rbp) + movq 0x1cf0(%rbp), %r10 + movq %r10, -0xcd0(%rbp) + movq 0x1cf8(%rbp), %r10 + movq %r10, -0xcc8(%rbp) + movq 0x1d00(%rbp), %r10 + movq %r10, -0xce0(%rbp) + movq 0x1d08(%rbp), %r10 + movq %r10, -0xcd8(%rbp) + movq 0x1d10(%rbp), %r10 + movq %r10, -0xcf0(%rbp) + movq 0x1d18(%rbp), %r10 + movq %r10, -0xce8(%rbp) + movq 0x1d20(%rbp), %r10 + movq %r10, -0xd00(%rbp) + movq 0x1d28(%rbp), %r10 + movq %r10, -0xcf8(%rbp) + movq 0x1d30(%rbp), %r10 + movq %r10, -0xd10(%rbp) + movq 0x1d38(%rbp), %r10 + movq %r10, -0xd08(%rbp) + movq 0x1d40(%rbp), %r10 + movq %r10, -0xd20(%rbp) + movq 0x1d48(%rbp), %r10 + movq %r10, -0xd18(%rbp) + movq 0x1d50(%rbp), %r10 + movq %r10, -0xd30(%rbp) + movq 0x1d58(%rbp), %r10 + movq %r10, -0xd28(%rbp) + movq 0x1d60(%rbp), %r10 + movq %r10, -0xd40(%rbp) + movq 0x1d68(%rbp), %r10 + movq %r10, -0xd38(%rbp) + movq 0x1d70(%rbp), %r10 + movq %r10, -0xd50(%rbp) + movq 0x1d78(%rbp), %r10 + movq %r10, -0xd48(%rbp) + movq 0x1d80(%rbp), %r10 + movq %r10, -0xd60(%rbp) + movq 0x1d88(%rbp), %r10 + movq %r10, -0xd58(%rbp) + movq 0x1d90(%rbp), %r10 + movq %r10, -0xd70(%rbp) + movq 0x1d98(%rbp), %r10 + movq %r10, -0xd68(%rbp) + movq 0x1da0(%rbp), %r10 + movq %r10, -0xd80(%rbp) + movq 0x1da8(%rbp), %r10 + movq %r10, -0xd78(%rbp) + movq 0x1db0(%rbp), %r10 + movq %r10, -0xd90(%rbp) + movq 0x1db8(%rbp), %r10 + movq %r10, -0xd88(%rbp) + movq 0x1dc0(%rbp), %r10 + movq %r10, -0xda0(%rbp) + movq 0x1dc8(%rbp), %r10 + movq %r10, -0xd98(%rbp) + movq 0x1dd0(%rbp), %r10 + movq %r10, -0xdb0(%rbp) + movq 0x1dd8(%rbp), %r10 + movq %r10, -0xda8(%rbp) + movq 0x1de0(%rbp), %r10 + movq %r10, -0xdc0(%rbp) + movq 0x1de8(%rbp), %r10 + movq %r10, -0xdb8(%rbp) + movq 0x1df0(%rbp), %r10 + movq %r10, -0xdd0(%rbp) + movq 0x1df8(%rbp), %r10 + movq %r10, -0xdc8(%rbp) + movq 0x1e00(%rbp), %r10 + movq %r10, -0xde0(%rbp) + movq 0x1e08(%rbp), %r10 + movq %r10, -0xdd8(%rbp) + movq 0x1e10(%rbp), %r10 + movq %r10, -0xdf0(%rbp) + movq 0x1e18(%rbp), %r10 + movq %r10, -0xde8(%rbp) + movq 0x1e20(%rbp), %r10 + movq %r10, -0xe00(%rbp) + movq 0x1e28(%rbp), %r10 + movq %r10, -0xdf8(%rbp) + movq 0x1e30(%rbp), %r10 + movq %r10, -0xe10(%rbp) + movq 0x1e38(%rbp), %r10 + movq %r10, -0xe08(%rbp) + movq 0x1e40(%rbp), %r10 + movq %r10, -0xe20(%rbp) + movq 0x1e48(%rbp), %r10 + movq %r10, -0xe18(%rbp) + movq 0x1e50(%rbp), %r10 + movq %r10, -0xe30(%rbp) + movq 0x1e58(%rbp), %r10 + movq %r10, -0xe28(%rbp) + movq 0x1e60(%rbp), %r10 + movq %r10, -0xe40(%rbp) + movq 0x1e68(%rbp), %r10 + movq %r10, -0xe38(%rbp) + movq 0x1e70(%rbp), %r10 + movq %r10, -0xe50(%rbp) + movq 0x1e78(%rbp), %r10 + movq %r10, -0xe48(%rbp) + movq 0x1e80(%rbp), %r10 + movq %r10, -0xe60(%rbp) + movq 0x1e88(%rbp), %r10 + movq %r10, -0xe58(%rbp) + movq 0x1e90(%rbp), %r10 + movq %r10, -0xe70(%rbp) + movq 0x1e98(%rbp), %r10 + movq %r10, -0xe68(%rbp) + movq 0x1ea0(%rbp), %r10 + movq %r10, -0xe80(%rbp) + movq 0x1ea8(%rbp), %r10 + movq %r10, -0xe78(%rbp) + movq 0x1eb0(%rbp), %r10 + movq %r10, -0xe90(%rbp) + movq 0x1eb8(%rbp), %r10 + movq %r10, -0xe88(%rbp) + movq 0x1ec0(%rbp), %r10 + movq %r10, -0xea0(%rbp) + movq 0x1ec8(%rbp), %r10 + movq %r10, -0xe98(%rbp) + movq 0x1ed0(%rbp), %r10 + movq %r10, -0xeb0(%rbp) + movq 0x1ed8(%rbp), %r10 + movq %r10, -0xea8(%rbp) + movq 0x1ee0(%rbp), %r10 + movq %r10, -0xec0(%rbp) + movq 0x1ee8(%rbp), %r10 + movq %r10, -0xeb8(%rbp) + movq 0x1ef0(%rbp), %r10 + movq %r10, -0xed0(%rbp) + movq 0x1ef8(%rbp), %r10 + movq %r10, -0xec8(%rbp) + movq 0x1f00(%rbp), %r10 + movq %r10, -0xee0(%rbp) + movq 0x1f08(%rbp), %r10 + movq %r10, -0xed8(%rbp) + movq 0x1f10(%rbp), %r10 + movq %r10, -0xef0(%rbp) + movq 0x1f18(%rbp), %r10 + movq %r10, -0xee8(%rbp) + movq 0x1f20(%rbp), %r10 + movq %r10, -0xf00(%rbp) + movq 0x1f28(%rbp), %r10 + movq %r10, -0xef8(%rbp) + movq 0x1f30(%rbp), %r10 + movq %r10, -0xf10(%rbp) + movq 0x1f38(%rbp), %r10 + movq %r10, -0xf08(%rbp) + movq 0x1f40(%rbp), %r10 + movq %r10, -0xf20(%rbp) + movq 0x1f48(%rbp), %r10 + movq %r10, -0xf18(%rbp) + movq 0x1f50(%rbp), %r10 + movq %r10, -0xf30(%rbp) + movq 0x1f58(%rbp), %r10 + movq %r10, -0xf28(%rbp) + movq 0x1f60(%rbp), %r10 + movq %r10, -0xf40(%rbp) + movq 0x1f68(%rbp), %r10 + movq %r10, -0xf38(%rbp) + movq 0x1f70(%rbp), %r10 + movq %r10, -0xf50(%rbp) + movq 0x1f78(%rbp), %r10 + movq %r10, -0xf48(%rbp) + movq 0x1f80(%rbp), %r10 + movq %r10, -0xf60(%rbp) + movq 0x1f88(%rbp), %r10 + movq %r10, -0xf58(%rbp) + movq 0x1f90(%rbp), %r10 + movq %r10, -0xf70(%rbp) + movq 0x1f98(%rbp), %r10 + movq %r10, -0xf68(%rbp) + movq 0x1fa0(%rbp), %r10 + movq %r10, -0xf80(%rbp) + movq 0x1fa8(%rbp), %r10 + movq %r10, -0xf78(%rbp) + movq 0x1fb0(%rbp), %r10 + movq %r10, -0xf90(%rbp) + movq 0x1fb8(%rbp), %r10 + movq %r10, -0xf88(%rbp) + movq 0x1fc0(%rbp), %r10 + movq %r10, -0xfa0(%rbp) + movq 0x1fc8(%rbp), %r10 + movq %r10, -0xf98(%rbp) + movq 0x1fd0(%rbp), %r10 + movq %r10, -0xfb0(%rbp) + movq 0x1fd8(%rbp), %r10 + movq %r10, -0xfa8(%rbp) + movq 0x1fe0(%rbp), %r10 + movq %r10, -0xfc0(%rbp) + movq 0x1fe8(%rbp), %r10 + movq %r10, -0xfb8(%rbp) + movq 0x1ff0(%rbp), %r10 + movq %r10, -0xfd0(%rbp) + movq 0x1ff8(%rbp), %r10 + movq %r10, -0xfc8(%rbp) + movq 0x2000(%rbp), %r10 + movq %r10, -0xfe0(%rbp) + movq 0x2008(%rbp), %r10 + movq %r10, -0xfd8(%rbp) + movq 0x2010(%rbp), %r10 + movq %r10, -0xff0(%rbp) + movq 0x2018(%rbp), %r10 + movq %r10, -0xfe8(%rbp) + movq 0x2020(%rbp), %r10 + movq %r10, -0x1000(%rbp) + movq 0x2028(%rbp), %r10 + movq %r10, -0xff8(%rbp) + movq 0x2030(%rbp), %r10 + movq %r10, -0x1010(%rbp) + movq 0x2038(%rbp), %r10 + movq %r10, -0x1008(%rbp) + movq 0x2040(%rbp), %r10 + movq %r10, -0x1020(%rbp) + movq 0x2048(%rbp), %r10 + movq %r10, -0x1018(%rbp) + movq 0x2050(%rbp), %r10 + movq %r10, -0x1030(%rbp) + movq 0x2058(%rbp), %r10 + movq %r10, -0x1028(%rbp) + movq 0x2060(%rbp), %r10 + movq %r10, -0x1040(%rbp) + movq 0x2068(%rbp), %r10 + movq %r10, -0x1038(%rbp) + movq 0x2070(%rbp), %r10 + movq %r10, -0x1050(%rbp) + movq 0x2078(%rbp), %r10 + movq %r10, -0x1048(%rbp) + xorq %rax, %rax + leaq -0x10(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x10(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x20(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x20(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x30(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x30(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x40(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x40(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x50(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x50(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x60(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x60(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x70(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x70(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x80(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x80(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x90(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x90(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x100(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x100(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x110(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x110(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x120(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x120(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x130(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x130(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x140(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x140(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x150(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x150(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x160(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x160(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x170(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x170(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x180(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x180(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x190(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x190(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1a0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1a0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1b0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1b0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1c0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1c0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1d0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1d0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1e0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1e0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1f0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1f0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x200(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x200(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x210(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x210(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x220(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x220(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x230(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x230(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x240(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x240(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x250(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x250(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x260(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x260(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x270(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x270(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x280(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x280(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x290(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x290(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x2a0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x2a0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x2b0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x2b0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x2c0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x2c0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x2d0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x2d0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x2e0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x2e0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x2f0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x2f0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x300(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x300(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x310(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x310(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x320(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x320(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x330(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x330(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x340(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x340(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x350(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x350(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x360(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x360(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x370(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x370(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x380(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x380(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x390(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x390(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x3a0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x3a0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x3b0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x3b0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x3c0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x3c0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x3d0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x3d0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x3e0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x3e0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x3f0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x3f0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x400(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x400(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x410(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x410(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x420(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x420(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x430(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x430(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x440(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x440(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x450(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x450(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x460(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x460(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x470(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x470(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x480(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x480(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x490(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x490(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x4a0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x4a0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x4b0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x4b0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x4c0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x4c0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x4d0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x4d0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x4e0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x4e0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x4f0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x4f0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x500(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x500(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x510(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x510(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x520(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x520(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x530(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x530(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x540(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x540(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x550(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x550(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x560(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x560(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x570(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x570(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x580(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x580(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x590(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x590(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x5a0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x5a0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x5b0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x5b0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x5c0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x5c0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x5d0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x5d0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x5e0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x5e0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x5f0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x5f0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x600(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x600(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x610(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x610(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x620(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x620(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x630(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x630(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x640(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x640(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x650(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x650(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x660(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x660(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x670(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x670(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x680(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x680(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x690(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x690(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x6a0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x6a0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x6b0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x6b0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x6c0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x6c0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x6d0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x6d0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x6e0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x6e0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x6f0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x6f0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x700(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x700(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x710(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x710(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x720(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x720(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x730(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x730(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x740(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x740(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x750(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x750(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x760(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x760(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x770(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x770(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x780(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x780(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x790(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x790(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x7a0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x7a0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x7b0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x7b0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x7c0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x7c0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x7d0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x7d0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x7e0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x7e0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x7f0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x7f0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x800(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x800(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x810(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x810(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x820(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x820(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x830(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x830(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x840(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x840(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x850(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x850(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x860(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x860(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x870(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x870(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x880(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x880(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x890(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x890(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x8a0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x8a0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x8b0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x8b0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x8c0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x8c0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x8d0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x8d0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x8e0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x8e0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x8f0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x8f0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x900(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x900(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x910(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x910(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x920(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x920(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x930(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x930(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x940(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x940(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x950(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x950(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x960(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x960(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x970(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x970(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x980(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x980(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x990(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x990(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x9a0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x9a0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x9b0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x9b0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x9c0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x9c0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x9d0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x9d0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x9e0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x9e0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x9f0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x9f0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa00(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa00(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa10(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa10(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa20(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa20(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa30(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa30(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa40(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa40(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa50(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa50(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa60(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa60(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa70(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa70(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa80(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa80(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xa90(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xa90(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xaa0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xaa0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xab0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xab0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xac0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xac0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xad0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xad0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xae0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xae0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xaf0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xaf0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb00(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb00(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb10(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb10(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb20(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb20(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb30(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb30(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb40(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb40(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb50(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb50(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb60(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb60(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb70(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb70(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb80(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb80(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xb90(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xb90(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xba0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xba0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xbb0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xbb0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xbc0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xbc0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xbd0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xbd0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xbe0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xbe0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xbf0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xbf0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc00(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc00(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc10(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc10(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc20(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc20(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc30(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc30(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc40(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc40(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc50(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc50(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc60(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc60(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc70(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc70(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc80(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc80(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xc90(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xc90(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xca0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xca0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xcb0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xcb0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xcc0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xcc0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xcd0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xcd0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xce0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xce0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xcf0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xcf0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd00(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd00(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd10(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd10(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd20(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd20(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd30(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd30(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd40(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd40(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd50(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd50(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd60(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd60(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd70(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd70(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd80(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd80(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xd90(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xd90(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xda0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xda0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xdb0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xdb0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xdc0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xdc0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xdd0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xdd0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xde0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xde0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xdf0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xdf0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe00(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe00(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe10(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe10(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe20(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe20(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe30(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe30(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe40(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe40(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe50(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe50(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe60(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe60(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe70(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe70(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe80(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe80(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xe90(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xe90(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xea0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xea0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xeb0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xeb0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xec0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xec0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xed0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xed0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xee0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xee0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xef0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xef0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf00(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf00(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf10(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf10(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf20(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf20(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf30(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf30(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf40(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf40(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf50(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf50(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf60(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf60(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf70(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf70(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf80(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf80(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xf90(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xf90(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xfa0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xfa0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xfb0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xfb0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xfc0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xfc0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xfd0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xfd0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xfe0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xfe0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0xff0(%rbp), %rcx + movq (%rcx), %rcx + leaq -0xff0(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1000(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1000(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1010(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1010(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1020(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1020(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1030(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1030(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1040(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1040(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + leaq -0x1050(%rbp), %rcx + movq (%rcx), %rcx + leaq -0x1050(%rbp), %rdx + movq 0x8(%rdx), %rdx + addq %rdx, %rcx + addq %rcx, %rax + addq $0x1060, %rsp # imm = 0x1060 + popq %rbp + popq %r11 + addq $0x1050, %rsp # imm = 0x1050 + pushq %r11 + retq + +: + popq %r10 + subq $0x1040, %rsp # imm = 0x1040 + movq 0x1040(%rsp), %rax + movq %rax, 0x60(%rsp) + movq 0x1048(%rsp), %rax + movq %rax, 0x70(%rsp) + movq 0x1050(%rsp), %rax + movq %rax, 0x80(%rsp) + movq 0x1058(%rsp), %rax + movq %rax, 0x90(%rsp) + movq 0x1060(%rsp), %rax + movq %rax, 0xa0(%rsp) + movq 0x1068(%rsp), %rax + movq %rax, 0xb0(%rsp) + movq 0x1070(%rsp), %rax + movq %rax, 0xc0(%rsp) + movq 0x1078(%rsp), %rax + movq %rax, 0xd0(%rsp) + movq 0x1080(%rsp), %rax + movq %rax, 0xe0(%rsp) + movq 0x1088(%rsp), %rax + movq %rax, 0xf0(%rsp) + movq 0x1090(%rsp), %rax + movq %rax, 0x100(%rsp) + movq 0x1098(%rsp), %rax + movq %rax, 0x110(%rsp) + movq 0x10a0(%rsp), %rax + movq %rax, 0x120(%rsp) + movq 0x10a8(%rsp), %rax + movq %rax, 0x130(%rsp) + movq 0x10b0(%rsp), %rax + movq %rax, 0x140(%rsp) + movq 0x10b8(%rsp), %rax + movq %rax, 0x150(%rsp) + movq 0x10c0(%rsp), %rax + movq %rax, 0x160(%rsp) + movq 0x10c8(%rsp), %rax + movq %rax, 0x170(%rsp) + movq 0x10d0(%rsp), %rax + movq %rax, 0x180(%rsp) + movq 0x10d8(%rsp), %rax + movq %rax, 0x190(%rsp) + movq 0x10e0(%rsp), %rax + movq %rax, 0x1a0(%rsp) + movq 0x10e8(%rsp), %rax + movq %rax, 0x1b0(%rsp) + movq 0x10f0(%rsp), %rax + movq %rax, 0x1c0(%rsp) + movq 0x10f8(%rsp), %rax + movq %rax, 0x1d0(%rsp) + movq 0x1100(%rsp), %rax + movq %rax, 0x1e0(%rsp) + movq 0x1108(%rsp), %rax + movq %rax, 0x1f0(%rsp) + movq 0x1110(%rsp), %rax + movq %rax, 0x200(%rsp) + movq 0x1118(%rsp), %rax + movq %rax, 0x210(%rsp) + movq 0x1120(%rsp), %rax + movq %rax, 0x220(%rsp) + movq 0x1128(%rsp), %rax + movq %rax, 0x230(%rsp) + movq 0x1130(%rsp), %rax + movq %rax, 0x240(%rsp) + movq 0x1138(%rsp), %rax + movq %rax, 0x250(%rsp) + movq 0x1140(%rsp), %rax + movq %rax, 0x260(%rsp) + movq 0x1148(%rsp), %rax + movq %rax, 0x270(%rsp) + movq 0x1150(%rsp), %rax + movq %rax, 0x280(%rsp) + movq 0x1158(%rsp), %rax + movq %rax, 0x290(%rsp) + movq 0x1160(%rsp), %rax + movq %rax, 0x2a0(%rsp) + movq 0x1168(%rsp), %rax + movq %rax, 0x2b0(%rsp) + movq 0x1170(%rsp), %rax + movq %rax, 0x2c0(%rsp) + movq 0x1178(%rsp), %rax + movq %rax, 0x2d0(%rsp) + movq 0x1180(%rsp), %rax + movq %rax, 0x2e0(%rsp) + movq 0x1188(%rsp), %rax + movq %rax, 0x2f0(%rsp) + movq 0x1190(%rsp), %rax + movq %rax, 0x300(%rsp) + movq 0x1198(%rsp), %rax + movq %rax, 0x310(%rsp) + movq 0x11a0(%rsp), %rax + movq %rax, 0x320(%rsp) + movq 0x11a8(%rsp), %rax + movq %rax, 0x330(%rsp) + movq 0x11b0(%rsp), %rax + movq %rax, 0x340(%rsp) + movq 0x11b8(%rsp), %rax + movq %rax, 0x350(%rsp) + movq 0x11c0(%rsp), %rax + movq %rax, 0x360(%rsp) + movq 0x11c8(%rsp), %rax + movq %rax, 0x370(%rsp) + movq 0x11d0(%rsp), %rax + movq %rax, 0x380(%rsp) + movq 0x11d8(%rsp), %rax + movq %rax, 0x390(%rsp) + movq 0x11e0(%rsp), %rax + movq %rax, 0x3a0(%rsp) + movq 0x11e8(%rsp), %rax + movq %rax, 0x3b0(%rsp) + movq 0x11f0(%rsp), %rax + movq %rax, 0x3c0(%rsp) + movq 0x11f8(%rsp), %rax + movq %rax, 0x3d0(%rsp) + movq 0x1200(%rsp), %rax + movq %rax, 0x3e0(%rsp) + movq 0x1208(%rsp), %rax + movq %rax, 0x3f0(%rsp) + movq 0x1210(%rsp), %rax + movq %rax, 0x400(%rsp) + movq 0x1218(%rsp), %rax + movq %rax, 0x410(%rsp) + movq 0x1220(%rsp), %rax + movq %rax, 0x420(%rsp) + movq 0x1228(%rsp), %rax + movq %rax, 0x430(%rsp) + movq 0x1230(%rsp), %rax + movq %rax, 0x440(%rsp) + movq 0x1238(%rsp), %rax + movq %rax, 0x450(%rsp) + movq 0x1240(%rsp), %rax + movq %rax, 0x460(%rsp) + movq 0x1248(%rsp), %rax + movq %rax, 0x470(%rsp) + movq 0x1250(%rsp), %rax + movq %rax, 0x480(%rsp) + movq 0x1258(%rsp), %rax + movq %rax, 0x490(%rsp) + movq 0x1260(%rsp), %rax + movq %rax, 0x4a0(%rsp) + movq 0x1268(%rsp), %rax + movq %rax, 0x4b0(%rsp) + movq 0x1270(%rsp), %rax + movq %rax, 0x4c0(%rsp) + movq 0x1278(%rsp), %rax + movq %rax, 0x4d0(%rsp) + movq 0x1280(%rsp), %rax + movq %rax, 0x4e0(%rsp) + movq 0x1288(%rsp), %rax + movq %rax, 0x4f0(%rsp) + movq 0x1290(%rsp), %rax + movq %rax, 0x500(%rsp) + movq 0x1298(%rsp), %rax + movq %rax, 0x510(%rsp) + movq 0x12a0(%rsp), %rax + movq %rax, 0x520(%rsp) + movq 0x12a8(%rsp), %rax + movq %rax, 0x530(%rsp) + movq 0x12b0(%rsp), %rax + movq %rax, 0x540(%rsp) + movq 0x12b8(%rsp), %rax + movq %rax, 0x550(%rsp) + movq 0x12c0(%rsp), %rax + movq %rax, 0x560(%rsp) + movq 0x12c8(%rsp), %rax + movq %rax, 0x570(%rsp) + movq 0x12d0(%rsp), %rax + movq %rax, 0x580(%rsp) + movq 0x12d8(%rsp), %rax + movq %rax, 0x590(%rsp) + movq 0x12e0(%rsp), %rax + movq %rax, 0x5a0(%rsp) + movq 0x12e8(%rsp), %rax + movq %rax, 0x5b0(%rsp) + movq 0x12f0(%rsp), %rax + movq %rax, 0x5c0(%rsp) + movq 0x12f8(%rsp), %rax + movq %rax, 0x5d0(%rsp) + movq 0x1300(%rsp), %rax + movq %rax, 0x5e0(%rsp) + movq 0x1308(%rsp), %rax + movq %rax, 0x5f0(%rsp) + movq 0x1310(%rsp), %rax + movq %rax, 0x600(%rsp) + movq 0x1318(%rsp), %rax + movq %rax, 0x610(%rsp) + movq 0x1320(%rsp), %rax + movq %rax, 0x620(%rsp) + movq 0x1328(%rsp), %rax + movq %rax, 0x630(%rsp) + movq 0x1330(%rsp), %rax + movq %rax, 0x640(%rsp) + movq 0x1338(%rsp), %rax + movq %rax, 0x650(%rsp) + movq 0x1340(%rsp), %rax + movq %rax, 0x660(%rsp) + movq 0x1348(%rsp), %rax + movq %rax, 0x670(%rsp) + movq 0x1350(%rsp), %rax + movq %rax, 0x680(%rsp) + movq 0x1358(%rsp), %rax + movq %rax, 0x690(%rsp) + movq 0x1360(%rsp), %rax + movq %rax, 0x6a0(%rsp) + movq 0x1368(%rsp), %rax + movq %rax, 0x6b0(%rsp) + movq 0x1370(%rsp), %rax + movq %rax, 0x6c0(%rsp) + movq 0x1378(%rsp), %rax + movq %rax, 0x6d0(%rsp) + movq 0x1380(%rsp), %rax + movq %rax, 0x6e0(%rsp) + movq 0x1388(%rsp), %rax + movq %rax, 0x6f0(%rsp) + movq 0x1390(%rsp), %rax + movq %rax, 0x700(%rsp) + movq 0x1398(%rsp), %rax + movq %rax, 0x710(%rsp) + movq 0x13a0(%rsp), %rax + movq %rax, 0x720(%rsp) + movq 0x13a8(%rsp), %rax + movq %rax, 0x730(%rsp) + movq 0x13b0(%rsp), %rax + movq %rax, 0x740(%rsp) + movq 0x13b8(%rsp), %rax + movq %rax, 0x750(%rsp) + movq 0x13c0(%rsp), %rax + movq %rax, 0x760(%rsp) + movq 0x13c8(%rsp), %rax + movq %rax, 0x770(%rsp) + movq 0x13d0(%rsp), %rax + movq %rax, 0x780(%rsp) + movq 0x13d8(%rsp), %rax + movq %rax, 0x790(%rsp) + movq 0x13e0(%rsp), %rax + movq %rax, 0x7a0(%rsp) + movq 0x13e8(%rsp), %rax + movq %rax, 0x7b0(%rsp) + movq 0x13f0(%rsp), %rax + movq %rax, 0x7c0(%rsp) + movq 0x13f8(%rsp), %rax + movq %rax, 0x7d0(%rsp) + movq 0x1400(%rsp), %rax + movq %rax, 0x7e0(%rsp) + movq 0x1408(%rsp), %rax + movq %rax, 0x7f0(%rsp) + movq 0x1410(%rsp), %rax + movq %rax, 0x800(%rsp) + movq 0x1418(%rsp), %rax + movq %rax, 0x810(%rsp) + movq 0x1420(%rsp), %rax + movq %rax, 0x820(%rsp) + movq 0x1428(%rsp), %rax + movq %rax, 0x830(%rsp) + movq 0x1430(%rsp), %rax + movq %rax, 0x840(%rsp) + movq 0x1438(%rsp), %rax + movq %rax, 0x850(%rsp) + movq 0x1440(%rsp), %rax + movq %rax, 0x860(%rsp) + movq 0x1448(%rsp), %rax + movq %rax, 0x870(%rsp) + movq 0x1450(%rsp), %rax + movq %rax, 0x880(%rsp) + movq 0x1458(%rsp), %rax + movq %rax, 0x890(%rsp) + movq 0x1460(%rsp), %rax + movq %rax, 0x8a0(%rsp) + movq 0x1468(%rsp), %rax + movq %rax, 0x8b0(%rsp) + movq 0x1470(%rsp), %rax + movq %rax, 0x8c0(%rsp) + movq 0x1478(%rsp), %rax + movq %rax, 0x8d0(%rsp) + movq 0x1480(%rsp), %rax + movq %rax, 0x8e0(%rsp) + movq 0x1488(%rsp), %rax + movq %rax, 0x8f0(%rsp) + movq 0x1490(%rsp), %rax + movq %rax, 0x900(%rsp) + movq 0x1498(%rsp), %rax + movq %rax, 0x910(%rsp) + movq 0x14a0(%rsp), %rax + movq %rax, 0x920(%rsp) + movq 0x14a8(%rsp), %rax + movq %rax, 0x930(%rsp) + movq 0x14b0(%rsp), %rax + movq %rax, 0x940(%rsp) + movq 0x14b8(%rsp), %rax + movq %rax, 0x950(%rsp) + movq 0x14c0(%rsp), %rax + movq %rax, 0x960(%rsp) + movq 0x14c8(%rsp), %rax + movq %rax, 0x970(%rsp) + movq 0x14d0(%rsp), %rax + movq %rax, 0x980(%rsp) + movq 0x14d8(%rsp), %rax + movq %rax, 0x990(%rsp) + movq 0x14e0(%rsp), %rax + movq %rax, 0x9a0(%rsp) + movq 0x14e8(%rsp), %rax + movq %rax, 0x9b0(%rsp) + movq 0x14f0(%rsp), %rax + movq %rax, 0x9c0(%rsp) + movq 0x14f8(%rsp), %rax + movq %rax, 0x9d0(%rsp) + movq 0x1500(%rsp), %rax + movq %rax, 0x9e0(%rsp) + movq 0x1508(%rsp), %rax + movq %rax, 0x9f0(%rsp) + movq 0x1510(%rsp), %rax + movq %rax, 0xa00(%rsp) + movq 0x1518(%rsp), %rax + movq %rax, 0xa10(%rsp) + movq 0x1520(%rsp), %rax + movq %rax, 0xa20(%rsp) + movq 0x1528(%rsp), %rax + movq %rax, 0xa30(%rsp) + movq 0x1530(%rsp), %rax + movq %rax, 0xa40(%rsp) + movq 0x1538(%rsp), %rax + movq %rax, 0xa50(%rsp) + movq 0x1540(%rsp), %rax + movq %rax, 0xa60(%rsp) + movq 0x1548(%rsp), %rax + movq %rax, 0xa70(%rsp) + movq 0x1550(%rsp), %rax + movq %rax, 0xa80(%rsp) + movq 0x1558(%rsp), %rax + movq %rax, 0xa90(%rsp) + movq 0x1560(%rsp), %rax + movq %rax, 0xaa0(%rsp) + movq 0x1568(%rsp), %rax + movq %rax, 0xab0(%rsp) + movq 0x1570(%rsp), %rax + movq %rax, 0xac0(%rsp) + movq 0x1578(%rsp), %rax + movq %rax, 0xad0(%rsp) + movq 0x1580(%rsp), %rax + movq %rax, 0xae0(%rsp) + movq 0x1588(%rsp), %rax + movq %rax, 0xaf0(%rsp) + movq 0x1590(%rsp), %rax + movq %rax, 0xb00(%rsp) + movq 0x1598(%rsp), %rax + movq %rax, 0xb10(%rsp) + movq 0x15a0(%rsp), %rax + movq %rax, 0xb20(%rsp) + movq 0x15a8(%rsp), %rax + movq %rax, 0xb30(%rsp) + movq 0x15b0(%rsp), %rax + movq %rax, 0xb40(%rsp) + movq 0x15b8(%rsp), %rax + movq %rax, 0xb50(%rsp) + movq 0x15c0(%rsp), %rax + movq %rax, 0xb60(%rsp) + movq 0x15c8(%rsp), %rax + movq %rax, 0xb70(%rsp) + movq 0x15d0(%rsp), %rax + movq %rax, 0xb80(%rsp) + movq 0x15d8(%rsp), %rax + movq %rax, 0xb90(%rsp) + movq 0x15e0(%rsp), %rax + movq %rax, 0xba0(%rsp) + movq 0x15e8(%rsp), %rax + movq %rax, 0xbb0(%rsp) + movq 0x15f0(%rsp), %rax + movq %rax, 0xbc0(%rsp) + movq 0x15f8(%rsp), %rax + movq %rax, 0xbd0(%rsp) + movq 0x1600(%rsp), %rax + movq %rax, 0xbe0(%rsp) + movq 0x1608(%rsp), %rax + movq %rax, 0xbf0(%rsp) + movq 0x1610(%rsp), %rax + movq %rax, 0xc00(%rsp) + movq 0x1618(%rsp), %rax + movq %rax, 0xc10(%rsp) + movq 0x1620(%rsp), %rax + movq %rax, 0xc20(%rsp) + movq 0x1628(%rsp), %rax + movq %rax, 0xc30(%rsp) + movq 0x1630(%rsp), %rax + movq %rax, 0xc40(%rsp) + movq 0x1638(%rsp), %rax + movq %rax, 0xc50(%rsp) + movq 0x1640(%rsp), %rax + movq %rax, 0xc60(%rsp) + movq 0x1648(%rsp), %rax + movq %rax, 0xc70(%rsp) + movq 0x1650(%rsp), %rax + movq %rax, 0xc80(%rsp) + movq 0x1658(%rsp), %rax + movq %rax, 0xc90(%rsp) + movq 0x1660(%rsp), %rax + movq %rax, 0xca0(%rsp) + movq 0x1668(%rsp), %rax + movq %rax, 0xcb0(%rsp) + movq 0x1670(%rsp), %rax + movq %rax, 0xcc0(%rsp) + movq 0x1678(%rsp), %rax + movq %rax, 0xcd0(%rsp) + movq 0x1680(%rsp), %rax + movq %rax, 0xce0(%rsp) + movq 0x1688(%rsp), %rax + movq %rax, 0xcf0(%rsp) + movq 0x1690(%rsp), %rax + movq %rax, 0xd00(%rsp) + movq 0x1698(%rsp), %rax + movq %rax, 0xd10(%rsp) + movq 0x16a0(%rsp), %rax + movq %rax, 0xd20(%rsp) + movq 0x16a8(%rsp), %rax + movq %rax, 0xd30(%rsp) + movq 0x16b0(%rsp), %rax + movq %rax, 0xd40(%rsp) + movq 0x16b8(%rsp), %rax + movq %rax, 0xd50(%rsp) + movq 0x16c0(%rsp), %rax + movq %rax, 0xd60(%rsp) + movq 0x16c8(%rsp), %rax + movq %rax, 0xd70(%rsp) + movq 0x16d0(%rsp), %rax + movq %rax, 0xd80(%rsp) + movq 0x16d8(%rsp), %rax + movq %rax, 0xd90(%rsp) + movq 0x16e0(%rsp), %rax + movq %rax, 0xda0(%rsp) + movq 0x16e8(%rsp), %rax + movq %rax, 0xdb0(%rsp) + movq 0x16f0(%rsp), %rax + movq %rax, 0xdc0(%rsp) + movq 0x16f8(%rsp), %rax + movq %rax, 0xdd0(%rsp) + movq 0x1700(%rsp), %rax + movq %rax, 0xde0(%rsp) + movq 0x1708(%rsp), %rax + movq %rax, 0xdf0(%rsp) + movq 0x1710(%rsp), %rax + movq %rax, 0xe00(%rsp) + movq 0x1718(%rsp), %rax + movq %rax, 0xe10(%rsp) + movq 0x1720(%rsp), %rax + movq %rax, 0xe20(%rsp) + movq 0x1728(%rsp), %rax + movq %rax, 0xe30(%rsp) + movq 0x1730(%rsp), %rax + movq %rax, 0xe40(%rsp) + movq 0x1738(%rsp), %rax + movq %rax, 0xe50(%rsp) + movq 0x1740(%rsp), %rax + movq %rax, 0xe60(%rsp) + movq 0x1748(%rsp), %rax + movq %rax, 0xe70(%rsp) + movq 0x1750(%rsp), %rax + movq %rax, 0xe80(%rsp) + movq 0x1758(%rsp), %rax + movq %rax, 0xe90(%rsp) + movq 0x1760(%rsp), %rax + movq %rax, 0xea0(%rsp) + movq 0x1768(%rsp), %rax + movq %rax, 0xeb0(%rsp) + movq 0x1770(%rsp), %rax + movq %rax, 0xec0(%rsp) + movq 0x1778(%rsp), %rax + movq %rax, 0xed0(%rsp) + movq 0x1780(%rsp), %rax + movq %rax, 0xee0(%rsp) + movq 0x1788(%rsp), %rax + movq %rax, 0xef0(%rsp) + movq 0x1790(%rsp), %rax + movq %rax, 0xf00(%rsp) + movq 0x1798(%rsp), %rax + movq %rax, 0xf10(%rsp) + movq 0x17a0(%rsp), %rax + movq %rax, 0xf20(%rsp) + movq 0x17a8(%rsp), %rax + movq %rax, 0xf30(%rsp) + movq 0x17b0(%rsp), %rax + movq %rax, 0xf40(%rsp) + movq 0x17b8(%rsp), %rax + movq %rax, 0xf50(%rsp) + movq 0x17c0(%rsp), %rax + movq %rax, 0xf60(%rsp) + movq 0x17c8(%rsp), %rax + movq %rax, 0xf70(%rsp) + movq 0x17d0(%rsp), %rax + movq %rax, 0xf80(%rsp) + movq 0x17d8(%rsp), %rax + movq %rax, 0xf90(%rsp) + movq 0x17e0(%rsp), %rax + movq %rax, 0xfa0(%rsp) + movq 0x17e8(%rsp), %rax + movq %rax, 0xfb0(%rsp) + movq 0x17f0(%rsp), %rax + movq %rax, 0xfc0(%rsp) + movq 0x17f8(%rsp), %rax + movq %rax, 0xfd0(%rsp) + movq 0x1800(%rsp), %rax + movq %rax, 0xfe0(%rsp) + movq 0x1808(%rsp), %rax + movq %rax, 0xff0(%rsp) + movq 0x1810(%rsp), %rax + movq %rax, 0x1000(%rsp) + movq 0x1818(%rsp), %rax + movq %rax, 0x1010(%rsp) + movq 0x1820(%rsp), %rax + movq %rax, 0x1020(%rsp) + movq 0x1828(%rsp), %rax + movq %rax, 0x1030(%rsp) + pushq %r10 + pushq %rbp + movq %rsp, %rbp + subq $0x20, %rsp + movq %rbx, (%rsp) + xorq %rax, %rax + addq %rdi, %rax + addq %rsi, %rax + addq %rdx, %rax + addq %rcx, %rax + addq %r8, %rax + addq %r9, %rax + movq 0x70(%rbp), %rcx + addq %rcx, %rax + movq 0x80(%rbp), %rcx + addq %rcx, %rax + movq 0x90(%rbp), %rcx + addq %rcx, %rax + movq 0xa0(%rbp), %rcx + addq %rcx, %rax + movq 0xb0(%rbp), %rcx + addq %rcx, %rax + movq 0xc0(%rbp), %rcx + addq %rcx, %rax + movq 0xd0(%rbp), %rcx + addq %rcx, %rax + movq 0xe0(%rbp), %rcx + addq %rcx, %rax + movq 0xf0(%rbp), %rcx + addq %rcx, %rax + movq 0x100(%rbp), %rcx + addq %rcx, %rax + movq 0x110(%rbp), %rcx + addq %rcx, %rax + movq 0x120(%rbp), %rcx + addq %rcx, %rax + movq 0x130(%rbp), %rcx + addq %rcx, %rax + movq 0x140(%rbp), %rcx + addq %rcx, %rax + movq 0x150(%rbp), %rcx + addq %rcx, %rax + movq 0x160(%rbp), %rcx + addq %rcx, %rax + movq 0x170(%rbp), %rcx + addq %rcx, %rax + movq 0x180(%rbp), %rcx + addq %rcx, %rax + movq 0x190(%rbp), %rcx + addq %rcx, %rax + movq 0x1a0(%rbp), %rcx + addq %rcx, %rax + movq 0x1b0(%rbp), %rcx + addq %rcx, %rax + movq 0x1c0(%rbp), %rcx + addq %rcx, %rax + movq 0x1d0(%rbp), %rcx + addq %rcx, %rax + movq 0x1e0(%rbp), %rcx + addq %rcx, %rax + movq 0x1f0(%rbp), %rcx + addq %rcx, %rax + movq 0x200(%rbp), %rcx + addq %rcx, %rax + movq 0x210(%rbp), %rcx + addq %rcx, %rax + movq 0x220(%rbp), %rcx + addq %rcx, %rax + movq 0x230(%rbp), %rcx + addq %rcx, %rax + movq 0x240(%rbp), %rcx + addq %rcx, %rax + movq 0x250(%rbp), %rcx + addq %rcx, %rax + movq 0x260(%rbp), %rcx + addq %rcx, %rax + movq 0x270(%rbp), %rcx + addq %rcx, %rax + movq 0x280(%rbp), %rcx + addq %rcx, %rax + movq 0x290(%rbp), %rcx + addq %rcx, %rax + movq 0x2a0(%rbp), %rcx + addq %rcx, %rax + movq 0x2b0(%rbp), %rcx + addq %rcx, %rax + movq 0x2c0(%rbp), %rcx + addq %rcx, %rax + movq 0x2d0(%rbp), %rcx + addq %rcx, %rax + movq 0x2e0(%rbp), %rcx + addq %rcx, %rax + movq 0x2f0(%rbp), %rcx + addq %rcx, %rax + movq 0x300(%rbp), %rcx + addq %rcx, %rax + movq 0x310(%rbp), %rcx + addq %rcx, %rax + movq 0x320(%rbp), %rcx + addq %rcx, %rax + movq 0x330(%rbp), %rcx + addq %rcx, %rax + movq 0x340(%rbp), %rcx + addq %rcx, %rax + movq 0x350(%rbp), %rcx + addq %rcx, %rax + movq 0x360(%rbp), %rcx + addq %rcx, %rax + movq 0x370(%rbp), %rcx + addq %rcx, %rax + movq 0x380(%rbp), %rcx + addq %rcx, %rax + movq 0x390(%rbp), %rcx + addq %rcx, %rax + movq 0x3a0(%rbp), %rcx + addq %rcx, %rax + movq 0x3b0(%rbp), %rcx + addq %rcx, %rax + movq 0x3c0(%rbp), %rcx + addq %rcx, %rax + movq 0x3d0(%rbp), %rcx + addq %rcx, %rax + movq 0x3e0(%rbp), %rcx + addq %rcx, %rax + movq 0x3f0(%rbp), %rcx + addq %rcx, %rax + movq 0x400(%rbp), %rcx + addq %rcx, %rax + movq 0x410(%rbp), %rcx + addq %rcx, %rax + movq 0x420(%rbp), %rcx + addq %rcx, %rax + movq 0x430(%rbp), %rcx + addq %rcx, %rax + movq 0x440(%rbp), %rcx + addq %rcx, %rax + movq 0x450(%rbp), %rcx + addq %rcx, %rax + movq 0x460(%rbp), %rcx + addq %rcx, %rax + movq 0x470(%rbp), %rcx + addq %rcx, %rax + movq 0x480(%rbp), %rcx + addq %rcx, %rax + movq 0x490(%rbp), %rcx + addq %rcx, %rax + movq 0x4a0(%rbp), %rcx + addq %rcx, %rax + movq 0x4b0(%rbp), %rcx + addq %rcx, %rax + movq 0x4c0(%rbp), %rcx + addq %rcx, %rax + movq 0x4d0(%rbp), %rcx + addq %rcx, %rax + movq 0x4e0(%rbp), %rcx + addq %rcx, %rax + movq 0x4f0(%rbp), %rcx + addq %rcx, %rax + movq 0x500(%rbp), %rcx + addq %rcx, %rax + movq 0x510(%rbp), %rcx + addq %rcx, %rax + movq 0x520(%rbp), %rcx + addq %rcx, %rax + movq 0x530(%rbp), %rcx + addq %rcx, %rax + movq 0x540(%rbp), %rcx + addq %rcx, %rax + movq 0x550(%rbp), %rcx + addq %rcx, %rax + movq 0x560(%rbp), %rcx + addq %rcx, %rax + movq 0x570(%rbp), %rcx + addq %rcx, %rax + movq 0x580(%rbp), %rcx + addq %rcx, %rax + movq 0x590(%rbp), %rcx + addq %rcx, %rax + movq 0x5a0(%rbp), %rcx + addq %rcx, %rax + movq 0x5b0(%rbp), %rcx + addq %rcx, %rax + movq 0x5c0(%rbp), %rcx + addq %rcx, %rax + movq 0x5d0(%rbp), %rcx + addq %rcx, %rax + movq 0x5e0(%rbp), %rcx + addq %rcx, %rax + movq 0x5f0(%rbp), %rcx + addq %rcx, %rax + movq 0x600(%rbp), %rcx + addq %rcx, %rax + movq 0x610(%rbp), %rcx + addq %rcx, %rax + movq 0x620(%rbp), %rcx + addq %rcx, %rax + movq 0x630(%rbp), %rcx + addq %rcx, %rax + movq 0x640(%rbp), %rcx + addq %rcx, %rax + movq 0x650(%rbp), %rcx + addq %rcx, %rax + movq 0x660(%rbp), %rcx + addq %rcx, %rax + movq 0x670(%rbp), %rcx + addq %rcx, %rax + movq 0x680(%rbp), %rcx + addq %rcx, %rax + movq 0x690(%rbp), %rcx + addq %rcx, %rax + movq 0x6a0(%rbp), %rcx + addq %rcx, %rax + movq 0x6b0(%rbp), %rcx + addq %rcx, %rax + movq 0x6c0(%rbp), %rcx + addq %rcx, %rax + movq 0x6d0(%rbp), %rcx + addq %rcx, %rax + movq 0x6e0(%rbp), %rcx + addq %rcx, %rax + movq 0x6f0(%rbp), %rcx + addq %rcx, %rax + movq 0x700(%rbp), %rcx + addq %rcx, %rax + movq 0x710(%rbp), %rcx + addq %rcx, %rax + movq 0x720(%rbp), %rcx + addq %rcx, %rax + movq 0x730(%rbp), %rcx + addq %rcx, %rax + movq 0x740(%rbp), %rcx + addq %rcx, %rax + movq 0x750(%rbp), %rcx + addq %rcx, %rax + movq 0x760(%rbp), %rcx + addq %rcx, %rax + movq 0x770(%rbp), %rcx + addq %rcx, %rax + movq 0x780(%rbp), %rcx + addq %rcx, %rax + movq 0x790(%rbp), %rcx + addq %rcx, %rax + movq 0x7a0(%rbp), %rcx + addq %rcx, %rax + movq 0x7b0(%rbp), %rcx + addq %rcx, %rax + movq 0x7c0(%rbp), %rcx + addq %rcx, %rax + movq 0x7d0(%rbp), %rcx + addq %rcx, %rax + movq 0x7e0(%rbp), %rcx + addq %rcx, %rax + movq 0x7f0(%rbp), %rcx + addq %rcx, %rax + movq 0x800(%rbp), %rcx + addq %rcx, %rax + movq 0x810(%rbp), %rcx + addq %rcx, %rax + movq 0x820(%rbp), %rcx + addq %rcx, %rax + movq 0x830(%rbp), %rcx + addq %rcx, %rax + movq 0x840(%rbp), %rcx + addq %rcx, %rax + movq 0x850(%rbp), %rcx + addq %rcx, %rax + movq 0x860(%rbp), %rcx + addq %rcx, %rax + movq 0x870(%rbp), %rcx + addq %rcx, %rax + movq 0x880(%rbp), %rcx + addq %rcx, %rax + movq 0x890(%rbp), %rcx + addq %rcx, %rax + movq 0x8a0(%rbp), %rcx + addq %rcx, %rax + movq 0x8b0(%rbp), %rcx + addq %rcx, %rax + movq 0x8c0(%rbp), %rcx + addq %rcx, %rax + movq 0x8d0(%rbp), %rcx + addq %rcx, %rax + movq 0x8e0(%rbp), %rcx + addq %rcx, %rax + movq 0x8f0(%rbp), %rcx + addq %rcx, %rax + movq 0x900(%rbp), %rcx + addq %rcx, %rax + movq 0x910(%rbp), %rcx + addq %rcx, %rax + movq 0x920(%rbp), %rcx + addq %rcx, %rax + movq 0x930(%rbp), %rcx + addq %rcx, %rax + movq 0x940(%rbp), %rcx + addq %rcx, %rax + movq 0x950(%rbp), %rcx + addq %rcx, %rax + movq 0x960(%rbp), %rcx + addq %rcx, %rax + movq 0x970(%rbp), %rcx + addq %rcx, %rax + movq 0x980(%rbp), %rcx + addq %rcx, %rax + movq 0x990(%rbp), %rcx + addq %rcx, %rax + movq 0x9a0(%rbp), %rcx + addq %rcx, %rax + movq 0x9b0(%rbp), %rcx + addq %rcx, %rax + movq 0x9c0(%rbp), %rcx + addq %rcx, %rax + movq 0x9d0(%rbp), %rcx + addq %rcx, %rax + movq 0x9e0(%rbp), %rcx + addq %rcx, %rax + movq 0x9f0(%rbp), %rcx + addq %rcx, %rax + movq 0xa00(%rbp), %rcx + addq %rcx, %rax + movq 0xa10(%rbp), %rcx + addq %rcx, %rax + movq 0xa20(%rbp), %rcx + addq %rcx, %rax + movq 0xa30(%rbp), %rcx + addq %rcx, %rax + movq 0xa40(%rbp), %rcx + addq %rcx, %rax + movq 0xa50(%rbp), %rcx + addq %rcx, %rax + movq 0xa60(%rbp), %rcx + addq %rcx, %rax + movq 0xa70(%rbp), %rcx + addq %rcx, %rax + movq 0xa80(%rbp), %rcx + addq %rcx, %rax + movq 0xa90(%rbp), %rcx + addq %rcx, %rax + movq 0xaa0(%rbp), %rcx + addq %rcx, %rax + movq 0xab0(%rbp), %rcx + addq %rcx, %rax + movq 0xac0(%rbp), %rcx + addq %rcx, %rax + movq 0xad0(%rbp), %rcx + addq %rcx, %rax + movq 0xae0(%rbp), %rcx + addq %rcx, %rax + movq 0xaf0(%rbp), %rcx + addq %rcx, %rax + movq 0xb00(%rbp), %rcx + addq %rcx, %rax + movq 0xb10(%rbp), %rcx + addq %rcx, %rax + movq 0xb20(%rbp), %rcx + addq %rcx, %rax + movq 0xb30(%rbp), %rcx + addq %rcx, %rax + movq 0xb40(%rbp), %rcx + addq %rcx, %rax + movq 0xb50(%rbp), %rcx + addq %rcx, %rax + movq 0xb60(%rbp), %rcx + addq %rcx, %rax + movq 0xb70(%rbp), %rcx + addq %rcx, %rax + movq 0xb80(%rbp), %rcx + addq %rcx, %rax + movq 0xb90(%rbp), %rcx + addq %rcx, %rax + movq 0xba0(%rbp), %rcx + addq %rcx, %rax + movq 0xbb0(%rbp), %rcx + addq %rcx, %rax + movq 0xbc0(%rbp), %rcx + addq %rcx, %rax + movq 0xbd0(%rbp), %rcx + addq %rcx, %rax + movq 0xbe0(%rbp), %rcx + addq %rcx, %rax + movq 0xbf0(%rbp), %rcx + addq %rcx, %rax + movq 0xc00(%rbp), %rcx + addq %rcx, %rax + movq 0xc10(%rbp), %rcx + addq %rcx, %rax + movq 0xc20(%rbp), %rcx + addq %rcx, %rax + movq 0xc30(%rbp), %rcx + addq %rcx, %rax + movq 0xc40(%rbp), %rcx + addq %rcx, %rax + movq 0xc50(%rbp), %rcx + addq %rcx, %rax + movq 0xc60(%rbp), %rcx + addq %rcx, %rax + movq 0xc70(%rbp), %rcx + addq %rcx, %rax + movq 0xc80(%rbp), %rcx + addq %rcx, %rax + movq 0xc90(%rbp), %rcx + addq %rcx, %rax + movq 0xca0(%rbp), %rcx + addq %rcx, %rax + movq 0xcb0(%rbp), %rcx + addq %rcx, %rax + movq 0xcc0(%rbp), %rcx + addq %rcx, %rax + movq 0xcd0(%rbp), %rcx + addq %rcx, %rax + movq 0xce0(%rbp), %rcx + addq %rcx, %rax + movq 0xcf0(%rbp), %rcx + addq %rcx, %rax + movq 0xd00(%rbp), %rcx + addq %rcx, %rax + movq 0xd10(%rbp), %rcx + addq %rcx, %rax + movq 0xd20(%rbp), %rcx + addq %rcx, %rax + movq 0xd30(%rbp), %rcx + addq %rcx, %rax + movq 0xd40(%rbp), %rcx + addq %rcx, %rax + movq 0xd50(%rbp), %rcx + addq %rcx, %rax + movq 0xd60(%rbp), %rcx + addq %rcx, %rax + movq 0xd70(%rbp), %rcx + addq %rcx, %rax + movq 0xd80(%rbp), %rcx + addq %rcx, %rax + movq 0xd90(%rbp), %rcx + addq %rcx, %rax + movq 0xda0(%rbp), %rcx + addq %rcx, %rax + movq 0xdb0(%rbp), %rcx + addq %rcx, %rax + movq 0xdc0(%rbp), %rcx + addq %rcx, %rax + movq 0xdd0(%rbp), %rcx + addq %rcx, %rax + movq 0xde0(%rbp), %rcx + addq %rcx, %rax + movq 0xdf0(%rbp), %rcx + addq %rcx, %rax + movq 0xe00(%rbp), %rcx + addq %rcx, %rax + movq 0xe10(%rbp), %rcx + addq %rcx, %rax + movq 0xe20(%rbp), %rcx + addq %rcx, %rax + movq 0xe30(%rbp), %rcx + addq %rcx, %rax + movq 0xe40(%rbp), %rcx + addq %rcx, %rax + movq 0xe50(%rbp), %rcx + addq %rcx, %rax + movq 0xe60(%rbp), %rcx + addq %rcx, %rax + movq 0xe70(%rbp), %rcx + addq %rcx, %rax + movq 0xe80(%rbp), %rcx + addq %rcx, %rax + movq 0xe90(%rbp), %rcx + addq %rcx, %rax + movq 0xea0(%rbp), %rcx + addq %rcx, %rax + movq 0xeb0(%rbp), %rcx + addq %rcx, %rax + movq 0xec0(%rbp), %rcx + addq %rcx, %rax + movq 0xed0(%rbp), %rcx + addq %rcx, %rax + movq 0xee0(%rbp), %rcx + addq %rcx, %rax + movq 0xef0(%rbp), %rcx + addq %rcx, %rax + movq 0xf00(%rbp), %rcx + addq %rcx, %rax + movq 0xf10(%rbp), %rcx + addq %rcx, %rax + movq 0xf20(%rbp), %rcx + addq %rcx, %rax + movq 0xf30(%rbp), %rcx + addq %rcx, %rax + movq 0xf40(%rbp), %rcx + addq %rcx, %rax + movq 0xf50(%rbp), %rcx + addq %rcx, %rax + movq 0xf60(%rbp), %rcx + addq %rcx, %rax + movq 0xf70(%rbp), %rcx + addq %rcx, %rax + movq 0xf80(%rbp), %rcx + addq %rcx, %rax + movq 0xf90(%rbp), %rcx + addq %rcx, %rax + movq 0xfa0(%rbp), %rcx + addq %rcx, %rax + movq 0xfb0(%rbp), %rcx + addq %rcx, %rax + movq 0xfc0(%rbp), %rcx + addq %rcx, %rax + movq 0xfd0(%rbp), %rcx + addq %rcx, %rax + movq 0xfe0(%rbp), %rcx + addq %rcx, %rax + movq 0xff0(%rbp), %rcx + addq %rcx, %rax + movq 0x1000(%rbp), %rcx + addq %rcx, %rax + movq 0x1010(%rbp), %rcx + addq %rcx, %rax + movq 0x1020(%rbp), %rcx + addq %rcx, %rax + movq 0x1030(%rbp), %rcx + addq %rcx, %rax + movq 0x1040(%rbp), %rcx + addq %rcx, %rax + movq (%rsp), %rbx + addq $0x20, %rsp + popq %rbp + popq %r11 + addq $0x1040, %rsp # imm = 0x1040 + pushq %r11 + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x1050, %rsp # imm = 0x1050 + movq %rbx, (%rsp) + movq %r12, 0x8(%rsp) + movq %r13, 0x10(%rsp) + movq %r14, 0x18(%rsp) + movq %r15, 0x20(%rsp) + leaq -, %rbx # + leaq -, %r12 # + xorq %rcx, %rcx + cmpq $0x105, %rcx # imm = 0x105 + jge + jmp + incq %rcx + jmp + leaq , %rax + movq %rcx, %rdx + shlq $0x4, %rdx + addq %rax, %rdx + movq %rcx, (%rdx) + movq %rcx, %rdx + shlq $0x4, %rdx + addq %rdx, %rax + movq %rcx, %rdx + shlq $0x1, %rdx + movq %rdx, 0x8(%rax) + jmp + leaq , %rdi + leaq 0x10(%rdi), %rsi + leaq 0x20(%rdi), %rdx + leaq 0x30(%rdi), %rcx + leaq 0x40(%rdi), %r8 + leaq 0x50(%rdi), %r9 + leaq 0x60(%rdi), %rax + leaq 0x70(%rdi), %r13 + leaq 0x80(%rdi), %r14 + leaq 0x90(%rdi), %r15 + leaq 0xa0(%rdi), %r10 + movq %r10, 0x808(%rsp) + leaq 0xb0(%rdi), %r10 + movq %r10, 0x800(%rsp) + leaq 0xc0(%rdi), %r10 + movq %r10, 0x7f8(%rsp) + leaq 0xd0(%rdi), %r10 + movq %r10, 0x7f0(%rsp) + leaq 0xe0(%rdi), %r10 + movq %r10, 0x7e8(%rsp) + leaq 0xf0(%rdi), %r10 + movq %r10, 0x7e0(%rsp) + leaq 0x100(%rdi), %r10 + movq %r10, 0x7d8(%rsp) + leaq 0x110(%rdi), %r10 + movq %r10, 0x7d0(%rsp) + leaq 0x120(%rdi), %r10 + movq %r10, 0x7c8(%rsp) + leaq 0x130(%rdi), %r10 + movq %r10, 0x7c0(%rsp) + leaq 0x140(%rdi), %r10 + movq %r10, 0x7b8(%rsp) + leaq 0x150(%rdi), %r10 + movq %r10, 0x7b0(%rsp) + leaq 0x160(%rdi), %r10 + movq %r10, 0x7a8(%rsp) + leaq 0x170(%rdi), %r10 + movq %r10, 0x7a0(%rsp) + leaq 0x180(%rdi), %r10 + movq %r10, 0x798(%rsp) + leaq 0x190(%rdi), %r10 + movq %r10, 0x790(%rsp) + leaq 0x1a0(%rdi), %r10 + movq %r10, 0x788(%rsp) + leaq 0x1b0(%rdi), %r10 + movq %r10, 0x780(%rsp) + leaq 0x1c0(%rdi), %r10 + movq %r10, 0x778(%rsp) + leaq 0x1d0(%rdi), %r10 + movq %r10, 0x770(%rsp) + leaq 0x1e0(%rdi), %r10 + movq %r10, 0x768(%rsp) + leaq 0x1f0(%rdi), %r10 + movq %r10, 0x760(%rsp) + leaq 0x200(%rdi), %r10 + movq %r10, 0x758(%rsp) + leaq 0x210(%rdi), %r10 + movq %r10, 0x750(%rsp) + leaq 0x220(%rdi), %r10 + movq %r10, 0x748(%rsp) + leaq 0x230(%rdi), %r10 + movq %r10, 0x740(%rsp) + leaq 0x240(%rdi), %r10 + movq %r10, 0x738(%rsp) + leaq 0x250(%rdi), %r10 + movq %r10, 0x730(%rsp) + leaq 0x260(%rdi), %r10 + movq %r10, 0x728(%rsp) + leaq 0x270(%rdi), %r10 + movq %r10, 0x720(%rsp) + leaq 0x280(%rdi), %r10 + movq %r10, 0x718(%rsp) + leaq 0x290(%rdi), %r10 + movq %r10, 0x710(%rsp) + leaq 0x2a0(%rdi), %r10 + movq %r10, 0x708(%rsp) + leaq 0x2b0(%rdi), %r10 + movq %r10, 0x700(%rsp) + leaq 0x2c0(%rdi), %r10 + movq %r10, 0x6f8(%rsp) + leaq 0x2d0(%rdi), %r10 + movq %r10, 0x6f0(%rsp) + leaq 0x2e0(%rdi), %r10 + movq %r10, 0x6e8(%rsp) + leaq 0x2f0(%rdi), %r10 + movq %r10, 0x6e0(%rsp) + leaq 0x300(%rdi), %r10 + movq %r10, 0x6d8(%rsp) + leaq 0x310(%rdi), %r10 + movq %r10, 0x6d0(%rsp) + leaq 0x320(%rdi), %r10 + movq %r10, 0x6c8(%rsp) + leaq 0x330(%rdi), %r10 + movq %r10, 0x6c0(%rsp) + leaq 0x340(%rdi), %r10 + movq %r10, 0x6b8(%rsp) + leaq 0x350(%rdi), %r10 + movq %r10, 0x6b0(%rsp) + leaq 0x360(%rdi), %r10 + movq %r10, 0x6a8(%rsp) + leaq 0x370(%rdi), %r10 + movq %r10, 0x6a0(%rsp) + leaq 0x380(%rdi), %r10 + movq %r10, 0x698(%rsp) + leaq 0x390(%rdi), %r10 + movq %r10, 0x690(%rsp) + leaq 0x3a0(%rdi), %r10 + movq %r10, 0x688(%rsp) + leaq 0x3b0(%rdi), %r10 + movq %r10, 0x680(%rsp) + leaq 0x3c0(%rdi), %r10 + movq %r10, 0x678(%rsp) + leaq 0x3d0(%rdi), %r10 + movq %r10, 0x670(%rsp) + leaq 0x3e0(%rdi), %r10 + movq %r10, 0x668(%rsp) + leaq 0x3f0(%rdi), %r10 + movq %r10, 0x660(%rsp) + leaq 0x400(%rdi), %r10 + movq %r10, 0x658(%rsp) + leaq 0x410(%rdi), %r10 + movq %r10, 0x650(%rsp) + leaq 0x420(%rdi), %r10 + movq %r10, 0x648(%rsp) + leaq 0x430(%rdi), %r10 + movq %r10, 0x640(%rsp) + leaq 0x440(%rdi), %r10 + movq %r10, 0x638(%rsp) + leaq 0x450(%rdi), %r10 + movq %r10, 0x630(%rsp) + leaq 0x460(%rdi), %r10 + movq %r10, 0x628(%rsp) + leaq 0x470(%rdi), %r10 + movq %r10, 0x620(%rsp) + leaq 0x480(%rdi), %r10 + movq %r10, 0x618(%rsp) + leaq 0x490(%rdi), %r10 + movq %r10, 0x610(%rsp) + leaq 0x4a0(%rdi), %r10 + movq %r10, 0x608(%rsp) + leaq 0x4b0(%rdi), %r10 + movq %r10, 0x600(%rsp) + leaq 0x4c0(%rdi), %r10 + movq %r10, 0x5f8(%rsp) + leaq 0x4d0(%rdi), %r10 + movq %r10, 0x5f0(%rsp) + leaq 0x4e0(%rdi), %r10 + movq %r10, 0x5e8(%rsp) + leaq 0x4f0(%rdi), %r10 + movq %r10, 0x5e0(%rsp) + leaq 0x500(%rdi), %r10 + movq %r10, 0x5d8(%rsp) + leaq 0x510(%rdi), %r10 + movq %r10, 0x5d0(%rsp) + leaq 0x520(%rdi), %r10 + movq %r10, 0x5c8(%rsp) + leaq 0x530(%rdi), %r10 + movq %r10, 0x5c0(%rsp) + leaq 0x540(%rdi), %r10 + movq %r10, 0x5b8(%rsp) + leaq 0x550(%rdi), %r10 + movq %r10, 0x5b0(%rsp) + leaq 0x560(%rdi), %r10 + movq %r10, 0x5a8(%rsp) + leaq 0x570(%rdi), %r10 + movq %r10, 0x5a0(%rsp) + leaq 0x580(%rdi), %r10 + movq %r10, 0x598(%rsp) + leaq 0x590(%rdi), %r10 + movq %r10, 0x590(%rsp) + leaq 0x5a0(%rdi), %r10 + movq %r10, 0x588(%rsp) + leaq 0x5b0(%rdi), %r10 + movq %r10, 0x580(%rsp) + leaq 0x5c0(%rdi), %r10 + movq %r10, 0x578(%rsp) + leaq 0x5d0(%rdi), %r10 + movq %r10, 0x570(%rsp) + leaq 0x5e0(%rdi), %r10 + movq %r10, 0x568(%rsp) + leaq 0x5f0(%rdi), %r10 + movq %r10, 0x560(%rsp) + leaq 0x600(%rdi), %r10 + movq %r10, 0x558(%rsp) + leaq 0x610(%rdi), %r10 + movq %r10, 0x550(%rsp) + leaq 0x620(%rdi), %r10 + movq %r10, 0x548(%rsp) + leaq 0x630(%rdi), %r10 + movq %r10, 0x540(%rsp) + leaq 0x640(%rdi), %r10 + movq %r10, 0x538(%rsp) + leaq 0x650(%rdi), %r10 + movq %r10, 0x530(%rsp) + leaq 0x660(%rdi), %r10 + movq %r10, 0x528(%rsp) + leaq 0x670(%rdi), %r10 + movq %r10, 0x520(%rsp) + leaq 0x680(%rdi), %r10 + movq %r10, 0x518(%rsp) + leaq 0x690(%rdi), %r10 + movq %r10, 0x510(%rsp) + leaq 0x6a0(%rdi), %r10 + movq %r10, 0x508(%rsp) + leaq 0x6b0(%rdi), %r10 + movq %r10, 0x500(%rsp) + leaq 0x6c0(%rdi), %r10 + movq %r10, 0x4f8(%rsp) + leaq 0x6d0(%rdi), %r10 + movq %r10, 0x4f0(%rsp) + leaq 0x6e0(%rdi), %r10 + movq %r10, 0x4e8(%rsp) + leaq 0x6f0(%rdi), %r10 + movq %r10, 0x4e0(%rsp) + leaq 0x700(%rdi), %r10 + movq %r10, 0x4d8(%rsp) + leaq 0x710(%rdi), %r10 + movq %r10, 0x4d0(%rsp) + leaq 0x720(%rdi), %r10 + movq %r10, 0x4c8(%rsp) + leaq 0x730(%rdi), %r10 + movq %r10, 0x4c0(%rsp) + leaq 0x740(%rdi), %r10 + movq %r10, 0x4b8(%rsp) + leaq 0x750(%rdi), %r10 + movq %r10, 0x4b0(%rsp) + leaq 0x760(%rdi), %r10 + movq %r10, 0x4a8(%rsp) + leaq 0x770(%rdi), %r10 + movq %r10, 0x4a0(%rsp) + leaq 0x780(%rdi), %r10 + movq %r10, 0x498(%rsp) + leaq 0x790(%rdi), %r10 + movq %r10, 0x490(%rsp) + leaq 0x7a0(%rdi), %r10 + movq %r10, 0x488(%rsp) + leaq 0x7b0(%rdi), %r10 + movq %r10, 0x480(%rsp) + leaq 0x7c0(%rdi), %r10 + movq %r10, 0x478(%rsp) + leaq 0x7d0(%rdi), %r10 + movq %r10, 0x470(%rsp) + leaq 0x7e0(%rdi), %r10 + movq %r10, 0x468(%rsp) + leaq 0x7f0(%rdi), %r10 + movq %r10, 0x460(%rsp) + leaq 0x800(%rdi), %r10 + movq %r10, 0x458(%rsp) + leaq 0x810(%rdi), %r10 + movq %r10, 0x450(%rsp) + leaq 0x820(%rdi), %r10 + movq %r10, 0x448(%rsp) + leaq 0x830(%rdi), %r10 + movq %r10, 0x440(%rsp) + leaq 0x840(%rdi), %r10 + movq %r10, 0x438(%rsp) + leaq 0x850(%rdi), %r10 + movq %r10, 0x430(%rsp) + leaq 0x860(%rdi), %r10 + movq %r10, 0x428(%rsp) + leaq 0x870(%rdi), %r10 + movq %r10, 0x420(%rsp) + leaq 0x880(%rdi), %r10 + movq %r10, 0x418(%rsp) + leaq 0x890(%rdi), %r10 + movq %r10, 0x410(%rsp) + leaq 0x8a0(%rdi), %r10 + movq %r10, 0x408(%rsp) + leaq 0x8b0(%rdi), %r10 + movq %r10, 0x400(%rsp) + leaq 0x8c0(%rdi), %r10 + movq %r10, 0x3f8(%rsp) + leaq 0x8d0(%rdi), %r10 + movq %r10, 0x3f0(%rsp) + leaq 0x8e0(%rdi), %r10 + movq %r10, 0x3e8(%rsp) + leaq 0x8f0(%rdi), %r10 + movq %r10, 0x3e0(%rsp) + leaq 0x900(%rdi), %r10 + movq %r10, 0x3d8(%rsp) + leaq 0x910(%rdi), %r10 + movq %r10, 0x3d0(%rsp) + leaq 0x920(%rdi), %r10 + movq %r10, 0x3c8(%rsp) + leaq 0x930(%rdi), %r10 + movq %r10, 0x3c0(%rsp) + leaq 0x940(%rdi), %r10 + movq %r10, 0x3b8(%rsp) + leaq 0x950(%rdi), %r10 + movq %r10, 0x3b0(%rsp) + leaq 0x960(%rdi), %r10 + movq %r10, 0x3a8(%rsp) + leaq 0x970(%rdi), %r10 + movq %r10, 0x3a0(%rsp) + leaq 0x980(%rdi), %r10 + movq %r10, 0x398(%rsp) + leaq 0x990(%rdi), %r10 + movq %r10, 0x390(%rsp) + leaq 0x9a0(%rdi), %r10 + movq %r10, 0x388(%rsp) + leaq 0x9b0(%rdi), %r10 + movq %r10, 0x380(%rsp) + leaq 0x9c0(%rdi), %r10 + movq %r10, 0x378(%rsp) + leaq 0x9d0(%rdi), %r10 + movq %r10, 0x370(%rsp) + leaq 0x9e0(%rdi), %r10 + movq %r10, 0x368(%rsp) + leaq 0x9f0(%rdi), %r10 + movq %r10, 0x360(%rsp) + leaq 0xa00(%rdi), %r10 + movq %r10, 0x358(%rsp) + leaq 0xa10(%rdi), %r10 + movq %r10, 0x350(%rsp) + leaq 0xa20(%rdi), %r10 + movq %r10, 0x348(%rsp) + leaq 0xa30(%rdi), %r10 + movq %r10, 0x340(%rsp) + leaq 0xa40(%rdi), %r10 + movq %r10, 0x338(%rsp) + leaq 0xa50(%rdi), %r10 + movq %r10, 0x330(%rsp) + leaq 0xa60(%rdi), %r10 + movq %r10, 0x328(%rsp) + leaq 0xa70(%rdi), %r10 + movq %r10, 0x320(%rsp) + leaq 0xa80(%rdi), %r10 + movq %r10, 0x318(%rsp) + leaq 0xa90(%rdi), %r10 + movq %r10, 0x310(%rsp) + leaq 0xaa0(%rdi), %r10 + movq %r10, 0x308(%rsp) + leaq 0xab0(%rdi), %r10 + movq %r10, 0x300(%rsp) + leaq 0xac0(%rdi), %r10 + movq %r10, 0x2f8(%rsp) + leaq 0xad0(%rdi), %r10 + movq %r10, 0x2f0(%rsp) + leaq 0xae0(%rdi), %r10 + movq %r10, 0x2e8(%rsp) + leaq 0xaf0(%rdi), %r10 + movq %r10, 0x2e0(%rsp) + leaq 0xb00(%rdi), %r10 + movq %r10, 0x2d8(%rsp) + leaq 0xb10(%rdi), %r10 + movq %r10, 0x2d0(%rsp) + leaq 0xb20(%rdi), %r10 + movq %r10, 0x2c8(%rsp) + leaq 0xb30(%rdi), %r10 + movq %r10, 0x2c0(%rsp) + leaq 0xb40(%rdi), %r10 + movq %r10, 0x2b8(%rsp) + leaq 0xb50(%rdi), %r10 + movq %r10, 0x2b0(%rsp) + leaq 0xb60(%rdi), %r10 + movq %r10, 0x2a8(%rsp) + leaq 0xb70(%rdi), %r10 + movq %r10, 0x2a0(%rsp) + leaq 0xb80(%rdi), %r10 + movq %r10, 0x298(%rsp) + leaq 0xb90(%rdi), %r10 + movq %r10, 0x290(%rsp) + leaq 0xba0(%rdi), %r10 + movq %r10, 0x288(%rsp) + leaq 0xbb0(%rdi), %r10 + movq %r10, 0x280(%rsp) + leaq 0xbc0(%rdi), %r10 + movq %r10, 0x278(%rsp) + leaq 0xbd0(%rdi), %r10 + movq %r10, 0x270(%rsp) + leaq 0xbe0(%rdi), %r10 + movq %r10, 0x268(%rsp) + leaq 0xbf0(%rdi), %r10 + movq %r10, 0x260(%rsp) + leaq 0xc00(%rdi), %r10 + movq %r10, 0x258(%rsp) + leaq 0xc10(%rdi), %r10 + movq %r10, 0x250(%rsp) + leaq 0xc20(%rdi), %r10 + movq %r10, 0x248(%rsp) + leaq 0xc30(%rdi), %r10 + movq %r10, 0x240(%rsp) + leaq 0xc40(%rdi), %r10 + movq %r10, 0x238(%rsp) + leaq 0xc50(%rdi), %r10 + movq %r10, 0x230(%rsp) + leaq 0xc60(%rdi), %r10 + movq %r10, 0x228(%rsp) + leaq 0xc70(%rdi), %r10 + movq %r10, 0x220(%rsp) + leaq 0xc80(%rdi), %r10 + movq %r10, 0x218(%rsp) + leaq 0xc90(%rdi), %r10 + movq %r10, 0x210(%rsp) + leaq 0xca0(%rdi), %r10 + movq %r10, 0x208(%rsp) + leaq 0xcb0(%rdi), %r10 + movq %r10, 0x200(%rsp) + leaq 0xcc0(%rdi), %r10 + movq %r10, 0x1f8(%rsp) + leaq 0xcd0(%rdi), %r10 + movq %r10, 0x1f0(%rsp) + leaq 0xce0(%rdi), %r10 + movq %r10, 0x1e8(%rsp) + leaq 0xcf0(%rdi), %r10 + movq %r10, 0x1e0(%rsp) + leaq 0xd00(%rdi), %r10 + movq %r10, 0x1d8(%rsp) + leaq 0xd10(%rdi), %r10 + movq %r10, 0x1d0(%rsp) + leaq 0xd20(%rdi), %r10 + movq %r10, 0x1c8(%rsp) + leaq 0xd30(%rdi), %r10 + movq %r10, 0x1c0(%rsp) + leaq 0xd40(%rdi), %r10 + movq %r10, 0x1b8(%rsp) + leaq 0xd50(%rdi), %r10 + movq %r10, 0x1b0(%rsp) + leaq 0xd60(%rdi), %r10 + movq %r10, 0x1a8(%rsp) + leaq 0xd70(%rdi), %r10 + movq %r10, 0x1a0(%rsp) + leaq 0xd80(%rdi), %r10 + movq %r10, 0x198(%rsp) + leaq 0xd90(%rdi), %r10 + movq %r10, 0x190(%rsp) + leaq 0xda0(%rdi), %r10 + movq %r10, 0x188(%rsp) + leaq 0xdb0(%rdi), %r10 + movq %r10, 0x180(%rsp) + leaq 0xdc0(%rdi), %r10 + movq %r10, 0x178(%rsp) + leaq 0xdd0(%rdi), %r10 + movq %r10, 0x170(%rsp) + leaq 0xde0(%rdi), %r10 + movq %r10, 0x168(%rsp) + leaq 0xdf0(%rdi), %r10 + movq %r10, 0x160(%rsp) + leaq 0xe00(%rdi), %r10 + movq %r10, 0x158(%rsp) + leaq 0xe10(%rdi), %r10 + movq %r10, 0x150(%rsp) + leaq 0xe20(%rdi), %r10 + movq %r10, 0x148(%rsp) + leaq 0xe30(%rdi), %r10 + movq %r10, 0x140(%rsp) + leaq 0xe40(%rdi), %r10 + movq %r10, 0x138(%rsp) + leaq 0xe50(%rdi), %r10 + movq %r10, 0x130(%rsp) + leaq 0xe60(%rdi), %r10 + movq %r10, 0x128(%rsp) + leaq 0xe70(%rdi), %r10 + movq %r10, 0x120(%rsp) + leaq 0xe80(%rdi), %r10 + movq %r10, 0x118(%rsp) + leaq 0xe90(%rdi), %r10 + movq %r10, 0x110(%rsp) + leaq 0xea0(%rdi), %r10 + movq %r10, 0x108(%rsp) + leaq 0xeb0(%rdi), %r10 + movq %r10, 0x100(%rsp) + leaq 0xec0(%rdi), %r10 + movq %r10, 0xf8(%rsp) + leaq 0xed0(%rdi), %r10 + movq %r10, 0xf0(%rsp) + leaq 0xee0(%rdi), %r10 + movq %r10, 0xe8(%rsp) + leaq 0xef0(%rdi), %r10 + movq %r10, 0xe0(%rsp) + leaq 0xf00(%rdi), %r10 + movq %r10, 0xd8(%rsp) + leaq 0xf10(%rdi), %r10 + movq %r10, 0xd0(%rsp) + leaq 0xf20(%rdi), %r10 + movq %r10, 0xc8(%rsp) + leaq 0xf30(%rdi), %r10 + movq %r10, 0xc0(%rsp) + leaq 0xf40(%rdi), %r10 + movq %r10, 0xb8(%rsp) + leaq 0xf50(%rdi), %r10 + movq %r10, 0xb0(%rsp) + leaq 0xf60(%rdi), %r10 + movq %r10, 0xa8(%rsp) + leaq 0xf70(%rdi), %r10 + movq %r10, 0xa0(%rsp) + leaq 0xf80(%rdi), %r10 + movq %r10, 0x98(%rsp) + leaq 0xf90(%rdi), %r10 + movq %r10, 0x90(%rsp) + leaq 0xfa0(%rdi), %r10 + movq %r10, 0x88(%rsp) + leaq 0xfb0(%rdi), %r10 + movq %r10, 0x80(%rsp) + leaq 0xfc0(%rdi), %r10 + movq %r10, 0x78(%rsp) + leaq 0xfd0(%rdi), %r10 + movq %r10, 0x70(%rsp) + leaq 0xfe0(%rdi), %r10 + movq %r10, 0x68(%rsp) + leaq 0xff0(%rdi), %r10 + movq %r10, 0x60(%rsp) + leaq 0x1000(%rdi), %r10 + movq %r10, 0x58(%rsp) + leaq 0x1010(%rdi), %r10 + movq %r10, 0x50(%rsp) + leaq 0x1020(%rdi), %r10 + movq %r10, 0x48(%rsp) + leaq 0x1030(%rdi), %r10 + movq %r10, 0x40(%rsp) + leaq 0x1040(%rdi), %r10 + movq %r10, 0x38(%rsp) + subq $0x1020, %rsp # imm = 0x1020 + movq %rcx, %r10 + movq (%r10), %r11 + movq %r11, (%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8(%rsp) + movq %r8, %r10 + movq (%r10), %r11 + movq %r11, 0x10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x18(%rsp) + movq %r9, %r10 + movq (%r10), %r11 + movq %r11, 0x20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x28(%rsp) + movq %rax, %r10 + movq (%r10), %r11 + movq %r11, 0x30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x38(%rsp) + movq %r13, %r10 + movq (%r10), %r11 + movq %r11, 0x40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x48(%rsp) + movq %r14, %r10 + movq (%r10), %r11 + movq %r11, 0x50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x58(%rsp) + movq %r15, %r10 + movq (%r10), %r11 + movq %r11, 0x60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x68(%rsp) + movq 0x1828(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x78(%rsp) + movq 0x1820(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x88(%rsp) + movq 0x1818(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x98(%rsp) + movq 0x1810(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa8(%rsp) + movq 0x1808(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb8(%rsp) + movq 0x1800(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc8(%rsp) + movq 0x17f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd8(%rsp) + movq 0x17f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe8(%rsp) + movq 0x17e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf8(%rsp) + movq 0x17e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x100(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x108(%rsp) + movq 0x17d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x110(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x118(%rsp) + movq 0x17d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x120(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x128(%rsp) + movq 0x17c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x130(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x138(%rsp) + movq 0x17c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x140(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x148(%rsp) + movq 0x17b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x150(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x158(%rsp) + movq 0x17b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x160(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x168(%rsp) + movq 0x17a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x170(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x178(%rsp) + movq 0x17a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x180(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x188(%rsp) + movq 0x1798(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x190(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x198(%rsp) + movq 0x1790(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1a8(%rsp) + movq 0x1788(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1b8(%rsp) + movq 0x1780(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1c8(%rsp) + movq 0x1778(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1d8(%rsp) + movq 0x1770(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1e8(%rsp) + movq 0x1768(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1f8(%rsp) + movq 0x1760(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x200(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x208(%rsp) + movq 0x1758(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x210(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x218(%rsp) + movq 0x1750(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x220(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x228(%rsp) + movq 0x1748(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x230(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x238(%rsp) + movq 0x1740(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x240(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x248(%rsp) + movq 0x1738(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x250(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x258(%rsp) + movq 0x1730(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x260(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x268(%rsp) + movq 0x1728(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x270(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x278(%rsp) + movq 0x1720(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x280(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x288(%rsp) + movq 0x1718(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x290(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x298(%rsp) + movq 0x1710(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2a8(%rsp) + movq 0x1708(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2b8(%rsp) + movq 0x1700(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2c8(%rsp) + movq 0x16f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2d8(%rsp) + movq 0x16f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2e8(%rsp) + movq 0x16e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2f8(%rsp) + movq 0x16e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x300(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x308(%rsp) + movq 0x16d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x310(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x318(%rsp) + movq 0x16d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x320(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x328(%rsp) + movq 0x16c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x330(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x338(%rsp) + movq 0x16c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x340(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x348(%rsp) + movq 0x16b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x350(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x358(%rsp) + movq 0x16b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x360(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x368(%rsp) + movq 0x16a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x370(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x378(%rsp) + movq 0x16a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x380(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x388(%rsp) + movq 0x1698(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x390(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x398(%rsp) + movq 0x1690(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3a8(%rsp) + movq 0x1688(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3b8(%rsp) + movq 0x1680(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3c8(%rsp) + movq 0x1678(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3d8(%rsp) + movq 0x1670(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3e8(%rsp) + movq 0x1668(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3f8(%rsp) + movq 0x1660(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x400(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x408(%rsp) + movq 0x1658(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x410(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x418(%rsp) + movq 0x1650(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x420(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x428(%rsp) + movq 0x1648(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x430(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x438(%rsp) + movq 0x1640(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x440(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x448(%rsp) + movq 0x1638(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x450(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x458(%rsp) + movq 0x1630(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x460(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x468(%rsp) + movq 0x1628(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x470(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x478(%rsp) + movq 0x1620(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x480(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x488(%rsp) + movq 0x1618(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x490(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x498(%rsp) + movq 0x1610(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4a8(%rsp) + movq 0x1608(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4b8(%rsp) + movq 0x1600(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4c8(%rsp) + movq 0x15f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4d8(%rsp) + movq 0x15f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4e8(%rsp) + movq 0x15e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4f8(%rsp) + movq 0x15e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x500(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x508(%rsp) + movq 0x15d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x510(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x518(%rsp) + movq 0x15d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x520(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x528(%rsp) + movq 0x15c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x530(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x538(%rsp) + movq 0x15c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x540(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x548(%rsp) + movq 0x15b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x550(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x558(%rsp) + movq 0x15b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x560(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x568(%rsp) + movq 0x15a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x570(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x578(%rsp) + movq 0x15a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x580(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x588(%rsp) + movq 0x1598(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x590(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x598(%rsp) + movq 0x1590(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5a8(%rsp) + movq 0x1588(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5b8(%rsp) + movq 0x1580(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5c8(%rsp) + movq 0x1578(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5d8(%rsp) + movq 0x1570(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5e8(%rsp) + movq 0x1568(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5f8(%rsp) + movq 0x1560(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x600(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x608(%rsp) + movq 0x1558(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x610(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x618(%rsp) + movq 0x1550(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x620(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x628(%rsp) + movq 0x1548(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x630(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x638(%rsp) + movq 0x1540(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x640(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x648(%rsp) + movq 0x1538(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x650(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x658(%rsp) + movq 0x1530(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x660(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x668(%rsp) + movq 0x1528(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x670(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x678(%rsp) + movq 0x1520(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x680(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x688(%rsp) + movq 0x1518(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x690(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x698(%rsp) + movq 0x1510(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6a8(%rsp) + movq 0x1508(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6b8(%rsp) + movq 0x1500(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6c8(%rsp) + movq 0x14f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6d8(%rsp) + movq 0x14f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6e8(%rsp) + movq 0x14e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6f8(%rsp) + movq 0x14e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x700(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x708(%rsp) + movq 0x14d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x710(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x718(%rsp) + movq 0x14d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x720(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x728(%rsp) + movq 0x14c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x730(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x738(%rsp) + movq 0x14c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x740(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x748(%rsp) + movq 0x14b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x750(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x758(%rsp) + movq 0x14b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x760(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x768(%rsp) + movq 0x14a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x770(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x778(%rsp) + movq 0x14a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x780(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x788(%rsp) + movq 0x1498(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x790(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x798(%rsp) + movq 0x1490(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7a8(%rsp) + movq 0x1488(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7b8(%rsp) + movq 0x1480(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7c8(%rsp) + movq 0x1478(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7d8(%rsp) + movq 0x1470(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7e8(%rsp) + movq 0x1468(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7f8(%rsp) + movq 0x1460(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x800(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x808(%rsp) + movq 0x1458(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x810(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x818(%rsp) + movq 0x1450(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x820(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x828(%rsp) + movq 0x1448(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x830(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x838(%rsp) + movq 0x1440(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x840(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x848(%rsp) + movq 0x1438(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x850(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x858(%rsp) + movq 0x1430(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x860(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x868(%rsp) + movq 0x1428(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x870(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x878(%rsp) + movq 0x1420(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x880(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x888(%rsp) + movq 0x1418(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x890(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x898(%rsp) + movq 0x1410(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8a8(%rsp) + movq 0x1408(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8b8(%rsp) + movq 0x1400(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8c8(%rsp) + movq 0x13f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8d8(%rsp) + movq 0x13f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8e8(%rsp) + movq 0x13e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8f8(%rsp) + movq 0x13e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x900(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x908(%rsp) + movq 0x13d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x910(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x918(%rsp) + movq 0x13d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x920(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x928(%rsp) + movq 0x13c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x930(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x938(%rsp) + movq 0x13c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x940(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x948(%rsp) + movq 0x13b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x950(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x958(%rsp) + movq 0x13b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x960(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x968(%rsp) + movq 0x13a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x970(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x978(%rsp) + movq 0x13a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x980(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x988(%rsp) + movq 0x1398(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x990(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x998(%rsp) + movq 0x1390(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9a8(%rsp) + movq 0x1388(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9b8(%rsp) + movq 0x1380(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9c8(%rsp) + movq 0x1378(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9d8(%rsp) + movq 0x1370(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9e8(%rsp) + movq 0x1368(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9f8(%rsp) + movq 0x1360(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa08(%rsp) + movq 0x1358(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa18(%rsp) + movq 0x1350(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa28(%rsp) + movq 0x1348(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa38(%rsp) + movq 0x1340(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa48(%rsp) + movq 0x1338(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa58(%rsp) + movq 0x1330(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa68(%rsp) + movq 0x1328(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa78(%rsp) + movq 0x1320(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa88(%rsp) + movq 0x1318(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa98(%rsp) + movq 0x1310(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xaa0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xaa8(%rsp) + movq 0x1308(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xab0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xab8(%rsp) + movq 0x1300(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xac0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xac8(%rsp) + movq 0x12f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xad0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xad8(%rsp) + movq 0x12f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xae0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xae8(%rsp) + movq 0x12e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xaf0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xaf8(%rsp) + movq 0x12e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb08(%rsp) + movq 0x12d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb18(%rsp) + movq 0x12d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb28(%rsp) + movq 0x12c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb38(%rsp) + movq 0x12c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb48(%rsp) + movq 0x12b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb58(%rsp) + movq 0x12b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb68(%rsp) + movq 0x12a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb78(%rsp) + movq 0x12a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb88(%rsp) + movq 0x1298(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb98(%rsp) + movq 0x1290(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xba0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xba8(%rsp) + movq 0x1288(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xbb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xbb8(%rsp) + movq 0x1280(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xbc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xbc8(%rsp) + movq 0x1278(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xbd0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xbd8(%rsp) + movq 0x1270(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xbe0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xbe8(%rsp) + movq 0x1268(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xbf0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xbf8(%rsp) + movq 0x1260(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc08(%rsp) + movq 0x1258(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc18(%rsp) + movq 0x1250(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc28(%rsp) + movq 0x1248(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc38(%rsp) + movq 0x1240(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc48(%rsp) + movq 0x1238(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc58(%rsp) + movq 0x1230(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc68(%rsp) + movq 0x1228(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc78(%rsp) + movq 0x1220(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc88(%rsp) + movq 0x1218(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc98(%rsp) + movq 0x1210(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xca0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xca8(%rsp) + movq 0x1208(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xcb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xcb8(%rsp) + movq 0x1200(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xcc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xcc8(%rsp) + movq 0x11f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xcd0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xcd8(%rsp) + movq 0x11f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xce0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xce8(%rsp) + movq 0x11e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xcf0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xcf8(%rsp) + movq 0x11e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd08(%rsp) + movq 0x11d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd18(%rsp) + movq 0x11d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd28(%rsp) + movq 0x11c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd38(%rsp) + movq 0x11c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd48(%rsp) + movq 0x11b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd58(%rsp) + movq 0x11b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd68(%rsp) + movq 0x11a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd78(%rsp) + movq 0x11a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd88(%rsp) + movq 0x1198(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd98(%rsp) + movq 0x1190(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xda0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xda8(%rsp) + movq 0x1188(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xdb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xdb8(%rsp) + movq 0x1180(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xdc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xdc8(%rsp) + movq 0x1178(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xdd0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xdd8(%rsp) + movq 0x1170(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xde0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xde8(%rsp) + movq 0x1168(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xdf0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xdf8(%rsp) + movq 0x1160(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe08(%rsp) + movq 0x1158(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe18(%rsp) + movq 0x1150(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe28(%rsp) + movq 0x1148(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe38(%rsp) + movq 0x1140(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe48(%rsp) + movq 0x1138(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe58(%rsp) + movq 0x1130(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe68(%rsp) + movq 0x1128(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe78(%rsp) + movq 0x1120(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe88(%rsp) + movq 0x1118(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe98(%rsp) + movq 0x1110(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xea0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xea8(%rsp) + movq 0x1108(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xeb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xeb8(%rsp) + movq 0x1100(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xec0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xec8(%rsp) + movq 0x10f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xed0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xed8(%rsp) + movq 0x10f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xee0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xee8(%rsp) + movq 0x10e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xef0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xef8(%rsp) + movq 0x10e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf08(%rsp) + movq 0x10d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf18(%rsp) + movq 0x10d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf28(%rsp) + movq 0x10c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf38(%rsp) + movq 0x10c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf48(%rsp) + movq 0x10b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf58(%rsp) + movq 0x10b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf68(%rsp) + movq 0x10a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf78(%rsp) + movq 0x10a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf88(%rsp) + movq 0x1098(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf98(%rsp) + movq 0x1090(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xfa0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xfa8(%rsp) + movq 0x1088(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xfb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xfb8(%rsp) + movq 0x1080(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xfc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xfc8(%rsp) + movq 0x1078(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xfd0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xfd8(%rsp) + movq 0x1070(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xfe0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xfe8(%rsp) + movq 0x1068(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xff0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xff8(%rsp) + movq 0x1060(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1000(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1008(%rsp) + movq 0x1058(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1010(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1018(%rsp) + movq %rdx, %r8 + movq %rsi, %rdx + movq 0x8(%rdi), %rsi + movq (%rdi), %rdi + movq 0x8(%rdx), %rcx + movq (%rdx), %rdx + movq 0x8(%r8), %r9 + movq (%r8), %r8 + callq + addq $0x1020, %rsp # imm = 0x1020 + cmpq $0x18d9e, %rax # imm = 0x18D9E + je + movl $0x1, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + addq $0x1050, %rsp # imm = 0x1050 + popq %rbp + retq + movl $0x1, %edi + movl $0x2, %esi + movl $0x3, %edx + movl $0x4, %ecx + movl $0x5, %r8d + movl $0x6, %r9d + movl $0x7, %eax + movl $0x8, %r13d + movl $0x9, %r14d + movl $0xa, %r15d + movl $0xb, %r10d + movq %r10, 0x808(%rsp) + movl $0xc, %r10d + movq %r10, 0x800(%rsp) + movl $0xd, %r10d + movq %r10, 0x7f8(%rsp) + movl $0xe, %r10d + movq %r10, 0x7f0(%rsp) + movl $0xf, %r10d + movq %r10, 0x7e8(%rsp) + movl $0x10, %r10d + movq %r10, 0x7e0(%rsp) + movl $0x11, %r10d + movq %r10, 0x7d8(%rsp) + movl $0x12, %r10d + movq %r10, 0x7d0(%rsp) + movl $0x13, %r10d + movq %r10, 0x7c8(%rsp) + movl $0x14, %r10d + movq %r10, 0x7c0(%rsp) + movl $0x15, %r10d + movq %r10, 0x7b8(%rsp) + movl $0x16, %r10d + movq %r10, 0x7b0(%rsp) + movl $0x17, %r10d + movq %r10, 0x7a8(%rsp) + movl $0x18, %r10d + movq %r10, 0x7a0(%rsp) + movl $0x19, %r10d + movq %r10, 0x798(%rsp) + movl $0x1a, %r10d + movq %r10, 0x790(%rsp) + movl $0x1b, %r10d + movq %r10, 0x788(%rsp) + movl $0x1c, %r10d + movq %r10, 0x780(%rsp) + movl $0x1d, %r10d + movq %r10, 0x778(%rsp) + movl $0x1e, %r10d + movq %r10, 0x770(%rsp) + movl $0x1f, %r10d + movq %r10, 0x768(%rsp) + movl $0x20, %r10d + movq %r10, 0x760(%rsp) + movl $0x21, %r10d + movq %r10, 0x758(%rsp) + movl $0x22, %r10d + movq %r10, 0x750(%rsp) + movl $0x23, %r10d + movq %r10, 0x748(%rsp) + movl $0x24, %r10d + movq %r10, 0x740(%rsp) + movl $0x25, %r10d + movq %r10, 0x738(%rsp) + movl $0x26, %r10d + movq %r10, 0x730(%rsp) + movl $0x27, %r10d + movq %r10, 0x728(%rsp) + movl $0x28, %r10d + movq %r10, 0x720(%rsp) + movl $0x29, %r10d + movq %r10, 0x718(%rsp) + movl $0x2a, %r10d + movq %r10, 0x710(%rsp) + movl $0x2b, %r10d + movq %r10, 0x708(%rsp) + movl $0x2c, %r10d + movq %r10, 0x700(%rsp) + movl $0x2d, %r10d + movq %r10, 0x6f8(%rsp) + movl $0x2e, %r10d + movq %r10, 0x6f0(%rsp) + movl $0x2f, %r10d + movq %r10, 0x6e8(%rsp) + movl $0x30, %r10d + movq %r10, 0x6e0(%rsp) + movl $0x31, %r10d + movq %r10, 0x6d8(%rsp) + movl $0x32, %r10d + movq %r10, 0x6d0(%rsp) + movl $0x33, %r10d + movq %r10, 0x6c8(%rsp) + movl $0x34, %r10d + movq %r10, 0x6c0(%rsp) + movl $0x35, %r10d + movq %r10, 0x6b8(%rsp) + movl $0x36, %r10d + movq %r10, 0x6b0(%rsp) + movl $0x37, %r10d + movq %r10, 0x6a8(%rsp) + movl $0x38, %r10d + movq %r10, 0x6a0(%rsp) + movl $0x39, %r10d + movq %r10, 0x698(%rsp) + movl $0x3a, %r10d + movq %r10, 0x690(%rsp) + movl $0x3b, %r10d + movq %r10, 0x688(%rsp) + movl $0x3c, %r10d + movq %r10, 0x680(%rsp) + movl $0x3d, %r10d + movq %r10, 0x678(%rsp) + movl $0x3e, %r10d + movq %r10, 0x670(%rsp) + movl $0x3f, %r10d + movq %r10, 0x668(%rsp) + movl $0x40, %r10d + movq %r10, 0x660(%rsp) + movl $0x41, %r10d + movq %r10, 0x658(%rsp) + movl $0x42, %r10d + movq %r10, 0x650(%rsp) + movl $0x43, %r10d + movq %r10, 0x648(%rsp) + movl $0x44, %r10d + movq %r10, 0x640(%rsp) + movl $0x45, %r10d + movq %r10, 0x638(%rsp) + movl $0x46, %r10d + movq %r10, 0x630(%rsp) + movl $0x47, %r10d + movq %r10, 0x628(%rsp) + movl $0x48, %r10d + movq %r10, 0x620(%rsp) + movl $0x49, %r10d + movq %r10, 0x618(%rsp) + movl $0x4a, %r10d + movq %r10, 0x610(%rsp) + movl $0x4b, %r10d + movq %r10, 0x608(%rsp) + movl $0x4c, %r10d + movq %r10, 0x600(%rsp) + movl $0x4d, %r10d + movq %r10, 0x5f8(%rsp) + movl $0x4e, %r10d + movq %r10, 0x5f0(%rsp) + movl $0x4f, %r10d + movq %r10, 0x5e8(%rsp) + movl $0x50, %r10d + movq %r10, 0x5e0(%rsp) + movl $0x51, %r10d + movq %r10, 0x5d8(%rsp) + movl $0x52, %r10d + movq %r10, 0x5d0(%rsp) + movl $0x53, %r10d + movq %r10, 0x5c8(%rsp) + movl $0x54, %r10d + movq %r10, 0x5c0(%rsp) + movl $0x55, %r10d + movq %r10, 0x5b8(%rsp) + movl $0x56, %r10d + movq %r10, 0x5b0(%rsp) + movl $0x57, %r10d + movq %r10, 0x5a8(%rsp) + movl $0x58, %r10d + movq %r10, 0x5a0(%rsp) + movl $0x59, %r10d + movq %r10, 0x598(%rsp) + movl $0x5a, %r10d + movq %r10, 0x590(%rsp) + movl $0x5b, %r10d + movq %r10, 0x588(%rsp) + movl $0x5c, %r10d + movq %r10, 0x580(%rsp) + movl $0x5d, %r10d + movq %r10, 0x578(%rsp) + movl $0x5e, %r10d + movq %r10, 0x570(%rsp) + movl $0x5f, %r10d + movq %r10, 0x568(%rsp) + movl $0x60, %r10d + movq %r10, 0x560(%rsp) + movl $0x61, %r10d + movq %r10, 0x558(%rsp) + movl $0x62, %r10d + movq %r10, 0x550(%rsp) + movl $0x63, %r10d + movq %r10, 0x548(%rsp) + movl $0x64, %r10d + movq %r10, 0x540(%rsp) + movl $0x65, %r10d + movq %r10, 0x538(%rsp) + movl $0x66, %r10d + movq %r10, 0x530(%rsp) + movl $0x67, %r10d + movq %r10, 0x528(%rsp) + movl $0x68, %r10d + movq %r10, 0x520(%rsp) + movl $0x69, %r10d + movq %r10, 0x518(%rsp) + movl $0x6a, %r10d + movq %r10, 0x510(%rsp) + movl $0x6b, %r10d + movq %r10, 0x508(%rsp) + movl $0x6c, %r10d + movq %r10, 0x500(%rsp) + movl $0x6d, %r10d + movq %r10, 0x4f8(%rsp) + movl $0x6e, %r10d + movq %r10, 0x4f0(%rsp) + movl $0x6f, %r10d + movq %r10, 0x4e8(%rsp) + movl $0x70, %r10d + movq %r10, 0x4e0(%rsp) + movl $0x71, %r10d + movq %r10, 0x4d8(%rsp) + movl $0x72, %r10d + movq %r10, 0x4d0(%rsp) + movl $0x73, %r10d + movq %r10, 0x4c8(%rsp) + movl $0x74, %r10d + movq %r10, 0x4c0(%rsp) + movl $0x75, %r10d + movq %r10, 0x4b8(%rsp) + movl $0x76, %r10d + movq %r10, 0x4b0(%rsp) + movl $0x77, %r10d + movq %r10, 0x4a8(%rsp) + movl $0x78, %r10d + movq %r10, 0x4a0(%rsp) + movl $0x79, %r10d + movq %r10, 0x498(%rsp) + movl $0x7a, %r10d + movq %r10, 0x490(%rsp) + movl $0x7b, %r10d + movq %r10, 0x488(%rsp) + movl $0x7c, %r10d + movq %r10, 0x480(%rsp) + movl $0x7d, %r10d + movq %r10, 0x478(%rsp) + movl $0x7e, %r10d + movq %r10, 0x470(%rsp) + movl $0x7f, %r10d + movq %r10, 0x468(%rsp) + movl $0x80, %r10d + movq %r10, 0x460(%rsp) + movl $0x81, %r10d + movq %r10, 0x458(%rsp) + movl $0x82, %r10d + movq %r10, 0x450(%rsp) + movl $0x83, %r10d + movq %r10, 0x448(%rsp) + movl $0x84, %r10d + movq %r10, 0x440(%rsp) + movl $0x85, %r10d + movq %r10, 0x438(%rsp) + movl $0x86, %r10d + movq %r10, 0x430(%rsp) + movl $0x87, %r10d + movq %r10, 0x428(%rsp) + movl $0x88, %r10d + movq %r10, 0x420(%rsp) + movl $0x89, %r10d + movq %r10, 0x418(%rsp) + movl $0x8a, %r10d + movq %r10, 0x410(%rsp) + movl $0x8b, %r10d + movq %r10, 0x408(%rsp) + movl $0x8c, %r10d + movq %r10, 0x400(%rsp) + movl $0x8d, %r10d + movq %r10, 0x3f8(%rsp) + movl $0x8e, %r10d + movq %r10, 0x3f0(%rsp) + movl $0x8f, %r10d + movq %r10, 0x3e8(%rsp) + movl $0x90, %r10d + movq %r10, 0x3e0(%rsp) + movl $0x91, %r10d + movq %r10, 0x3d8(%rsp) + movl $0x92, %r10d + movq %r10, 0x3d0(%rsp) + movl $0x93, %r10d + movq %r10, 0x3c8(%rsp) + movl $0x94, %r10d + movq %r10, 0x3c0(%rsp) + movl $0x95, %r10d + movq %r10, 0x3b8(%rsp) + movl $0x96, %r10d + movq %r10, 0x3b0(%rsp) + movl $0x97, %r10d + movq %r10, 0x3a8(%rsp) + movl $0x98, %r10d + movq %r10, 0x3a0(%rsp) + movl $0x99, %r10d + movq %r10, 0x398(%rsp) + movl $0x9a, %r10d + movq %r10, 0x390(%rsp) + movl $0x9b, %r10d + movq %r10, 0x388(%rsp) + movl $0x9c, %r10d + movq %r10, 0x380(%rsp) + movl $0x9d, %r10d + movq %r10, 0x378(%rsp) + movl $0x9e, %r10d + movq %r10, 0x370(%rsp) + movl $0x9f, %r10d + movq %r10, 0x368(%rsp) + movl $0xa0, %r10d + movq %r10, 0x360(%rsp) + movl $0xa1, %r10d + movq %r10, 0x358(%rsp) + movl $0xa2, %r10d + movq %r10, 0x350(%rsp) + movl $0xa3, %r10d + movq %r10, 0x348(%rsp) + movl $0xa4, %r10d + movq %r10, 0x340(%rsp) + movl $0xa5, %r10d + movq %r10, 0x338(%rsp) + movl $0xa6, %r10d + movq %r10, 0x330(%rsp) + movl $0xa7, %r10d + movq %r10, 0x328(%rsp) + movl $0xa8, %r10d + movq %r10, 0x320(%rsp) + movl $0xa9, %r10d + movq %r10, 0x318(%rsp) + movl $0xaa, %r10d + movq %r10, 0x310(%rsp) + movl $0xab, %r10d + movq %r10, 0x308(%rsp) + movl $0xac, %r10d + movq %r10, 0x300(%rsp) + movl $0xad, %r10d + movq %r10, 0x2f8(%rsp) + movl $0xae, %r10d + movq %r10, 0x2f0(%rsp) + movl $0xaf, %r10d + movq %r10, 0x2e8(%rsp) + movl $0xb0, %r10d + movq %r10, 0x2e0(%rsp) + movl $0xb1, %r10d + movq %r10, 0x2d8(%rsp) + movl $0xb2, %r10d + movq %r10, 0x2d0(%rsp) + movl $0xb3, %r10d + movq %r10, 0x2c8(%rsp) + movl $0xb4, %r10d + movq %r10, 0x2c0(%rsp) + movl $0xb5, %r10d + movq %r10, 0x2b8(%rsp) + movl $0xb6, %r10d + movq %r10, 0x2b0(%rsp) + movl $0xb7, %r10d + movq %r10, 0x2a8(%rsp) + movl $0xb8, %r10d + movq %r10, 0x2a0(%rsp) + movl $0xb9, %r10d + movq %r10, 0x298(%rsp) + movl $0xba, %r10d + movq %r10, 0x290(%rsp) + movl $0xbb, %r10d + movq %r10, 0x288(%rsp) + movl $0xbc, %r10d + movq %r10, 0x280(%rsp) + movl $0xbd, %r10d + movq %r10, 0x278(%rsp) + movl $0xbe, %r10d + movq %r10, 0x270(%rsp) + movl $0xbf, %r10d + movq %r10, 0x268(%rsp) + movl $0xc0, %r10d + movq %r10, 0x260(%rsp) + movl $0xc1, %r10d + movq %r10, 0x258(%rsp) + movl $0xc2, %r10d + movq %r10, 0x250(%rsp) + movl $0xc3, %r10d + movq %r10, 0x248(%rsp) + movl $0xc4, %r10d + movq %r10, 0x240(%rsp) + movl $0xc5, %r10d + movq %r10, 0x238(%rsp) + movl $0xc6, %r10d + movq %r10, 0x230(%rsp) + movl $0xc7, %r10d + movq %r10, 0x228(%rsp) + movl $0xc8, %r10d + movq %r10, 0x220(%rsp) + movl $0xc9, %r10d + movq %r10, 0x218(%rsp) + movl $0xca, %r10d + movq %r10, 0x210(%rsp) + movl $0xcb, %r10d + movq %r10, 0x208(%rsp) + movl $0xcc, %r10d + movq %r10, 0x200(%rsp) + movl $0xcd, %r10d + movq %r10, 0x1f8(%rsp) + movl $0xce, %r10d + movq %r10, 0x1f0(%rsp) + movl $0xcf, %r10d + movq %r10, 0x1e8(%rsp) + movl $0xd0, %r10d + movq %r10, 0x1e0(%rsp) + movl $0xd1, %r10d + movq %r10, 0x1d8(%rsp) + movl $0xd2, %r10d + movq %r10, 0x1d0(%rsp) + movl $0xd3, %r10d + movq %r10, 0x1c8(%rsp) + movl $0xd4, %r10d + movq %r10, 0x1c0(%rsp) + movl $0xd5, %r10d + movq %r10, 0x1b8(%rsp) + movl $0xd6, %r10d + movq %r10, 0x1b0(%rsp) + movl $0xd7, %r10d + movq %r10, 0x1a8(%rsp) + movl $0xd8, %r10d + movq %r10, 0x1a0(%rsp) + movl $0xd9, %r10d + movq %r10, 0x198(%rsp) + movl $0xda, %r10d + movq %r10, 0x190(%rsp) + movl $0xdb, %r10d + movq %r10, 0x188(%rsp) + movl $0xdc, %r10d + movq %r10, 0x180(%rsp) + movl $0xdd, %r10d + movq %r10, 0x178(%rsp) + movl $0xde, %r10d + movq %r10, 0x170(%rsp) + movl $0xdf, %r10d + movq %r10, 0x168(%rsp) + movl $0xe0, %r10d + movq %r10, 0x160(%rsp) + movl $0xe1, %r10d + movq %r10, 0x158(%rsp) + movl $0xe2, %r10d + movq %r10, 0x150(%rsp) + movl $0xe3, %r10d + movq %r10, 0x148(%rsp) + movl $0xe4, %r10d + movq %r10, 0x140(%rsp) + movl $0xe5, %r10d + movq %r10, 0x138(%rsp) + movl $0xe6, %r10d + movq %r10, 0x130(%rsp) + movl $0xe7, %r10d + movq %r10, 0x128(%rsp) + movl $0xe8, %r10d + movq %r10, 0x120(%rsp) + movl $0xe9, %r10d + movq %r10, 0x118(%rsp) + movl $0xea, %r10d + movq %r10, 0x110(%rsp) + movl $0xeb, %r10d + movq %r10, 0x108(%rsp) + movl $0xec, %r10d + movq %r10, 0x100(%rsp) + movl $0xed, %r10d + movq %r10, 0xf8(%rsp) + movl $0xee, %r10d + movq %r10, 0xf0(%rsp) + movl $0xef, %r10d + movq %r10, 0xe8(%rsp) + movl $0xf0, %r10d + movq %r10, 0xe0(%rsp) + movl $0xf1, %r10d + movq %r10, 0xd8(%rsp) + movl $0xf2, %r10d + movq %r10, 0xd0(%rsp) + movl $0xf3, %r10d + movq %r10, 0xc8(%rsp) + movl $0xf4, %r10d + movq %r10, 0xc0(%rsp) + movl $0xf5, %r10d + movq %r10, 0xb8(%rsp) + movl $0xf6, %r10d + movq %r10, 0xb0(%rsp) + movl $0xf7, %r10d + movq %r10, 0xa8(%rsp) + movl $0xf8, %r10d + movq %r10, 0xa0(%rsp) + movl $0xf9, %r10d + movq %r10, 0x98(%rsp) + movl $0xfa, %r10d + movq %r10, 0x90(%rsp) + movl $0xfb, %r10d + movq %r10, 0x88(%rsp) + movl $0xfc, %r10d + movq %r10, 0x80(%rsp) + movl $0xfd, %r10d + movq %r10, 0x78(%rsp) + movl $0xfe, %r10d + movq %r10, 0x70(%rsp) + movl $0xff, %r10d + movq %r10, 0x68(%rsp) + movl $0x100, %r10d # imm = 0x100 + movq %r10, 0x60(%rsp) + movl $0x101, %r10d # imm = 0x101 + movq %r10, 0x58(%rsp) + movl $0x102, %r10d # imm = 0x102 + movq %r10, 0x50(%rsp) + movl $0x103, %r10d # imm = 0x103 + movq %r10, 0x48(%rsp) + movl $0x104, %r10d # imm = 0x104 + movq %r10, 0x40(%rsp) + subq $0x10, %rsp + movq %rbx, (%rsp) + subq $0x7f0, %rsp # imm = 0x7F0 + movq %rax, (%rsp) + movq %r13, 0x8(%rsp) + movq %r14, 0x10(%rsp) + movq %r15, 0x18(%rsp) + movq 0x1008(%rsp), %r10 + movq %r10, 0x20(%rsp) + movq 0x1000(%rsp), %r10 + movq %r10, 0x28(%rsp) + movq 0xff8(%rsp), %r10 + movq %r10, 0x30(%rsp) + movq 0xff0(%rsp), %r10 + movq %r10, 0x38(%rsp) + movq 0xfe8(%rsp), %r10 + movq %r10, 0x40(%rsp) + movq 0xfe0(%rsp), %r10 + movq %r10, 0x48(%rsp) + movq 0xfd8(%rsp), %r10 + movq %r10, 0x50(%rsp) + movq 0xfd0(%rsp), %r10 + movq %r10, 0x58(%rsp) + movq 0xfc8(%rsp), %r10 + movq %r10, 0x60(%rsp) + movq 0xfc0(%rsp), %r10 + movq %r10, 0x68(%rsp) + movq 0xfb8(%rsp), %r10 + movq %r10, 0x70(%rsp) + movq 0xfb0(%rsp), %r10 + movq %r10, 0x78(%rsp) + movq 0xfa8(%rsp), %r10 + movq %r10, 0x80(%rsp) + movq 0xfa0(%rsp), %r10 + movq %r10, 0x88(%rsp) + movq 0xf98(%rsp), %r10 + movq %r10, 0x90(%rsp) + movq 0xf90(%rsp), %r10 + movq %r10, 0x98(%rsp) + movq 0xf88(%rsp), %r10 + movq %r10, 0xa0(%rsp) + movq 0xf80(%rsp), %r10 + movq %r10, 0xa8(%rsp) + movq 0xf78(%rsp), %r10 + movq %r10, 0xb0(%rsp) + movq 0xf70(%rsp), %r10 + movq %r10, 0xb8(%rsp) + movq 0xf68(%rsp), %r10 + movq %r10, 0xc0(%rsp) + movq 0xf60(%rsp), %r10 + movq %r10, 0xc8(%rsp) + movq 0xf58(%rsp), %r10 + movq %r10, 0xd0(%rsp) + movq 0xf50(%rsp), %r10 + movq %r10, 0xd8(%rsp) + movq 0xf48(%rsp), %r10 + movq %r10, 0xe0(%rsp) + movq 0xf40(%rsp), %r10 + movq %r10, 0xe8(%rsp) + movq 0xf38(%rsp), %r10 + movq %r10, 0xf0(%rsp) + movq 0xf30(%rsp), %r10 + movq %r10, 0xf8(%rsp) + movq 0xf28(%rsp), %r10 + movq %r10, 0x100(%rsp) + movq 0xf20(%rsp), %r10 + movq %r10, 0x108(%rsp) + movq 0xf18(%rsp), %r10 + movq %r10, 0x110(%rsp) + movq 0xf10(%rsp), %r10 + movq %r10, 0x118(%rsp) + movq 0xf08(%rsp), %r10 + movq %r10, 0x120(%rsp) + movq 0xf00(%rsp), %r10 + movq %r10, 0x128(%rsp) + movq 0xef8(%rsp), %r10 + movq %r10, 0x130(%rsp) + movq 0xef0(%rsp), %r10 + movq %r10, 0x138(%rsp) + movq 0xee8(%rsp), %r10 + movq %r10, 0x140(%rsp) + movq 0xee0(%rsp), %r10 + movq %r10, 0x148(%rsp) + movq 0xed8(%rsp), %r10 + movq %r10, 0x150(%rsp) + movq 0xed0(%rsp), %r10 + movq %r10, 0x158(%rsp) + movq 0xec8(%rsp), %r10 + movq %r10, 0x160(%rsp) + movq 0xec0(%rsp), %r10 + movq %r10, 0x168(%rsp) + movq 0xeb8(%rsp), %r10 + movq %r10, 0x170(%rsp) + movq 0xeb0(%rsp), %r10 + movq %r10, 0x178(%rsp) + movq 0xea8(%rsp), %r10 + movq %r10, 0x180(%rsp) + movq 0xea0(%rsp), %r10 + movq %r10, 0x188(%rsp) + movq 0xe98(%rsp), %r10 + movq %r10, 0x190(%rsp) + movq 0xe90(%rsp), %r10 + movq %r10, 0x198(%rsp) + movq 0xe88(%rsp), %r10 + movq %r10, 0x1a0(%rsp) + movq 0xe80(%rsp), %r10 + movq %r10, 0x1a8(%rsp) + movq 0xe78(%rsp), %r10 + movq %r10, 0x1b0(%rsp) + movq 0xe70(%rsp), %r10 + movq %r10, 0x1b8(%rsp) + movq 0xe68(%rsp), %r10 + movq %r10, 0x1c0(%rsp) + movq 0xe60(%rsp), %r10 + movq %r10, 0x1c8(%rsp) + movq 0xe58(%rsp), %r10 + movq %r10, 0x1d0(%rsp) + movq 0xe50(%rsp), %r10 + movq %r10, 0x1d8(%rsp) + movq 0xe48(%rsp), %r10 + movq %r10, 0x1e0(%rsp) + movq 0xe40(%rsp), %r10 + movq %r10, 0x1e8(%rsp) + movq 0xe38(%rsp), %r10 + movq %r10, 0x1f0(%rsp) + movq 0xe30(%rsp), %r10 + movq %r10, 0x1f8(%rsp) + movq 0xe28(%rsp), %r10 + movq %r10, 0x200(%rsp) + movq 0xe20(%rsp), %r10 + movq %r10, 0x208(%rsp) + movq 0xe18(%rsp), %r10 + movq %r10, 0x210(%rsp) + movq 0xe10(%rsp), %r10 + movq %r10, 0x218(%rsp) + movq 0xe08(%rsp), %r10 + movq %r10, 0x220(%rsp) + movq 0xe00(%rsp), %r10 + movq %r10, 0x228(%rsp) + movq 0xdf8(%rsp), %r10 + movq %r10, 0x230(%rsp) + movq 0xdf0(%rsp), %r10 + movq %r10, 0x238(%rsp) + movq 0xde8(%rsp), %r10 + movq %r10, 0x240(%rsp) + movq 0xde0(%rsp), %r10 + movq %r10, 0x248(%rsp) + movq 0xdd8(%rsp), %r10 + movq %r10, 0x250(%rsp) + movq 0xdd0(%rsp), %r10 + movq %r10, 0x258(%rsp) + movq 0xdc8(%rsp), %r10 + movq %r10, 0x260(%rsp) + movq 0xdc0(%rsp), %r10 + movq %r10, 0x268(%rsp) + movq 0xdb8(%rsp), %r10 + movq %r10, 0x270(%rsp) + movq 0xdb0(%rsp), %r10 + movq %r10, 0x278(%rsp) + movq 0xda8(%rsp), %r10 + movq %r10, 0x280(%rsp) + movq 0xda0(%rsp), %r10 + movq %r10, 0x288(%rsp) + movq 0xd98(%rsp), %r10 + movq %r10, 0x290(%rsp) + movq 0xd90(%rsp), %r10 + movq %r10, 0x298(%rsp) + movq 0xd88(%rsp), %r10 + movq %r10, 0x2a0(%rsp) + movq 0xd80(%rsp), %r10 + movq %r10, 0x2a8(%rsp) + movq 0xd78(%rsp), %r10 + movq %r10, 0x2b0(%rsp) + movq 0xd70(%rsp), %r10 + movq %r10, 0x2b8(%rsp) + movq 0xd68(%rsp), %r10 + movq %r10, 0x2c0(%rsp) + movq 0xd60(%rsp), %r10 + movq %r10, 0x2c8(%rsp) + movq 0xd58(%rsp), %r10 + movq %r10, 0x2d0(%rsp) + movq 0xd50(%rsp), %r10 + movq %r10, 0x2d8(%rsp) + movq 0xd48(%rsp), %r10 + movq %r10, 0x2e0(%rsp) + movq 0xd40(%rsp), %r10 + movq %r10, 0x2e8(%rsp) + movq 0xd38(%rsp), %r10 + movq %r10, 0x2f0(%rsp) + movq 0xd30(%rsp), %r10 + movq %r10, 0x2f8(%rsp) + movq 0xd28(%rsp), %r10 + movq %r10, 0x300(%rsp) + movq 0xd20(%rsp), %r10 + movq %r10, 0x308(%rsp) + movq 0xd18(%rsp), %r10 + movq %r10, 0x310(%rsp) + movq 0xd10(%rsp), %r10 + movq %r10, 0x318(%rsp) + movq 0xd08(%rsp), %r10 + movq %r10, 0x320(%rsp) + movq 0xd00(%rsp), %r10 + movq %r10, 0x328(%rsp) + movq 0xcf8(%rsp), %r10 + movq %r10, 0x330(%rsp) + movq 0xcf0(%rsp), %r10 + movq %r10, 0x338(%rsp) + movq 0xce8(%rsp), %r10 + movq %r10, 0x340(%rsp) + movq 0xce0(%rsp), %r10 + movq %r10, 0x348(%rsp) + movq 0xcd8(%rsp), %r10 + movq %r10, 0x350(%rsp) + movq 0xcd0(%rsp), %r10 + movq %r10, 0x358(%rsp) + movq 0xcc8(%rsp), %r10 + movq %r10, 0x360(%rsp) + movq 0xcc0(%rsp), %r10 + movq %r10, 0x368(%rsp) + movq 0xcb8(%rsp), %r10 + movq %r10, 0x370(%rsp) + movq 0xcb0(%rsp), %r10 + movq %r10, 0x378(%rsp) + movq 0xca8(%rsp), %r10 + movq %r10, 0x380(%rsp) + movq 0xca0(%rsp), %r10 + movq %r10, 0x388(%rsp) + movq 0xc98(%rsp), %r10 + movq %r10, 0x390(%rsp) + movq 0xc90(%rsp), %r10 + movq %r10, 0x398(%rsp) + movq 0xc88(%rsp), %r10 + movq %r10, 0x3a0(%rsp) + movq 0xc80(%rsp), %r10 + movq %r10, 0x3a8(%rsp) + movq 0xc78(%rsp), %r10 + movq %r10, 0x3b0(%rsp) + movq 0xc70(%rsp), %r10 + movq %r10, 0x3b8(%rsp) + movq 0xc68(%rsp), %r10 + movq %r10, 0x3c0(%rsp) + movq 0xc60(%rsp), %r10 + movq %r10, 0x3c8(%rsp) + movq 0xc58(%rsp), %r10 + movq %r10, 0x3d0(%rsp) + movq 0xc50(%rsp), %r10 + movq %r10, 0x3d8(%rsp) + movq 0xc48(%rsp), %r10 + movq %r10, 0x3e0(%rsp) + movq 0xc40(%rsp), %r10 + movq %r10, 0x3e8(%rsp) + movq 0xc38(%rsp), %r10 + movq %r10, 0x3f0(%rsp) + movq 0xc30(%rsp), %r10 + movq %r10, 0x3f8(%rsp) + movq 0xc28(%rsp), %r10 + movq %r10, 0x400(%rsp) + movq 0xc20(%rsp), %r10 + movq %r10, 0x408(%rsp) + movq 0xc18(%rsp), %r10 + movq %r10, 0x410(%rsp) + movq 0xc10(%rsp), %r10 + movq %r10, 0x418(%rsp) + movq 0xc08(%rsp), %r10 + movq %r10, 0x420(%rsp) + movq 0xc00(%rsp), %r10 + movq %r10, 0x428(%rsp) + movq 0xbf8(%rsp), %r10 + movq %r10, 0x430(%rsp) + movq 0xbf0(%rsp), %r10 + movq %r10, 0x438(%rsp) + movq 0xbe8(%rsp), %r10 + movq %r10, 0x440(%rsp) + movq 0xbe0(%rsp), %r10 + movq %r10, 0x448(%rsp) + movq 0xbd8(%rsp), %r10 + movq %r10, 0x450(%rsp) + movq 0xbd0(%rsp), %r10 + movq %r10, 0x458(%rsp) + movq 0xbc8(%rsp), %r10 + movq %r10, 0x460(%rsp) + movq 0xbc0(%rsp), %r10 + movq %r10, 0x468(%rsp) + movq 0xbb8(%rsp), %r10 + movq %r10, 0x470(%rsp) + movq 0xbb0(%rsp), %r10 + movq %r10, 0x478(%rsp) + movq 0xba8(%rsp), %r10 + movq %r10, 0x480(%rsp) + movq 0xba0(%rsp), %r10 + movq %r10, 0x488(%rsp) + movq 0xb98(%rsp), %r10 + movq %r10, 0x490(%rsp) + movq 0xb90(%rsp), %r10 + movq %r10, 0x498(%rsp) + movq 0xb88(%rsp), %r10 + movq %r10, 0x4a0(%rsp) + movq 0xb80(%rsp), %r10 + movq %r10, 0x4a8(%rsp) + movq 0xb78(%rsp), %r10 + movq %r10, 0x4b0(%rsp) + movq 0xb70(%rsp), %r10 + movq %r10, 0x4b8(%rsp) + movq 0xb68(%rsp), %r10 + movq %r10, 0x4c0(%rsp) + movq 0xb60(%rsp), %r10 + movq %r10, 0x4c8(%rsp) + movq 0xb58(%rsp), %r10 + movq %r10, 0x4d0(%rsp) + movq 0xb50(%rsp), %r10 + movq %r10, 0x4d8(%rsp) + movq 0xb48(%rsp), %r10 + movq %r10, 0x4e0(%rsp) + movq 0xb40(%rsp), %r10 + movq %r10, 0x4e8(%rsp) + movq 0xb38(%rsp), %r10 + movq %r10, 0x4f0(%rsp) + movq 0xb30(%rsp), %r10 + movq %r10, 0x4f8(%rsp) + movq 0xb28(%rsp), %r10 + movq %r10, 0x500(%rsp) + movq 0xb20(%rsp), %r10 + movq %r10, 0x508(%rsp) + movq 0xb18(%rsp), %r10 + movq %r10, 0x510(%rsp) + movq 0xb10(%rsp), %r10 + movq %r10, 0x518(%rsp) + movq 0xb08(%rsp), %r10 + movq %r10, 0x520(%rsp) + movq 0xb00(%rsp), %r10 + movq %r10, 0x528(%rsp) + movq 0xaf8(%rsp), %r10 + movq %r10, 0x530(%rsp) + movq 0xaf0(%rsp), %r10 + movq %r10, 0x538(%rsp) + movq 0xae8(%rsp), %r10 + movq %r10, 0x540(%rsp) + movq 0xae0(%rsp), %r10 + movq %r10, 0x548(%rsp) + movq 0xad8(%rsp), %r10 + movq %r10, 0x550(%rsp) + movq 0xad0(%rsp), %r10 + movq %r10, 0x558(%rsp) + movq 0xac8(%rsp), %r10 + movq %r10, 0x560(%rsp) + movq 0xac0(%rsp), %r10 + movq %r10, 0x568(%rsp) + movq 0xab8(%rsp), %r10 + movq %r10, 0x570(%rsp) + movq 0xab0(%rsp), %r10 + movq %r10, 0x578(%rsp) + movq 0xaa8(%rsp), %r10 + movq %r10, 0x580(%rsp) + movq 0xaa0(%rsp), %r10 + movq %r10, 0x588(%rsp) + movq 0xa98(%rsp), %r10 + movq %r10, 0x590(%rsp) + movq 0xa90(%rsp), %r10 + movq %r10, 0x598(%rsp) + movq 0xa88(%rsp), %r10 + movq %r10, 0x5a0(%rsp) + movq 0xa80(%rsp), %r10 + movq %r10, 0x5a8(%rsp) + movq 0xa78(%rsp), %r10 + movq %r10, 0x5b0(%rsp) + movq 0xa70(%rsp), %r10 + movq %r10, 0x5b8(%rsp) + movq 0xa68(%rsp), %r10 + movq %r10, 0x5c0(%rsp) + movq 0xa60(%rsp), %r10 + movq %r10, 0x5c8(%rsp) + movq 0xa58(%rsp), %r10 + movq %r10, 0x5d0(%rsp) + movq 0xa50(%rsp), %r10 + movq %r10, 0x5d8(%rsp) + movq 0xa48(%rsp), %r10 + movq %r10, 0x5e0(%rsp) + movq 0xa40(%rsp), %r10 + movq %r10, 0x5e8(%rsp) + movq 0xa38(%rsp), %r10 + movq %r10, 0x5f0(%rsp) + movq 0xa30(%rsp), %r10 + movq %r10, 0x5f8(%rsp) + movq 0xa28(%rsp), %r10 + movq %r10, 0x600(%rsp) + movq 0xa20(%rsp), %r10 + movq %r10, 0x608(%rsp) + movq 0xa18(%rsp), %r10 + movq %r10, 0x610(%rsp) + movq 0xa10(%rsp), %r10 + movq %r10, 0x618(%rsp) + movq 0xa08(%rsp), %r10 + movq %r10, 0x620(%rsp) + movq 0xa00(%rsp), %r10 + movq %r10, 0x628(%rsp) + movq 0x9f8(%rsp), %r10 + movq %r10, 0x630(%rsp) + movq 0x9f0(%rsp), %r10 + movq %r10, 0x638(%rsp) + movq 0x9e8(%rsp), %r10 + movq %r10, 0x640(%rsp) + movq 0x9e0(%rsp), %r10 + movq %r10, 0x648(%rsp) + movq 0x9d8(%rsp), %r10 + movq %r10, 0x650(%rsp) + movq 0x9d0(%rsp), %r10 + movq %r10, 0x658(%rsp) + movq 0x9c8(%rsp), %r10 + movq %r10, 0x660(%rsp) + movq 0x9c0(%rsp), %r10 + movq %r10, 0x668(%rsp) + movq 0x9b8(%rsp), %r10 + movq %r10, 0x670(%rsp) + movq 0x9b0(%rsp), %r10 + movq %r10, 0x678(%rsp) + movq 0x9a8(%rsp), %r10 + movq %r10, 0x680(%rsp) + movq 0x9a0(%rsp), %r10 + movq %r10, 0x688(%rsp) + movq 0x998(%rsp), %r10 + movq %r10, 0x690(%rsp) + movq 0x990(%rsp), %r10 + movq %r10, 0x698(%rsp) + movq 0x988(%rsp), %r10 + movq %r10, 0x6a0(%rsp) + movq 0x980(%rsp), %r10 + movq %r10, 0x6a8(%rsp) + movq 0x978(%rsp), %r10 + movq %r10, 0x6b0(%rsp) + movq 0x970(%rsp), %r10 + movq %r10, 0x6b8(%rsp) + movq 0x968(%rsp), %r10 + movq %r10, 0x6c0(%rsp) + movq 0x960(%rsp), %r10 + movq %r10, 0x6c8(%rsp) + movq 0x958(%rsp), %r10 + movq %r10, 0x6d0(%rsp) + movq 0x950(%rsp), %r10 + movq %r10, 0x6d8(%rsp) + movq 0x948(%rsp), %r10 + movq %r10, 0x6e0(%rsp) + movq 0x940(%rsp), %r10 + movq %r10, 0x6e8(%rsp) + movq 0x938(%rsp), %r10 + movq %r10, 0x6f0(%rsp) + movq 0x930(%rsp), %r10 + movq %r10, 0x6f8(%rsp) + movq 0x928(%rsp), %r10 + movq %r10, 0x700(%rsp) + movq 0x920(%rsp), %r10 + movq %r10, 0x708(%rsp) + movq 0x918(%rsp), %r10 + movq %r10, 0x710(%rsp) + movq 0x910(%rsp), %r10 + movq %r10, 0x718(%rsp) + movq 0x908(%rsp), %r10 + movq %r10, 0x720(%rsp) + movq 0x900(%rsp), %r10 + movq %r10, 0x728(%rsp) + movq 0x8f8(%rsp), %r10 + movq %r10, 0x730(%rsp) + movq 0x8f0(%rsp), %r10 + movq %r10, 0x738(%rsp) + movq 0x8e8(%rsp), %r10 + movq %r10, 0x740(%rsp) + movq 0x8e0(%rsp), %r10 + movq %r10, 0x748(%rsp) + movq 0x8d8(%rsp), %r10 + movq %r10, 0x750(%rsp) + movq 0x8d0(%rsp), %r10 + movq %r10, 0x758(%rsp) + movq 0x8c8(%rsp), %r10 + movq %r10, 0x760(%rsp) + movq 0x8c0(%rsp), %r10 + movq %r10, 0x768(%rsp) + movq 0x8b8(%rsp), %r10 + movq %r10, 0x770(%rsp) + movq 0x8b0(%rsp), %r10 + movq %r10, 0x778(%rsp) + movq 0x8a8(%rsp), %r10 + movq %r10, 0x780(%rsp) + movq 0x8a0(%rsp), %r10 + movq %r10, 0x788(%rsp) + movq 0x898(%rsp), %r10 + movq %r10, 0x790(%rsp) + movq 0x890(%rsp), %r10 + movq %r10, 0x798(%rsp) + movq 0x888(%rsp), %r10 + movq %r10, 0x7a0(%rsp) + movq 0x880(%rsp), %r10 + movq %r10, 0x7a8(%rsp) + movq 0x878(%rsp), %r10 + movq %r10, 0x7b0(%rsp) + movq 0x870(%rsp), %r10 + movq %r10, 0x7b8(%rsp) + movq 0x868(%rsp), %r10 + movq %r10, 0x7c0(%rsp) + movq 0x860(%rsp), %r10 + movq %r10, 0x7c8(%rsp) + movq 0x858(%rsp), %r10 + movq %r10, 0x7d0(%rsp) + movq 0x850(%rsp), %r10 + movq %r10, 0x7d8(%rsp) + movq 0x848(%rsp), %r10 + movq %r10, 0x7e0(%rsp) + movq 0x840(%rsp), %r10 + movq %r10, 0x7e8(%rsp) + movq 0x7f0(%rsp), %r10 + callq *%r10 + addq $0x7f0, %rsp # imm = 0x7F0 + addq $0x10, %rsp + cmpq $0x848a, %rax # imm = 0x848A + je + movl $0x2, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + addq $0x1050, %rsp # imm = 0x1050 + popq %rbp + retq + leaq , %rdi + leaq 0x10(%rdi), %rsi + leaq 0x20(%rdi), %rdx + leaq 0x30(%rdi), %rcx + leaq 0x40(%rdi), %r8 + leaq 0x50(%rdi), %r9 + leaq 0x60(%rdi), %rax + leaq 0x70(%rdi), %rbx + leaq 0x80(%rdi), %r13 + leaq 0x90(%rdi), %r14 + leaq 0xa0(%rdi), %r15 + leaq 0xb0(%rdi), %r10 + movq %r10, 0x808(%rsp) + leaq 0xc0(%rdi), %r10 + movq %r10, 0x800(%rsp) + leaq 0xd0(%rdi), %r10 + movq %r10, 0x7f8(%rsp) + leaq 0xe0(%rdi), %r10 + movq %r10, 0x7f0(%rsp) + leaq 0xf0(%rdi), %r10 + movq %r10, 0x7e8(%rsp) + leaq 0x100(%rdi), %r10 + movq %r10, 0x7e0(%rsp) + leaq 0x110(%rdi), %r10 + movq %r10, 0x7d8(%rsp) + leaq 0x120(%rdi), %r10 + movq %r10, 0x7d0(%rsp) + leaq 0x130(%rdi), %r10 + movq %r10, 0x7c8(%rsp) + leaq 0x140(%rdi), %r10 + movq %r10, 0x7c0(%rsp) + leaq 0x150(%rdi), %r10 + movq %r10, 0x7b8(%rsp) + leaq 0x160(%rdi), %r10 + movq %r10, 0x7b0(%rsp) + leaq 0x170(%rdi), %r10 + movq %r10, 0x7a8(%rsp) + leaq 0x180(%rdi), %r10 + movq %r10, 0x7a0(%rsp) + leaq 0x190(%rdi), %r10 + movq %r10, 0x798(%rsp) + leaq 0x1a0(%rdi), %r10 + movq %r10, 0x790(%rsp) + leaq 0x1b0(%rdi), %r10 + movq %r10, 0x788(%rsp) + leaq 0x1c0(%rdi), %r10 + movq %r10, 0x780(%rsp) + leaq 0x1d0(%rdi), %r10 + movq %r10, 0x778(%rsp) + leaq 0x1e0(%rdi), %r10 + movq %r10, 0x770(%rsp) + leaq 0x1f0(%rdi), %r10 + movq %r10, 0x768(%rsp) + leaq 0x200(%rdi), %r10 + movq %r10, 0x760(%rsp) + leaq 0x210(%rdi), %r10 + movq %r10, 0x758(%rsp) + leaq 0x220(%rdi), %r10 + movq %r10, 0x750(%rsp) + leaq 0x230(%rdi), %r10 + movq %r10, 0x748(%rsp) + leaq 0x240(%rdi), %r10 + movq %r10, 0x740(%rsp) + leaq 0x250(%rdi), %r10 + movq %r10, 0x738(%rsp) + leaq 0x260(%rdi), %r10 + movq %r10, 0x730(%rsp) + leaq 0x270(%rdi), %r10 + movq %r10, 0x728(%rsp) + leaq 0x280(%rdi), %r10 + movq %r10, 0x720(%rsp) + leaq 0x290(%rdi), %r10 + movq %r10, 0x718(%rsp) + leaq 0x2a0(%rdi), %r10 + movq %r10, 0x710(%rsp) + leaq 0x2b0(%rdi), %r10 + movq %r10, 0x708(%rsp) + leaq 0x2c0(%rdi), %r10 + movq %r10, 0x700(%rsp) + leaq 0x2d0(%rdi), %r10 + movq %r10, 0x6f8(%rsp) + leaq 0x2e0(%rdi), %r10 + movq %r10, 0x6f0(%rsp) + leaq 0x2f0(%rdi), %r10 + movq %r10, 0x6e8(%rsp) + leaq 0x300(%rdi), %r10 + movq %r10, 0x6e0(%rsp) + leaq 0x310(%rdi), %r10 + movq %r10, 0x6d8(%rsp) + leaq 0x320(%rdi), %r10 + movq %r10, 0x6d0(%rsp) + leaq 0x330(%rdi), %r10 + movq %r10, 0x6c8(%rsp) + leaq 0x340(%rdi), %r10 + movq %r10, 0x6c0(%rsp) + leaq 0x350(%rdi), %r10 + movq %r10, 0x6b8(%rsp) + leaq 0x360(%rdi), %r10 + movq %r10, 0x6b0(%rsp) + leaq 0x370(%rdi), %r10 + movq %r10, 0x6a8(%rsp) + leaq 0x380(%rdi), %r10 + movq %r10, 0x6a0(%rsp) + leaq 0x390(%rdi), %r10 + movq %r10, 0x698(%rsp) + leaq 0x3a0(%rdi), %r10 + movq %r10, 0x690(%rsp) + leaq 0x3b0(%rdi), %r10 + movq %r10, 0x688(%rsp) + leaq 0x3c0(%rdi), %r10 + movq %r10, 0x680(%rsp) + leaq 0x3d0(%rdi), %r10 + movq %r10, 0x678(%rsp) + leaq 0x3e0(%rdi), %r10 + movq %r10, 0x670(%rsp) + leaq 0x3f0(%rdi), %r10 + movq %r10, 0x668(%rsp) + leaq 0x400(%rdi), %r10 + movq %r10, 0x660(%rsp) + leaq 0x410(%rdi), %r10 + movq %r10, 0x658(%rsp) + leaq 0x420(%rdi), %r10 + movq %r10, 0x650(%rsp) + leaq 0x430(%rdi), %r10 + movq %r10, 0x648(%rsp) + leaq 0x440(%rdi), %r10 + movq %r10, 0x640(%rsp) + leaq 0x450(%rdi), %r10 + movq %r10, 0x638(%rsp) + leaq 0x460(%rdi), %r10 + movq %r10, 0x630(%rsp) + leaq 0x470(%rdi), %r10 + movq %r10, 0x628(%rsp) + leaq 0x480(%rdi), %r10 + movq %r10, 0x620(%rsp) + leaq 0x490(%rdi), %r10 + movq %r10, 0x618(%rsp) + leaq 0x4a0(%rdi), %r10 + movq %r10, 0x610(%rsp) + leaq 0x4b0(%rdi), %r10 + movq %r10, 0x608(%rsp) + leaq 0x4c0(%rdi), %r10 + movq %r10, 0x600(%rsp) + leaq 0x4d0(%rdi), %r10 + movq %r10, 0x5f8(%rsp) + leaq 0x4e0(%rdi), %r10 + movq %r10, 0x5f0(%rsp) + leaq 0x4f0(%rdi), %r10 + movq %r10, 0x5e8(%rsp) + leaq 0x500(%rdi), %r10 + movq %r10, 0x5e0(%rsp) + leaq 0x510(%rdi), %r10 + movq %r10, 0x5d8(%rsp) + leaq 0x520(%rdi), %r10 + movq %r10, 0x5d0(%rsp) + leaq 0x530(%rdi), %r10 + movq %r10, 0x5c8(%rsp) + leaq 0x540(%rdi), %r10 + movq %r10, 0x5c0(%rsp) + leaq 0x550(%rdi), %r10 + movq %r10, 0x5b8(%rsp) + leaq 0x560(%rdi), %r10 + movq %r10, 0x5b0(%rsp) + leaq 0x570(%rdi), %r10 + movq %r10, 0x5a8(%rsp) + leaq 0x580(%rdi), %r10 + movq %r10, 0x5a0(%rsp) + leaq 0x590(%rdi), %r10 + movq %r10, 0x598(%rsp) + leaq 0x5a0(%rdi), %r10 + movq %r10, 0x590(%rsp) + leaq 0x5b0(%rdi), %r10 + movq %r10, 0x588(%rsp) + leaq 0x5c0(%rdi), %r10 + movq %r10, 0x580(%rsp) + leaq 0x5d0(%rdi), %r10 + movq %r10, 0x578(%rsp) + leaq 0x5e0(%rdi), %r10 + movq %r10, 0x570(%rsp) + leaq 0x5f0(%rdi), %r10 + movq %r10, 0x568(%rsp) + leaq 0x600(%rdi), %r10 + movq %r10, 0x560(%rsp) + leaq 0x610(%rdi), %r10 + movq %r10, 0x558(%rsp) + leaq 0x620(%rdi), %r10 + movq %r10, 0x550(%rsp) + leaq 0x630(%rdi), %r10 + movq %r10, 0x548(%rsp) + leaq 0x640(%rdi), %r10 + movq %r10, 0x540(%rsp) + leaq 0x650(%rdi), %r10 + movq %r10, 0x538(%rsp) + leaq 0x660(%rdi), %r10 + movq %r10, 0x530(%rsp) + leaq 0x670(%rdi), %r10 + movq %r10, 0x528(%rsp) + leaq 0x680(%rdi), %r10 + movq %r10, 0x520(%rsp) + leaq 0x690(%rdi), %r10 + movq %r10, 0x518(%rsp) + leaq 0x6a0(%rdi), %r10 + movq %r10, 0x510(%rsp) + leaq 0x6b0(%rdi), %r10 + movq %r10, 0x508(%rsp) + leaq 0x6c0(%rdi), %r10 + movq %r10, 0x500(%rsp) + leaq 0x6d0(%rdi), %r10 + movq %r10, 0x4f8(%rsp) + leaq 0x6e0(%rdi), %r10 + movq %r10, 0x4f0(%rsp) + leaq 0x6f0(%rdi), %r10 + movq %r10, 0x4e8(%rsp) + leaq 0x700(%rdi), %r10 + movq %r10, 0x4e0(%rsp) + leaq 0x710(%rdi), %r10 + movq %r10, 0x4d8(%rsp) + leaq 0x720(%rdi), %r10 + movq %r10, 0x4d0(%rsp) + leaq 0x730(%rdi), %r10 + movq %r10, 0x4c8(%rsp) + leaq 0x740(%rdi), %r10 + movq %r10, 0x4c0(%rsp) + leaq 0x750(%rdi), %r10 + movq %r10, 0x4b8(%rsp) + leaq 0x760(%rdi), %r10 + movq %r10, 0x4b0(%rsp) + leaq 0x770(%rdi), %r10 + movq %r10, 0x4a8(%rsp) + leaq 0x780(%rdi), %r10 + movq %r10, 0x4a0(%rsp) + leaq 0x790(%rdi), %r10 + movq %r10, 0x498(%rsp) + leaq 0x7a0(%rdi), %r10 + movq %r10, 0x490(%rsp) + leaq 0x7b0(%rdi), %r10 + movq %r10, 0x488(%rsp) + leaq 0x7c0(%rdi), %r10 + movq %r10, 0x480(%rsp) + leaq 0x7d0(%rdi), %r10 + movq %r10, 0x478(%rsp) + leaq 0x7e0(%rdi), %r10 + movq %r10, 0x470(%rsp) + leaq 0x7f0(%rdi), %r10 + movq %r10, 0x468(%rsp) + leaq 0x800(%rdi), %r10 + movq %r10, 0x460(%rsp) + leaq 0x810(%rdi), %r10 + movq %r10, 0x458(%rsp) + leaq 0x820(%rdi), %r10 + movq %r10, 0x450(%rsp) + leaq 0x830(%rdi), %r10 + movq %r10, 0x448(%rsp) + leaq 0x840(%rdi), %r10 + movq %r10, 0x440(%rsp) + leaq 0x850(%rdi), %r10 + movq %r10, 0x438(%rsp) + leaq 0x860(%rdi), %r10 + movq %r10, 0x430(%rsp) + leaq 0x870(%rdi), %r10 + movq %r10, 0x428(%rsp) + leaq 0x880(%rdi), %r10 + movq %r10, 0x420(%rsp) + leaq 0x890(%rdi), %r10 + movq %r10, 0x418(%rsp) + leaq 0x8a0(%rdi), %r10 + movq %r10, 0x410(%rsp) + leaq 0x8b0(%rdi), %r10 + movq %r10, 0x408(%rsp) + leaq 0x8c0(%rdi), %r10 + movq %r10, 0x400(%rsp) + leaq 0x8d0(%rdi), %r10 + movq %r10, 0x3f8(%rsp) + leaq 0x8e0(%rdi), %r10 + movq %r10, 0x3f0(%rsp) + leaq 0x8f0(%rdi), %r10 + movq %r10, 0x3e8(%rsp) + leaq 0x900(%rdi), %r10 + movq %r10, 0x3e0(%rsp) + leaq 0x910(%rdi), %r10 + movq %r10, 0x3d8(%rsp) + leaq 0x920(%rdi), %r10 + movq %r10, 0x3d0(%rsp) + leaq 0x930(%rdi), %r10 + movq %r10, 0x3c8(%rsp) + leaq 0x940(%rdi), %r10 + movq %r10, 0x3c0(%rsp) + leaq 0x950(%rdi), %r10 + movq %r10, 0x3b8(%rsp) + leaq 0x960(%rdi), %r10 + movq %r10, 0x3b0(%rsp) + leaq 0x970(%rdi), %r10 + movq %r10, 0x3a8(%rsp) + leaq 0x980(%rdi), %r10 + movq %r10, 0x3a0(%rsp) + leaq 0x990(%rdi), %r10 + movq %r10, 0x398(%rsp) + leaq 0x9a0(%rdi), %r10 + movq %r10, 0x390(%rsp) + leaq 0x9b0(%rdi), %r10 + movq %r10, 0x388(%rsp) + leaq 0x9c0(%rdi), %r10 + movq %r10, 0x380(%rsp) + leaq 0x9d0(%rdi), %r10 + movq %r10, 0x378(%rsp) + leaq 0x9e0(%rdi), %r10 + movq %r10, 0x370(%rsp) + leaq 0x9f0(%rdi), %r10 + movq %r10, 0x368(%rsp) + leaq 0xa00(%rdi), %r10 + movq %r10, 0x360(%rsp) + leaq 0xa10(%rdi), %r10 + movq %r10, 0x358(%rsp) + leaq 0xa20(%rdi), %r10 + movq %r10, 0x350(%rsp) + leaq 0xa30(%rdi), %r10 + movq %r10, 0x348(%rsp) + leaq 0xa40(%rdi), %r10 + movq %r10, 0x340(%rsp) + leaq 0xa50(%rdi), %r10 + movq %r10, 0x338(%rsp) + leaq 0xa60(%rdi), %r10 + movq %r10, 0x330(%rsp) + leaq 0xa70(%rdi), %r10 + movq %r10, 0x328(%rsp) + leaq 0xa80(%rdi), %r10 + movq %r10, 0x320(%rsp) + leaq 0xa90(%rdi), %r10 + movq %r10, 0x318(%rsp) + leaq 0xaa0(%rdi), %r10 + movq %r10, 0x310(%rsp) + leaq 0xab0(%rdi), %r10 + movq %r10, 0x308(%rsp) + leaq 0xac0(%rdi), %r10 + movq %r10, 0x300(%rsp) + leaq 0xad0(%rdi), %r10 + movq %r10, 0x2f8(%rsp) + leaq 0xae0(%rdi), %r10 + movq %r10, 0x2f0(%rsp) + leaq 0xaf0(%rdi), %r10 + movq %r10, 0x2e8(%rsp) + leaq 0xb00(%rdi), %r10 + movq %r10, 0x2e0(%rsp) + leaq 0xb10(%rdi), %r10 + movq %r10, 0x2d8(%rsp) + leaq 0xb20(%rdi), %r10 + movq %r10, 0x2d0(%rsp) + leaq 0xb30(%rdi), %r10 + movq %r10, 0x2c8(%rsp) + leaq 0xb40(%rdi), %r10 + movq %r10, 0x2c0(%rsp) + leaq 0xb50(%rdi), %r10 + movq %r10, 0x2b8(%rsp) + leaq 0xb60(%rdi), %r10 + movq %r10, 0x2b0(%rsp) + leaq 0xb70(%rdi), %r10 + movq %r10, 0x2a8(%rsp) + leaq 0xb80(%rdi), %r10 + movq %r10, 0x2a0(%rsp) + leaq 0xb90(%rdi), %r10 + movq %r10, 0x298(%rsp) + leaq 0xba0(%rdi), %r10 + movq %r10, 0x290(%rsp) + leaq 0xbb0(%rdi), %r10 + movq %r10, 0x288(%rsp) + leaq 0xbc0(%rdi), %r10 + movq %r10, 0x280(%rsp) + leaq 0xbd0(%rdi), %r10 + movq %r10, 0x278(%rsp) + leaq 0xbe0(%rdi), %r10 + movq %r10, 0x270(%rsp) + leaq 0xbf0(%rdi), %r10 + movq %r10, 0x268(%rsp) + leaq 0xc00(%rdi), %r10 + movq %r10, 0x260(%rsp) + leaq 0xc10(%rdi), %r10 + movq %r10, 0x258(%rsp) + leaq 0xc20(%rdi), %r10 + movq %r10, 0x250(%rsp) + leaq 0xc30(%rdi), %r10 + movq %r10, 0x248(%rsp) + leaq 0xc40(%rdi), %r10 + movq %r10, 0x240(%rsp) + leaq 0xc50(%rdi), %r10 + movq %r10, 0x238(%rsp) + leaq 0xc60(%rdi), %r10 + movq %r10, 0x230(%rsp) + leaq 0xc70(%rdi), %r10 + movq %r10, 0x228(%rsp) + leaq 0xc80(%rdi), %r10 + movq %r10, 0x220(%rsp) + leaq 0xc90(%rdi), %r10 + movq %r10, 0x218(%rsp) + leaq 0xca0(%rdi), %r10 + movq %r10, 0x210(%rsp) + leaq 0xcb0(%rdi), %r10 + movq %r10, 0x208(%rsp) + leaq 0xcc0(%rdi), %r10 + movq %r10, 0x200(%rsp) + leaq 0xcd0(%rdi), %r10 + movq %r10, 0x1f8(%rsp) + leaq 0xce0(%rdi), %r10 + movq %r10, 0x1f0(%rsp) + leaq 0xcf0(%rdi), %r10 + movq %r10, 0x1e8(%rsp) + leaq 0xd00(%rdi), %r10 + movq %r10, 0x1e0(%rsp) + leaq 0xd10(%rdi), %r10 + movq %r10, 0x1d8(%rsp) + leaq 0xd20(%rdi), %r10 + movq %r10, 0x1d0(%rsp) + leaq 0xd30(%rdi), %r10 + movq %r10, 0x1c8(%rsp) + leaq 0xd40(%rdi), %r10 + movq %r10, 0x1c0(%rsp) + leaq 0xd50(%rdi), %r10 + movq %r10, 0x1b8(%rsp) + leaq 0xd60(%rdi), %r10 + movq %r10, 0x1b0(%rsp) + leaq 0xd70(%rdi), %r10 + movq %r10, 0x1a8(%rsp) + leaq 0xd80(%rdi), %r10 + movq %r10, 0x1a0(%rsp) + leaq 0xd90(%rdi), %r10 + movq %r10, 0x198(%rsp) + leaq 0xda0(%rdi), %r10 + movq %r10, 0x190(%rsp) + leaq 0xdb0(%rdi), %r10 + movq %r10, 0x188(%rsp) + leaq 0xdc0(%rdi), %r10 + movq %r10, 0x180(%rsp) + leaq 0xdd0(%rdi), %r10 + movq %r10, 0x178(%rsp) + leaq 0xde0(%rdi), %r10 + movq %r10, 0x170(%rsp) + leaq 0xdf0(%rdi), %r10 + movq %r10, 0x168(%rsp) + leaq 0xe00(%rdi), %r10 + movq %r10, 0x160(%rsp) + leaq 0xe10(%rdi), %r10 + movq %r10, 0x158(%rsp) + leaq 0xe20(%rdi), %r10 + movq %r10, 0x150(%rsp) + leaq 0xe30(%rdi), %r10 + movq %r10, 0x148(%rsp) + leaq 0xe40(%rdi), %r10 + movq %r10, 0x140(%rsp) + leaq 0xe50(%rdi), %r10 + movq %r10, 0x138(%rsp) + leaq 0xe60(%rdi), %r10 + movq %r10, 0x130(%rsp) + leaq 0xe70(%rdi), %r10 + movq %r10, 0x128(%rsp) + leaq 0xe80(%rdi), %r10 + movq %r10, 0x120(%rsp) + leaq 0xe90(%rdi), %r10 + movq %r10, 0x118(%rsp) + leaq 0xea0(%rdi), %r10 + movq %r10, 0x110(%rsp) + leaq 0xeb0(%rdi), %r10 + movq %r10, 0x108(%rsp) + leaq 0xec0(%rdi), %r10 + movq %r10, 0x100(%rsp) + leaq 0xed0(%rdi), %r10 + movq %r10, 0xf8(%rsp) + leaq 0xee0(%rdi), %r10 + movq %r10, 0xf0(%rsp) + leaq 0xef0(%rdi), %r10 + movq %r10, 0xe8(%rsp) + leaq 0xf00(%rdi), %r10 + movq %r10, 0xe0(%rsp) + leaq 0xf10(%rdi), %r10 + movq %r10, 0xd8(%rsp) + leaq 0xf20(%rdi), %r10 + movq %r10, 0xd0(%rsp) + leaq 0xf30(%rdi), %r10 + movq %r10, 0xc8(%rsp) + leaq 0xf40(%rdi), %r10 + movq %r10, 0xc0(%rsp) + leaq 0xf50(%rdi), %r10 + movq %r10, 0xb8(%rsp) + leaq 0xf60(%rdi), %r10 + movq %r10, 0xb0(%rsp) + leaq 0xf70(%rdi), %r10 + movq %r10, 0xa8(%rsp) + leaq 0xf80(%rdi), %r10 + movq %r10, 0xa0(%rsp) + leaq 0xf90(%rdi), %r10 + movq %r10, 0x98(%rsp) + leaq 0xfa0(%rdi), %r10 + movq %r10, 0x90(%rsp) + leaq 0xfb0(%rdi), %r10 + movq %r10, 0x88(%rsp) + leaq 0xfc0(%rdi), %r10 + movq %r10, 0x80(%rsp) + leaq 0xfd0(%rdi), %r10 + movq %r10, 0x78(%rsp) + leaq 0xfe0(%rdi), %r10 + movq %r10, 0x70(%rsp) + leaq 0xff0(%rdi), %r10 + movq %r10, 0x68(%rsp) + leaq 0x1000(%rdi), %r10 + movq %r10, 0x60(%rsp) + leaq 0x1010(%rdi), %r10 + movq %r10, 0x58(%rsp) + leaq 0x1020(%rdi), %r10 + movq %r10, 0x50(%rsp) + leaq 0x1030(%rdi), %r10 + movq %r10, 0x48(%rsp) + leaq 0x1040(%rdi), %r10 + movq %r10, 0x40(%rsp) + subq $0x10, %rsp + movq %r12, (%rsp) + subq $0x1020, %rsp # imm = 0x1020 + movq %rcx, %r10 + movq (%r10), %r11 + movq %r11, (%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8(%rsp) + movq %r8, %r10 + movq (%r10), %r11 + movq %r11, 0x10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x18(%rsp) + movq %r9, %r10 + movq (%r10), %r11 + movq %r11, 0x20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x28(%rsp) + movq %rax, %r10 + movq (%r10), %r11 + movq %r11, 0x30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x38(%rsp) + movq %rbx, %r10 + movq (%r10), %r11 + movq %r11, 0x40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x48(%rsp) + movq %r13, %r10 + movq (%r10), %r11 + movq %r11, 0x50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x58(%rsp) + movq %r14, %r10 + movq (%r10), %r11 + movq %r11, 0x60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x68(%rsp) + movq %r15, %r10 + movq (%r10), %r11 + movq %r11, 0x70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x78(%rsp) + movq 0x1838(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x88(%rsp) + movq 0x1830(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x98(%rsp) + movq 0x1828(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa8(%rsp) + movq 0x1820(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb8(%rsp) + movq 0x1818(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc8(%rsp) + movq 0x1810(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd8(%rsp) + movq 0x1808(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe8(%rsp) + movq 0x1800(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf8(%rsp) + movq 0x17f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x100(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x108(%rsp) + movq 0x17f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x110(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x118(%rsp) + movq 0x17e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x120(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x128(%rsp) + movq 0x17e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x130(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x138(%rsp) + movq 0x17d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x140(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x148(%rsp) + movq 0x17d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x150(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x158(%rsp) + movq 0x17c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x160(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x168(%rsp) + movq 0x17c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x170(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x178(%rsp) + movq 0x17b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x180(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x188(%rsp) + movq 0x17b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x190(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x198(%rsp) + movq 0x17a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1a8(%rsp) + movq 0x17a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1b8(%rsp) + movq 0x1798(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1c8(%rsp) + movq 0x1790(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1d8(%rsp) + movq 0x1788(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1e8(%rsp) + movq 0x1780(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1f8(%rsp) + movq 0x1778(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x200(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x208(%rsp) + movq 0x1770(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x210(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x218(%rsp) + movq 0x1768(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x220(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x228(%rsp) + movq 0x1760(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x230(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x238(%rsp) + movq 0x1758(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x240(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x248(%rsp) + movq 0x1750(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x250(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x258(%rsp) + movq 0x1748(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x260(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x268(%rsp) + movq 0x1740(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x270(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x278(%rsp) + movq 0x1738(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x280(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x288(%rsp) + movq 0x1730(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x290(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x298(%rsp) + movq 0x1728(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2a8(%rsp) + movq 0x1720(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2b8(%rsp) + movq 0x1718(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2c8(%rsp) + movq 0x1710(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2d8(%rsp) + movq 0x1708(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2e8(%rsp) + movq 0x1700(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x2f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x2f8(%rsp) + movq 0x16f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x300(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x308(%rsp) + movq 0x16f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x310(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x318(%rsp) + movq 0x16e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x320(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x328(%rsp) + movq 0x16e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x330(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x338(%rsp) + movq 0x16d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x340(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x348(%rsp) + movq 0x16d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x350(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x358(%rsp) + movq 0x16c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x360(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x368(%rsp) + movq 0x16c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x370(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x378(%rsp) + movq 0x16b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x380(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x388(%rsp) + movq 0x16b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x390(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x398(%rsp) + movq 0x16a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3a8(%rsp) + movq 0x16a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3b8(%rsp) + movq 0x1698(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3c8(%rsp) + movq 0x1690(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3d8(%rsp) + movq 0x1688(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3e8(%rsp) + movq 0x1680(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x3f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x3f8(%rsp) + movq 0x1678(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x400(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x408(%rsp) + movq 0x1670(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x410(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x418(%rsp) + movq 0x1668(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x420(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x428(%rsp) + movq 0x1660(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x430(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x438(%rsp) + movq 0x1658(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x440(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x448(%rsp) + movq 0x1650(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x450(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x458(%rsp) + movq 0x1648(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x460(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x468(%rsp) + movq 0x1640(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x470(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x478(%rsp) + movq 0x1638(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x480(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x488(%rsp) + movq 0x1630(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x490(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x498(%rsp) + movq 0x1628(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4a8(%rsp) + movq 0x1620(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4b8(%rsp) + movq 0x1618(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4c8(%rsp) + movq 0x1610(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4d8(%rsp) + movq 0x1608(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4e8(%rsp) + movq 0x1600(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x4f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x4f8(%rsp) + movq 0x15f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x500(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x508(%rsp) + movq 0x15f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x510(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x518(%rsp) + movq 0x15e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x520(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x528(%rsp) + movq 0x15e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x530(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x538(%rsp) + movq 0x15d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x540(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x548(%rsp) + movq 0x15d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x550(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x558(%rsp) + movq 0x15c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x560(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x568(%rsp) + movq 0x15c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x570(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x578(%rsp) + movq 0x15b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x580(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x588(%rsp) + movq 0x15b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x590(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x598(%rsp) + movq 0x15a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5a8(%rsp) + movq 0x15a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5b8(%rsp) + movq 0x1598(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5c8(%rsp) + movq 0x1590(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5d8(%rsp) + movq 0x1588(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5e8(%rsp) + movq 0x1580(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x5f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x5f8(%rsp) + movq 0x1578(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x600(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x608(%rsp) + movq 0x1570(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x610(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x618(%rsp) + movq 0x1568(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x620(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x628(%rsp) + movq 0x1560(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x630(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x638(%rsp) + movq 0x1558(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x640(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x648(%rsp) + movq 0x1550(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x650(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x658(%rsp) + movq 0x1548(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x660(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x668(%rsp) + movq 0x1540(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x670(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x678(%rsp) + movq 0x1538(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x680(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x688(%rsp) + movq 0x1530(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x690(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x698(%rsp) + movq 0x1528(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6a8(%rsp) + movq 0x1520(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6b8(%rsp) + movq 0x1518(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6c8(%rsp) + movq 0x1510(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6d8(%rsp) + movq 0x1508(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6e8(%rsp) + movq 0x1500(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x6f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x6f8(%rsp) + movq 0x14f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x700(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x708(%rsp) + movq 0x14f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x710(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x718(%rsp) + movq 0x14e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x720(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x728(%rsp) + movq 0x14e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x730(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x738(%rsp) + movq 0x14d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x740(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x748(%rsp) + movq 0x14d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x750(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x758(%rsp) + movq 0x14c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x760(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x768(%rsp) + movq 0x14c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x770(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x778(%rsp) + movq 0x14b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x780(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x788(%rsp) + movq 0x14b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x790(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x798(%rsp) + movq 0x14a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7a8(%rsp) + movq 0x14a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7b8(%rsp) + movq 0x1498(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7c8(%rsp) + movq 0x1490(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7d8(%rsp) + movq 0x1488(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7e8(%rsp) + movq 0x1480(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x7f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x7f8(%rsp) + movq 0x1478(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x800(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x808(%rsp) + movq 0x1470(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x810(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x818(%rsp) + movq 0x1468(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x820(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x828(%rsp) + movq 0x1460(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x830(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x838(%rsp) + movq 0x1458(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x840(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x848(%rsp) + movq 0x1450(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x850(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x858(%rsp) + movq 0x1448(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x860(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x868(%rsp) + movq 0x1440(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x870(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x878(%rsp) + movq 0x1438(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x880(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x888(%rsp) + movq 0x1430(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x890(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x898(%rsp) + movq 0x1428(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8a8(%rsp) + movq 0x1420(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8b8(%rsp) + movq 0x1418(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8c8(%rsp) + movq 0x1410(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8d8(%rsp) + movq 0x1408(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8e8(%rsp) + movq 0x1400(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x8f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8f8(%rsp) + movq 0x13f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x900(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x908(%rsp) + movq 0x13f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x910(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x918(%rsp) + movq 0x13e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x920(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x928(%rsp) + movq 0x13e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x930(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x938(%rsp) + movq 0x13d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x940(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x948(%rsp) + movq 0x13d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x950(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x958(%rsp) + movq 0x13c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x960(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x968(%rsp) + movq 0x13c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x970(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x978(%rsp) + movq 0x13b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x980(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x988(%rsp) + movq 0x13b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x990(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x998(%rsp) + movq 0x13a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9a0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9a8(%rsp) + movq 0x13a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9b0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9b8(%rsp) + movq 0x1398(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9c0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9c8(%rsp) + movq 0x1390(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9d0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9d8(%rsp) + movq 0x1388(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9e0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9e8(%rsp) + movq 0x1380(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x9f0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x9f8(%rsp) + movq 0x1378(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa08(%rsp) + movq 0x1370(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa18(%rsp) + movq 0x1368(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa28(%rsp) + movq 0x1360(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa38(%rsp) + movq 0x1358(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa48(%rsp) + movq 0x1350(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa58(%rsp) + movq 0x1348(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa68(%rsp) + movq 0x1340(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa78(%rsp) + movq 0x1338(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa88(%rsp) + movq 0x1330(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa98(%rsp) + movq 0x1328(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xaa0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xaa8(%rsp) + movq 0x1320(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xab0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xab8(%rsp) + movq 0x1318(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xac0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xac8(%rsp) + movq 0x1310(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xad0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xad8(%rsp) + movq 0x1308(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xae0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xae8(%rsp) + movq 0x1300(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xaf0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xaf8(%rsp) + movq 0x12f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb08(%rsp) + movq 0x12f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb18(%rsp) + movq 0x12e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb28(%rsp) + movq 0x12e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb38(%rsp) + movq 0x12d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb48(%rsp) + movq 0x12d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb58(%rsp) + movq 0x12c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb68(%rsp) + movq 0x12c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb78(%rsp) + movq 0x12b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb88(%rsp) + movq 0x12b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb98(%rsp) + movq 0x12a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xba0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xba8(%rsp) + movq 0x12a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xbb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xbb8(%rsp) + movq 0x1298(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xbc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xbc8(%rsp) + movq 0x1290(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xbd0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xbd8(%rsp) + movq 0x1288(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xbe0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xbe8(%rsp) + movq 0x1280(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xbf0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xbf8(%rsp) + movq 0x1278(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc08(%rsp) + movq 0x1270(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc18(%rsp) + movq 0x1268(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc28(%rsp) + movq 0x1260(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc38(%rsp) + movq 0x1258(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc48(%rsp) + movq 0x1250(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc58(%rsp) + movq 0x1248(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc68(%rsp) + movq 0x1240(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc78(%rsp) + movq 0x1238(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc88(%rsp) + movq 0x1230(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc98(%rsp) + movq 0x1228(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xca0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xca8(%rsp) + movq 0x1220(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xcb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xcb8(%rsp) + movq 0x1218(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xcc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xcc8(%rsp) + movq 0x1210(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xcd0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xcd8(%rsp) + movq 0x1208(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xce0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xce8(%rsp) + movq 0x1200(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xcf0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xcf8(%rsp) + movq 0x11f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd08(%rsp) + movq 0x11f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd18(%rsp) + movq 0x11e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd28(%rsp) + movq 0x11e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd38(%rsp) + movq 0x11d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd48(%rsp) + movq 0x11d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd58(%rsp) + movq 0x11c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd68(%rsp) + movq 0x11c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd78(%rsp) + movq 0x11b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd88(%rsp) + movq 0x11b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xd90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xd98(%rsp) + movq 0x11a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xda0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xda8(%rsp) + movq 0x11a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xdb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xdb8(%rsp) + movq 0x1198(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xdc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xdc8(%rsp) + movq 0x1190(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xdd0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xdd8(%rsp) + movq 0x1188(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xde0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xde8(%rsp) + movq 0x1180(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xdf0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xdf8(%rsp) + movq 0x1178(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe08(%rsp) + movq 0x1170(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe18(%rsp) + movq 0x1168(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe28(%rsp) + movq 0x1160(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe38(%rsp) + movq 0x1158(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe48(%rsp) + movq 0x1150(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe58(%rsp) + movq 0x1148(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe68(%rsp) + movq 0x1140(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe78(%rsp) + movq 0x1138(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe88(%rsp) + movq 0x1130(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xe90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xe98(%rsp) + movq 0x1128(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xea0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xea8(%rsp) + movq 0x1120(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xeb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xeb8(%rsp) + movq 0x1118(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xec0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xec8(%rsp) + movq 0x1110(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xed0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xed8(%rsp) + movq 0x1108(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xee0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xee8(%rsp) + movq 0x1100(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xef0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xef8(%rsp) + movq 0x10f8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf00(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf08(%rsp) + movq 0x10f0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf18(%rsp) + movq 0x10e8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf28(%rsp) + movq 0x10e0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf38(%rsp) + movq 0x10d8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf48(%rsp) + movq 0x10d0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf58(%rsp) + movq 0x10c8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf68(%rsp) + movq 0x10c0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf78(%rsp) + movq 0x10b8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf88(%rsp) + movq 0x10b0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xf90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xf98(%rsp) + movq 0x10a8(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xfa0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xfa8(%rsp) + movq 0x10a0(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xfb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xfb8(%rsp) + movq 0x1098(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xfc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xfc8(%rsp) + movq 0x1090(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xfd0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xfd8(%rsp) + movq 0x1088(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xfe0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xfe8(%rsp) + movq 0x1080(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xff0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xff8(%rsp) + movq 0x1078(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1000(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1008(%rsp) + movq 0x1070(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x1010(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x1018(%rsp) + movq %rdx, %r8 + movq %rsi, %rdx + movq 0x8(%rdi), %rsi + movq (%rdi), %rdi + movq 0x8(%rdx), %rcx + movq (%rdx), %rdx + movq 0x8(%r8), %r9 + movq (%r8), %r8 + movq 0x1020(%rsp), %r10 + callq *%r10 + addq $0x1020, %rsp # imm = 0x1020 + addq $0x10, %rsp + cmpq $0x18d9e, %rax # imm = 0x18D9E + je + movl $0x3, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + addq $0x1050, %rsp # imm = 0x1050 + popq %rbp + retq + xorq %rax, %rax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + addq $0x1050, %rsp # imm = 0x1050 + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/cast_fn_ptr_call.aarch64.asm b/tests/snapshots/asm/cast_fn_ptr_call.aarch64.asm index e51519a52..e535e4b82 100644 --- a/tests/snapshots/asm/cast_fn_ptr_call.aarch64.asm +++ b/tests/snapshots/asm/cast_fn_ptr_call.aarch64.asm @@ -28,8 +28,8 @@ Disassembly of section .text: adrp x20, add x20, x20, mov x0, #0x29 // =41 - mov x9, x20 str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -43,8 +43,8 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret mov x0, #0x7 // =7 - mov x9, x20 str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -60,8 +60,8 @@ Disassembly of section .text: adrp x0, add x0, x0, mov x1, #0x15 // =21 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/cast_fn_typedef_ptr_in_initializer.aarch64.asm b/tests/snapshots/asm/cast_fn_typedef_ptr_in_initializer.aarch64.asm index 147826384..6492c2a0f 100644 --- a/tests/snapshots/asm/cast_fn_typedef_ptr_in_initializer.aarch64.asm +++ b/tests/snapshots/asm/cast_fn_typedef_ptr_in_initializer.aarch64.asm @@ -26,9 +26,9 @@ Disassembly of section .text: ldr x0, [x0] mov x1, #0x2 // =2 mov x2, #0x3 // =3 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/clock_monotonic_advances.aarch64.asm b/tests/snapshots/asm/clock_monotonic_advances.aarch64.asm index 0001d4221..2c9fd8e6f 100644 --- a/tests/snapshots/asm/clock_monotonic_advances.aarch64.asm +++ b/tests/snapshots/asm/clock_monotonic_advances.aarch64.asm @@ -88,18 +88,19 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret mov x1, #0x0 // =0 - mov x0, x1 - sxtw x2, w1 + stur w1, [x29, #-0x28] + sxtw x0, w1 mov x17, #0x4240 // =16960 movk x17, #0xf, lsl #16 - cmp x2, x17 + cmp x0, x17 b.ge b - sxtw x1, w1 - add x1, x1, #0x1 + sxtw x0, w1 + add x1, x0, #0x1 b + ldursw x0, [x29, #-0x28] add x0, x0, #0x1 - sxtw x0, w0 + stur w0, [x29, #-0x28] b mov x0, #0x1 // =1 sub x1, x29, #0x20 diff --git a/tests/snapshots/asm/clock_monotonic_advances.x64.asm b/tests/snapshots/asm/clock_monotonic_advances.x64.asm index fc3e8e176..9292601ae 100644 --- a/tests/snapshots/asm/clock_monotonic_advances.x64.asm +++ b/tests/snapshots/asm/clock_monotonic_advances.x64.asm @@ -80,16 +80,17 @@ Disassembly of section .text: popq %rbp retq xorq %rcx, %rcx - movq %rcx, %rax - movslq %ecx, %rdx - cmpq $0xf4240, %rdx # imm = 0xF4240 + movl %ecx, -0x28(%rbp) + movslq %ecx, %rax + cmpq $0xf4240, %rax # imm = 0xF4240 jge jmp - movslq %ecx, %rcx - incq %rcx + movslq %ecx, %rax + leaq 0x1(%rax), %rcx jmp + movslq -0x28(%rbp), %rax incq %rax - movslq %eax, %rax + movl %eax, -0x28(%rbp) jmp movl $0x1, %edi leaq -0x20(%rbp), %rsi @@ -145,4 +146,4 @@ Disassembly of section .text: jmp jmp jmp - addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/compound_assign_unsigned_div.aarch64.asm b/tests/snapshots/asm/compound_assign_unsigned_div.aarch64.asm new file mode 100644 index 000000000..b22201f68 --- /dev/null +++ b/tests/snapshots/asm/compound_assign_unsigned_div.aarch64.asm @@ -0,0 +1,117 @@ + +compound_assign_unsigned_div.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x30 + mov x0, #0xffff // =65535 + movk x0, #0xffff, lsl #16 + mov x1, #0xfffe // =65534 + movk x1, #0xffff, lsl #16 + udiv x0, x0, x1 + mov w0, w0 + mov x17, #0x1 // =1 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x1 // =1 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xffff // =65535 + movk x0, #0xffff, lsl #16 + mov x1, #0xfffe // =65534 + movk x1, #0xffff, lsl #16 + udiv x17, x0, x1 + msub x0, x17, x1, x0 + mov w0, w0 + mov x17, #0x1 // =1 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x2 // =2 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xfffe // =65534 + movk x0, #0xffff, lsl #16 + movk x0, #0xffff, lsl #32 + movk x0, #0xffff, lsl #48 + mov x1, #0x2 // =2 + mov w0, w0 + udiv x0, x0, x1 + sxtw x0, w0 + mov x17, #0xffff // =65535 + movk x17, #0x7fff, lsl #16 + cmp x0, x17 + b.eq + mov x0, #0x3 // =3 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xfff9 // =65529 + movk x0, #0xffff, lsl #16 + movk x0, #0xffff, lsl #32 + movk x0, #0xffff, lsl #48 + mov x1, #0x3 // =3 + sdiv x17, x0, x1 + msub x0, x17, x1, x0 + sxtw x0, w0 + mov x17, #0xffff // =65535 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + cmp x0, x17 + b.eq + mov x0, #0x4 // =4 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xffff // =65535 + movk x0, #0xffff, lsl #16 + movk x0, #0xffff, lsl #32 + movk x0, #0xffff, lsl #48 + mov x1, #0x3 // =3 + udiv x0, x0, x1 + mov x17, #0x5555 // =21845 + movk x17, #0x5555, lsl #16 + movk x17, #0x5555, lsl #32 + movk x17, #0x5555, lsl #48 + cmp x0, x17 + b.eq + mov x0, #0x5 // =5 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xff // =255 + mov x1, #0xfffe // =65534 + movk x1, #0xffff, lsl #16 + movk x1, #0xffff, lsl #32 + movk x1, #0xffff, lsl #48 + sdiv x0, x0, x1 + mov x17, #0xff // =255 + and x0, x0, x17 + mov x17, #0x81 // =129 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x6 // =6 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/compound_assign_unsigned_div.x64.asm b/tests/snapshots/asm/compound_assign_unsigned_div.x64.asm new file mode 100644 index 000000000..34cbd9cf6 --- /dev/null +++ b/tests/snapshots/asm/compound_assign_unsigned_div.x64.asm @@ -0,0 +1,109 @@ + +compound_assign_unsigned_div.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x30, %rsp + movl $0xffffffff, %eax # imm = 0xFFFFFFFF + movl $0xfffffffe, %ecx # imm = 0xFFFFFFFE + pushq %rdx + xorq %rdx, %rdx + divq %rcx + popq %rdx + movl %eax, %eax + xorq $0x1, %rax + movl %eax, %eax + testq %rax, %rax + je + movl $0x1, %eax + addq $0x30, %rsp + popq %rbp + retq + movl $0xffffffff, %eax # imm = 0xFFFFFFFF + movl $0xfffffffe, %ecx # imm = 0xFFFFFFFE + pushq %rdx + xorq %rdx, %rdx + divq %rcx + movq %rdx, %rax + popq %rdx + movl %eax, %eax + xorq $0x1, %rax + movl %eax, %eax + testq %rax, %rax + je + movl $0x2, %eax + addq $0x30, %rsp + popq %rbp + retq + movabsq $-0x2, %rax + movl $0x2, %ecx + movl %eax, %eax + pushq %rdx + xorq %rdx, %rdx + divq %rcx + popq %rdx + movslq %eax, %rax + cmpq $0x7fffffff, %rax # imm = 0x7FFFFFFF + je + movl $0x3, %eax + addq $0x30, %rsp + popq %rbp + retq + movabsq $-0x7, %rax + movl $0x3, %ecx + pushq %rdx + cqto + idivq %rcx + movq %rdx, %rax + popq %rdx + movslq %eax, %rax + cmpq $-0x1, %rax + je + movl $0x4, %eax + addq $0x30, %rsp + popq %rbp + retq + movabsq $-0x1, %rax + movl $0x3, %ecx + pushq %rdx + xorq %rdx, %rdx + divq %rcx + popq %rdx + movabsq $0x5555555555555555, %r11 # imm = 0x5555555555555555 + cmpq %r11, %rax + je + movl $0x5, %eax + addq $0x30, %rsp + popq %rbp + retq + movl $0xff, %eax + movabsq $-0x2, %rcx + pushq %rdx + cqto + idivq %rcx + popq %rdx + andq $0xff, %rax + xorq $0x81, %rax + movl %eax, %eax + testq %rax, %rax + je + movl $0x6, %eax + addq $0x30, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x30, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/const_expr_unsigned_fold.aarch64.asm b/tests/snapshots/asm/const_expr_unsigned_fold.aarch64.asm new file mode 100644 index 000000000..d60d73ebd --- /dev/null +++ b/tests/snapshots/asm/const_expr_unsigned_fold.aarch64.asm @@ -0,0 +1,110 @@ + +const_expr_unsigned_fold.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + adrp x0, + add x0, x0, + ldr x0, [x0] + mov x17, #0x5555 // =21845 + movk x17, #0x5555, lsl #16 + movk x17, #0x5555, lsl #32 + movk x17, #0x5555, lsl #48 + cmp x0, x17 + b.eq + mov x0, #0x1 // =1 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + ldr x0, [x0] + mov x17, #0xffff // =65535 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xfff, lsl #48 + cmp x0, x17 + b.eq + mov x0, #0x2 // =2 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + ldr x0, [x0] + cmp x0, #0x1 + b.eq + mov x0, #0x3 // =3 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + ldrsw x0, [x0] + cmp x0, #0x1 + b.eq + mov x0, #0x4 // =4 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + ldrsw x0, [x0] + cmp x0, #0x0 + b.eq + mov x0, #0x5 // =5 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + ldr x0, [x0] + mov x17, #-0x8000000000000000 // =-9223372036854775808 + cmp x0, x17 + b.eq + mov x0, #0x6 // =6 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x10 // =16 + mov x1, #0x0 // =0 + add x0, x0, x1 + asr x0, x0, #2 + cmp x0, #0x4 + b.eq + mov x0, #0x7 // =7 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xc // =12 + mov x1, #0x0 // =0 + add x0, x0, x1 + asr x0, x0, #2 + cmp x0, #0x3 + cset x1, ne + cbnz x1, + adrp x0, + add x0, x0, + ldrsw x0, [x0] + cmp x0, #0x0 + cset x1, ne + cbz x1, + mov x0, #0x8 // =8 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + b diff --git a/tests/snapshots/asm/const_expr_unsigned_fold.x64.asm b/tests/snapshots/asm/const_expr_unsigned_fold.x64.asm new file mode 100644 index 000000000..94f7d29d4 --- /dev/null +++ b/tests/snapshots/asm/const_expr_unsigned_fold.x64.asm @@ -0,0 +1,103 @@ + +const_expr_unsigned_fold.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x10, %rsp + leaq , %rax + movq (%rax), %rax + movabsq $0x5555555555555555, %r11 # imm = 0x5555555555555555 + cmpq %r11, %rax + je + movl $0x1, %eax + addq $0x10, %rsp + popq %rbp + retq + leaq , %rax + movq (%rax), %rax + movabsq $0xfffffffffffffff, %r11 # imm = 0xFFFFFFFFFFFFFFF + cmpq %r11, %rax + je + movl $0x2, %eax + addq $0x10, %rsp + popq %rbp + retq + leaq , %rax + movq (%rax), %rax + cmpq $0x1, %rax + je + movl $0x3, %eax + addq $0x10, %rsp + popq %rbp + retq + leaq , %rax + movslq (%rax), %rax + cmpq $0x1, %rax + je + movl $0x4, %eax + addq $0x10, %rsp + popq %rbp + retq + leaq , %rax + movslq (%rax), %rax + testq %rax, %rax + je + movl $0x5, %eax + addq $0x10, %rsp + popq %rbp + retq + leaq , %rax + movq (%rax), %rax + movabsq $-0x8000000000000000, %r11 # imm = 0x8000000000000000 + cmpq %r11, %rax + je + movl $0x6, %eax + addq $0x10, %rsp + popq %rbp + retq + movl $0x10, %eax + xorq %rcx, %rcx + addq %rcx, %rax + sarq $0x2, %rax + cmpq $0x4, %rax + je + movl $0x7, %eax + addq $0x10, %rsp + popq %rbp + retq + movl $0xc, %eax + xorq %rcx, %rcx + addq %rcx, %rax + sarq $0x2, %rax + cmpq $0x3, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + jne + leaq , %rax + movslq (%rax), %rax + testq %rax, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x8, %eax + addq $0x10, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x10, %rsp + popq %rbp + retq + jmp + addb %al, (%rax) diff --git a/tests/snapshots/asm/data_reloc_one_past_end.aarch64.asm b/tests/snapshots/asm/data_reloc_one_past_end.aarch64.asm new file mode 100644 index 000000000..da8fa6471 --- /dev/null +++ b/tests/snapshots/asm/data_reloc_one_past_end.aarch64.asm @@ -0,0 +1,35 @@ + +data_reloc_one_past_end.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + mov x2, #0x0 // =0 + adrp x1, + add x1, x1, + adrp x0, + add x0, x0, + ldr x0, [x0] + cmp x1, x0 + b.eq + ldr x0, [x1] + add x2, x2, x0 + add x1, x1, #0x8 + b + adrp x0, + add x0, x0, + ldr x0, [x0, #0x18] + add x0, x2, x0 + sxtw x0, w0 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/data_reloc_one_past_end.x64.asm b/tests/snapshots/asm/data_reloc_one_past_end.x64.asm new file mode 100644 index 000000000..55f3dc1eb --- /dev/null +++ b/tests/snapshots/asm/data_reloc_one_past_end.x64.asm @@ -0,0 +1,35 @@ + +data_reloc_one_past_end.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x10, %rsp + xorq %rdx, %rdx + leaq , %rcx + leaq , %rax + movq (%rax), %rax + cmpq %rax, %rcx + je + movq (%rcx), %rax + addq %rax, %rdx + addq $0x8, %rcx + jmp + leaq , %rax + movq 0x18(%rax), %rax + addq %rdx, %rax + movslq %eax, %rax + addq $0x10, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/decl_specifier_any_order.aarch64.asm b/tests/snapshots/asm/decl_specifier_any_order.aarch64.asm new file mode 100644 index 000000000..926afb583 --- /dev/null +++ b/tests/snapshots/asm/decl_specifier_any_order.aarch64.asm @@ -0,0 +1,89 @@ + +decl_specifier_any_order.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x30 + b + mov x0, #0x1 // =1 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + b + mov x0, #0x2 // =2 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x100000000 // =4294967296 + asr x0, x0, #32 + cmp x0, #0x1 + b.eq + mov x0, #0x3 // =3 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xffff // =65535 + movk x0, #0xffff, lsl #16 + movk x0, #0xffff, lsl #32 + movk x0, #0xffff, lsl #48 + mov w0, w0 + cmp x0, #0x0 + cset x0, hi + cmp x0, #0x0 + b.ne + mov x0, #0x4 // =4 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xffff // =65535 + movk x0, #0xffff, lsl #16 + movk x0, #0xffff, lsl #32 + movk x0, #0xffff, lsl #48 + mov x17, #0xff // =255 + and x0, x0, x17 + mov x17, #0xff // =255 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x5 // =5 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + b + mov x0, #0x6 // =6 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + b + mov x0, #0x7 // =7 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x30 + mov x1, #0xfffb // =65531 + movk x1, #0xffff, lsl #16 + movk x1, #0xffff, lsl #32 + movk x1, #0xffff, lsl #48 + str x1, [x0, #0x8] + sub x0, x29, #0x30 + ldr x0, [x0, #0x8] + cmp x0, #0x0 + b.lt + mov x0, #0x8 // =8 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/decl_specifier_any_order.x64.asm b/tests/snapshots/asm/decl_specifier_any_order.x64.asm new file mode 100644 index 000000000..ff8048b3c --- /dev/null +++ b/tests/snapshots/asm/decl_specifier_any_order.x64.asm @@ -0,0 +1,80 @@ + +decl_specifier_any_order.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x30, %rsp + jmp + movl $0x1, %eax + addq $0x30, %rsp + popq %rbp + retq + jmp + movl $0x2, %eax + addq $0x30, %rsp + popq %rbp + retq + movabsq $0x100000000, %rax # imm = 0x100000000 + sarq $0x20, %rax + cmpq $0x1, %rax + je + movl $0x3, %eax + addq $0x30, %rsp + popq %rbp + retq + movabsq $-0x1, %rax + movl %eax, %eax + testq %rax, %rax + seta %al + movzbq %al, %rax + testq %rax, %rax + jne + movl $0x4, %eax + addq $0x30, %rsp + popq %rbp + retq + movabsq $-0x1, %rax + andq $0xff, %rax + xorq $0xff, %rax + movl %eax, %eax + testq %rax, %rax + je + movl $0x5, %eax + addq $0x30, %rsp + popq %rbp + retq + jmp + movl $0x6, %eax + addq $0x30, %rsp + popq %rbp + retq + jmp + movl $0x7, %eax + addq $0x30, %rsp + popq %rbp + retq + leaq -0x30(%rbp), %rax + movabsq $-0x5, %rcx + movq %rcx, 0x8(%rax) + leaq -0x30(%rbp), %rax + movq 0x8(%rax), %rax + testq %rax, %rax + jl + movl $0x8, %eax + addq $0x30, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x30, %rsp + popq %rbp + retq diff --git a/tests/snapshots/asm/dlopen_atoi.aarch64.asm b/tests/snapshots/asm/dlopen_atoi.aarch64.asm index 2cdfd5a5c..36b1294bd 100644 --- a/tests/snapshots/asm/dlopen_atoi.aarch64.asm +++ b/tests/snapshots/asm/dlopen_atoi.aarch64.asm @@ -48,8 +48,8 @@ Disassembly of section .text: ret adrp x0, add x0, x0, - mov x9, x21 str x0, [sp, #-0x10]! + mov x9, x21 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/dlopen_strlen.aarch64.asm b/tests/snapshots/asm/dlopen_strlen.aarch64.asm index 3ca80adf2..c3f5435bd 100644 --- a/tests/snapshots/asm/dlopen_strlen.aarch64.asm +++ b/tests/snapshots/asm/dlopen_strlen.aarch64.asm @@ -22,8 +22,8 @@ Disassembly of section .text: bl adrp x1, add x1, x1, - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/fcntl_lock_via_cast_fnptr.aarch64.asm b/tests/snapshots/asm/fcntl_lock_via_cast_fnptr.aarch64.asm new file mode 100644 index 000000000..1985dd1b1 --- /dev/null +++ b/tests/snapshots/asm/fcntl_lock_via_cast_fnptr.aarch64.asm @@ -0,0 +1,133 @@ + +fcntl_lock_via_cast_fnptr.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x4d0 // =1232 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x140 + str x20, [sp] + str x21, [sp, #0x8] + str x22, [sp, #0x10] + str x23, [sp, #0x18] + str x24, [sp, #0x20] + str x19, [sp, #0x30] + sub x20, x29, #0x40 + mov x21, #0x40 // =64 + adrp x22, + add x22, x22, + bl + sxtw x0, w0 + mov x3, x0 + mov x0, x20 + mov x2, x22 + mov x1, x21 + bl + sxtw x0, w0 + sub x0, x29, #0x40 + mov x1, #0x42 // =66 + mov x2, #0x1a4 // =420 + bl + sxtw x0, w0 + mov x20, x0 + sxtw x0, w20 + cmp x0, #0x0 + b.ge + mov x0, #0x3 // =3 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x23, [sp, #0x18] + ldr x24, [sp, #0x20] + ldr x19, [sp, #0x30] + add sp, sp, #0x140 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0xa8 + mov x21, #0x0 // =0 + mov x2, #0x60 // =96 + mov x1, x21 + bl + sub x0, x29, #0xa8 + mov x22, #0x1 // =1 + strh w22, [x0] + sub x0, x29, #0xa8 + strh w21, [x0, #0x2] + sxtw x0, w20 + mov x21, #0x6 // =6 + sub x2, x29, #0xa8 + mov x1, x21 + bl + sxtw x0, w0 + mov x23, x0 + sub x0, x29, #0xa8 + mov x1, #0x2 // =2 + strh w1, [x0] + sxtw x0, w20 + sub x2, x29, #0xa8 + mov x1, x21 + bl + sxtw x0, w0 + mov x24, x0 + sub x0, x29, #0xa8 + strh w22, [x0] + adrp x0, + add x0, x0, + ldr x0, [x0] + sxtw x1, w20 + sub x2, x29, #0xa8 + mov x9, x0 + mov x0, x1 + mov x1, x21 + blr x9 + sxtw x21, w0 + sxtw x0, w20 + bl + sxtw x0, w0 + sub x0, x29, #0x40 + bl + sxtw x0, w0 + sxtw x0, w23 + cmp x0, #0x0 + cset x1, ne + cbnz x1, + sxtw x0, w24 + cmp x0, #0x0 + cset x1, ne + cbz x1, + mov x0, #0x2 // =2 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x23, [sp, #0x18] + ldr x24, [sp, #0x20] + ldr x19, [sp, #0x30] + add sp, sp, #0x140 + ldp x29, x30, [sp], #0x10 + ret + cmp x21, #0x0 + b.ne + mov x1, #0x0 // =0 + b + mov x1, #0x1 // =1 + mov x0, x1 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x23, [sp, #0x18] + ldr x24, [sp, #0x20] + ldr x19, [sp, #0x30] + add sp, sp, #0x140 + ldp x29, x30, [sp], #0x10 + ret + b + +<__c5_sys_fcntl>: + b diff --git a/tests/snapshots/asm/fcntl_lock_via_cast_fnptr.x64.asm b/tests/snapshots/asm/fcntl_lock_via_cast_fnptr.x64.asm new file mode 100644 index 000000000..a9a17c270 --- /dev/null +++ b/tests/snapshots/asm/fcntl_lock_via_cast_fnptr.x64.asm @@ -0,0 +1,142 @@ + +fcntl_lock_via_cast_fnptr.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x130, %rsp # imm = 0x130 + movq %rbx, (%rsp) + movq %r12, 0x8(%rsp) + movq %r13, 0x10(%rsp) + movq %r14, 0x18(%rsp) + movq %r15, 0x20(%rsp) + leaq -0x40(%rbp), %rbx + movl $0x40, %r12d + leaq , %r13 + xorl %eax, %eax + callq + movslq %eax, %rax + movq %rax, %rcx + movq %rbx, %rdi + movq %r13, %rdx + movq %r12, %rsi + movb $0x0, %al + callq + movslq %eax, %rax + leaq -0x40(%rbp), %rdi + movl $0x42, %esi + movl $0x1a4, %edx # imm = 0x1A4 + movb $0x0, %al + callq + movslq %eax, %rax + movq %rax, %rbx + movslq %ebx, %rax + testq %rax, %rax + jge + movl $0x3, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + addq $0x130, %rsp # imm = 0x130 + popq %rbp + retq + leaq -0xa8(%rbp), %rdi + xorq %r12, %r12 + movl $0x60, %edx + movq %r12, %rsi + xorl %eax, %eax + callq + leaq -0xa8(%rbp), %rax + movl $0x1, %r13d + movw %r13w, (%rax) + leaq -0xa8(%rbp), %rax + movw %r12w, 0x2(%rax) + movslq %ebx, %rdi + movl $0x6, %r12d + leaq -0xa8(%rbp), %rdx + movq %r12, %rsi + movb $0x0, %al + callq + movslq %eax, %rax + movq %rax, %r14 + leaq -0xa8(%rbp), %rax + movl $0x2, %ecx + movw %cx, (%rax) + movslq %ebx, %rdi + leaq -0xa8(%rbp), %rdx + movq %r12, %rsi + movb $0x0, %al + callq + movslq %eax, %rax + movq %rax, %r15 + leaq -0xa8(%rbp), %rax + movw %r13w, (%rax) + leaq , %rax + movq (%rax), %rax + movslq %ebx, %rdi + leaq -0xa8(%rbp), %rdx + movq %rax, %rcx + movq %r12, %rsi + movb $0x0, %al + callq *%rcx + movslq %eax, %r12 + movslq %ebx, %rdi + xorl %eax, %eax + callq + movslq %eax, %rax + leaq -0x40(%rbp), %rdi + xorl %eax, %eax + callq + movslq %eax, %rax + movslq %r14d, %rax + testq %rax, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + jne + movslq %r15d, %rax + testq %rax, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x2, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + addq $0x130, %rsp # imm = 0x130 + popq %rbp + retq + testq %r12, %r12 + jne + xorq %rcx, %rcx + jmp + movl $0x1, %ecx + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + movq %rcx, %rax + addq $0x130, %rsp # imm = 0x130 + popq %rbp + retq + jmp + +<__c5_sys_fcntl>: + jmp + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/float_arith_in_static_init.aarch64.asm b/tests/snapshots/asm/float_arith_in_static_init.aarch64.asm index cc1d48671..faed97e86 100644 --- a/tests/snapshots/asm/float_arith_in_static_init.aarch64.asm +++ b/tests/snapshots/asm/float_arith_in_static_init.aarch64.asm @@ -26,8 +26,7 @@ Disassembly of section .text: add sp, sp, #0x10 ldp x29, x30, [sp], #0x10 ret - add x1, x0, #0x4 - ldr s0, [x1] + ldr s0, [x0, #0x4] mov x1, #0x4004000000000000 // =4612811918334230528 fmov d16, x1 fneg d1, d16 @@ -39,8 +38,7 @@ Disassembly of section .text: add sp, sp, #0x10 ldp x29, x30, [sp], #0x10 ret - add x0, x0, #0x8 - ldr s0, [x0] + ldr s0, [x0, #0x8] mov x0, #0x4028000000000000 // =4622945017495814144 fcvt d0, s0 fmov d17, x0 @@ -79,8 +77,7 @@ Disassembly of section .text: ret adrp x0, add x0, x0, - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0x3fe8000000000000 // =4604930618986332160 fmov d16, x0 fneg d1, d16 diff --git a/tests/snapshots/asm/float_arith_in_static_init.x64.asm b/tests/snapshots/asm/float_arith_in_static_init.x64.asm index 6f5827631..d58817a1d 100644 --- a/tests/snapshots/asm/float_arith_in_static_init.x64.asm +++ b/tests/snapshots/asm/float_arith_in_static_init.x64.asm @@ -31,8 +31,7 @@ Disassembly of section .text: addq $0x10, %rsp popq %rbp retq - leaq 0x4(%rax), %rcx - movss (%rcx,%riz), %xmm0 + movss 0x4(%rax,%riz), %xmm0 movabsq $0x4004000000000000, %rcx # imm = 0x4004000000000000 movq %rcx, %xmm1 movabsq $-0x8000000000000000, %r10 # imm = 0x8000000000000000 @@ -51,8 +50,7 @@ Disassembly of section .text: addq $0x10, %rsp popq %rbp retq - addq $0x8, %rax - movss (%rax,%riz), %xmm0 + movss 0x8(%rax,%riz), %xmm0 movabsq $0x4028000000000000, %rax # imm = 0x4028000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -94,8 +92,7 @@ Disassembly of section .text: popq %rbp retq leaq , %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x3fe8000000000000, %rax # imm = 0x3FE8000000000000 movq %rax, %xmm1 movabsq $-0x8000000000000000, %r10 # imm = 0x8000000000000000 @@ -118,5 +115,3 @@ Disassembly of section .text: popq %rbp retq jmp - addb %al, (%rax) - addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/float_increment_decrement.aarch64.asm b/tests/snapshots/asm/float_increment_decrement.aarch64.asm index 14909594c..10bb7e4dd 100644 --- a/tests/snapshots/asm/float_increment_decrement.aarch64.asm +++ b/tests/snapshots/asm/float_increment_decrement.aarch64.asm @@ -175,12 +175,11 @@ Disassembly of section .text: fcvt s0, d0 str s0, [x0] sub x0, x29, #0x60 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x1, #-0x4010000000000000 // =-4616189618054758400 fmov d17, x1 fadd d0, d0, d17 - str d0, [x0] + str d0, [x0, #0x8] sub x0, x29, #0x60 ldr s0, [x0] mov x0, #0x4004000000000000 // =4612811918334230528 @@ -190,8 +189,7 @@ Disassembly of section .text: cset x1, ne cbnz x1, sub x0, x29, #0x60 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0x3ff8000000000000 // =4609434218613702656 fmov d17, x0 fcmp d0, d17 @@ -234,30 +232,26 @@ Disassembly of section .text: str x10, [x0, #0x10] ldr x10, [sp], #0x10 sub x0, x29, #0x78 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x1, #0x3ff0000000000000 // =4607182418800017408 fmov d17, x1 fadd d0, d0, d17 - str d0, [x0] + str d0, [x0, #0x8] sub x0, x29, #0x78 - add x0, x0, #0x10 - ldr d0, [x0] + ldr d0, [x0, #0x10] mov x1, #-0x4010000000000000 // =-4616189618054758400 fmov d17, x1 fadd d0, d0, d17 - str d0, [x0] + str d0, [x0, #0x10] sub x0, x29, #0x78 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0x4000000000000000 // =4611686018427387904 fmov d17, x0 fcmp d0, d17 cset x1, ne cbnz x1, sub x0, x29, #0x78 - add x0, x0, #0x10 - ldr d0, [x0] + ldr d0, [x0, #0x10] mov x0, #0x3ff0000000000000 // =4607182418800017408 fmov d17, x0 fcmp d0, d17 diff --git a/tests/snapshots/asm/float_increment_decrement.x64.asm b/tests/snapshots/asm/float_increment_decrement.x64.asm index 6577ea860..e3d4a4920 100644 --- a/tests/snapshots/asm/float_increment_decrement.x64.asm +++ b/tests/snapshots/asm/float_increment_decrement.x64.asm @@ -207,12 +207,11 @@ Disassembly of section .text: cvtsd2ss %xmm0, %xmm0 movss %xmm0, (%rax,%riz) leaq -0x60(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $-0x4010000000000000, %rcx # imm = 0xBFF0000000000000 movq %rcx, %xmm15 addsd %xmm15, %xmm0 - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x8(%rax,%riz) leaq -0x60(%rbp), %rax movss (%rax,%riz), %xmm0 movabsq $0x4004000000000000, %rax # imm = 0x4004000000000000 @@ -227,8 +226,7 @@ Disassembly of section .text: testq %rcx, %rcx jne leaq -0x60(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x3ff8000000000000, %rax # imm = 0x3FF8000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -279,22 +277,19 @@ Disassembly of section .text: movq %rdx, 0x10(%rax) popq %rdx leaq -0x78(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x3ff0000000000000, %rcx # imm = 0x3FF0000000000000 movq %rcx, %xmm15 addsd %xmm15, %xmm0 - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x8(%rax,%riz) leaq -0x78(%rbp), %rax - addq $0x10, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x10(%rax,%riz), %xmm0 movabsq $-0x4010000000000000, %rcx # imm = 0xBFF0000000000000 movq %rcx, %xmm15 addsd %xmm15, %xmm0 - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x10(%rax,%riz) leaq -0x78(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x4000000000000000, %rax # imm = 0x4000000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -306,8 +301,7 @@ Disassembly of section .text: testq %rcx, %rcx jne leaq -0x78(%rbp), %rax - addq $0x10, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x10(%rax,%riz), %xmm0 movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -359,5 +353,4 @@ Disassembly of section .text: jmp jmp jmp - addb %al, (%rax) addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/float_is_four_bytes.aarch64.asm b/tests/snapshots/asm/float_is_four_bytes.aarch64.asm index b8233ec2a..9c028eee0 100644 --- a/tests/snapshots/asm/float_is_four_bytes.aarch64.asm +++ b/tests/snapshots/asm/float_is_four_bytes.aarch64.asm @@ -130,8 +130,7 @@ Disassembly of section .text: mov x20, #0x7 // =7 adrp x0, add x0, x0, - add x0, x0, #0x4 - ldr s0, [x0] + ldr s0, [x0, #0x4] mov x0, #0x4004000000000000 // =4612811918334230528 fcvt d0, s0 fmov d17, x0 @@ -142,16 +141,14 @@ Disassembly of section .text: add x0, x0, adrp x1, add x1, x1, - add x1, x1, #0x4 - ldr s0, [x1] + ldr s0, [x1, #0x4] fcvt d0, s0 bl sxtw x0, w0 mov x20, #0x8 // =8 adrp x0, add x0, x0, - add x0, x0, #0x8 - ldr s0, [x0] + ldr s0, [x0, #0x8] mov x0, #0x400c000000000000 // =4615063718147915776 fcvt d0, s0 fmov d17, x0 @@ -162,16 +159,14 @@ Disassembly of section .text: add x0, x0, adrp x1, add x1, x1, - add x1, x1, #0x8 - ldr s0, [x1] + ldr s0, [x1, #0x8] fcvt d0, s0 bl sxtw x0, w0 mov x20, #0x9 // =9 adrp x0, add x0, x0, - add x0, x0, #0xc - ldr s0, [x0] + ldr s0, [x0, #0xc] mov x0, #0x4012000000000000 // =4616752568008179712 fcvt d0, s0 fmov d17, x0 @@ -182,8 +177,7 @@ Disassembly of section .text: add x0, x0, adrp x1, add x1, x1, - add x1, x1, #0xc - ldr s0, [x1] + ldr s0, [x1, #0xc] fcvt d0, s0 bl sxtw x0, w0 diff --git a/tests/snapshots/asm/float_is_four_bytes.x64.asm b/tests/snapshots/asm/float_is_four_bytes.x64.asm index 0389887f4..309c468c1 100644 --- a/tests/snapshots/asm/float_is_four_bytes.x64.asm +++ b/tests/snapshots/asm/float_is_four_bytes.x64.asm @@ -127,8 +127,7 @@ Disassembly of section .text: movslq %eax, %rax movl $0x7, %ebx leaq , %rax - addq $0x4, %rax - movss (%rax,%riz), %xmm0 + movss 0x4(%rax,%riz), %xmm0 movabsq $0x4004000000000000, %rax # imm = 0x4004000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -142,16 +141,14 @@ Disassembly of section .text: je leaq , %rdi leaq , %rax - addq $0x4, %rax - movss (%rax,%riz), %xmm0 + movss 0x4(%rax,%riz), %xmm0 cvtss2sd %xmm0, %xmm0 movb $0x1, %al callq movslq %eax, %rax movl $0x8, %ebx leaq , %rax - addq $0x8, %rax - movss (%rax,%riz), %xmm0 + movss 0x8(%rax,%riz), %xmm0 movabsq $0x400c000000000000, %rax # imm = 0x400C000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -165,16 +162,14 @@ Disassembly of section .text: je leaq , %rdi leaq , %rax - addq $0x8, %rax - movss (%rax,%riz), %xmm0 + movss 0x8(%rax,%riz), %xmm0 cvtss2sd %xmm0, %xmm0 movb $0x1, %al callq movslq %eax, %rax movl $0x9, %ebx leaq , %rax - addq $0xc, %rax - movss (%rax,%riz), %xmm0 + movss 0xc(%rax,%riz), %xmm0 movabsq $0x4012000000000000, %rax # imm = 0x4012000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -188,8 +183,7 @@ Disassembly of section .text: je leaq , %rdi leaq , %rax - addq $0xc, %rax - movss (%rax,%riz), %xmm0 + movss 0xc(%rax,%riz), %xmm0 cvtss2sd %xmm0, %xmm0 movb $0x1, %al callq @@ -356,5 +350,4 @@ Disassembly of section .text: jmp jmp jmp - addb %al, (%rax) addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/float_ternary_promote.aarch64.asm b/tests/snapshots/asm/float_ternary_promote.aarch64.asm new file mode 100644 index 000000000..5000596d4 --- /dev/null +++ b/tests/snapshots/asm/float_ternary_promote.aarch64.asm @@ -0,0 +1,150 @@ + +float_ternary_promote.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x20 + sxtw x0, w0 + fmov d2, d0 + cbz x0, + b + fmov d2, d1 + fmov d0, d2 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x60 + str d8, [sp] + str x20, [sp, #0x10] + mov x0, #0x1 // =1 + mov x20, #0x3ff8000000000000 // =4609434218613702656 + fmov d16, x20 + fcvt s0, d16 + mov x1, #0x4004000000000000 // =4612811918334230528 + fmov d16, x1 + fneg d1, d16 + fcvt s1, d1 + bl + fcvt d0, s0 + fmov d17, x20 + fcmp d0, d17 + cset x0, ne + cbz x0, + mov x0, #0x1 // =1 + ldr x20, [sp, #0x10] + ldr d8, [sp] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + mov x1, #0x3ff8000000000000 // =4609434218613702656 + fmov d16, x1 + fcvt s0, d16 + mov x1, #0x4004000000000000 // =4612811918334230528 + fmov d16, x1 + fneg d8, d16 + fcvt s1, d8 + bl + fcvt d0, s0 + fcmp d0, d8 + cset x0, ne + cbz x0, + mov x0, #0x2 // =2 + ldr x20, [sp, #0x10] + ldr d8, [sp] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x400a000000000000 // =4614500768194494464 + fmov d16, x0 + fcvt s2, d16 + mov x0, #0x0 // =0 + fcvt d0, s2 + fmov d17, x0 + fcmp d0, d17 + cset x0, gt + cbz x0, + fmov d0, d2 + b + fneg s0, s2 + mov x0, #0x0 // =0 + fcvt d1, s2 + fmov d17, x0 + fcmp d1, d17 + cset x0, mi + cbz x0, + fneg s2, s2 + b + fadd s0, s0, s2 + mov x0, #0x401a000000000000 // =4619004367821864960 + fcvt d0, s0 + fmov d17, x0 + fcmp d0, d17 + cset x0, ne + cbz x0, + mov x0, #0x3 // =3 + ldr x20, [sp, #0x10] + ldr d8, [sp] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x2 // =2 + cmp x0, #0x0 + b.ne + mov x0, #0x0 // =0 + fmov d16, x0 + sub x17, x29, #0x38 + str d16, [x17] + b + cmp x0, #0x1 + b.ne + b + sub x16, x29, #0x38 + ldr d0, [x16] + fcvt s0, d0 + mov x0, #0x4034000000000000 // =4626322717216342016 + fcvt d0, s0 + fmov d17, x0 + fcmp d0, d17 + cset x0, ne + cbz x0, + b + mov x0, #0x4024000000000000 // =4621819117588971520 + fmov d16, x0 + sub x17, x29, #0x40 + str d16, [x17] + b + mov x0, #0x4034000000000000 // =4626322717216342016 + fmov d16, x0 + sub x17, x29, #0x40 + str d16, [x17] + sub x16, x29, #0x40 + ldr d0, [x16] + sub x17, x29, #0x38 + str d0, [x17] + b + mov x0, #0x4 // =4 + ldr x20, [sp, #0x10] + ldr d8, [sp] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x20, [sp, #0x10] + ldr d8, [sp] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/float_ternary_promote.x64.asm b/tests/snapshots/asm/float_ternary_promote.x64.asm new file mode 100644 index 000000000..4baa9b1e4 --- /dev/null +++ b/tests/snapshots/asm/float_ternary_promote.x64.asm @@ -0,0 +1,181 @@ + +float_ternary_promote.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + subq $0x20, %rsp + movslq %edi, %rdi + movapd %xmm0, %xmm2 + testq %rdi, %rdi + je + jmp + movapd %xmm1, %xmm2 + movapd %xmm2, %xmm0 + addq $0x20, %rsp + popq %rbp + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x60, %rsp + movq %rbx, (%rsp) + movl $0x1, %edi + movabsq $0x3ff8000000000000, %rbx # imm = 0x3FF8000000000000 + movq %rbx, %xmm14 + cvtsd2ss %xmm14, %xmm0 + movabsq $0x4004000000000000, %rax # imm = 0x4004000000000000 + movq %rax, %xmm1 + movabsq $-0x8000000000000000, %r10 # imm = 0x8000000000000000 + movq %r10, %xmm15 + xorpd %xmm15, %xmm1 + cvtsd2ss %xmm1, %xmm1 + callq + cvtss2sd %xmm0, %xmm0 + movq %rbx, %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x1, %eax + movq (%rsp), %rbx + addq $0x60, %rsp + popq %rbp + retq + xorq %rdi, %rdi + movabsq $0x3ff8000000000000, %rax # imm = 0x3FF8000000000000 + movq %rax, %xmm14 + cvtsd2ss %xmm14, %xmm0 + movabsq $0x4004000000000000, %rax # imm = 0x4004000000000000 + movq %rax, %xmm14 + movabsq $-0x8000000000000000, %r10 # imm = 0x8000000000000000 + movq %r10, %xmm15 + xorpd %xmm15, %xmm14 + movsd %xmm14, 0x18(%rsp) + movsd 0x18(%rsp), %xmm14 + cvtsd2ss %xmm14, %xmm1 + callq + cvtss2sd %xmm0, %xmm0 + movsd 0x18(%rsp), %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x2, %eax + movq (%rsp), %rbx + addq $0x60, %rsp + popq %rbp + retq + movabsq $0x400a000000000000, %rax # imm = 0x400A000000000000 + movq %rax, %xmm14 + cvtsd2ss %xmm14, %xmm2 + xorq %rax, %rax + cvtss2sd %xmm2, %xmm0 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + seta %al + movzbq %al, %rax + testq %rax, %rax + je + movapd %xmm2, %xmm0 + jmp + movapd %xmm2, %xmm0 + movl $0x80000000, %r10d # imm = 0x80000000 + movq %r10, %xmm15 + xorpd %xmm15, %xmm0 + xorq %rax, %rax + cvtss2sd %xmm2, %xmm1 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm1 + setb %al + movzbq %al, %rax + setnp %r10b + movzbq %r10b, %r10 + andq %r10, %rax + testq %rax, %rax + je + movl $0x80000000, %r10d # imm = 0x80000000 + movq %r10, %xmm15 + xorpd %xmm15, %xmm2 + jmp + addss %xmm2, %xmm0 + movabsq $0x401a000000000000, %rax # imm = 0x401A000000000000 + cvtss2sd %xmm0, %xmm0 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x3, %eax + movq (%rsp), %rbx + addq $0x60, %rsp + popq %rbp + retq + movl $0x2, %eax + testq %rax, %rax + jne + xorq %rax, %rax + movq %rax, %xmm14 + movsd %xmm14, -0x38(%rbp,%riz) + jmp + cmpq $0x1, %rax + jne + jmp + movsd -0x38(%rbp,%riz), %xmm0 + cvtsd2ss %xmm0, %xmm0 + movabsq $0x4034000000000000, %rax # imm = 0x4034000000000000 + cvtss2sd %xmm0, %xmm0 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + jmp + movabsq $0x4024000000000000, %rax # imm = 0x4024000000000000 + movq %rax, %xmm14 + movsd %xmm14, -0x40(%rbp,%riz) + jmp + movabsq $0x4034000000000000, %rax # imm = 0x4034000000000000 + movq %rax, %xmm14 + movsd %xmm14, -0x40(%rbp,%riz) + movsd -0x40(%rbp,%riz), %xmm0 + movsd %xmm0, -0x38(%rbp,%riz) + jmp + movl $0x4, %eax + movq (%rsp), %rbx + addq $0x60, %rsp + popq %rbp + retq + xorq %rax, %rax + movq (%rsp), %rbx + addq $0x60, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/float_variadic_promotion.aarch64.asm b/tests/snapshots/asm/float_variadic_promotion.aarch64.asm index c9890d1d7..e0ea58670 100644 --- a/tests/snapshots/asm/float_variadic_promotion.aarch64.asm +++ b/tests/snapshots/asm/float_variadic_promotion.aarch64.asm @@ -93,6 +93,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x10 str w16, [x17, #0x1c] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/fma_numeric_kernels.aarch64.asm b/tests/snapshots/asm/fma_numeric_kernels.aarch64.asm index 3f795f3bc..303448f11 100644 --- a/tests/snapshots/asm/fma_numeric_kernels.aarch64.asm +++ b/tests/snapshots/asm/fma_numeric_kernels.aarch64.asm @@ -138,25 +138,21 @@ Disassembly of section .text: fmov d16, x1 str d16, [x0] sub x0, x29, #0x28 - add x0, x0, #0x8 mov x2, #0x4000000000000000 // =4611686018427387904 fmov d16, x2 - str d16, [x0] + str d16, [x0, #0x8] sub x0, x29, #0x28 - add x0, x0, #0x10 mov x1, #0x4008000000000000 // =4613937818241073152 fmov d16, x1 - str d16, [x0] + str d16, [x0, #0x10] sub x0, x29, #0x28 - add x0, x0, #0x18 mov x1, #0x4010000000000000 // =4616189618054758400 fmov d16, x1 - str d16, [x0] + str d16, [x0, #0x18] sub x0, x29, #0x28 - add x0, x0, #0x20 mov x1, #0x4014000000000000 // =4617315517961601024 fmov d16, x1 - str d16, [x0] + str d16, [x0, #0x20] sub x0, x29, #0x28 mov x1, #0x5 // =5 fmov d0, x2 diff --git a/tests/snapshots/asm/fma_numeric_kernels.x64.asm b/tests/snapshots/asm/fma_numeric_kernels.x64.asm index 8b28194af..d6838c151 100644 --- a/tests/snapshots/asm/fma_numeric_kernels.x64.asm +++ b/tests/snapshots/asm/fma_numeric_kernels.x64.asm @@ -168,25 +168,21 @@ Disassembly of section .text: movq %rcx, %xmm14 movsd %xmm14, (%rax,%riz) leaq -0x28(%rbp), %rax - addq $0x8, %rax movabsq $0x4000000000000000, %rdx # imm = 0x4000000000000000 movq %rdx, %xmm14 - movsd %xmm14, (%rax,%riz) + movsd %xmm14, 0x8(%rax,%riz) leaq -0x28(%rbp), %rax - addq $0x10, %rax movabsq $0x4008000000000000, %rcx # imm = 0x4008000000000000 movq %rcx, %xmm14 - movsd %xmm14, (%rax,%riz) + movsd %xmm14, 0x10(%rax,%riz) leaq -0x28(%rbp), %rax - addq $0x18, %rax movabsq $0x4010000000000000, %rcx # imm = 0x4010000000000000 movq %rcx, %xmm14 - movsd %xmm14, (%rax,%riz) + movsd %xmm14, 0x18(%rax,%riz) leaq -0x28(%rbp), %rax - addq $0x20, %rax movabsq $0x4014000000000000, %rcx # imm = 0x4014000000000000 movq %rcx, %xmm14 - movsd %xmm14, (%rax,%riz) + movsd %xmm14, 0x20(%rax,%riz) leaq -0x28(%rbp), %rdi movl $0x5, %esi movq %rdx, %xmm0 diff --git a/tests/snapshots/asm/fn_ptr_decay_inside_block.aarch64.asm b/tests/snapshots/asm/fn_ptr_decay_inside_block.aarch64.asm index 86fff3d75..183981708 100644 --- a/tests/snapshots/asm/fn_ptr_decay_inside_block.aarch64.asm +++ b/tests/snapshots/asm/fn_ptr_decay_inside_block.aarch64.asm @@ -38,15 +38,15 @@ Disassembly of section .text: adrp x21, add x21, x21, mov x0, #0x1 // =1 - mov x9, x21 str x0, [sp, #-0x10]! + mov x9, x21 ldr x0, [sp] blr x9 add sp, sp, #0x10 add x20, x20, x0 mov x0, #0x2 // =2 - mov x9, x21 str x0, [sp, #-0x10]! + mov x9, x21 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -58,8 +58,8 @@ Disassembly of section .text: mov x1, #0x0 // =0 b mov x0, #0x3 // =3 - mov x9, x1 str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -71,8 +71,8 @@ Disassembly of section .text: sub x0, x29, #0x48 ldr x0, [x0] mov x1, #0x4 // =4 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/fn_ptr_explicit_deref.aarch64.asm b/tests/snapshots/asm/fn_ptr_explicit_deref.aarch64.asm index 47f4f915e..b441ff29a 100644 --- a/tests/snapshots/asm/fn_ptr_explicit_deref.aarch64.asm +++ b/tests/snapshots/asm/fn_ptr_explicit_deref.aarch64.asm @@ -25,8 +25,8 @@ Disassembly of section .text: stur x0, [x29, #-0x8] mov x0, #0x28 // =40 ldur x1, [x29, #-0x8] - mov x9, x1 str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -41,8 +41,8 @@ Disassembly of section .text: ret mov x0, #0x28 // =40 ldur x1, [x29, #-0x8] - mov x9, x1 str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -58,8 +58,8 @@ Disassembly of section .text: sub x20, x29, #0x8 ldr x0, [x20] mov x1, #0x28 // =40 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -74,8 +74,8 @@ Disassembly of section .text: ret ldr x0, [x20] mov x1, #0x28 // =40 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/fn_ptr_float_arg.aarch64.asm b/tests/snapshots/asm/fn_ptr_float_arg.aarch64.asm index 91aeccaec..3f5f29da9 100644 --- a/tests/snapshots/asm/fn_ptr_float_arg.aarch64.asm +++ b/tests/snapshots/asm/fn_ptr_float_arg.aarch64.asm @@ -40,10 +40,10 @@ Disassembly of section .text: sub sp, sp, #0x30 str x19, [sp] sxtw x0, w0 - mov x9, x1 fmov x16, d0 str x16, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] ldr d0, [sp, #0x10] blr x9 @@ -77,9 +77,9 @@ Disassembly of section .text: mov x0, #0x4004000000000000 // =4612811918334230528 fmov d16, x0 fcvt s0, d16 - mov x9, x20 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x20 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -98,10 +98,10 @@ Disassembly of section .text: mov x2, #0x4012000000000000 // =4616752568008179712 fmov d16, x2 fcvt s0, d16 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr d0, [sp, #0x10] blr x9 @@ -133,9 +133,9 @@ Disassembly of section .text: mov x0, #0x400c000000000000 // =4615063718147915776 fmov d16, x0 fcvt s0, d16 - mov x9, x20 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x20 ldr d0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/fn_ptr_float_arg_narrow.aarch64.asm b/tests/snapshots/asm/fn_ptr_float_arg_narrow.aarch64.asm index 6eddddaf6..fd5140825 100644 --- a/tests/snapshots/asm/fn_ptr_float_arg_narrow.aarch64.asm +++ b/tests/snapshots/asm/fn_ptr_float_arg_narrow.aarch64.asm @@ -60,9 +60,9 @@ Disassembly of section .text: mov x1, #0x4008000000000000 // =4613937818241073152 fmov d16, x1 fcvt s0, d16 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -83,9 +83,9 @@ Disassembly of section .text: mov x20, #0x4008000000000000 // =4613937818241073152 fmov d16, x20 fcvt s0, d16 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -107,9 +107,9 @@ Disassembly of section .text: mov x1, #0x4010000000000000 // =4616189618054758400 fmov d16, x1 fcvt s0, d16 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -140,11 +140,11 @@ Disassembly of section .text: mov x1, #0x4000000000000000 // =4611686018427387904 fmov d16, x1 fcvt s1, d16 - mov x9, x0 fmov x16, d1 str x16, [sp, #-0x10]! fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] ldr d1, [sp, #0x10] blr x9 @@ -166,9 +166,9 @@ Disassembly of section .text: mov x1, #0x4014000000000000 // =4617315517961601024 fmov d16, x1 fcvt s0, d16 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -189,9 +189,9 @@ Disassembly of section .text: fcvt s0, d16 sub x0, x29, #0x10 ldr x0, [x0] - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -222,9 +222,9 @@ Disassembly of section .text: mov x1, #0x4008000000000000 // =4613937818241073152 fmov d16, x1 fcvt s0, d16 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -244,9 +244,9 @@ Disassembly of section .text: mov x1, #0x4008000000000000 // =4613937818241073152 fmov d16, x1 fcvt s0, d16 - mov x9, x0 fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -269,11 +269,11 @@ Disassembly of section .text: mov x1, #0x4000000000000000 // =4611686018427387904 fmov d16, x1 fcvt s1, d16 - mov x9, x0 fmov x16, d1 str x16, [sp, #-0x10]! fmov x16, d0 str x16, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] ldr d1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/fn_ptr_float_return.aarch64.asm b/tests/snapshots/asm/fn_ptr_float_return.aarch64.asm index 3af29b9a5..206e7029b 100644 --- a/tests/snapshots/asm/fn_ptr_float_return.aarch64.asm +++ b/tests/snapshots/asm/fn_ptr_float_return.aarch64.asm @@ -64,8 +64,8 @@ Disassembly of section .text: adrp x0, add x0, x0, mov x1, #0xa // =10 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -84,8 +84,8 @@ Disassembly of section .text: adrp x0, add x0, x0, mov x1, #0x4000000000000000 // =4611686018427387904 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr d0, [sp] blr x9 add sp, sp, #0x10 @@ -118,8 +118,8 @@ Disassembly of section .text: adrp x0, add x0, x0, mov x1, #0x8 // =8 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/fn_ptr_multi_deref.aarch64.asm b/tests/snapshots/asm/fn_ptr_multi_deref.aarch64.asm index 58cf0ac12..eca3e6117 100644 --- a/tests/snapshots/asm/fn_ptr_multi_deref.aarch64.asm +++ b/tests/snapshots/asm/fn_ptr_multi_deref.aarch64.asm @@ -38,9 +38,9 @@ Disassembly of section .text: add x20, x20, mov x1, #0x4 // =4 mov x2, #0x5 // =5 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -56,9 +56,9 @@ Disassembly of section .text: ret mov x0, #0x6 // =6 mov x1, #0x7 // =7 - mov x9, x20 str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/fn_ptr_struct_return.aarch64.asm b/tests/snapshots/asm/fn_ptr_struct_return.aarch64.asm index 50d48c953..6a4d7e5fd 100644 --- a/tests/snapshots/asm/fn_ptr_struct_return.aarch64.asm +++ b/tests/snapshots/asm/fn_ptr_struct_return.aarch64.asm @@ -25,8 +25,8 @@ Disassembly of section .text: adrp x20, add x20, x20, ldr x1, [x20] - mov x9, x1 str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -41,8 +41,8 @@ Disassembly of section .text: ret ldr x0, [x20] mov x1, #0x0 // =0 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -57,8 +57,8 @@ Disassembly of section .text: ret ldr x0, [x20] mov x1, #0x0 // =0 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -74,8 +74,8 @@ Disassembly of section .text: adrp x21, add x21, x21, mov x0, #0x0 // =0 - mov x9, x21 str x0, [sp, #-0x10]! + mov x9, x21 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -89,8 +89,8 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret mov x0, #0x0 // =0 - mov x9, x21 str x0, [sp, #-0x10]! + mov x9, x21 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -105,8 +105,8 @@ Disassembly of section .text: ret ldr x0, [x20] mov x1, #0x0 // =0 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/fn_ptr_ternary_call_return.aarch64.asm b/tests/snapshots/asm/fn_ptr_ternary_call_return.aarch64.asm index 7fdd5db90..998365d77 100644 --- a/tests/snapshots/asm/fn_ptr_ternary_call_return.aarch64.asm +++ b/tests/snapshots/asm/fn_ptr_ternary_call_return.aarch64.asm @@ -39,8 +39,8 @@ Disassembly of section .text: b adrp x1, add x1, x1, - mov x9, x1 str x20, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -53,8 +53,8 @@ Disassembly of section .text: mov x0, #0x7890 // =30864 movk x0, #0x3456, lsl #16 movk x0, #0x12, lsl #32 - mov x9, x1 str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/fn_ptr_typedef_multi_declarator.aarch64.asm b/tests/snapshots/asm/fn_ptr_typedef_multi_declarator.aarch64.asm index 6fc1b8d36..5a7f5d34b 100644 --- a/tests/snapshots/asm/fn_ptr_typedef_multi_declarator.aarch64.asm +++ b/tests/snapshots/asm/fn_ptr_typedef_multi_declarator.aarch64.asm @@ -62,8 +62,8 @@ Disassembly of section .text: adrp x21, add x21, x21, sub x0, x29, #0x28 - mov x9, x21 str x0, [sp, #-0x10]! + mov x9, x21 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -78,8 +78,8 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret sub x0, x29, #0x28 - mov x9, x21 str x0, [sp, #-0x10]! + mov x9, x21 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/fn_returning_fn_ptr.aarch64.asm b/tests/snapshots/asm/fn_returning_fn_ptr.aarch64.asm index 6963c8d18..825fff43e 100644 --- a/tests/snapshots/asm/fn_returning_fn_ptr.aarch64.asm +++ b/tests/snapshots/asm/fn_returning_fn_ptr.aarch64.asm @@ -38,9 +38,9 @@ Disassembly of section .text: bl mov x1, #0x7 // =7 mov x2, #0x3 // =3 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -57,9 +57,9 @@ Disassembly of section .text: bl mov x1, #0xa // =10 mov x2, #0x6 // =6 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -85,9 +85,9 @@ Disassembly of section .text: bl mov x1, #0x9 // =9 mov x2, #0x2 // =2 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/fnptr_param_indirection.aarch64.asm b/tests/snapshots/asm/fnptr_param_indirection.aarch64.asm index 8b2cb04c5..4f5a7d96c 100644 --- a/tests/snapshots/asm/fnptr_param_indirection.aarch64.asm +++ b/tests/snapshots/asm/fnptr_param_indirection.aarch64.asm @@ -54,8 +54,8 @@ Disassembly of section .text: ret mov x0, #0xa // =10 ldur x1, [x29, #-0x8] - mov x9, x1 str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -82,8 +82,8 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret mov x0, #0xa // =10 - mov x9, x1 str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -106,8 +106,8 @@ Disassembly of section .text: cbnz x1, mov x0, #0x3 // =3 ldur x1, [x29, #-0x20] - mov x9, x1 str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/fnptr_typedef_return_proto.aarch64.asm b/tests/snapshots/asm/fnptr_typedef_return_proto.aarch64.asm index 34ae33cc4..a444ea863 100644 --- a/tests/snapshots/asm/fnptr_typedef_return_proto.aarch64.asm +++ b/tests/snapshots/asm/fnptr_typedef_return_proto.aarch64.asm @@ -33,9 +33,9 @@ Disassembly of section .text: add x0, x0, mov x1, #0x14 // =20 mov x2, #0x16 // =22 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/forge_code_pointer.aarch64.asm b/tests/snapshots/asm/forge_code_pointer.aarch64.asm index 42d96a3c5..c1779ed6b 100644 --- a/tests/snapshots/asm/forge_code_pointer.aarch64.asm +++ b/tests/snapshots/asm/forge_code_pointer.aarch64.asm @@ -16,8 +16,8 @@ Disassembly of section .text: str x19, [sp] mov x0, #0x2a // =42 mov x1, #0x0 // =0 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/forward_fn_ptr_in_static_init.aarch64.asm b/tests/snapshots/asm/forward_fn_ptr_in_static_init.aarch64.asm index 216c79f54..58e057527 100644 --- a/tests/snapshots/asm/forward_fn_ptr_in_static_init.aarch64.asm +++ b/tests/snapshots/asm/forward_fn_ptr_in_static_init.aarch64.asm @@ -35,8 +35,8 @@ Disassembly of section .text: adrp x2, add x2, x2, ldr x0, [x2, x0, lsl #3] - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/fp_load_folded_disp.aarch64.asm b/tests/snapshots/asm/fp_load_folded_disp.aarch64.asm new file mode 100644 index 000000000..e27ae1726 --- /dev/null +++ b/tests/snapshots/asm/fp_load_folded_disp.aarch64.asm @@ -0,0 +1,114 @@ + +fp_load_folded_disp.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + ldr s0, [x0, #0x8] + ret + +: + ldr d0, [x0, #0x10] + ret + +: + ldr s0, [x0, #0x20] + ret + +: + ldr d0, [x0, #0x10] + mov x1, #0x3fe0000000000000 // =4602678819172646912 + fmov d17, x1 + fadd d0, d0, d17 + str d0, [x0, #0x10] + mov x0, #0x0 // =0 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x30 + sub x0, x29, #0x28 + mov x1, #0xffff // =65535 + movk x1, #0xffff, lsl #16 + movk x1, #0xffff, lsl #32 + movk x1, #0xffff, lsl #48 + str x1, [x0] + sub x0, x29, #0x28 + mov x1, #0x3ff4000000000000 // =4608308318706860032 + fmov d16, x1 + fcvt s0, d16 + str s0, [x0, #0x8] + sub x0, x29, #0x28 + mov x2, #0x4004000000000000 // =4612811918334230528 + fmov d16, x2 + str d16, [x0, #0x10] + sub x0, x29, #0x28 + mov x2, #0x0 // =0 + fmov d16, x2 + fcvt s0, d16 + str s0, [x0, #0x18] + sub x0, x29, #0x28 + str s0, [x0, #0x1c] + sub x0, x29, #0x28 + mov x2, #0x4013000000000000 // =4617034042984890368 + fmov d16, x2 + fcvt s0, d16 + str s0, [x0, #0x20] + sub x0, x29, #0x28 + ldr s0, [x0, #0x8] + fcvt d0, s0 + fmov d17, x1 + fcmp d0, d17 + cset x0, ne + cbz x0, + mov x0, #0x1 // =1 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x28 + ldr d0, [x0, #0x10] + mov x0, #0x4004000000000000 // =4612811918334230528 + fmov d17, x0 + fcmp d0, d17 + cset x0, ne + cbz x0, + mov x0, #0x2 // =2 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x28 + ldr s0, [x0, #0x20] + mov x0, #0x4013000000000000 // =4617034042984890368 + fcvt d0, s0 + fmov d17, x0 + fcmp d0, d17 + cset x0, ne + cbz x0, + mov x0, #0x3 // =3 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x28 + bl + sub x0, x29, #0x28 + ldr d0, [x0, #0x10] + mov x0, #0x4008000000000000 // =4613937818241073152 + fmov d17, x0 + fcmp d0, d17 + cset x0, ne + cbz x0, + mov x0, #0x4 // =4 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/fp_load_folded_disp.x64.asm b/tests/snapshots/asm/fp_load_folded_disp.x64.asm new file mode 100644 index 000000000..e20c64f57 --- /dev/null +++ b/tests/snapshots/asm/fp_load_folded_disp.x64.asm @@ -0,0 +1,134 @@ + +fp_load_folded_disp.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + movss 0x8(%rdi,%riz), %xmm0 + retq + +: + movsd 0x10(%rdi,%riz), %xmm0 + retq + +: + movss 0x20(%rdi,%riz), %xmm0 + retq + +: + movsd 0x10(%rdi,%riz), %xmm0 + movabsq $0x3fe0000000000000, %rax # imm = 0x3FE0000000000000 + movq %rax, %xmm15 + addsd %xmm15, %xmm0 + movsd %xmm0, 0x10(%rdi,%riz) + xorq %rax, %rax + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x30, %rsp + leaq -0x28(%rbp), %rax + movabsq $-0x1, %rcx + movq %rcx, (%rax) + leaq -0x28(%rbp), %rax + movabsq $0x3ff4000000000000, %rcx # imm = 0x3FF4000000000000 + movq %rcx, %xmm14 + cvtsd2ss %xmm14, %xmm0 + movss %xmm0, 0x8(%rax,%riz) + leaq -0x28(%rbp), %rax + movabsq $0x4004000000000000, %rdx # imm = 0x4004000000000000 + movq %rdx, %xmm14 + movsd %xmm14, 0x10(%rax,%riz) + leaq -0x28(%rbp), %rax + xorq %rdx, %rdx + movq %rdx, %xmm14 + cvtsd2ss %xmm14, %xmm0 + movss %xmm0, 0x18(%rax,%riz) + leaq -0x28(%rbp), %rax + movss %xmm0, 0x1c(%rax,%riz) + leaq -0x28(%rbp), %rax + movabsq $0x4013000000000000, %rdx # imm = 0x4013000000000000 + movq %rdx, %xmm14 + cvtsd2ss %xmm14, %xmm0 + movss %xmm0, 0x20(%rax,%riz) + leaq -0x28(%rbp), %rax + movss 0x8(%rax,%riz), %xmm0 + cvtss2sd %xmm0, %xmm0 + movq %rcx, %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x1, %eax + addq $0x30, %rsp + popq %rbp + retq + leaq -0x28(%rbp), %rax + movsd 0x10(%rax,%riz), %xmm0 + movabsq $0x4004000000000000, %rax # imm = 0x4004000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x2, %eax + addq $0x30, %rsp + popq %rbp + retq + leaq -0x28(%rbp), %rax + movss 0x20(%rax,%riz), %xmm0 + movabsq $0x4013000000000000, %rax # imm = 0x4013000000000000 + cvtss2sd %xmm0, %xmm0 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x3, %eax + addq $0x30, %rsp + popq %rbp + retq + leaq -0x28(%rbp), %rdi + callq + leaq -0x28(%rbp), %rax + movsd 0x10(%rax,%riz), %xmm0 + movabsq $0x4008000000000000, %rax # imm = 0x4008000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x4, %eax + addq $0x30, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x30, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/fp_param_ternary.aarch64.asm b/tests/snapshots/asm/fp_param_ternary.aarch64.asm index c4fdb65a7..f6301b43a 100644 --- a/tests/snapshots/asm/fp_param_ternary.aarch64.asm +++ b/tests/snapshots/asm/fp_param_ternary.aarch64.asm @@ -14,17 +14,13 @@ Disassembly of section .text: mov x29, sp sub sp, sp, #0x10 sxtw x0, w0 + fmov d1, d0 mov x17, #0x1 // =1 and x0, x0, x17 cbz x0, - sub x0, x29, #0x10 - str s0, [x0] b - fneg s0, s0 - sub x0, x29, #0x10 - str s0, [x0] - sub x16, x29, #0x10 - ldr s0, [x16] + fneg s1, s1 + fmov d0, d1 add sp, sp, #0x10 ldp x29, x30, [sp], #0x10 ret @@ -34,29 +30,18 @@ Disassembly of section .text: mov x29, sp sub sp, sp, #0x30 sxtw x0, w0 + fmov d2, d0 mov x17, #0x1 // =1 and x1, x0, x17 cbz x1, - sub x1, x29, #0x28 - str s0, [x1] b - fneg s0, s0 - sub x1, x29, #0x28 - str s0, [x1] - sub x16, x29, #0x28 - ldr s0, [x16] + fneg s2, s2 mov x17, #0x2 // =2 and x0, x0, x17 cbz x0, - sub x0, x29, #0x30 - str s1, [x0] b fneg s1, s1 - sub x0, x29, #0x30 - str s1, [x0] - sub x16, x29, #0x30 - ldr s1, [x16] - fadd s0, s0, s1 + fadd s0, s2, s1 add sp, sp, #0x30 ldp x29, x30, [sp], #0x10 ret diff --git a/tests/snapshots/asm/fp_param_ternary.x64.asm b/tests/snapshots/asm/fp_param_ternary.x64.asm index fba209ac9..69f2cee19 100644 --- a/tests/snapshots/asm/fp_param_ternary.x64.asm +++ b/tests/snapshots/asm/fp_param_ternary.x64.asm @@ -15,19 +15,16 @@ Disassembly of section .text: movq %rsp, %rbp subq $0x10, %rsp movslq %edi, %rdi + movapd %xmm0, %xmm1 movq %rdi, %rax andq $0x1, %rax testq %rax, %rax je - leaq -0x10(%rbp), %rax - movss %xmm0, (%rax,%riz) jmp movl $0x80000000, %r10d # imm = 0x80000000 movq %r10, %xmm15 - xorpd %xmm15, %xmm0 - leaq -0x10(%rbp), %rax - movss %xmm0, (%rax,%riz) - movss -0x10(%rbp,%riz), %xmm0 + xorpd %xmm15, %xmm1 + movapd %xmm1, %xmm0 addq $0x10, %rsp popq %rbp retq @@ -37,32 +34,24 @@ Disassembly of section .text: movq %rsp, %rbp subq $0x30, %rsp movslq %edi, %rdi + movapd %xmm0, %xmm2 movq %rdi, %rax andq $0x1, %rax testq %rax, %rax je - leaq -0x28(%rbp), %rax - movss %xmm0, (%rax,%riz) jmp movl $0x80000000, %r10d # imm = 0x80000000 movq %r10, %xmm15 - xorpd %xmm15, %xmm0 - leaq -0x28(%rbp), %rax - movss %xmm0, (%rax,%riz) - movss -0x28(%rbp,%riz), %xmm0 + xorpd %xmm15, %xmm2 movq %rdi, %rax andq $0x2, %rax testq %rax, %rax je - leaq -0x30(%rbp), %rax - movss %xmm1, (%rax,%riz) jmp movl $0x80000000, %r10d # imm = 0x80000000 movq %r10, %xmm15 xorpd %xmm15, %xmm1 - leaq -0x30(%rbp), %rax - movss %xmm1, (%rax,%riz) - movss -0x30(%rbp,%riz), %xmm1 + movapd %xmm2, %xmm0 addss %xmm1, %xmm0 addq $0x30, %rsp popq %rbp @@ -255,3 +244,4 @@ Disassembly of section .text: addq $0x10, %rsp popq %rbp retq + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/funcptr_global_addressof_init.aarch64.asm b/tests/snapshots/asm/funcptr_global_addressof_init.aarch64.asm index 57fe85763..6075eb157 100644 --- a/tests/snapshots/asm/funcptr_global_addressof_init.aarch64.asm +++ b/tests/snapshots/asm/funcptr_global_addressof_init.aarch64.asm @@ -24,8 +24,8 @@ Disassembly of section .text: adrp x20, add x20, x20, ldr x1, [x20] - mov x9, x1 str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -42,8 +42,8 @@ Disassembly of section .text: adrp x1, add x1, x1, ldr x1, [x1] - mov x9, x1 str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/function_pointer_typedefs.aarch64.asm b/tests/snapshots/asm/function_pointer_typedefs.aarch64.asm index d1c38636e..772792cfe 100644 --- a/tests/snapshots/asm/function_pointer_typedefs.aarch64.asm +++ b/tests/snapshots/asm/function_pointer_typedefs.aarch64.asm @@ -43,9 +43,9 @@ Disassembly of section .text: str x19, [sp] sxtw x1, w1 sxtw x2, w2 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -66,9 +66,9 @@ Disassembly of section .text: add x20, x20, mov x0, #0x3 // =3 mov x1, #0x5 // =5 - mov x9, x20 str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -88,9 +88,9 @@ Disassembly of section .text: ret mov x0, #0x7 // =7 mov x1, #0x2 // =2 - mov x9, x20 str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -105,9 +105,9 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret mov x0, #0x4 // =4 - mov x9, x20 str x0, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -135,9 +135,9 @@ Disassembly of section .text: ldr x0, [x0] mov x1, #0x2 // =2 mov x2, #0x3 // =3 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -155,9 +155,9 @@ Disassembly of section .text: ldr x0, [x0, #0x8] mov x1, #0xa // =10 mov x2, #0x4 // =4 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -175,9 +175,9 @@ Disassembly of section .text: ldr x0, [x0, #0x10] mov x1, #0x1 // =1 mov x2, #0x2 // =2 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/function_pointers.aarch64.asm b/tests/snapshots/asm/function_pointers.aarch64.asm index 8057b11a8..ffdb6acfc 100644 --- a/tests/snapshots/asm/function_pointers.aarch64.asm +++ b/tests/snapshots/asm/function_pointers.aarch64.asm @@ -30,9 +30,9 @@ Disassembly of section .text: add x0, x0, mov x20, #0xa // =10 mov x1, #0x14 // =20 - mov x9, x0 str x1, [sp, #-0x10]! str x20, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -41,9 +41,9 @@ Disassembly of section .text: adrp x0, add x0, x0, mov x1, #0x5 // =5 - mov x9, x0 str x1, [sp, #-0x10]! str x20, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/function_type_typedef.aarch64.asm b/tests/snapshots/asm/function_type_typedef.aarch64.asm index bca69ae28..9ed73b202 100644 --- a/tests/snapshots/asm/function_type_typedef.aarch64.asm +++ b/tests/snapshots/asm/function_type_typedef.aarch64.asm @@ -26,9 +26,9 @@ Disassembly of section .text: str x19, [sp] sxtw x1, w1 sxtw x2, w2 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -45,9 +45,9 @@ Disassembly of section .text: str x19, [sp] sxtw x1, w1 sxtw x2, w2 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/function_type_typedef_declaration.aarch64.asm b/tests/snapshots/asm/function_type_typedef_declaration.aarch64.asm index 3737d9b69..8efb6f443 100644 --- a/tests/snapshots/asm/function_type_typedef_declaration.aarch64.asm +++ b/tests/snapshots/asm/function_type_typedef_declaration.aarch64.asm @@ -26,9 +26,9 @@ Disassembly of section .text: str x19, [sp] sxtw x1, w1 sxtw x2, w2 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -70,9 +70,9 @@ Disassembly of section .text: add x0, x0, mov x1, #0x2 // =2 mov x2, #0x5 // =5 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -101,9 +101,9 @@ Disassembly of section .text: add x0, x0, mov x1, #0x8 // =8 mov x2, #0x3 // =3 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/function_typed_parameter.aarch64.asm b/tests/snapshots/asm/function_typed_parameter.aarch64.asm index 3b0db2829..3cba0747e 100644 --- a/tests/snapshots/asm/function_typed_parameter.aarch64.asm +++ b/tests/snapshots/asm/function_typed_parameter.aarch64.asm @@ -15,8 +15,8 @@ Disassembly of section .text: sub sp, sp, #0x10 str x19, [sp] sxtw x1, w1 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -32,8 +32,8 @@ Disassembly of section .text: sub sp, sp, #0x10 str x19, [sp] sxtw x1, w1 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -49,8 +49,8 @@ Disassembly of section .text: sub sp, sp, #0x10 str x19, [sp] sxtw x1, w1 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/hfa_param_interleave.aarch64.asm b/tests/snapshots/asm/hfa_param_interleave.aarch64.asm index 1c70192c3..2f9edcf26 100644 --- a/tests/snapshots/asm/hfa_param_interleave.aarch64.asm +++ b/tests/snapshots/asm/hfa_param_interleave.aarch64.asm @@ -34,29 +34,25 @@ Disassembly of section .text: sub x0, x29, #0x8 ldr s1, [x0] sub x0, x29, #0x8 - add x0, x0, #0x4 - ldr s2, [x0] + ldr s2, [x0, #0x4] fadd s1, s1, s2 sub x0, x29, #0x10 ldr s2, [x0] fadd s1, s1, s2 sub x0, x29, #0x10 - add x0, x0, #0x4 - ldr s2, [x0] + ldr s2, [x0, #0x4] fadd s1, s1, s2 sub x0, x29, #0x18 ldr s2, [x0] fadd s1, s1, s2 sub x0, x29, #0x18 - add x0, x0, #0x4 - ldr s2, [x0] + ldr s2, [x0, #0x4] fadd s1, s1, s2 sub x0, x29, #0x20 ldr s2, [x0] fadd s1, s1, s2 sub x0, x29, #0x20 - add x0, x0, #0x4 - ldr s2, [x0] + ldr s2, [x0, #0x4] fadd s1, s1, s2 fadd s0, s1, s0 sub x0, x29, #0x28 diff --git a/tests/snapshots/asm/hfa_param_interleave.x64.asm b/tests/snapshots/asm/hfa_param_interleave.x64.asm index 31d4a7626..f7058c209 100644 --- a/tests/snapshots/asm/hfa_param_interleave.x64.asm +++ b/tests/snapshots/asm/hfa_param_interleave.x64.asm @@ -26,29 +26,25 @@ Disassembly of section .text: leaq -0x8(%rbp), %rax movss (%rax,%riz), %xmm1 leaq -0x8(%rbp), %rax - addq $0x4, %rax - movss (%rax,%riz), %xmm2 + movss 0x4(%rax,%riz), %xmm2 addss %xmm2, %xmm1 leaq -0x10(%rbp), %rax movss (%rax,%riz), %xmm2 addss %xmm2, %xmm1 leaq -0x10(%rbp), %rax - addq $0x4, %rax - movss (%rax,%riz), %xmm2 + movss 0x4(%rax,%riz), %xmm2 addss %xmm2, %xmm1 leaq -0x18(%rbp), %rax movss (%rax,%riz), %xmm2 addss %xmm2, %xmm1 leaq -0x18(%rbp), %rax - addq $0x4, %rax - movss (%rax,%riz), %xmm2 + movss 0x4(%rax,%riz), %xmm2 addss %xmm2, %xmm1 leaq -0x20(%rbp), %rax movss (%rax,%riz), %xmm2 addss %xmm2, %xmm1 leaq -0x20(%rbp), %rax - addq $0x4, %rax - movss (%rax,%riz), %xmm2 + movss 0x4(%rax,%riz), %xmm2 addss %xmm2, %xmm1 movapd %xmm0, %xmm15 movapd %xmm1, %xmm0 diff --git a/tests/snapshots/asm/hfa_struct_return.aarch64.asm b/tests/snapshots/asm/hfa_struct_return.aarch64.asm index ff867c81b..0fcdc0bb9 100644 --- a/tests/snapshots/asm/hfa_struct_return.aarch64.asm +++ b/tests/snapshots/asm/hfa_struct_return.aarch64.asm @@ -29,8 +29,7 @@ Disassembly of section .text: sub x0, x29, #0x10 str d0, [x0] sub x0, x29, #0x10 - add x0, x0, #0x8 - str d1, [x0] + str d1, [x0, #0x8] sub x0, x29, #0x10 mov x16, x0 ldr d0, [x16] @@ -46,11 +45,9 @@ Disassembly of section .text: sub x0, x29, #0x18 str d0, [x0] sub x0, x29, #0x18 - add x0, x0, #0x8 - str d1, [x0] + str d1, [x0, #0x8] sub x0, x29, #0x18 - add x0, x0, #0x10 - str d2, [x0] + str d2, [x0, #0x10] sub x0, x29, #0x18 mov x16, x0 ldr d0, [x16] @@ -67,14 +64,11 @@ Disassembly of section .text: sub x0, x29, #0x20 str d0, [x0] sub x0, x29, #0x20 - add x0, x0, #0x8 - str d1, [x0] + str d1, [x0, #0x8] sub x0, x29, #0x20 - add x0, x0, #0x10 - str d2, [x0] + str d2, [x0, #0x10] sub x0, x29, #0x20 - add x0, x0, #0x18 - str d3, [x0] + str d3, [x0, #0x18] sub x0, x29, #0x20 mov x16, x0 ldr d0, [x16] @@ -92,8 +86,7 @@ Disassembly of section .text: sub x0, x29, #0x18 str s0, [x0] sub x0, x29, #0x18 - add x0, x0, #0x4 - str s1, [x0] + str s1, [x0, #0x4] sub x0, x29, #0x18 mov x16, x0 ldr s0, [x16] @@ -113,8 +106,7 @@ Disassembly of section .text: sub x0, x29, #0x10 ldr d0, [x0] sub x0, x29, #0x10 - add x0, x0, #0x8 - ldr d1, [x0] + ldr d1, [x0, #0x8] fadd d0, d0, d1 add sp, sp, #0x10 ldp x29, x30, [sp], #0x10 @@ -134,16 +126,13 @@ Disassembly of section .text: sub x0, x29, #0x20 ldr d0, [x0] sub x0, x29, #0x20 - add x0, x0, #0x8 - ldr d1, [x0] + ldr d1, [x0, #0x8] fadd d0, d0, d1 sub x0, x29, #0x20 - add x0, x0, #0x10 - ldr d1, [x0] + ldr d1, [x0, #0x10] fadd d0, d0, d1 sub x0, x29, #0x20 - add x0, x0, #0x18 - ldr d1, [x0] + ldr d1, [x0, #0x18] fadd d0, d0, d1 add sp, sp, #0x20 ldp x29, x30, [sp], #0x10 @@ -163,16 +152,13 @@ Disassembly of section .text: sub x0, x29, #0x10 ldr s0, [x0] sub x0, x29, #0x10 - add x0, x0, #0x4 - ldr s1, [x0] + ldr s1, [x0, #0x4] fadd s0, s0, s1 sub x0, x29, #0x10 - add x0, x0, #0x8 - ldr s1, [x0] + ldr s1, [x0, #0x8] fadd s0, s0, s1 sub x0, x29, #0x10 - add x0, x0, #0xc - ldr s1, [x0] + ldr s1, [x0, #0xc] fadd s0, s0, s1 add sp, sp, #0x10 ldp x29, x30, [sp], #0x10 @@ -233,8 +219,7 @@ Disassembly of section .text: cset x20, ne cbnz x20, sub x0, x29, #0x20 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0x3fe0000000000000 // =4602678819172646912 fmov d17, x0 fcmp d0, d17 @@ -276,8 +261,7 @@ Disassembly of section .text: mov x20, #0x1 // =1 cbnz x0, sub x0, x29, #0x48 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0x4000000000000000 // =4611686018427387904 fmov d17, x0 fcmp d0, d17 @@ -286,8 +270,7 @@ Disassembly of section .text: cset x20, ne cbnz x20, sub x0, x29, #0x48 - add x0, x0, #0x10 - ldr d0, [x0] + ldr d0, [x0, #0x10] mov x0, #0x4008000000000000 // =4613937818241073152 fmov d17, x0 fcmp d0, d17 @@ -334,8 +317,7 @@ Disassembly of section .text: mov x20, #0x1 // =1 cbnz x0, sub x0, x29, #0x80 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0x4034000000000000 // =4626322717216342016 fmov d17, x0 fcmp d0, d17 @@ -345,8 +327,7 @@ Disassembly of section .text: mov x21, #0x1 // =1 cbnz x20, sub x0, x29, #0x80 - add x0, x0, #0x10 - ldr d0, [x0] + ldr d0, [x0, #0x10] mov x0, #0x403e000000000000 // =4629137466983448576 fmov d17, x0 fcmp d0, d17 @@ -355,8 +336,7 @@ Disassembly of section .text: cset x21, ne cbnz x21, sub x0, x29, #0x80 - add x0, x0, #0x18 - ldr d0, [x0] + ldr d0, [x0, #0x18] mov x0, #0x4044000000000000 // =4630826316843712512 fmov d17, x0 fcmp d0, d17 @@ -393,8 +373,7 @@ Disassembly of section .text: cset x20, ne cbnz x20, sub x0, x29, #0xa8 - add x0, x0, #0x4 - ldr s0, [x0] + ldr s0, [x0, #0x4] mov x0, #0x4004000000000000 // =4612811918334230528 fcvt d0, s0 fmov d17, x0 diff --git a/tests/snapshots/asm/hfa_struct_return.x64.asm b/tests/snapshots/asm/hfa_struct_return.x64.asm index 924cbae06..eae9f0c0b 100644 --- a/tests/snapshots/asm/hfa_struct_return.x64.asm +++ b/tests/snapshots/asm/hfa_struct_return.x64.asm @@ -30,8 +30,7 @@ Disassembly of section .text: leaq -0x10(%rbp), %rax movsd %xmm0, (%rax,%riz) leaq -0x10(%rbp), %rax - addq $0x8, %rax - movsd %xmm1, (%rax,%riz) + movsd %xmm1, 0x8(%rax,%riz) leaq -0x10(%rbp), %rax movq %rax, %rcx movsd (%rcx,%riz), %xmm0 @@ -55,13 +54,11 @@ Disassembly of section .text: movsd 0x20(%rbp,%riz), %xmm0 movsd %xmm0, (%rax,%riz) leaq -0x18(%rbp), %rax - addq $0x8, %rax movsd 0x30(%rbp,%riz), %xmm0 - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x8(%rax,%riz) leaq -0x18(%rbp), %rax - addq $0x10, %rax movsd 0x40(%rbp,%riz), %xmm0 - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x10(%rax,%riz) movq 0x10(%rbp), %rax leaq -0x18(%rbp), %rcx pushq %rdx @@ -96,17 +93,14 @@ Disassembly of section .text: movsd 0x20(%rbp,%riz), %xmm0 movsd %xmm0, (%rax,%riz) leaq -0x20(%rbp), %rax - addq $0x8, %rax movsd 0x30(%rbp,%riz), %xmm0 - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x8(%rax,%riz) leaq -0x20(%rbp), %rax - addq $0x10, %rax movsd 0x40(%rbp,%riz), %xmm0 - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x10(%rax,%riz) leaq -0x20(%rbp), %rax - addq $0x18, %rax movsd 0x50(%rbp,%riz), %xmm0 - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x18(%rax,%riz) movq 0x10(%rbp), %rax leaq -0x20(%rbp), %rcx pushq %rdx @@ -134,8 +128,7 @@ Disassembly of section .text: leaq -0x18(%rbp), %rax movss %xmm0, (%rax,%riz) leaq -0x18(%rbp), %rax - addq $0x4, %rax - movss %xmm1, (%rax,%riz) + movss %xmm1, 0x4(%rax,%riz) leaq -0x18(%rbp), %rax movq %rax, %rcx movsd (%rcx,%riz), %xmm0 @@ -155,8 +148,7 @@ Disassembly of section .text: leaq -0x10(%rbp), %rax movsd (%rax,%riz), %xmm0 leaq -0x10(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm1 + movsd 0x8(%rax,%riz), %xmm1 addsd %xmm1, %xmm0 addq $0x10, %rsp popq %rbp @@ -183,16 +175,13 @@ Disassembly of section .text: leaq -0x20(%rbp), %rax movsd (%rax,%riz), %xmm0 leaq -0x20(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm1 + movsd 0x8(%rax,%riz), %xmm1 addsd %xmm1, %xmm0 leaq -0x20(%rbp), %rax - addq $0x10, %rax - movsd (%rax,%riz), %xmm1 + movsd 0x10(%rax,%riz), %xmm1 addsd %xmm1, %xmm0 leaq -0x20(%rbp), %rax - addq $0x18, %rax - movsd (%rax,%riz), %xmm1 + movsd 0x18(%rax,%riz), %xmm1 addsd %xmm1, %xmm0 addq $0x20, %rsp popq %rbp @@ -213,16 +202,13 @@ Disassembly of section .text: leaq -0x10(%rbp), %rax movss (%rax,%riz), %xmm0 leaq -0x10(%rbp), %rax - addq $0x4, %rax - movss (%rax,%riz), %xmm1 + movss 0x4(%rax,%riz), %xmm1 addss %xmm1, %xmm0 leaq -0x10(%rbp), %rax - addq $0x8, %rax - movss (%rax,%riz), %xmm1 + movss 0x8(%rax,%riz), %xmm1 addss %xmm1, %xmm0 leaq -0x10(%rbp), %rax - addq $0xc, %rax - movss (%rax,%riz), %xmm1 + movss 0xc(%rax,%riz), %xmm1 addss %xmm1, %xmm0 addq $0x10, %rsp popq %rbp @@ -293,8 +279,7 @@ Disassembly of section .text: testq %rbx, %rbx jne leaq -0x20(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x3fe0000000000000, %rax # imm = 0x3FE0000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -341,8 +326,7 @@ Disassembly of section .text: testq %rax, %rax jne leaq -0x48(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x4000000000000000, %rax # imm = 0x4000000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -357,8 +341,7 @@ Disassembly of section .text: testq %rbx, %rbx jne leaq -0x48(%rbp), %rax - addq $0x10, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x10(%rax,%riz), %xmm0 movabsq $0x4008000000000000, %rax # imm = 0x4008000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -408,8 +391,7 @@ Disassembly of section .text: testq %rax, %rax jne leaq -0x80(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x4034000000000000, %rax # imm = 0x4034000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -425,8 +407,7 @@ Disassembly of section .text: testq %rbx, %rbx jne leaq -0x80(%rbp), %rax - addq $0x10, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x10(%rax,%riz), %xmm0 movabsq $0x403e000000000000, %rax # imm = 0x403E000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -441,8 +422,7 @@ Disassembly of section .text: testq %r12, %r12 jne leaq -0x80(%rbp), %rax - addq $0x18, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x18(%rax,%riz), %xmm0 movabsq $0x4044000000000000, %rax # imm = 0x4044000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -487,8 +467,7 @@ Disassembly of section .text: testq %rbx, %rbx jne leaq -0xa8(%rbp), %rax - addq $0x4, %rax - movss (%rax,%riz), %xmm0 + movss 0x4(%rax,%riz), %xmm0 movabsq $0x4004000000000000, %rax # imm = 0x4004000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -599,4 +578,3 @@ Disassembly of section .text: jmp jmp jmp - addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/indirect_call_six_args_spilled_target.aarch64.asm b/tests/snapshots/asm/indirect_call_six_args_spilled_target.aarch64.asm index cf46a3943..cb0bf9aad 100644 --- a/tests/snapshots/asm/indirect_call_six_args_spilled_target.aarch64.asm +++ b/tests/snapshots/asm/indirect_call_six_args_spilled_target.aarch64.asm @@ -34,13 +34,13 @@ Disassembly of section .text: sub x6, x29, #0x8 add x1, x1, #0x10 add x3, x3, #0x10 - mov x9, x5 str x4, [sp, #-0x10]! str x3, [sp, #-0x10]! str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! str x6, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x5 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] diff --git a/tests/snapshots/asm/indirect_call_target_scratch_exhausted.aarch64.asm b/tests/snapshots/asm/indirect_call_target_scratch_exhausted.aarch64.asm new file mode 100644 index 000000000..2cf53c42d --- /dev/null +++ b/tests/snapshots/asm/indirect_call_target_scratch_exhausted.aarch64.asm @@ -0,0 +1,476 @@ + +indirect_call_target_scratch_exhausted.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + sub sp, sp, #0x90 + ldr x16, [sp, #0x90] + str x16, [sp] + ldr x16, [sp, #0x98] + str x16, [sp, #0x10] + ldr x16, [sp, #0xa0] + str x16, [sp, #0x20] + ldr x16, [sp, #0xa8] + str x16, [sp, #0x30] + ldr x16, [sp, #0xb0] + str x16, [sp, #0x40] + ldr x16, [sp, #0xb8] + str x16, [sp, #0x50] + ldr x16, [sp, #0xc0] + str x16, [sp, #0x60] + ldr x16, [sp, #0xc8] + str x16, [sp, #0x70] + ldr x16, [sp, #0xd0] + str x16, [sp, #0x80] + sub sp, sp, #0x80 + stp x29, x30, [sp, #-0x10]! + mov x29, sp + add x0, x0, x1 + add x0, x0, x2 + add x0, x0, x3 + add x0, x0, x4 + add x0, x0, x5 + add x0, x0, x6 + add x0, x0, x7 + ldur x1, [x29, #0x90] + add x0, x0, x1 + ldur x1, [x29, #0xa0] + add x0, x0, x1 + ldur x1, [x29, #0xb0] + add x0, x0, x1 + ldur x1, [x29, #0xc0] + add x0, x0, x1 + ldur x1, [x29, #0xd0] + add x0, x0, x1 + ldur x1, [x29, #0xe0] + add x0, x0, x1 + ldur x1, [x29, #0xf0] + add x0, x0, x1 + add x16, x29, #0x100 + ldr x1, [x16] + add x0, x0, x1 + add x16, x29, #0x110 + ldr x1, [x16] + add x0, x0, x1 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x110 + ret + +: + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x100 + sub x16, x29, #0x10 + str x0, [x16] + str x1, [x16, #0x8] + sub x16, x29, #0x20 + str x2, [x16] + str x3, [x16, #0x8] + sub x16, x29, #0x30 + str x4, [x16] + str x5, [x16, #0x8] + sub x16, x29, #0x40 + str x6, [x16] + str x7, [x16, #0x8] + sub x16, x29, #0x50 + ldr x17, [x29, #0x110] + str x17, [x16] + ldr x17, [x29, #0x118] + str x17, [x16, #0x8] + sub x16, x29, #0x60 + ldr x17, [x29, #0x120] + str x17, [x16] + ldr x17, [x29, #0x128] + str x17, [x16, #0x8] + sub x16, x29, #0x70 + ldr x17, [x29, #0x130] + str x17, [x16] + ldr x17, [x29, #0x138] + str x17, [x16, #0x8] + sub x16, x29, #0x80 + ldr x17, [x29, #0x140] + str x17, [x16] + ldr x17, [x29, #0x148] + str x17, [x16, #0x8] + sub x16, x29, #0x90 + ldr x17, [x29, #0x150] + str x17, [x16] + ldr x17, [x29, #0x158] + str x17, [x16, #0x8] + sub x16, x29, #0xa0 + ldr x17, [x29, #0x160] + str x17, [x16] + ldr x17, [x29, #0x168] + str x17, [x16, #0x8] + sub x16, x29, #0xb0 + ldr x17, [x29, #0x170] + str x17, [x16] + ldr x17, [x29, #0x178] + str x17, [x16, #0x8] + sub x16, x29, #0xc0 + ldr x17, [x29, #0x180] + str x17, [x16] + ldr x17, [x29, #0x188] + str x17, [x16, #0x8] + sub x16, x29, #0xd0 + ldr x17, [x29, #0x190] + str x17, [x16] + ldr x17, [x29, #0x198] + str x17, [x16, #0x8] + sub x16, x29, #0xe0 + ldr x17, [x29, #0x1a0] + str x17, [x16] + ldr x17, [x29, #0x1a8] + str x17, [x16, #0x8] + sub x16, x29, #0xf0 + ldr x17, [x29, #0x1b0] + str x17, [x16] + ldr x17, [x29, #0x1b8] + str x17, [x16, #0x8] + sub x16, x29, #0x100 + ldr x17, [x29, #0x1c0] + str x17, [x16] + ldr x17, [x29, #0x1c8] + str x17, [x16, #0x8] + sub x0, x29, #0x10 + ldr x0, [x0] + sub x1, x29, #0x10 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0x20 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0x20 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0x30 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0x30 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0x40 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0x40 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0x50 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0x50 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0x60 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0x60 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0x70 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0x70 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0x80 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0x80 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0x90 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0x90 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0xa0 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0xa0 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0xb0 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0xb0 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0xc0 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0xc0 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0xd0 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0xd0 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0xe0 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0xe0 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0xf0 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0xf0 + ldr x1, [x1, #0x8] + add x0, x0, x1 + sub x1, x29, #0x100 + ldr x1, [x1] + add x0, x0, x1 + sub x1, x29, #0x100 + ldr x1, [x1, #0x8] + add x0, x0, x1 + add sp, sp, #0x100 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x100 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0xd0 + str x20, [sp] + str x21, [sp, #0x8] + str x22, [sp, #0x10] + str x23, [sp, #0x18] + str x19, [sp, #0x20] + adrp x0, + add x0, x0, + adrp x20, + add x20, x20, + mov x2, #0x0 // =0 + cmp x2, #0x10 + b.ge + b + add x2, x2, #0x1 + b + adrp x1, + add x1, x1, + lsl x3, x2, #4 + add x3, x1, x3 + str x2, [x3] + lsl x3, x2, #4 + add x1, x1, x3 + lsl x3, x2, #1 + str x3, [x1, #0x8] + b + mov x1, #0x1 // =1 + mov x2, #0x2 // =2 + mov x3, #0x3 // =3 + mov x4, #0x4 // =4 + mov x5, #0x5 // =5 + mov x6, #0x6 // =6 + mov x7, #0x7 // =7 + mov x8, #0x8 // =8 + mov x9, #0x9 // =9 + mov x10, #0xa // =10 + mov x11, #0xb // =11 + mov x12, #0xc // =12 + mov x13, #0xd // =13 + mov x14, #0xe // =14 + mov x15, #0xf // =15 + mov x21, #0x10 // =16 + mov x22, #0x11 // =17 + str x22, [sp, #-0x10]! + str x21, [sp, #-0x10]! + str x15, [sp, #-0x10]! + str x14, [sp, #-0x10]! + str x13, [sp, #-0x10]! + str x12, [sp, #-0x10]! + str x11, [sp, #-0x10]! + str x10, [sp, #-0x10]! + str x9, [sp, #-0x10]! + str x8, [sp, #-0x10]! + str x7, [sp, #-0x10]! + str x6, [sp, #-0x10]! + str x5, [sp, #-0x10]! + str x4, [sp, #-0x10]! + str x3, [sp, #-0x10]! + str x2, [sp, #-0x10]! + str x1, [sp, #-0x10]! + mov x9, x0 + sub sp, sp, #0x50 + ldr x0, [sp, #0x50] + ldr x1, [sp, #0x60] + ldr x2, [sp, #0x70] + ldr x3, [sp, #0x80] + ldr x4, [sp, #0x90] + ldr x5, [sp, #0xa0] + ldr x6, [sp, #0xb0] + ldr x7, [sp, #0xc0] + ldr x16, [sp, #0xd0] + str x16, [sp] + ldr x16, [sp, #0xe0] + str x16, [sp, #0x8] + ldr x16, [sp, #0xf0] + str x16, [sp, #0x10] + ldr x16, [sp, #0x100] + str x16, [sp, #0x18] + ldr x16, [sp, #0x110] + str x16, [sp, #0x20] + ldr x16, [sp, #0x120] + str x16, [sp, #0x28] + ldr x16, [sp, #0x130] + str x16, [sp, #0x30] + ldr x16, [sp, #0x140] + str x16, [sp, #0x38] + ldr x16, [sp, #0x150] + str x16, [sp, #0x40] + blr x9 + add sp, sp, #0x50 + add sp, sp, #0x110 + cmp x0, #0x99 + b.eq + mov x0, #0x1 // =1 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x23, [sp, #0x18] + ldr x19, [sp, #0x20] + add sp, sp, #0xd0 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + add x1, x0, #0x10 + add x2, x0, #0x20 + add x3, x0, #0x30 + add x4, x0, #0x40 + add x5, x0, #0x50 + add x6, x0, #0x60 + add x7, x0, #0x70 + add x8, x0, #0x80 + add x9, x0, #0x90 + add x10, x0, #0xa0 + add x11, x0, #0xb0 + add x12, x0, #0xc0 + add x13, x0, #0xd0 + add x14, x0, #0xe0 + add x15, x0, #0xf0 + mov x16, x20 + sub sp, sp, #0xd0 + str x16, [sp, #0xc0] + mov x16, x4 + ldr x17, [x16] + str x17, [sp] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8] + mov x16, x5 + ldr x17, [x16] + str x17, [sp, #0x10] + ldr x17, [x16, #0x8] + str x17, [sp, #0x18] + mov x16, x6 + ldr x17, [x16] + str x17, [sp, #0x20] + ldr x17, [x16, #0x8] + str x17, [sp, #0x28] + mov x16, x7 + ldr x17, [x16] + str x17, [sp, #0x30] + ldr x17, [x16, #0x8] + str x17, [sp, #0x38] + mov x16, x8 + ldr x17, [x16] + str x17, [sp, #0x40] + ldr x17, [x16, #0x8] + str x17, [sp, #0x48] + mov x16, x9 + ldr x17, [x16] + str x17, [sp, #0x50] + ldr x17, [x16, #0x8] + str x17, [sp, #0x58] + mov x16, x10 + ldr x17, [x16] + str x17, [sp, #0x60] + ldr x17, [x16, #0x8] + str x17, [sp, #0x68] + mov x16, x11 + ldr x17, [x16] + str x17, [sp, #0x70] + ldr x17, [x16, #0x8] + str x17, [sp, #0x78] + mov x16, x12 + ldr x17, [x16] + str x17, [sp, #0x80] + ldr x17, [x16, #0x8] + str x17, [sp, #0x88] + mov x16, x13 + ldr x17, [x16] + str x17, [sp, #0x90] + ldr x17, [x16, #0x8] + str x17, [sp, #0x98] + mov x16, x14 + ldr x17, [x16] + str x17, [sp, #0xa0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xa8] + mov x16, x15 + ldr x17, [x16] + str x17, [sp, #0xb0] + ldr x17, [x16, #0x8] + str x17, [sp, #0xb8] + mov x4, x2 + mov x6, x3 + mov x2, x1 + ldr x1, [x0, #0x8] + ldr x0, [x0] + ldr x3, [x2, #0x8] + ldr x2, [x2] + ldr x5, [x4, #0x8] + ldr x4, [x4] + ldr x7, [x6, #0x8] + ldr x6, [x6] + ldr x9, [sp, #0xc0] + blr x9 + add sp, sp, #0xd0 + cmp x0, #0x168 + b.eq + mov x0, #0x2 // =2 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x23, [sp, #0x18] + ldr x19, [sp, #0x20] + add sp, sp, #0xd0 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x23, [sp, #0x18] + ldr x19, [sp, #0x20] + add sp, sp, #0xd0 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/indirect_call_target_scratch_exhausted.x64.asm b/tests/snapshots/asm/indirect_call_target_scratch_exhausted.x64.asm new file mode 100644 index 000000000..a8a519a42 --- /dev/null +++ b/tests/snapshots/asm/indirect_call_target_scratch_exhausted.x64.asm @@ -0,0 +1,447 @@ + +indirect_call_target_scratch_exhausted.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + popq %r10 + subq $0x110, %rsp # imm = 0x110 + movq 0x110(%rsp), %rax + movq %rax, 0x60(%rsp) + movq 0x118(%rsp), %rax + movq %rax, 0x70(%rsp) + movq 0x120(%rsp), %rax + movq %rax, 0x80(%rsp) + movq 0x128(%rsp), %rax + movq %rax, 0x90(%rsp) + movq 0x130(%rsp), %rax + movq %rax, 0xa0(%rsp) + movq 0x138(%rsp), %rax + movq %rax, 0xb0(%rsp) + movq 0x140(%rsp), %rax + movq %rax, 0xc0(%rsp) + movq 0x148(%rsp), %rax + movq %rax, 0xd0(%rsp) + movq 0x150(%rsp), %rax + movq %rax, 0xe0(%rsp) + movq 0x158(%rsp), %rax + movq %rax, 0xf0(%rsp) + movq 0x160(%rsp), %rax + movq %rax, 0x100(%rsp) + pushq %r10 + pushq %rbp + movq %rsp, %rbp + leaq (%rdi,%rsi), %rax + addq %rdx, %rax + addq %rcx, %rax + addq %r8, %rax + addq %r9, %rax + movq 0x70(%rbp), %rcx + addq %rcx, %rax + movq 0x80(%rbp), %rcx + addq %rcx, %rax + movq 0x90(%rbp), %rcx + addq %rcx, %rax + movq 0xa0(%rbp), %rcx + addq %rcx, %rax + movq 0xb0(%rbp), %rcx + addq %rcx, %rax + movq 0xc0(%rbp), %rcx + addq %rcx, %rax + movq 0xd0(%rbp), %rcx + addq %rcx, %rax + movq 0xe0(%rbp), %rcx + addq %rcx, %rax + movq 0xf0(%rbp), %rcx + addq %rcx, %rax + movq 0x100(%rbp), %rcx + addq %rcx, %rax + movq 0x110(%rbp), %rcx + addq %rcx, %rax + popq %rbp + popq %r11 + addq $0x110, %rsp # imm = 0x110 + pushq %r11 + retq + +: + popq %r10 + subq $0x100, %rsp # imm = 0x100 + pushq %r10 + pushq %rbp + movq %rsp, %rbp + subq $0x100, %rsp # imm = 0x100 + movq %rdi, -0x10(%rbp) + movq %rsi, -0x8(%rbp) + movq %rdx, -0x20(%rbp) + movq %rcx, -0x18(%rbp) + movq %r8, -0x30(%rbp) + movq %r9, -0x28(%rbp) + movq 0x110(%rbp), %r10 + movq %r10, -0x40(%rbp) + movq 0x118(%rbp), %r10 + movq %r10, -0x38(%rbp) + movq 0x120(%rbp), %r10 + movq %r10, -0x50(%rbp) + movq 0x128(%rbp), %r10 + movq %r10, -0x48(%rbp) + movq 0x130(%rbp), %r10 + movq %r10, -0x60(%rbp) + movq 0x138(%rbp), %r10 + movq %r10, -0x58(%rbp) + movq 0x140(%rbp), %r10 + movq %r10, -0x70(%rbp) + movq 0x148(%rbp), %r10 + movq %r10, -0x68(%rbp) + movq 0x150(%rbp), %r10 + movq %r10, -0x80(%rbp) + movq 0x158(%rbp), %r10 + movq %r10, -0x78(%rbp) + movq 0x160(%rbp), %r10 + movq %r10, -0x90(%rbp) + movq 0x168(%rbp), %r10 + movq %r10, -0x88(%rbp) + movq 0x170(%rbp), %r10 + movq %r10, -0xa0(%rbp) + movq 0x178(%rbp), %r10 + movq %r10, -0x98(%rbp) + movq 0x180(%rbp), %r10 + movq %r10, -0xb0(%rbp) + movq 0x188(%rbp), %r10 + movq %r10, -0xa8(%rbp) + movq 0x190(%rbp), %r10 + movq %r10, -0xc0(%rbp) + movq 0x198(%rbp), %r10 + movq %r10, -0xb8(%rbp) + movq 0x1a0(%rbp), %r10 + movq %r10, -0xd0(%rbp) + movq 0x1a8(%rbp), %r10 + movq %r10, -0xc8(%rbp) + movq 0x1b0(%rbp), %r10 + movq %r10, -0xe0(%rbp) + movq 0x1b8(%rbp), %r10 + movq %r10, -0xd8(%rbp) + movq 0x1c0(%rbp), %r10 + movq %r10, -0xf0(%rbp) + movq 0x1c8(%rbp), %r10 + movq %r10, -0xe8(%rbp) + movq 0x1d0(%rbp), %r10 + movq %r10, -0x100(%rbp) + movq 0x1d8(%rbp), %r10 + movq %r10, -0xf8(%rbp) + leaq -0x10(%rbp), %rax + movq (%rax), %rax + leaq -0x10(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0x20(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0x20(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0x30(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0x30(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0x40(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0x40(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0x50(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0x50(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0x60(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0x60(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0x70(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0x70(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0x80(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0x80(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0x90(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0x90(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0xa0(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0xa0(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0xb0(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0xb0(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0xc0(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0xc0(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0xd0(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0xd0(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0xe0(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0xe0(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0xf0(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0xf0(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + leaq -0x100(%rbp), %rcx + movq (%rcx), %rcx + addq %rcx, %rax + leaq -0x100(%rbp), %rcx + movq 0x8(%rcx), %rcx + addq %rcx, %rax + addq $0x100, %rsp # imm = 0x100 + popq %rbp + popq %r11 + addq $0x100, %rsp # imm = 0x100 + pushq %r11 + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x110, %rsp # imm = 0x110 + movq %rbx, (%rsp) + movq %r12, 0x8(%rsp) + movq %r13, 0x10(%rsp) + movq %r14, 0x18(%rsp) + movq %r15, 0x20(%rsp) + leaq -, %rax # + leaq -, %rbx # + xorq %rdx, %rdx + cmpq $0x10, %rdx + jge + jmp + incq %rdx + jmp + leaq , %rcx + movq %rdx, %rsi + shlq $0x4, %rsi + addq %rcx, %rsi + movq %rdx, (%rsi) + movq %rdx, %rsi + shlq $0x4, %rsi + addq %rsi, %rcx + movq %rdx, %rsi + shlq $0x1, %rsi + movq %rsi, 0x8(%rcx) + jmp + movl $0x1, %edi + movl $0x2, %esi + movl $0x3, %edx + movl $0x4, %ecx + movl $0x5, %r8d + movl $0x6, %r9d + movl $0x7, %r12d + movl $0x8, %r13d + movl $0x9, %r14d + movl $0xa, %r15d + movl $0xb, %r10d + movq %r10, 0x68(%rsp) + movl $0xc, %r10d + movq %r10, 0x60(%rsp) + movl $0xd, %r10d + movq %r10, 0x58(%rsp) + movl $0xe, %r10d + movq %r10, 0x50(%rsp) + movl $0xf, %r10d + movq %r10, 0x48(%rsp) + movl $0x10, %r10d + movq %r10, 0x40(%rsp) + movl $0x11, %r10d + movq %r10, 0x38(%rsp) + subq $0x60, %rsp + movq %r12, (%rsp) + movq %r13, 0x8(%rsp) + movq %r14, 0x10(%rsp) + movq %r15, 0x18(%rsp) + movq 0xc8(%rsp), %r10 + movq %r10, 0x20(%rsp) + movq 0xc0(%rsp), %r10 + movq %r10, 0x28(%rsp) + movq 0xb8(%rsp), %r10 + movq %r10, 0x30(%rsp) + movq 0xb0(%rsp), %r10 + movq %r10, 0x38(%rsp) + movq 0xa8(%rsp), %r10 + movq %r10, 0x40(%rsp) + movq 0xa0(%rsp), %r10 + movq %r10, 0x48(%rsp) + movq 0x98(%rsp), %r10 + movq %r10, 0x50(%rsp) + callq *%rax + addq $0x60, %rsp + cmpq $0x99, %rax + je + movl $0x1, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + addq $0x110, %rsp # imm = 0x110 + popq %rbp + retq + leaq , %rdi + leaq 0x10(%rdi), %rsi + leaq 0x20(%rdi), %rdx + leaq 0x30(%rdi), %rcx + leaq 0x40(%rdi), %r8 + leaq 0x50(%rdi), %r9 + leaq 0x60(%rdi), %rax + leaq 0x70(%rdi), %r12 + leaq 0x80(%rdi), %r13 + leaq 0x90(%rdi), %r14 + leaq 0xa0(%rdi), %r15 + leaq 0xb0(%rdi), %r10 + movq %r10, 0x68(%rsp) + leaq 0xc0(%rdi), %r10 + movq %r10, 0x60(%rsp) + leaq 0xd0(%rdi), %r10 + movq %r10, 0x58(%rsp) + leaq 0xe0(%rdi), %r10 + movq %r10, 0x50(%rsp) + leaq 0xf0(%rdi), %r10 + movq %r10, 0x48(%rsp) + subq $0x10, %rsp + movq %rbx, (%rsp) + subq $0xd0, %rsp + movq %rcx, %r10 + movq (%r10), %r11 + movq %r11, (%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x8(%rsp) + movq %r8, %r10 + movq (%r10), %r11 + movq %r11, 0x10(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x18(%rsp) + movq %r9, %r10 + movq (%r10), %r11 + movq %r11, 0x20(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x28(%rsp) + movq %rax, %r10 + movq (%r10), %r11 + movq %r11, 0x30(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x38(%rsp) + movq %r12, %r10 + movq (%r10), %r11 + movq %r11, 0x40(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x48(%rsp) + movq %r13, %r10 + movq (%r10), %r11 + movq %r11, 0x50(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x58(%rsp) + movq %r14, %r10 + movq (%r10), %r11 + movq %r11, 0x60(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x68(%rsp) + movq %r15, %r10 + movq (%r10), %r11 + movq %r11, 0x70(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x78(%rsp) + movq 0x148(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x80(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x88(%rsp) + movq 0x140(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0x90(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x98(%rsp) + movq 0x138(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xa0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xa8(%rsp) + movq 0x130(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xb0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xb8(%rsp) + movq 0x128(%rsp), %r10 + movq (%r10), %r11 + movq %r11, 0xc0(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0xc8(%rsp) + movq %rdx, %r8 + movq %rsi, %rdx + movq 0x8(%rdi), %rsi + movq (%rdi), %rdi + movq 0x8(%rdx), %rcx + movq (%rdx), %rdx + movq 0x8(%r8), %r9 + movq (%r8), %r8 + movq 0xd0(%rsp), %r10 + callq *%r10 + addq $0xd0, %rsp + addq $0x10, %rsp + cmpq $0x168, %rax # imm = 0x168 + je + movl $0x2, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + addq $0x110, %rsp # imm = 0x110 + popq %rbp + retq + xorq %rax, %rax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + addq $0x110, %rsp # imm = 0x110 + popq %rbp + retq + addb %al, (%rax) diff --git a/tests/snapshots/asm/indirect_call_through_global_fn_ptr.aarch64.asm b/tests/snapshots/asm/indirect_call_through_global_fn_ptr.aarch64.asm index c3ca4cbc4..2ca837bb0 100644 --- a/tests/snapshots/asm/indirect_call_through_global_fn_ptr.aarch64.asm +++ b/tests/snapshots/asm/indirect_call_through_global_fn_ptr.aarch64.asm @@ -36,10 +36,10 @@ Disassembly of section .text: adrp x0, add x0, x0, ldr x0, [x0] - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! str x20, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] diff --git a/tests/snapshots/asm/init_float_to_int.aarch64.asm b/tests/snapshots/asm/init_float_to_int.aarch64.asm index d2fd75b14..2745bdb42 100644 --- a/tests/snapshots/asm/init_float_to_int.aarch64.asm +++ b/tests/snapshots/asm/init_float_to_int.aarch64.asm @@ -80,8 +80,7 @@ Disassembly of section .text: cbnz x1, adrp x0, add x0, x0, - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0x4000000000000000 // =4611686018427387904 fmov d17, x0 fcmp d0, d17 diff --git a/tests/snapshots/asm/init_float_to_int.x64.asm b/tests/snapshots/asm/init_float_to_int.x64.asm index b5f32f434..a4db111ad 100644 --- a/tests/snapshots/asm/init_float_to_int.x64.asm +++ b/tests/snapshots/asm/init_float_to_int.x64.asm @@ -82,8 +82,7 @@ Disassembly of section .text: testq %rcx, %rcx jne leaq , %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x4000000000000000, %rax # imm = 0x4000000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -107,4 +106,3 @@ Disassembly of section .text: jmp jmp addb %al, (%rax) - addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/init_scalar_conversion.aarch64.asm b/tests/snapshots/asm/init_scalar_conversion.aarch64.asm index f3bb30119..e43a47c5d 100644 --- a/tests/snapshots/asm/init_scalar_conversion.aarch64.asm +++ b/tests/snapshots/asm/init_scalar_conversion.aarch64.asm @@ -27,8 +27,7 @@ Disassembly of section .text: cset x0, eq cbz x0, sub x0, x29, #0x20 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0x0 // =0 fmov d17, x0 fcmp d0, d17 @@ -38,8 +37,7 @@ Disassembly of section .text: mov x1, #0x0 // =0 cbz x2, sub x0, x29, #0x20 - add x0, x0, #0x10 - ldr d0, [x0] + ldr d0, [x0, #0x10] mov x0, #0x400000000000 // =70368744177664 movk x0, #0x408a, lsl #48 fmov d17, x0 @@ -50,8 +48,7 @@ Disassembly of section .text: mov x2, #0x0 // =0 cbz x1, sub x0, x29, #0x20 - add x0, x0, #0x18 - ldr d0, [x0] + ldr d0, [x0, #0x18] mov x0, #0xe00000000000 // =246290604621824 movk x0, #0x4080, lsl #48 fmov d17, x0 @@ -91,8 +88,7 @@ Disassembly of section .text: str d0, [x0] scvtf d0, x21 sub x0, x29, #0x20 - add x0, x0, #0x8 - str d0, [x0] + str d0, [x0, #0x8] sub x0, x29, #0x20 ldr d0, [x0] mov x0, #0x400000000000 // =70368744177664 @@ -102,8 +98,7 @@ Disassembly of section .text: cset x22, ne cbnz x22, sub x0, x29, #0x20 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0xe00000000000 // =246290604621824 movk x0, #0x4080, lsl #48 fmov d17, x0 @@ -135,19 +130,15 @@ Disassembly of section .text: sub x0, x29, #0x40 str d0, [x0] sub x0, x29, #0x40 - add x0, x0, #0x8 - str d0, [x0] + str d0, [x0, #0x8] scvtf d0, x20 sub x0, x29, #0x40 - add x0, x0, #0x10 - str d0, [x0] + str d0, [x0, #0x10] scvtf d0, x21 sub x0, x29, #0x40 - add x0, x0, #0x18 - str d0, [x0] + str d0, [x0, #0x18] sub x0, x29, #0x40 - add x0, x0, #0x10 - ldr d0, [x0] + ldr d0, [x0, #0x10] mov x0, #0x400000000000 // =70368744177664 movk x0, #0x408a, lsl #48 fmov d17, x0 @@ -155,8 +146,7 @@ Disassembly of section .text: cset x22, ne cbnz x22, sub x0, x29, #0x40 - add x0, x0, #0x18 - ldr d0, [x0] + ldr d0, [x0, #0x18] mov x0, #0xe00000000000 // =246290604621824 movk x0, #0x4080, lsl #48 fmov d17, x0 @@ -184,8 +174,7 @@ Disassembly of section .text: str d0, [x0] scvtf d0, x21 sub x0, x29, #0x50 - add x0, x0, #0x8 - str d0, [x0] + str d0, [x0, #0x8] sub x0, x29, #0x50 ldr d0, [x0] mov x0, #0x400000000000 // =70368744177664 @@ -195,8 +184,7 @@ Disassembly of section .text: cset x22, ne cbnz x22, sub x0, x29, #0x50 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0xe00000000000 // =246290604621824 movk x0, #0x4080, lsl #48 fmov d17, x0 @@ -330,16 +318,13 @@ Disassembly of section .text: sub x0, x29, #0x98 str d0, [x0] sub x0, x29, #0x98 - add x0, x0, #0x8 - str d0, [x0] + str d0, [x0, #0x8] scvtf d0, x20 sub x0, x29, #0x98 - add x0, x0, #0x10 - str d0, [x0] + str d0, [x0, #0x10] scvtf d0, x21 sub x0, x29, #0x98 - add x0, x0, #0x18 - str d0, [x0] + str d0, [x0, #0x18] sub x0, x29, #0x98 ldr d0, [x0] ldr d1, [x0, #0x8] diff --git a/tests/snapshots/asm/init_scalar_conversion.x64.asm b/tests/snapshots/asm/init_scalar_conversion.x64.asm index 52bf2df7b..8e043c803 100644 --- a/tests/snapshots/asm/init_scalar_conversion.x64.asm +++ b/tests/snapshots/asm/init_scalar_conversion.x64.asm @@ -38,8 +38,7 @@ Disassembly of section .text: testq %rax, %rax je leaq -0x20(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 xorq %rax, %rax movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -55,8 +54,7 @@ Disassembly of section .text: testq %rdx, %rdx je leaq -0x20(%rbp), %rax - addq $0x10, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x10(%rax,%riz), %xmm0 movabsq $0x408a400000000000, %rax # imm = 0x408A400000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -72,8 +70,7 @@ Disassembly of section .text: testq %rcx, %rcx je leaq -0x20(%rbp), %rax - addq $0x18, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x18(%rax,%riz), %xmm0 movabsq $0x4080e00000000000, %rax # imm = 0x4080E00000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -118,8 +115,7 @@ Disassembly of section .text: movsd %xmm0, (%rax,%riz) cvtsi2sd %r12, %xmm0 leaq -0x20(%rbp), %rax - addq $0x8, %rax - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x8(%rax,%riz) leaq -0x20(%rbp), %rax movsd (%rax,%riz), %xmm0 movabsq $0x408a400000000000, %rax # imm = 0x408A400000000000 @@ -133,8 +129,7 @@ Disassembly of section .text: testq %r13, %r13 jne leaq -0x20(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x4080e00000000000, %rax # imm = 0x4080E00000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -169,19 +164,15 @@ Disassembly of section .text: leaq -0x40(%rbp), %rax movsd %xmm0, (%rax,%riz) leaq -0x40(%rbp), %rax - addq $0x8, %rax - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x8(%rax,%riz) cvtsi2sd %rbx, %xmm0 leaq -0x40(%rbp), %rax - addq $0x10, %rax - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x10(%rax,%riz) cvtsi2sd %r12, %xmm0 leaq -0x40(%rbp), %rax - addq $0x18, %rax - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x18(%rax,%riz) leaq -0x40(%rbp), %rax - addq $0x10, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x10(%rax,%riz), %xmm0 movabsq $0x408a400000000000, %rax # imm = 0x408A400000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -193,8 +184,7 @@ Disassembly of section .text: testq %r13, %r13 jne leaq -0x40(%rbp), %rax - addq $0x18, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x18(%rax,%riz), %xmm0 movabsq $0x4080e00000000000, %rax # imm = 0x4080E00000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -225,8 +215,7 @@ Disassembly of section .text: movsd %xmm0, (%rax,%riz) cvtsi2sd %r12, %xmm0 leaq -0x50(%rbp), %rax - addq $0x8, %rax - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x8(%rax,%riz) leaq -0x50(%rbp), %rax movsd (%rax,%riz), %xmm0 movabsq $0x408a400000000000, %rax # imm = 0x408A400000000000 @@ -240,8 +229,7 @@ Disassembly of section .text: testq %r13, %r13 jne leaq -0x50(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x4080e00000000000, %rax # imm = 0x4080E00000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -382,16 +370,13 @@ Disassembly of section .text: leaq -0x98(%rbp), %rax movsd %xmm0, (%rax,%riz) leaq -0x98(%rbp), %rax - addq $0x8, %rax - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x8(%rax,%riz) cvtsi2sd %rbx, %xmm0 leaq -0x98(%rbp), %rax - addq $0x10, %rax - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x10(%rax,%riz) cvtsi2sd %r12, %xmm0 leaq -0x98(%rbp), %rax - addq $0x18, %rax - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x18(%rax,%riz) leaq -0x98(%rbp), %rdi subq $0x20, %rsp movq %rdi, %r10 @@ -426,4 +411,4 @@ Disassembly of section .text: jmp jmp jmp - addb %al, 0x41(%rdx) + addb %al, (%rax) diff --git a/tests/snapshots/asm/inline_multi_block_result_forward.aarch64.asm b/tests/snapshots/asm/inline_multi_block_result_forward.aarch64.asm new file mode 100644 index 000000000..d12ebbcef --- /dev/null +++ b/tests/snapshots/asm/inline_multi_block_result_forward.aarch64.asm @@ -0,0 +1,50 @@ + +inline_multi_block_result_forward.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + add x0, x0, x0 + sxtw x0, w0 + ret + +: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + sxtw x0, w0 + lsl x0, x0, #1 + sxtw x0, w0 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + +: + sxtw x0, w0 + b + add x2, x0, x0 + cmp x0, #0x3 + b.le + sxtw x0, w1 + ret + add x0, x1, x2 + sxtw x0, w0 + ret + sxtw x1, w0 + lsl x1, x1, #1 + sxtw x1, w1 + b + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + mov x0, #0x5 // =5 + bl + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/inline_multi_block_result_forward.x64.asm b/tests/snapshots/asm/inline_multi_block_result_forward.x64.asm new file mode 100644 index 000000000..dfcc24e95 --- /dev/null +++ b/tests/snapshots/asm/inline_multi_block_result_forward.x64.asm @@ -0,0 +1,52 @@ + +inline_multi_block_result_forward.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + leaq (%rdi,%rdi), %rax + movslq %eax, %rax + retq + +: + pushq %rbp + movq %rsp, %rbp + subq $0x10, %rsp + movslq %edi, %rdi + movq %rdi, %rax + shlq $0x1, %rax + movslq %eax, %rax + addq $0x10, %rsp + popq %rbp + retq + +: + movslq %edi, %rdi + jmp + leaq (%rdi,%rdi), %rdx + cmpq $0x3, %rdi + jle + movslq %ecx, %rax + retq + leaq (%rcx,%rdx), %rax + movslq %eax, %rax + retq + movslq %edi, %rax + shlq $0x1, %rax + movslq %eax, %rcx + jmp + +
: + pushq %rbp + movq %rsp, %rbp + movl $0x5, %edi + popq %rbp + jmp + addb %al, (%rax) diff --git a/tests/snapshots/asm/int_literal_boundary_types.aarch64.asm b/tests/snapshots/asm/int_literal_boundary_types.aarch64.asm new file mode 100644 index 000000000..9aae0b7f2 --- /dev/null +++ b/tests/snapshots/asm/int_literal_boundary_types.aarch64.asm @@ -0,0 +1,84 @@ + +int_literal_boundary_types.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x20 + mov x0, #0xffff // =65535 + movk x0, #0x7fff, lsl #16 + movk x0, #0xffff, lsl #32 + movk x0, #0xffff, lsl #48 + mov x17, #0xffff // =65535 + movk x17, #0x7fff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + cmp x0, x17 + b.eq + mov x0, #0x1 // =1 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + mov x1, #0x0 // =0 + b + mov x1, #0x0 // =0 + cbz x1, + mov x0, #0x2 // =2 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x80000000 // =2147483648 + mov x1, #0xffff // =65535 + movk x1, #0xffff, lsl #16 + cmp x1, x0 + b.hs + mov x0, #0x3 // =3 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + b + mov x0, #0x4 // =4 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + b + mov x0, #0x5 // =5 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + b + mov x0, #0x6 // =6 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + mov x2, #0x1 // =1 + mov x2, #0x0 // =0 + cbnz x2, + mov x2, #0x0 // =0 + cbz x2, + mov x0, #0x7 // =7 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x8 // =8 + mov x1, #0xffff // =65535 + movk x1, #0xffff, lsl #16 + cmp x1, x0 + b.hs + mov x0, #0x8 // =8 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + b diff --git a/tests/snapshots/asm/int_literal_boundary_types.x64.asm b/tests/snapshots/asm/int_literal_boundary_types.x64.asm new file mode 100644 index 000000000..512073ab5 --- /dev/null +++ b/tests/snapshots/asm/int_literal_boundary_types.x64.asm @@ -0,0 +1,80 @@ + +int_literal_boundary_types.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x20, %rsp + movabsq $-0x80000001, %rax # imm = 0xFFFFFFFF7FFFFFFF + movabsq $-0x80000001, %r11 # imm = 0xFFFFFFFF7FFFFFFF + cmpq %r11, %rax + je + movl $0x1, %eax + addq $0x20, %rsp + popq %rbp + retq + xorq %rcx, %rcx + jmp + xorq %rcx, %rcx + testq %rcx, %rcx + je + movl $0x2, %eax + addq $0x20, %rsp + popq %rbp + retq + movl $0x80000000, %eax # imm = 0x80000000 + movl $0xffffffff, %ecx # imm = 0xFFFFFFFF + cmpq %rax, %rcx + jae + movl $0x3, %eax + addq $0x20, %rsp + popq %rbp + retq + jmp + movl $0x4, %eax + addq $0x20, %rsp + popq %rbp + retq + jmp + movl $0x5, %eax + addq $0x20, %rsp + popq %rbp + retq + jmp + movl $0x6, %eax + addq $0x20, %rsp + popq %rbp + retq + movl $0x1, %edx + xorq %rdx, %rdx + testq %rdx, %rdx + jne + xorq %rdx, %rdx + testq %rdx, %rdx + je + movl $0x7, %eax + addq $0x20, %rsp + popq %rbp + retq + movl $0x8, %eax + movl $0xffffffff, %ecx # imm = 0xFFFFFFFF + cmpq %rax, %rcx + jae + movl $0x8, %eax + addq $0x20, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x20, %rsp + popq %rbp + retq + jmp diff --git a/tests/snapshots/asm/integer_literal_suffix.x64.asm b/tests/snapshots/asm/integer_literal_suffix.x64.asm index 6420e91d4..9701c3d5b 100644 --- a/tests/snapshots/asm/integer_literal_suffix.x64.asm +++ b/tests/snapshots/asm/integer_literal_suffix.x64.asm @@ -26,8 +26,10 @@ Disassembly of section .text: movl $0x1, %ecx movq %rax, %r10 movq %rcx, %rax + pushq %rcx movq %r10, %rcx shlq %cl, %rax + popq %rcx decq %rax movabsq $0xfffffffff, %r11 # imm = 0xFFFFFFFFF cmpq %r11, %rax @@ -81,3 +83,4 @@ Disassembly of section .text: popq %rbp retq jmp + addb %al, (%rax) diff --git a/tests/snapshots/asm/ioctl_fionread_pipe.aarch64.asm b/tests/snapshots/asm/ioctl_fionread_pipe.aarch64.asm new file mode 100644 index 000000000..f207bd9d4 --- /dev/null +++ b/tests/snapshots/asm/ioctl_fionread_pipe.aarch64.asm @@ -0,0 +1,83 @@ + +ioctl_fionread_pipe.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x420 // =1056 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x50 + str x20, [sp] + str x19, [sp, #0x10] + mov x0, #0x0 // =0 + stur w0, [x29, #-0x10] + sub x0, x29, #0x8 + bl + sxtw x0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x1 // =1 + ldr x20, [sp] + ldr x19, [sp, #0x10] + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x8 + ldrsw x0, [x0, #0x4] + adrp x1, + add x1, x1, + mov x2, #0x5 // =5 + bl + sxtw x0, w0 + cmp x0, #0x5 + b.eq + mov x0, #0x2 // =2 + ldr x20, [sp] + ldr x19, [sp, #0x10] + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x8 + ldrsw x0, [x0] + mov x1, #0x541b // =21531 + sub x2, x29, #0x10 + bl + sxtw x0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x3 // =3 + ldr x20, [sp] + ldr x19, [sp, #0x10] + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret + ldursw x0, [x29, #-0x10] + cmp x0, #0x5 + b.eq + mov x0, #0x4 // =4 + ldr x20, [sp] + ldr x19, [sp, #0x10] + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x8 + mov x20, #0x0 // =0 + ldrsw x0, [x0] + bl + sxtw x0, w0 + sub x0, x29, #0x8 + ldrsw x0, [x0, #0x4] + bl + sxtw x0, w0 + mov x0, x20 + ldr x20, [sp] + ldr x19, [sp, #0x10] + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/ioctl_fionread_pipe.x64.asm b/tests/snapshots/asm/ioctl_fionread_pipe.x64.asm new file mode 100644 index 000000000..d84c4b011 --- /dev/null +++ b/tests/snapshots/asm/ioctl_fionread_pipe.x64.asm @@ -0,0 +1,84 @@ + +ioctl_fionread_pipe.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x40, %rsp + movq %rbx, (%rsp) + xorq %rax, %rax + movl %eax, -0x10(%rbp) + leaq -0x8(%rbp), %rdi + xorl %eax, %eax + callq + movslq %eax, %rax + testq %rax, %rax + je + movl $0x1, %eax + movq (%rsp), %rbx + addq $0x40, %rsp + popq %rbp + retq + leaq -0x8(%rbp), %rax + movslq 0x4(%rax), %rdi + leaq , %rsi + movl $0x5, %edx + xorl %eax, %eax + callq + movslq %eax, %rax + cmpq $0x5, %rax + je + movl $0x2, %eax + movq (%rsp), %rbx + addq $0x40, %rsp + popq %rbp + retq + leaq -0x8(%rbp), %rax + movslq (%rax), %rdi + movl $0x541b, %esi # imm = 0x541B + leaq -0x10(%rbp), %rdx + movb $0x0, %al + callq + movslq %eax, %rax + testq %rax, %rax + je + movl $0x3, %eax + movq (%rsp), %rbx + addq $0x40, %rsp + popq %rbp + retq + movslq -0x10(%rbp), %rax + cmpq $0x5, %rax + je + movl $0x4, %eax + movq (%rsp), %rbx + addq $0x40, %rsp + popq %rbp + retq + leaq -0x8(%rbp), %rax + xorq %rbx, %rbx + movslq (%rax), %rdi + xorl %eax, %eax + callq + movslq %eax, %rax + leaq -0x8(%rbp), %rax + movslq 0x4(%rax), %rdi + xorl %eax, %eax + callq + movslq %eax, %rax + movq %rbx, %rax + movq (%rsp), %rbx + addq $0x40, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/libc_fp_classify.aarch64.asm b/tests/snapshots/asm/libc_fp_classify.aarch64.asm index 8cde21431..c71127733 100644 --- a/tests/snapshots/asm/libc_fp_classify.aarch64.asm +++ b/tests/snapshots/asm/libc_fp_classify.aarch64.asm @@ -66,6 +66,7 @@ Disassembly of section .text: sub x0, x29, #0x8 ldr x0, [x0] lsr x0, x0, #63 + sxtw x0, w0 add sp, sp, #0x10 ldp x29, x30, [sp], #0x10 ret diff --git a/tests/snapshots/asm/libc_fp_classify.x64.asm b/tests/snapshots/asm/libc_fp_classify.x64.asm index ca372184d..fdc7cc245 100644 --- a/tests/snapshots/asm/libc_fp_classify.x64.asm +++ b/tests/snapshots/asm/libc_fp_classify.x64.asm @@ -63,6 +63,7 @@ Disassembly of section .text: leaq -0x8(%rbp), %rax movq (%rax), %rax shrq $0x3f, %rax + movslq %eax, %rax addq $0x10, %rsp popq %rbp retq @@ -282,3 +283,4 @@ Disassembly of section .text: popq %rbp retq addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/libc_pread64_pwrite64.aarch64.asm b/tests/snapshots/asm/libc_pread64_pwrite64.aarch64.asm index d2d720de5..7770e85ea 100644 --- a/tests/snapshots/asm/libc_pread64_pwrite64.aarch64.asm +++ b/tests/snapshots/asm/libc_pread64_pwrite64.aarch64.asm @@ -118,11 +118,11 @@ Disassembly of section .text: sub x2, x29, #0x58 mov x3, #0x8 // =8 mov x4, #0x10 // =16 - mov x9, x1 str x4, [sp, #-0x10]! str x3, [sp, #-0x10]! str x2, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] @@ -150,11 +150,11 @@ Disassembly of section .text: sxtw x0, w20 sub x1, x29, #0x68 mov x2, #0x8 // =8 - mov x9, x21 str x22, [sp, #-0x10]! str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x21 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] diff --git a/tests/snapshots/asm/local_array_partial_init_zero.aarch64.asm b/tests/snapshots/asm/local_array_partial_init_zero.aarch64.asm index 8b8d99b4e..f4d7921df 100644 --- a/tests/snapshots/asm/local_array_partial_init_zero.aarch64.asm +++ b/tests/snapshots/asm/local_array_partial_init_zero.aarch64.asm @@ -26,7 +26,15 @@ Disassembly of section .text: mov w4, w0 str w4, [x1, x3, lsl #2] b + sub x0, x29, #0xa0 mov x1, #0x0 // =0 + ldr w0, [x0] + sub x2, x29, #0xa0 + ldr w2, [x2, #0x9c] + add x0, x0, x2 + mov w0, w0 + stur w0, [x29, #-0xb0] + ldur w0, [x29, #-0xb0] mov x0, x1 add sp, sp, #0xb0 ldp x29, x30, [sp], #0x10 diff --git a/tests/snapshots/asm/local_array_partial_init_zero.x64.asm b/tests/snapshots/asm/local_array_partial_init_zero.x64.asm index bd83f8e7a..6f3bed646 100644 --- a/tests/snapshots/asm/local_array_partial_init_zero.x64.asm +++ b/tests/snapshots/asm/local_array_partial_init_zero.x64.asm @@ -27,7 +27,15 @@ Disassembly of section .text: movl %edi, %esi movl %esi, (%rax,%rdx,4) jmp + leaq -0xa0(%rbp), %rax xorq %rcx, %rcx + movl (%rax), %eax + leaq -0xa0(%rbp), %rdx + movl 0x9c(%rdx), %edx + addq %rdx, %rax + movl %eax, %eax + movl %eax, -0xb0(%rbp) + movl -0xb0(%rbp), %eax movq %rcx, %rax addq $0xb0, %rsp popq %rbp @@ -126,5 +134,3 @@ Disassembly of section .text: addq $0x10, %rsp popq %rbp retq - addb %al, (%rax) - addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/math_classify.aarch64.asm b/tests/snapshots/asm/math_classify.aarch64.asm index a8b075fa9..14768c97c 100644 --- a/tests/snapshots/asm/math_classify.aarch64.asm +++ b/tests/snapshots/asm/math_classify.aarch64.asm @@ -93,6 +93,7 @@ Disassembly of section .text: sub x0, x29, #0x8 ldr x0, [x0] lsr x0, x0, #63 + sxtw x0, w0 add sp, sp, #0x10 ldp x29, x30, [sp], #0x10 ret diff --git a/tests/snapshots/asm/math_classify.x64.asm b/tests/snapshots/asm/math_classify.x64.asm index 032a0e01c..260477607 100644 --- a/tests/snapshots/asm/math_classify.x64.asm +++ b/tests/snapshots/asm/math_classify.x64.asm @@ -93,6 +93,7 @@ Disassembly of section .text: leaq -0x8(%rbp), %rax movq (%rax), %rax shrq $0x3f, %rax + movslq %eax, %rax addq $0x10, %rsp popq %rbp retq @@ -257,3 +258,4 @@ Disassembly of section .text: addq $0x50, %rsp popq %rbp retq + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/mem2reg_value_across_call.aarch64.asm b/tests/snapshots/asm/mem2reg_value_across_call.aarch64.asm index 044f1b855..12d288506 100644 --- a/tests/snapshots/asm/mem2reg_value_across_call.aarch64.asm +++ b/tests/snapshots/asm/mem2reg_value_across_call.aarch64.asm @@ -37,8 +37,8 @@ Disassembly of section .text: lsl x0, x22, #1 add x0, x0, #0x1 add x23, x23, x0 - mov x9, x21 str x22, [sp, #-0x10]! + mov x9, x21 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/mixed_sse_int_aggregate_args.aarch64.asm b/tests/snapshots/asm/mixed_sse_int_aggregate_args.aarch64.asm new file mode 100644 index 000000000..625369877 --- /dev/null +++ b/tests/snapshots/asm/mixed_sse_int_aggregate_args.aarch64.asm @@ -0,0 +1,161 @@ + +mixed_sse_int_aggregate_args.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + sub sp, sp, #0x10 + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x50 + sub x16, x29, #0x10 + str x0, [x16] + str x1, [x16, #0x8] + sub x16, x29, #0x20 + str x3, [x16] + str x4, [x16, #0x8] + sub x16, x29, #0x30 + str d1, [x16] + str d2, [x16, #0x8] + mov x1, x2 + sub x0, x29, #0x10 + ldr d1, [x0] + mov x0, #0x4004000000000000 // =4612811918334230528 + fmov d17, x0 + fcmp d1, d17 + cset x2, ne + cbnz x2, + sub x0, x29, #0x10 + ldr x0, [x0, #0x8] + cmp x0, #0x7 + cset x2, ne + cbz x2, + mov x0, #0x1 // =1 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x50 + ret + cmp x1, #0x4 + b.eq + mov x0, #0x2 // =2 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x50 + ret + sub x0, x29, #0x20 + ldr x0, [x0] + cmp x0, #0xb + cset x1, ne + cbnz x1, + sub x0, x29, #0x20 + ldr d1, [x0, #0x8] + mov x0, #0x3fe0000000000000 // =4602678819172646912 + fmov d17, x0 + fcmp d1, d17 + cset x1, ne + cbz x1, + mov x0, #0x3 // =3 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x50 + ret + mov x0, #0x3ff4000000000000 // =4608308318706860032 + fmov d17, x0 + fcmp d0, d17 + cset x0, ne + cbz x0, + mov x0, #0x4 // =4 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x50 + ret + sub x0, x29, #0x30 + ldr d0, [x0] + mov x0, #0x400c000000000000 // =4615063718147915776 + fmov d17, x0 + fcmp d0, d17 + cset x1, ne + cbnz x1, + sub x0, x29, #0x30 + ldr d0, [x0, #0x8] + mov x0, #0x4012000000000000 // =4616752568008179712 + fmov d17, x0 + fcmp d0, d17 + cset x1, ne + cbz x1, + mov x0, #0x5 // =5 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x50 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x50 + ret + b + b + b + +: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + ldr d1, [x3] + ldr d2, [x3, #0x8] + mov x3, x2 + mov x2, x0 + mov x0, x1 + ldr x1, [x0, #0x8] + ldr x0, [x0] + ldr x4, [x3, #0x8] + ldr x3, [x3] + bl + ldp x29, x30, [sp], #0x10 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x60 + sub x0, x29, #0x10 + mov x1, #0x4004000000000000 // =4612811918334230528 + fmov d16, x1 + str d16, [x0] + sub x0, x29, #0x10 + mov x1, #0x7 // =7 + str x1, [x0, #0x8] + sub x0, x29, #0x20 + mov x1, #0xb // =11 + str x1, [x0] + sub x0, x29, #0x20 + mov x1, #0x3fe0000000000000 // =4602678819172646912 + fmov d16, x1 + str d16, [x0, #0x8] + sub x0, x29, #0x30 + mov x1, #0x400c000000000000 // =4615063718147915776 + fmov d16, x1 + str d16, [x0] + sub x0, x29, #0x30 + mov x1, #0x4012000000000000 // =4616752568008179712 + fmov d16, x1 + str d16, [x0, #0x8] + mov x0, #0x4 // =4 + sub x1, x29, #0x10 + sub x2, x29, #0x20 + sub x3, x29, #0x30 + mov x4, #0x3ff4000000000000 // =4608308318706860032 + fmov d0, x4 + bl + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/mixed_sse_int_aggregate_args.x64.asm b/tests/snapshots/asm/mixed_sse_int_aggregate_args.x64.asm new file mode 100644 index 000000000..a724e7101 --- /dev/null +++ b/tests/snapshots/asm/mixed_sse_int_aggregate_args.x64.asm @@ -0,0 +1,199 @@ + +mixed_sse_int_aggregate_args.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + popq %r10 + subq $0x50, %rsp + pushq %r10 + pushq %rbp + movq %rsp, %rbp + subq $0x50, %rsp + movsd %xmm0, -0x10(%rbp,%riz) + movq %rdi, -0x8(%rbp) + movq %rdx, -0x20(%rbp) + movsd %xmm1, -0x18(%rbp,%riz) + movsd %xmm3, -0x30(%rbp,%riz) + movsd %xmm4, -0x28(%rbp,%riz) + movapd %xmm2, %xmm0 + leaq -0x10(%rbp), %rax + movsd (%rax,%riz), %xmm1 + movabsq $0x4004000000000000, %rax # imm = 0x4004000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm1 + setne %cl + movzbq %cl, %rcx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rcx + testq %rcx, %rcx + jne + leaq -0x10(%rbp), %rax + movq 0x8(%rax), %rax + cmpq $0x7, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x1, %eax + addq $0x50, %rsp + popq %rbp + popq %r11 + addq $0x50, %rsp + pushq %r11 + retq + cmpq $0x4, %rsi + je + movl $0x2, %eax + addq $0x50, %rsp + popq %rbp + popq %r11 + addq $0x50, %rsp + pushq %r11 + retq + leaq -0x20(%rbp), %rax + movq (%rax), %rax + cmpq $0xb, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + jne + leaq -0x20(%rbp), %rax + movsd 0x8(%rax,%riz), %xmm1 + movabsq $0x3fe0000000000000, %rax # imm = 0x3FE0000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm1 + setne %cl + movzbq %cl, %rcx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rcx + testq %rcx, %rcx + je + movl $0x3, %eax + addq $0x50, %rsp + popq %rbp + popq %r11 + addq $0x50, %rsp + pushq %r11 + retq + movabsq $0x3ff4000000000000, %rax # imm = 0x3FF4000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x4, %eax + addq $0x50, %rsp + popq %rbp + popq %r11 + addq $0x50, %rsp + pushq %r11 + retq + leaq -0x30(%rbp), %rax + movsd (%rax,%riz), %xmm0 + movabsq $0x400c000000000000, %rax # imm = 0x400C000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %cl + movzbq %cl, %rcx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rcx + testq %rcx, %rcx + jne + leaq -0x30(%rbp), %rax + movsd 0x8(%rax,%riz), %xmm0 + movabsq $0x4012000000000000, %rax # imm = 0x4012000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %cl + movzbq %cl, %rcx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rcx + testq %rcx, %rcx + je + movl $0x5, %eax + addq $0x50, %rsp + popq %rbp + popq %r11 + addq $0x50, %rsp + pushq %r11 + retq + xorq %rax, %rax + addq $0x50, %rsp + popq %rbp + popq %r11 + addq $0x50, %rsp + pushq %r11 + retq + jmp + jmp + jmp + +: + pushq %rbp + movq %rsp, %rbp + movapd %xmm0, %xmm2 + movq %rcx, %r10 + movsd (%r10,%riz), %xmm3 + movsd 0x8(%r10,%riz), %xmm4 + xchgq %rsi, %rdi + movsd (%rdi,%riz), %xmm0 + movq 0x8(%rdi), %rdi + movsd 0x8(%rdx,%riz), %xmm1 + movq (%rdx), %rdx + callq + popq %rbp + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x60, %rsp + leaq -0x10(%rbp), %rax + movabsq $0x4004000000000000, %rcx # imm = 0x4004000000000000 + movq %rcx, %xmm14 + movsd %xmm14, (%rax,%riz) + leaq -0x10(%rbp), %rax + movl $0x7, %ecx + movq %rcx, 0x8(%rax) + leaq -0x20(%rbp), %rax + movl $0xb, %ecx + movq %rcx, (%rax) + leaq -0x20(%rbp), %rax + movabsq $0x3fe0000000000000, %rcx # imm = 0x3FE0000000000000 + movq %rcx, %xmm14 + movsd %xmm14, 0x8(%rax,%riz) + leaq -0x30(%rbp), %rax + movabsq $0x400c000000000000, %rcx # imm = 0x400C000000000000 + movq %rcx, %xmm14 + movsd %xmm14, (%rax,%riz) + leaq -0x30(%rbp), %rax + movabsq $0x4012000000000000, %rcx # imm = 0x4012000000000000 + movq %rcx, %xmm14 + movsd %xmm14, 0x8(%rax,%riz) + movl $0x4, %edi + leaq -0x10(%rbp), %rsi + leaq -0x20(%rbp), %rdx + leaq -0x30(%rbp), %rcx + movabsq $0x3ff4000000000000, %r8 # imm = 0x3FF4000000000000 + movq %r8, %xmm0 + callq + addq $0x60, %rsp + popq %rbp + retq + addb %al, (%rax) diff --git a/tests/snapshots/asm/mixed_struct_gpr_abi.aarch64.asm b/tests/snapshots/asm/mixed_struct_gpr_abi.aarch64.asm index 5c087c8cb..0a8fa4e5a 100644 --- a/tests/snapshots/asm/mixed_struct_gpr_abi.aarch64.asm +++ b/tests/snapshots/asm/mixed_struct_gpr_abi.aarch64.asm @@ -24,8 +24,7 @@ Disassembly of section .text: ldr x0, [x0] scvtf d0, x0 sub x0, x29, #0x10 - add x0, x0, #0x8 - ldr d1, [x0] + ldr d1, [x0, #0x8] mov x0, #0x4000000000000000 // =4611686018427387904 fmov d17, x0 fmadd d0, d1, d17, d0 @@ -55,8 +54,7 @@ Disassembly of section .text: ldr x1, [x1] add x0, x0, x1 sub x1, x29, #0x10 - add x1, x1, #0x8 - ldr d0, [x1] + ldr d0, [x1, #0x8] fcvtzs x1, d0 add x0, x0, x1 add sp, sp, #0x10 @@ -82,8 +80,7 @@ Disassembly of section .text: sxtw x1, w1 ldr x2, [x0] scvtf d0, x2 - add x0, x0, #0x8 - ldr d1, [x0] + ldr d1, [x0, #0x8] mov x0, #0x4000000000000000 // =4611686018427387904 fmov d17, x0 fmadd d0, d1, d17, d0 @@ -110,8 +107,7 @@ Disassembly of section .text: sxtw x0, w0 ldr x1, [x6] add x0, x0, x1 - add x1, x6, #0x8 - ldr d0, [x1] + ldr d0, [x6, #0x8] fcvtzs x1, d0 add x0, x0, x1 cmp x0, #0x1c diff --git a/tests/snapshots/asm/mixed_struct_gpr_abi.x64.asm b/tests/snapshots/asm/mixed_struct_gpr_abi.x64.asm index 453ed19b6..abb438fdf 100644 --- a/tests/snapshots/asm/mixed_struct_gpr_abi.x64.asm +++ b/tests/snapshots/asm/mixed_struct_gpr_abi.x64.asm @@ -24,8 +24,7 @@ Disassembly of section .text: movq (%rax), %rax cvtsi2sd %rax, %xmm0 leaq -0x10(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm1 + movsd 0x8(%rax,%riz), %xmm1 movabsq $0x4000000000000000, %rax # imm = 0x4000000000000000 movapd %xmm1, %xmm14 movq %rax, %xmm15 @@ -60,8 +59,7 @@ Disassembly of section .text: movq (%rcx), %rcx addq %rcx, %rax leaq -0x10(%rbp), %rcx - addq $0x8, %rcx - movsd (%rcx,%riz), %xmm0 + movsd 0x8(%rcx,%riz), %xmm0 cvttsd2si %xmm0, %rcx addq %rcx, %rax addq $0x10, %rsp @@ -85,9 +83,8 @@ Disassembly of section .text: popq %rdx leaq -0x10(%rbp), %rdi movl $0x2, %esi - movq %rdi, %r10 - movq (%r10), %rdi - movsd 0x8(%r10,%riz), %xmm0 + movsd 0x8(%rdi,%riz), %xmm0 + movq (%rdi), %rdi callq cmpq $0xe, %rax je @@ -120,3 +117,4 @@ Disassembly of section .text: addq $0x50, %rsp popq %rbp retq + addb %al, (%rax) diff --git a/tests/snapshots/asm/msvc_callconv.aarch64.asm b/tests/snapshots/asm/msvc_callconv.aarch64.asm index 9bb5f134d..f03aa77c1 100644 --- a/tests/snapshots/asm/msvc_callconv.aarch64.asm +++ b/tests/snapshots/asm/msvc_callconv.aarch64.asm @@ -46,9 +46,9 @@ Disassembly of section .text: add x20, x20, mov x1, #0x14 // =20 mov x2, #0x16 // =22 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -61,8 +61,8 @@ Disassembly of section .text: add x1, x1, x2 add x0, x0, x1 sxtw x21, w0 - mov x9, x20 str x21, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/negative_float_in_array_init.aarch64.asm b/tests/snapshots/asm/negative_float_in_array_init.aarch64.asm index 711893168..d105f69ba 100644 --- a/tests/snapshots/asm/negative_float_in_array_init.aarch64.asm +++ b/tests/snapshots/asm/negative_float_in_array_init.aarch64.asm @@ -25,8 +25,7 @@ Disassembly of section .text: add sp, sp, #0x10 ldp x29, x30, [sp], #0x10 ret - add x1, x0, #0x8 - ldr d0, [x1] + ldr d0, [x0, #0x8] mov x1, #0x4004000000000000 // =4612811918334230528 fmov d16, x1 fneg d1, d16 @@ -37,8 +36,7 @@ Disassembly of section .text: add sp, sp, #0x10 ldp x29, x30, [sp], #0x10 ret - add x1, x0, #0x10 - ldr d0, [x1] + ldr d0, [x0, #0x10] mov x1, #0x94000000 // =2483027968 movk x1, #0x449a, lsl #32 movk x1, #0x421e, lsl #48 @@ -52,11 +50,9 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret ldr d0, [x0] - add x1, x0, #0x8 - ldr d1, [x1] + ldr d1, [x0, #0x8] fadd d0, d0, d1 - add x0, x0, #0x10 - ldr d1, [x0] + ldr d1, [x0, #0x10] fadd d0, d0, d1 mov x0, #0x94000000 // =2483027968 movk x0, #0x449a, lsl #32 diff --git a/tests/snapshots/asm/negative_float_in_array_init.x64.asm b/tests/snapshots/asm/negative_float_in_array_init.x64.asm index 6598bae3b..067bb05f4 100644 --- a/tests/snapshots/asm/negative_float_in_array_init.x64.asm +++ b/tests/snapshots/asm/negative_float_in_array_init.x64.asm @@ -30,8 +30,7 @@ Disassembly of section .text: addq $0x10, %rsp popq %rbp retq - leaq 0x8(%rax), %rcx - movsd (%rcx,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x4004000000000000, %rcx # imm = 0x4004000000000000 movq %rcx, %xmm1 movabsq $-0x8000000000000000, %r10 # imm = 0x8000000000000000 @@ -49,8 +48,7 @@ Disassembly of section .text: addq $0x10, %rsp popq %rbp retq - leaq 0x10(%rax), %rcx - movsd (%rcx,%riz), %xmm0 + movsd 0x10(%rax,%riz), %xmm0 movabsq $0x421e449a94000000, %rcx # imm = 0x421E449A94000000 movq %rcx, %xmm1 movabsq $-0x8000000000000000, %r10 # imm = 0x8000000000000000 @@ -69,11 +67,9 @@ Disassembly of section .text: popq %rbp retq movsd (%rax,%riz), %xmm0 - leaq 0x8(%rax), %rcx - movsd (%rcx,%riz), %xmm1 + movsd 0x8(%rax,%riz), %xmm1 addsd %xmm1, %xmm0 - addq $0x10, %rax - movsd (%rax,%riz), %xmm1 + movsd 0x10(%rax,%riz), %xmm1 addsd %xmm1, %xmm0 movabsq $0x421e449a94000000, %rax # imm = 0x421E449A94000000 movq %rax, %xmm1 @@ -113,4 +109,4 @@ Disassembly of section .text: popq %rbp retq jmp - addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/nested_designator_string_member.aarch64.asm b/tests/snapshots/asm/nested_designator_string_member.aarch64.asm new file mode 100644 index 000000000..37c037376 --- /dev/null +++ b/tests/snapshots/asm/nested_designator_string_member.aarch64.asm @@ -0,0 +1,189 @@ + +nested_designator_string_member.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + mov x2, x0 + ldrb w3, [x2] + cbz x3, + b + add x2, x2, #0x1 + add x1, x1, #0x1 + b + ldrb w0, [x2] + ldrb w1, [x1] + cmp x0, x1 + cset x0, eq + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + ldrb w0, [x2] + ldrb w3, [x1] + cmp x0, x3 + cset x3, eq + cbz x3, + b + b + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x60 + str x20, [sp] + str x21, [sp, #0x8] + str x22, [sp, #0x10] + mov x20, x0 + adrp x21, + add x21, x21, + add x0, x21, #0x4 + adrp x1, + add x1, x1, + bl + cmp x0, #0x0 + b.ne + mov x0, #0x1 // =1 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + ldrb w0, [x21, #0x7] + cmp x0, #0x0 + cset x22, ne + cbnz x22, + ldrb w0, [x21, #0xb] + cmp x0, #0x0 + cset x22, ne + cbz x22, + mov x0, #0x2 // =2 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + ldrsw x0, [x21, #0xc] + cmp x0, #0x7 + cset x22, ne + cbnz x22, + ldrsw x0, [x21] + cmp x0, #0x5 + cset x22, ne + cbz x22, + mov x0, #0x3 // =3 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x10 + adrp x1, + add x1, x1, + str x10, [sp, #-0x10]! + ldr x10, [x1] + str x10, [x0] + ldr x10, [x1, #0x8] + str x10, [x0, #0x8] + ldr x10, [sp], #0x10 + mov x0, #0x77 // =119 + sub x1, x29, #0x10 + strb w0, [x1, #0x4] + mov x0, #0x78 // =120 + sub x1, x29, #0x10 + strb w0, [x1, #0x5] + mov x0, #0x79 // =121 + sub x1, x29, #0x10 + strb w0, [x1, #0x6] + mov x0, #0x7a // =122 + sub x1, x29, #0x10 + strb w0, [x1, #0x7] + mov x0, #0x0 // =0 + sub x1, x29, #0x10 + strb w0, [x1, #0x8] + sub x1, x29, #0x10 + strb w0, [x1, #0x9] + sub x1, x29, #0x10 + strb w0, [x1, #0xa] + sub x1, x29, #0x10 + strb w0, [x1, #0xb] + add x0, x20, #0x6 + sub x1, x29, #0x10 + str w0, [x1, #0xc] + add x0, x20, #0x4 + sub x1, x29, #0x10 + str w0, [x1] + sub x0, x29, #0x10 + add x0, x0, #0x4 + adrp x1, + add x1, x1, + bl + cmp x0, #0x0 + b.ne + mov x0, #0x4 // =4 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x10 + ldrb w0, [x0, #0x8] + cmp x0, #0x0 + cset x1, ne + cbnz x1, + sub x0, x29, #0x10 + ldrb w0, [x0, #0xb] + cmp x0, #0x0 + cset x1, ne + cbz x1, + mov x0, #0x5 // =5 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x10 + ldrsw x0, [x0, #0xc] + add x1, x20, #0x6 + sxtw x1, w1 + cmp x0, x1 + cset x1, ne + cbnz x1, + sub x0, x29, #0x10 + ldrsw x0, [x0] + add x1, x20, #0x4 + sxtw x1, w1 + cmp x0, x1 + cset x1, ne + cbz x1, + mov x0, #0x6 // =6 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret + b + b + b + b diff --git a/tests/snapshots/asm/nested_designator_string_member.x64.asm b/tests/snapshots/asm/nested_designator_string_member.x64.asm new file mode 100644 index 000000000..afa5f07da --- /dev/null +++ b/tests/snapshots/asm/nested_designator_string_member.x64.asm @@ -0,0 +1,206 @@ + +nested_designator_string_member.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + subq $0x10, %rsp + movsbq (%rdi), %rcx + testq %rcx, %rcx + je + jmp + incq %rdi + incq %rsi + jmp + movsbq (%rdi), %rax + movsbq (%rsi), %rcx + cmpq %rcx, %rax + sete %al + movzbq %al, %rax + addq $0x10, %rsp + popq %rbp + retq + movsbq (%rdi), %rax + movsbq (%rsi), %rcx + cmpq %rcx, %rax + sete %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + jmp + jmp + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x60, %rsp + movq %rbx, (%rsp) + movq %r12, 0x8(%rsp) + movq %r13, 0x10(%rsp) + movq %rdi, %rbx + leaq , %r12 + leaq 0x4(%r12), %rdi + leaq , %rsi + callq + testq %rax, %rax + jne + movl $0x1, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x60, %rsp + popq %rbp + retq + movsbq 0x7(%r12), %rax + testq %rax, %rax + setne %r13b + movzbq %r13b, %r13 + testq %r13, %r13 + jne + movsbq 0xb(%r12), %rax + testq %rax, %rax + setne %r13b + movzbq %r13b, %r13 + testq %r13, %r13 + je + movl $0x2, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x60, %rsp + popq %rbp + retq + movslq 0xc(%r12), %rax + cmpq $0x7, %rax + setne %r13b + movzbq %r13b, %r13 + testq %r13, %r13 + jne + movslq (%r12), %rax + cmpq $0x5, %rax + setne %r13b + movzbq %r13b, %r13 + testq %r13, %r13 + je + movl $0x3, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x60, %rsp + popq %rbp + retq + leaq -0x10(%rbp), %rax + leaq , %rcx + pushq %rdx + movq (%rcx), %rdx + movq %rdx, (%rax) + movq 0x8(%rcx), %rdx + movq %rdx, 0x8(%rax) + popq %rdx + movl $0x77, %eax + leaq -0x10(%rbp), %rcx + movb %al, 0x4(%rcx) + movl $0x78, %eax + leaq -0x10(%rbp), %rcx + movb %al, 0x5(%rcx) + movl $0x79, %eax + leaq -0x10(%rbp), %rcx + movb %al, 0x6(%rcx) + movl $0x7a, %eax + leaq -0x10(%rbp), %rcx + movb %al, 0x7(%rcx) + xorq %rax, %rax + leaq -0x10(%rbp), %rcx + movb %al, 0x8(%rcx) + leaq -0x10(%rbp), %rcx + movb %al, 0x9(%rcx) + leaq -0x10(%rbp), %rcx + movb %al, 0xa(%rcx) + leaq -0x10(%rbp), %rcx + movb %al, 0xb(%rcx) + leaq 0x6(%rbx), %rax + leaq -0x10(%rbp), %rcx + movl %eax, 0xc(%rcx) + leaq 0x4(%rbx), %rax + leaq -0x10(%rbp), %rcx + movl %eax, (%rcx) + leaq -0x10(%rbp), %rax + leaq 0x4(%rax), %rdi + leaq , %rsi + callq + testq %rax, %rax + jne + movl $0x4, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x60, %rsp + popq %rbp + retq + leaq -0x10(%rbp), %rax + movsbq 0x8(%rax), %rax + testq %rax, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + jne + leaq -0x10(%rbp), %rax + movsbq 0xb(%rax), %rax + testq %rax, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x5, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x60, %rsp + popq %rbp + retq + leaq -0x10(%rbp), %rax + movslq 0xc(%rax), %rax + leaq 0x6(%rbx), %rcx + movslq %ecx, %rcx + cmpq %rcx, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + jne + leaq -0x10(%rbp), %rax + movslq (%rax), %rax + leaq 0x4(%rbx), %rcx + movslq %ecx, %rcx + cmpq %rcx, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x6, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x60, %rsp + popq %rbp + retq + xorq %rax, %rax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x60, %rsp + popq %rbp + retq + jmp + jmp + jmp + jmp + addb %al, (%rax) diff --git a/tests/snapshots/asm/out_pointer_return_float_args.aarch64.asm b/tests/snapshots/asm/out_pointer_return_float_args.aarch64.asm index be641702a..bee1fb173 100644 --- a/tests/snapshots/asm/out_pointer_return_float_args.aarch64.asm +++ b/tests/snapshots/asm/out_pointer_return_float_args.aarch64.asm @@ -16,14 +16,11 @@ Disassembly of section .text: sub x0, x29, #0x30 str s0, [x0] sub x0, x29, #0x30 - add x0, x0, #0x4 - str s1, [x0] + str s1, [x0, #0x4] sub x0, x29, #0x30 - add x0, x0, #0x8 - str s2, [x0] + str s2, [x0, #0x8] sub x0, x29, #0x30 - add x0, x0, #0xc - str s3, [x0] + str s3, [x0, #0xc] sub x0, x29, #0x30 mov x16, x0 ldr s0, [x16] @@ -43,17 +40,13 @@ Disassembly of section .text: sub x0, x29, #0x40 str s0, [x0] sub x0, x29, #0x40 - add x0, x0, #0x4 - str s1, [x0] + str s1, [x0, #0x4] sub x0, x29, #0x40 - add x0, x0, #0x8 - str s2, [x0] + str s2, [x0, #0x8] sub x0, x29, #0x40 - add x0, x0, #0xc - str s3, [x0] + str s3, [x0, #0xc] sub x0, x29, #0x40 - add x0, x0, #0x10 - str s4, [x0] + str s4, [x0, #0x10] sub x0, x29, #0x40 mov x16, x0 sub x17, x29, #0x48 @@ -82,11 +75,9 @@ Disassembly of section .text: sub x0, x29, #0x18 str d0, [x0] sub x0, x29, #0x18 - add x0, x0, #0x8 - str d1, [x0] + str d1, [x0, #0x8] sub x0, x29, #0x18 - add x0, x0, #0x10 - str d2, [x0] + str d2, [x0, #0x10] sub x0, x29, #0x18 mov x16, x0 ldr d0, [x16] @@ -138,8 +129,7 @@ Disassembly of section .text: mov x20, #0x1 // =1 cbnz x0, sub x0, x29, #0x10 - add x0, x0, #0x4 - ldr s0, [x0] + ldr s0, [x0, #0x4] mov x0, #0x4000000000000000 // =4611686018427387904 fcvt d0, s0 fmov d17, x0 @@ -150,8 +140,7 @@ Disassembly of section .text: mov x21, #0x1 // =1 cbnz x20, sub x0, x29, #0x10 - add x0, x0, #0x8 - ldr s0, [x0] + ldr s0, [x0, #0x8] mov x0, #0x4008000000000000 // =4613937818241073152 fcvt d0, s0 fmov d17, x0 @@ -161,8 +150,7 @@ Disassembly of section .text: cset x21, ne cbnz x21, sub x0, x29, #0x10 - add x0, x0, #0xc - ldr s0, [x0] + ldr s0, [x0, #0xc] mov x0, #0x4010000000000000 // =4616189618054758400 fcvt d0, s0 fmov d17, x0 @@ -218,8 +206,7 @@ Disassembly of section .text: mov x20, #0x1 // =1 cbnz x0, sub x0, x29, #0x38 - add x0, x0, #0x4 - ldr s0, [x0] + ldr s0, [x0, #0x4] mov x0, #0x4004000000000000 // =4612811918334230528 fcvt d0, s0 fmov d17, x0 @@ -230,8 +217,7 @@ Disassembly of section .text: mov x21, #0x1 // =1 cbnz x20, sub x0, x29, #0x38 - add x0, x0, #0x8 - ldr s0, [x0] + ldr s0, [x0, #0x8] mov x0, #0x400c000000000000 // =4615063718147915776 fcvt d0, s0 fmov d17, x0 @@ -242,8 +228,7 @@ Disassembly of section .text: mov x20, #0x1 // =1 cbnz x21, sub x0, x29, #0x38 - add x0, x0, #0xc - ldr s0, [x0] + ldr s0, [x0, #0xc] mov x0, #0x4012000000000000 // =4616752568008179712 fcvt d0, s0 fmov d17, x0 @@ -253,8 +238,7 @@ Disassembly of section .text: cset x20, ne cbnz x20, sub x0, x29, #0x38 - add x0, x0, #0x10 - ldr s0, [x0] + ldr s0, [x0, #0x10] mov x0, #0x4016000000000000 // =4617878467915022336 fcvt d0, s0 fmov d17, x0 @@ -297,8 +281,7 @@ Disassembly of section .text: mov x2, #0x1 // =1 cbnz x0, sub x0, x29, #0x68 - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] mov x0, #0x4034000000000000 // =4626322717216342016 fmov d17, x0 fcmp d0, d17 @@ -307,8 +290,7 @@ Disassembly of section .text: cset x2, ne cbnz x2, sub x0, x29, #0x68 - add x0, x0, #0x10 - ldr d0, [x0] + ldr d0, [x0, #0x10] mov x0, #0x403e000000000000 // =4629137466983448576 fmov d17, x0 fcmp d0, d17 diff --git a/tests/snapshots/asm/out_pointer_return_float_args.x64.asm b/tests/snapshots/asm/out_pointer_return_float_args.x64.asm index be302a423..b49b87843 100644 --- a/tests/snapshots/asm/out_pointer_return_float_args.x64.asm +++ b/tests/snapshots/asm/out_pointer_return_float_args.x64.asm @@ -17,14 +17,11 @@ Disassembly of section .text: leaq -0x30(%rbp), %rax movss %xmm0, (%rax,%riz) leaq -0x30(%rbp), %rax - addq $0x4, %rax - movss %xmm1, (%rax,%riz) + movss %xmm1, 0x4(%rax,%riz) leaq -0x30(%rbp), %rax - addq $0x8, %rax - movss %xmm2, (%rax,%riz) + movss %xmm2, 0x8(%rax,%riz) leaq -0x30(%rbp), %rax - addq $0xc, %rax - movss %xmm3, (%rax,%riz) + movss %xmm3, 0xc(%rax,%riz) leaq -0x30(%rbp), %rax movq %rax, %rcx movsd (%rcx,%riz), %xmm0 @@ -70,21 +67,17 @@ Disassembly of section .text: movss -0x8(%rbp,%riz), %xmm0 movss %xmm0, (%rax,%riz) leaq -0x40(%rbp), %rax - addq $0x4, %rax movss -0x10(%rbp,%riz), %xmm0 - movss %xmm0, (%rax,%riz) + movss %xmm0, 0x4(%rax,%riz) leaq -0x40(%rbp), %rax - addq $0x8, %rax movss -0x18(%rbp,%riz), %xmm0 - movss %xmm0, (%rax,%riz) + movss %xmm0, 0x8(%rax,%riz) leaq -0x40(%rbp), %rax - addq $0xc, %rax movss -0x20(%rbp,%riz), %xmm0 - movss %xmm0, (%rax,%riz) + movss %xmm0, 0xc(%rax,%riz) leaq -0x40(%rbp), %rax - addq $0x10, %rax movss -0x28(%rbp,%riz), %xmm0 - movss %xmm0, (%rax,%riz) + movss %xmm0, 0x10(%rax,%riz) movq 0x10(%rbp), %rax leaq -0x40(%rbp), %rcx pushq %rdx @@ -124,13 +117,11 @@ Disassembly of section .text: movsd 0x20(%rbp,%riz), %xmm0 movsd %xmm0, (%rax,%riz) leaq -0x18(%rbp), %rax - addq $0x8, %rax movsd 0x30(%rbp,%riz), %xmm0 - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x8(%rax,%riz) leaq -0x18(%rbp), %rax - addq $0x10, %rax movsd 0x40(%rbp,%riz), %xmm0 - movsd %xmm0, (%rax,%riz) + movsd %xmm0, 0x10(%rax,%riz) movq 0x10(%rbp), %rax leaq -0x18(%rbp), %rcx pushq %rdx @@ -193,8 +184,7 @@ Disassembly of section .text: testq %rax, %rax jne leaq -0x10(%rbp), %rax - addq $0x4, %rax - movss (%rax,%riz), %xmm0 + movss 0x4(%rax,%riz), %xmm0 movabsq $0x4000000000000000, %rax # imm = 0x4000000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -211,8 +201,7 @@ Disassembly of section .text: testq %rbx, %rbx jne leaq -0x10(%rbp), %rax - addq $0x8, %rax - movss (%rax,%riz), %xmm0 + movss 0x8(%rax,%riz), %xmm0 movabsq $0x4008000000000000, %rax # imm = 0x4008000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -228,8 +217,7 @@ Disassembly of section .text: testq %r12, %r12 jne leaq -0x10(%rbp), %rax - addq $0xc, %rax - movss (%rax,%riz), %xmm0 + movss 0xc(%rax,%riz), %xmm0 movabsq $0x4010000000000000, %rax # imm = 0x4010000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -315,8 +303,7 @@ Disassembly of section .text: testq %rax, %rax jne leaq -0x38(%rbp), %rax - addq $0x4, %rax - movss (%rax,%riz), %xmm0 + movss 0x4(%rax,%riz), %xmm0 movabsq $0x4004000000000000, %rax # imm = 0x4004000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -333,8 +320,7 @@ Disassembly of section .text: testq %rbx, %rbx jne leaq -0x38(%rbp), %rax - addq $0x8, %rax - movss (%rax,%riz), %xmm0 + movss 0x8(%rax,%riz), %xmm0 movabsq $0x400c000000000000, %rax # imm = 0x400C000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -351,8 +337,7 @@ Disassembly of section .text: testq %r12, %r12 jne leaq -0x38(%rbp), %rax - addq $0xc, %rax - movss (%rax,%riz), %xmm0 + movss 0xc(%rax,%riz), %xmm0 movabsq $0x4012000000000000, %rax # imm = 0x4012000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -368,8 +353,7 @@ Disassembly of section .text: testq %rbx, %rbx jne leaq -0x38(%rbp), %rax - addq $0x10, %rax - movss (%rax,%riz), %xmm0 + movss 0x10(%rax,%riz), %xmm0 movabsq $0x4016000000000000, %rax # imm = 0x4016000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -417,8 +401,7 @@ Disassembly of section .text: testq %rax, %rax jne leaq -0x68(%rbp), %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 movabsq $0x4034000000000000, %rax # imm = 0x4034000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -433,8 +416,7 @@ Disassembly of section .text: testq %rdx, %rdx jne leaq -0x68(%rbp), %rax - addq $0x10, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x10(%rax,%riz), %xmm0 movabsq $0x403e000000000000, %rax # imm = 0x403E000000000000 movq %rax, %xmm15 ucomisd %xmm15, %xmm0 @@ -466,4 +448,3 @@ Disassembly of section .text: jmp jmp jmp - addb %al, (%rax) diff --git a/tests/snapshots/asm/packed_bitfield_repack.aarch64.asm b/tests/snapshots/asm/packed_bitfield_repack.aarch64.asm new file mode 100644 index 000000000..51f763818 --- /dev/null +++ b/tests/snapshots/asm/packed_bitfield_repack.aarch64.asm @@ -0,0 +1,247 @@ + +packed_bitfield_repack.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x70 + mov x1, #0x0 // =0 + mov x1, #0x0 // =0 + cbz x1, + mov x0, #0x1 // =1 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret + mov x1, #0x0 // =0 + mov x1, #0x0 // =0 + cbz x1, + mov x0, #0x2 // =2 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret + mov x1, #0x0 // =0 + mov x1, #0x0 // =0 + cbz x1, + mov x0, #0x3 // =3 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret + b + mov x0, #0x4 // =4 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x8 + mov x1, #0x55 // =85 + ldrb w2, [x0] + mov x17, #0xff00 // =65280 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + and x2, x2, x17 + orr x1, x2, x1 + strb w1, [x0] + sub x0, x29, #0x8 + mov x1, #0x7 // =7 + strb w1, [x0, #0x1] + sub x0, x29, #0x8 + ldrb w0, [x0] + sxtb x0, w0 + cmp x0, #0x55 + cset x1, ne + cbnz x1, + sub x0, x29, #0x8 + ldrb w0, [x0, #0x1] + mov x17, #0x7 // =7 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + cset x1, ne + cbz x1, + mov x0, #0x5 // =5 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x10 + mov x1, #0xfde8 // =65000 + ldr w2, [x0] + mov x17, #0xfffe0000 // =4294836224 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + and x2, x2, x17 + orr x1, x2, x1 + str w1, [x0] + sub x0, x29, #0x10 + ldrh w1, [x0, #0x2] + mov x17, #0xf801 // =63489 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + and x1, x1, x17 + mov x2, #0x3e8 // =1000 + orr x1, x1, x2 + strh w1, [x0, #0x2] + sub x0, x29, #0x10 + mov x1, #0x9 // =9 + strb w1, [x0, #0x4] + sub x0, x29, #0x10 + ldr w0, [x0] + mov x17, #0xffff // =65535 + movk x17, #0x1, lsl #16 + and x0, x0, x17 + lsl x0, x0, #47 + asr x0, x0, #47 + mov x17, #0xfde8 // =65000 + cmp x0, x17 + cset x0, ne + mov x2, #0x1 // =1 + cbnz x0, + sub x0, x29, #0x10 + ldrh w0, [x0, #0x2] + asr x0, x0, #1 + mov x17, #0x3ff // =1023 + and x0, x0, x17 + lsl x0, x0, #54 + asr x0, x0, #54 + cmp x0, #0x1f4 + cset x0, ne + cmp x0, #0x0 + cset x2, ne + cbnz x2, + sub x0, x29, #0x10 + ldrb w0, [x0, #0x4] + mov x17, #0x9 // =9 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + cset x2, ne + cbz x2, + mov x0, #0x6 // =6 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x18 + mov x1, #0x3 // =3 + ldrb w2, [x0] + mov x17, #0xfff8 // =65528 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + and x2, x2, x17 + orr x1, x2, x1 + strb w1, [x0] + sub x0, x29, #0x18 + ldrh w1, [x0] + mov x17, #0xfc07 // =64519 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + and x1, x1, x17 + mov x2, #0x1e0 // =480 + orr x1, x1, x2 + strh w1, [x0] + sub x0, x29, #0x18 + mov x1, #0x4 // =4 + strb w1, [x0, #0x2] + sub x0, x29, #0x18 + ldrb w0, [x0] + mov x17, #0x7 // =7 + and x0, x0, x17 + cmp x0, #0x3 + cset x0, ne + mov x2, #0x1 // =1 + cbnz x0, + sub x0, x29, #0x18 + ldrh w0, [x0] + asr x0, x0, #3 + mov x17, #0x7f // =127 + and x0, x0, x17 + cmp x0, #0x3c + cset x0, ne + cmp x0, #0x0 + cset x2, ne + cbnz x2, + sub x0, x29, #0x18 + ldrb w0, [x0, #0x2] + mov x17, #0x4 // =4 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + cset x2, ne + cbz x2, + mov x0, #0x7 // =7 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x20 + mov x1, #0xb // =11 + strb w1, [x0] + sub x0, x29, #0x20 + add x0, x0, #0x1 + mov x1, #0x7530 // =30000 + ldrh w2, [x0] + mov x17, #0xffff0000 // =4294901760 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + and x2, x2, x17 + orr x1, x2, x1 + strh w1, [x0] + sub x0, x29, #0x20 + ldrb w0, [x0] + mov x17, #0xb // =11 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + cset x1, ne + cbnz x1, + sub x0, x29, #0x20 + add x0, x0, #0x1 + ldrh w0, [x0] + sxth x0, w0 + mov x17, #0x7530 // =30000 + cmp x0, x17 + cset x1, ne + cbz x1, + mov x0, #0x8 // =8 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + ldrb w0, [x0] + sxtb x0, w0 + cmp x0, #0x55 + cset x1, ne + cbnz x1, + adrp x0, + add x0, x0, + ldrb w0, [x0, #0x1] + mov x17, #0x7 // =7 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + cset x1, ne + cbz x1, + mov x0, #0x9 // =9 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret + b + b + b + b + b + b + b diff --git a/tests/snapshots/asm/packed_bitfield_repack.x64.asm b/tests/snapshots/asm/packed_bitfield_repack.x64.asm new file mode 100644 index 000000000..12b6325e0 --- /dev/null +++ b/tests/snapshots/asm/packed_bitfield_repack.x64.asm @@ -0,0 +1,237 @@ + +packed_bitfield_repack.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x70, %rsp + xorq %rcx, %rcx + xorq %rcx, %rcx + testq %rcx, %rcx + je + movl $0x1, %eax + addq $0x70, %rsp + popq %rbp + retq + xorq %rcx, %rcx + xorq %rcx, %rcx + testq %rcx, %rcx + je + movl $0x2, %eax + addq $0x70, %rsp + popq %rbp + retq + xorq %rcx, %rcx + xorq %rcx, %rcx + testq %rcx, %rcx + je + movl $0x3, %eax + addq $0x70, %rsp + popq %rbp + retq + jmp + movl $0x4, %eax + addq $0x70, %rsp + popq %rbp + retq + leaq -0x8(%rbp), %rax + movl $0x55, %ecx + movzbq (%rax), %rdx + andq $-0x100, %rdx + orq %rdx, %rcx + movb %cl, (%rax) + leaq -0x8(%rbp), %rax + movl $0x7, %ecx + movb %cl, 0x1(%rax) + leaq -0x8(%rbp), %rax + movzbq (%rax), %rax + movsbq %al, %rax + cmpq $0x55, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + jne + leaq -0x8(%rbp), %rax + movsbq 0x1(%rax), %rax + cmpq $0x7, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x5, %eax + addq $0x70, %rsp + popq %rbp + retq + leaq -0x10(%rbp), %rax + movl $0xfde8, %ecx # imm = 0xFDE8 + movl (%rax), %edx + andq $-0x20000, %rdx # imm = 0xFFFE0000 + orq %rdx, %rcx + movl %ecx, (%rax) + leaq -0x10(%rbp), %rax + movzwq 0x2(%rax), %rcx + andq $-0x7ff, %rcx # imm = 0xF801 + movl $0x3e8, %edx # imm = 0x3E8 + orq %rdx, %rcx + movw %cx, 0x2(%rax) + leaq -0x10(%rbp), %rax + movl $0x9, %ecx + movb %cl, 0x4(%rax) + leaq -0x10(%rbp), %rax + movl (%rax), %eax + andq $0x1ffff, %rax # imm = 0x1FFFF + shlq $0x2f, %rax + sarq $0x2f, %rax + cmpq $0xfde8, %rax # imm = 0xFDE8 + setne %al + movzbq %al, %rax + movl $0x1, %edx + testq %rax, %rax + jne + leaq -0x10(%rbp), %rax + movzwq 0x2(%rax), %rax + sarq $0x1, %rax + andq $0x3ff, %rax # imm = 0x3FF + shlq $0x36, %rax + sarq $0x36, %rax + cmpq $0x1f4, %rax # imm = 0x1F4 + setne %al + movzbq %al, %rax + testq %rax, %rax + setne %dl + movzbq %dl, %rdx + testq %rdx, %rdx + jne + leaq -0x10(%rbp), %rax + movsbq 0x4(%rax), %rax + cmpq $0x9, %rax + setne %dl + movzbq %dl, %rdx + testq %rdx, %rdx + je + movl $0x6, %eax + addq $0x70, %rsp + popq %rbp + retq + leaq -0x18(%rbp), %rax + movl $0x3, %ecx + movzbq (%rax), %rdx + andq $-0x8, %rdx + orq %rdx, %rcx + movb %cl, (%rax) + leaq -0x18(%rbp), %rax + movzwq (%rax), %rcx + andq $-0x3f9, %rcx # imm = 0xFC07 + movl $0x1e0, %edx # imm = 0x1E0 + orq %rdx, %rcx + movw %cx, (%rax) + leaq -0x18(%rbp), %rax + movl $0x4, %ecx + movb %cl, 0x2(%rax) + leaq -0x18(%rbp), %rax + movzbq (%rax), %rax + andq $0x7, %rax + shlq $0x3d, %rax + sarq $0x3d, %rax + cmpq $0x3, %rax + setne %al + movzbq %al, %rax + movl $0x1, %edx + testq %rax, %rax + jne + leaq -0x18(%rbp), %rax + movzwq (%rax), %rax + sarq $0x3, %rax + andq $0x7f, %rax + shlq $0x39, %rax + sarq $0x39, %rax + cmpq $0x3c, %rax + setne %al + movzbq %al, %rax + testq %rax, %rax + setne %dl + movzbq %dl, %rdx + testq %rdx, %rdx + jne + leaq -0x18(%rbp), %rax + movsbq 0x2(%rax), %rax + cmpq $0x4, %rax + setne %dl + movzbq %dl, %rdx + testq %rdx, %rdx + je + movl $0x7, %eax + addq $0x70, %rsp + popq %rbp + retq + leaq -0x20(%rbp), %rax + movl $0xb, %ecx + movb %cl, (%rax) + leaq -0x20(%rbp), %rax + incq %rax + movl $0x7530, %ecx # imm = 0x7530 + movzwq (%rax), %rdx + andq $-0x10000, %rdx # imm = 0xFFFF0000 + orq %rdx, %rcx + movw %cx, (%rax) + leaq -0x20(%rbp), %rax + movsbq (%rax), %rax + cmpq $0xb, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + jne + leaq -0x20(%rbp), %rax + incq %rax + movzwq (%rax), %rax + movswq %ax, %rax + cmpq $0x7530, %rax # imm = 0x7530 + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x8, %eax + addq $0x70, %rsp + popq %rbp + retq + leaq , %rax + movzbq (%rax), %rax + movsbq %al, %rax + cmpq $0x55, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + jne + leaq , %rax + movsbq 0x1(%rax), %rax + cmpq $0x7, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x9, %eax + addq $0x70, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x70, %rsp + popq %rbp + retq + jmp + jmp + jmp + jmp + jmp + jmp + jmp + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/posix_os_headers.x64.asm b/tests/snapshots/asm/posix_os_headers.x64.asm index 95a08b574..b49372de3 100644 --- a/tests/snapshots/asm/posix_os_headers.x64.asm +++ b/tests/snapshots/asm/posix_os_headers.x64.asm @@ -113,7 +113,7 @@ Disassembly of section .text: movl $0x5413, %esi # imm = 0x5413 leaq -0x70(%rbp), %rdx movq %rbx, %rdi - xorl %eax, %eax + movb $0x0, %al callq movslq %eax, %rax movq %rbx, %rax diff --git a/tests/snapshots/asm/pthread_create.aarch64.asm b/tests/snapshots/asm/pthread_create.aarch64.asm index 98283214a..400bf422c 100644 --- a/tests/snapshots/asm/pthread_create.aarch64.asm +++ b/tests/snapshots/asm/pthread_create.aarch64.asm @@ -39,11 +39,11 @@ Disassembly of section .text: sub x0, x29, #0x20 adrp x2, add x2, x2, - mov x9, x22 str x20, [sp, #-0x10]! str x2, [sp, #-0x10]! str x20, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x22 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] @@ -52,9 +52,9 @@ Disassembly of section .text: add sp, sp, #0x40 ldur x0, [x29, #-0x20] sub x1, x29, #0x28 - mov x9, x21 str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x21 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/rotate_variable_count.aarch64.asm b/tests/snapshots/asm/rotate_variable_count.aarch64.asm index 19dee3af5..d9bf4ba51 100644 --- a/tests/snapshots/asm/rotate_variable_count.aarch64.asm +++ b/tests/snapshots/asm/rotate_variable_count.aarch64.asm @@ -50,10 +50,9 @@ Disassembly of section .text:
: stp x29, x30, [sp, #-0x10]! mov x29, sp - sub sp, sp, #0x80 + sub sp, sp, #0x70 str x20, [sp] str x21, [sp, #0x8] - str x22, [sp, #0x10] sub x0, x29, #0x30 adrp x1, add x1, x1, @@ -84,59 +83,62 @@ Disassembly of section .text: mov w0, w20 add x20, x0, #0x1 b - mov x21, #0x1 // =1 + mov x0, #0x1 // =1 + stur w0, [x29, #-0x40] b mov x0, #0xcdef // =52719 movk x0, #0x89ab, lsl #16 movk x0, #0x4567, lsl #32 movk x0, #0x123, lsl #48 - ror x20, x0, #0x7 + stur x0, [x29, #-0x48] + ldur x1, [x29, #-0x48] + lsr x1, x1, #7 + ldur x2, [x29, #-0x48] + lsl x2, x2, #57 + orr x20, x1, x2 mov x1, #0x7 // =7 bl cmp x20, x0 b.eq b - sxtw x0, w21 + ldursw x0, [x29, #-0x40] cmp x0, #0x40 b.ge b - sxtw x0, w21 - add x21, x0, #0x1 + ldursw x0, [x29, #-0x40] + add x0, x0, #0x1 + stur w0, [x29, #-0x40] b sub x0, x29, #0x30 mov w1, w20 ldr x0, [x0, x1, lsl #3] - sxtw x1, w21 - sxtw x1, w1 - ror x22, x0, x1 + ldursw x1, [x29, #-0x40] + ror x21, x0, x1 sub x0, x29, #0x30 mov w1, w20 ldr x0, [x0, x1, lsl #3] - sxtw x1, w21 + ldursw x1, [x29, #-0x40] bl - cmp x22, x0 + cmp x21, x0 b.eq b b mov x0, #0x1 // =1 ldr x20, [sp] ldr x21, [sp, #0x8] - ldr x22, [sp, #0x10] - add sp, sp, #0x80 + add sp, sp, #0x70 ldp x29, x30, [sp], #0x10 ret b mov x0, #0x2 // =2 ldr x20, [sp] ldr x21, [sp, #0x8] - ldr x22, [sp, #0x10] - add sp, sp, #0x80 + add sp, sp, #0x70 ldp x29, x30, [sp], #0x10 ret mov x0, #0x0 // =0 ldr x20, [sp] ldr x21, [sp, #0x8] - ldr x22, [sp, #0x10] - add sp, sp, #0x80 + add sp, sp, #0x70 ldp x29, x30, [sp], #0x10 ret diff --git a/tests/snapshots/asm/rotate_variable_count.x64.asm b/tests/snapshots/asm/rotate_variable_count.x64.asm index e0f2892fb..2df0f9e20 100644 --- a/tests/snapshots/asm/rotate_variable_count.x64.asm +++ b/tests/snapshots/asm/rotate_variable_count.x64.asm @@ -13,8 +13,10 @@ Disassembly of section .text: : movslq %esi, %rsi movq %rdi, %rax + pushq %rcx movq %rsi, %rcx rorq %cl, %rax + popq %rcx retq : @@ -61,10 +63,9 @@ Disassembly of section .text:
: pushq %rbp movq %rsp, %rbp - subq $0x80, %rsp + subq $0x70, %rsp movq %rbx, (%rsp) movq %r12, 0x8(%rsp) - movq %r13, 0x10(%rsp) leaq -0x30(%rbp), %rax leaq , %rcx pushq %rdx @@ -94,60 +95,62 @@ Disassembly of section .text: movl %ebx, %eax leaq 0x1(%rax), %rbx jmp - movl $0x1, %r12d + movl $0x1, %eax + movl %eax, -0x40(%rbp) jmp movabsq $0x123456789abcdef, %rdi # imm = 0x123456789ABCDEF - movq %rdi, %rbx - rorq $0x7, %rbx + movq %rdi, -0x48(%rbp) + movq -0x48(%rbp), %rax + shrq $0x7, %rax + movq -0x48(%rbp), %rcx + shlq $0x39, %rcx + movq %rax, %rbx + orq %rcx, %rbx movl $0x7, %esi callq cmpq %rax, %rbx je jmp - movslq %r12d, %rax + movslq -0x40(%rbp), %rax cmpq $0x40, %rax jge jmp - movslq %r12d, %rax - leaq 0x1(%rax), %r12 + movslq -0x40(%rbp), %rax + incq %rax + movl %eax, -0x40(%rbp) jmp leaq -0x30(%rbp), %rax movl %ebx, %ecx movq (%rax,%rcx,8), %rax - movslq %r12d, %rcx - movslq %ecx, %rcx - movq %rax, %r13 - rorq %cl, %r13 + movslq -0x40(%rbp), %rcx + movq %rax, %r12 + rorq %cl, %r12 leaq -0x30(%rbp), %rax movl %ebx, %ecx movq (%rax,%rcx,8), %rdi - movslq %r12d, %rsi + movslq -0x40(%rbp), %rsi callq - cmpq %rax, %r13 + cmpq %rax, %r12 je jmp jmp movl $0x1, %eax movq (%rsp), %rbx movq 0x8(%rsp), %r12 - movq 0x10(%rsp), %r13 - addq $0x80, %rsp + addq $0x70, %rsp popq %rbp retq jmp movl $0x2, %eax movq (%rsp), %rbx movq 0x8(%rsp), %r12 - movq 0x10(%rsp), %r13 - addq $0x80, %rsp + addq $0x70, %rsp popq %rbp retq xorq %rax, %rax movq (%rsp), %rbx movq 0x8(%rsp), %r12 - movq 0x10(%rsp), %r13 - addq $0x80, %rsp + addq $0x70, %rsp popq %rbp retq addb %al, (%rax) - addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/setenv_overwrite.aarch64.asm b/tests/snapshots/asm/setenv_overwrite.aarch64.asm new file mode 100644 index 000000000..af5842795 --- /dev/null +++ b/tests/snapshots/asm/setenv_overwrite.aarch64.asm @@ -0,0 +1,70 @@ + +setenv_overwrite.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x2b0 // =688 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + str x19, [sp] + adrp x0, + add x0, x0, + adrp x1, + add x1, x1, + mov x2, #0x1 // =1 + bl + sxtw x0, w0 + adrp x0, + add x0, x0, + adrp x1, + add x1, x1, + mov x2, #0x0 // =0 + bl + sxtw x0, w0 + adrp x0, + add x0, x0, + bl + ldrb w0, [x0] + mov x17, #0x66 // =102 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x1 // =1 + ldr x19, [sp] + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + adrp x1, + add x1, x1, + mov x2, #0x1 // =1 + bl + sxtw x0, w0 + adrp x0, + add x0, x0, + bl + ldrb w0, [x0] + mov x17, #0x74 // =116 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x2 // =2 + ldr x19, [sp] + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x19, [sp] + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/setenv_overwrite.x64.asm b/tests/snapshots/asm/setenv_overwrite.x64.asm new file mode 100644 index 000000000..0efbb701a --- /dev/null +++ b/tests/snapshots/asm/setenv_overwrite.x64.asm @@ -0,0 +1,55 @@ + +setenv_overwrite.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + leaq , %rdi + leaq , %rsi + movl $0x1, %edx + xorl %eax, %eax + callq + movslq %eax, %rax + leaq , %rdi + leaq , %rsi + xorq %rdx, %rdx + xorl %eax, %eax + callq + movslq %eax, %rax + leaq , %rdi + xorl %eax, %eax + callq + movsbq (%rax), %rax + cmpq $0x66, %rax + je + movl $0x1, %eax + popq %rbp + retq + leaq , %rdi + leaq , %rsi + movl $0x1, %edx + xorl %eax, %eax + callq + movslq %eax, %rax + leaq , %rdi + xorl %eax, %eax + callq + movsbq (%rax), %rax + cmpq $0x74, %rax + je + movl $0x2, %eax + popq %rbp + retq + xorq %rax, %rax + popq %rbp + retq + addb %al, (%rax) diff --git a/tests/snapshots/asm/setjmp_longjmp.aarch64.asm b/tests/snapshots/asm/setjmp_longjmp.aarch64.asm index 1e57f42b2..acb009f3d 100644 --- a/tests/snapshots/asm/setjmp_longjmp.aarch64.asm +++ b/tests/snapshots/asm/setjmp_longjmp.aarch64.asm @@ -29,49 +29,53 @@ Disassembly of section .text: mov x29, sp sub sp, sp, #0x250 str x20, [sp] - str x21, [sp, #0x8] str x19, [sp, #0x10] b mov x0, #0xb // =11 ldr x20, [sp] - ldr x21, [sp, #0x8] ldr x19, [sp, #0x10] add sp, sp, #0x250 ldp x29, x30, [sp], #0x10 ret - mov x20, #0x0 // =0 + mov x0, #0x0 // =0 + sub x17, x29, #0x210 + str w0, [x17] sub x0, x29, #0x208 bl sxtw x0, w0 - mov x21, x0 - sxtw x0, w21 + mov x20, x0 + sxtw x0, w20 cmp x0, #0x0 b.ne + sub x16, x29, #0x210 + ldrsw x0, [x16] + add x0, x0, #0x1 + sub x17, x29, #0x210 + str w0, [x17] sub x0, x29, #0x208 mov x1, #0x7 // =7 bl mov x0, #0xc // =12 ldr x20, [sp] - ldr x21, [sp, #0x8] ldr x19, [sp, #0x10] add sp, sp, #0x250 ldp x29, x30, [sp], #0x10 ret - sxtw x0, w21 + sxtw x0, w20 cmp x0, #0x7 b.eq mov x0, #0xd // =13 ldr x20, [sp] - ldr x21, [sp, #0x8] ldr x19, [sp, #0x10] add sp, sp, #0x250 ldp x29, x30, [sp], #0x10 ret - cmp x20, #0x1 + sub x16, x29, #0x210 + ldrsw x0, [x16] + cmp x0, #0x1 b.eq mov x0, #0xe // =14 ldr x20, [sp] - ldr x21, [sp, #0x8] ldr x19, [sp, #0x10] add sp, sp, #0x250 ldp x29, x30, [sp], #0x10 @@ -82,14 +86,12 @@ Disassembly of section .text: b.eq mov x0, #0xf // =15 ldr x20, [sp] - ldr x21, [sp, #0x8] ldr x19, [sp, #0x10] add sp, sp, #0x250 ldp x29, x30, [sp], #0x10 ret mov x0, #0x0 // =0 ldr x20, [sp] - ldr x21, [sp, #0x8] ldr x19, [sp, #0x10] add sp, sp, #0x250 ldp x29, x30, [sp], #0x10 diff --git a/tests/snapshots/asm/setjmp_longjmp.x64.asm b/tests/snapshots/asm/setjmp_longjmp.x64.asm index 53eeb202a..9433b7070 100644 --- a/tests/snapshots/asm/setjmp_longjmp.x64.asm +++ b/tests/snapshots/asm/setjmp_longjmp.x64.asm @@ -27,46 +27,46 @@ Disassembly of section .text: movq %rsp, %rbp subq $0x240, %rsp # imm = 0x240 movq %rbx, (%rsp) - movq %r12, 0x8(%rsp) jmp movl $0xb, %eax movq (%rsp), %rbx - movq 0x8(%rsp), %r12 addq $0x240, %rsp # imm = 0x240 popq %rbp retq - xorq %rbx, %rbx + xorq %rax, %rax + movl %eax, -0x210(%rbp) leaq -0x208(%rbp), %rdi xorl %eax, %eax callq movslq %eax, %rax - movq %rax, %r12 - movslq %r12d, %rax + movq %rax, %rbx + movslq %ebx, %rax testq %rax, %rax jne + movslq -0x210(%rbp), %rax + incq %rax + movl %eax, -0x210(%rbp) leaq -0x208(%rbp), %rdi movl $0x7, %esi callq movl $0xc, %eax movq (%rsp), %rbx - movq 0x8(%rsp), %r12 addq $0x240, %rsp # imm = 0x240 popq %rbp retq - movslq %r12d, %rax + movslq %ebx, %rax cmpq $0x7, %rax je movl $0xd, %eax movq (%rsp), %rbx - movq 0x8(%rsp), %r12 addq $0x240, %rsp # imm = 0x240 popq %rbp retq - cmpq $0x1, %rbx + movslq -0x210(%rbp), %rax + cmpq $0x1, %rax je movl $0xe, %eax movq (%rsp), %rbx - movq 0x8(%rsp), %r12 addq $0x240, %rsp # imm = 0x240 popq %rbp retq @@ -76,14 +76,13 @@ Disassembly of section .text: je movl $0xf, %eax movq (%rsp), %rbx - movq 0x8(%rsp), %r12 addq $0x240, %rsp # imm = 0x240 popq %rbp retq xorq %rax, %rax movq (%rsp), %rbx - movq 0x8(%rsp), %r12 addq $0x240, %rsp # imm = 0x240 popq %rbp retq + addb %al, (%rax) addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/setjmp_value_live_across.aarch64.asm b/tests/snapshots/asm/setjmp_value_live_across.aarch64.asm new file mode 100644 index 000000000..75970a0c0 --- /dev/null +++ b/tests/snapshots/asm/setjmp_value_live_across.aarch64.asm @@ -0,0 +1,72 @@ + +setjmp_value_live_across.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x2b0 // =688 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + str x19, [sp] + adrp x0, + add x0, x0, + mov x1, #0x1 // =1 + bl + uxtb w0, w0 + mov x0, #0x0 // =0 + ldr x19, [sp] + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + +: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x30 + str x20, [sp] + str x19, [sp, #0x10] + mov x17, #0x7 // =7 + mul x0, x0, x17 + add x0, x0, x1 + sxtw x20, w0 + adrp x0, + add x0, x0, + bl + sxtw x0, w0 + cbz x0, + mov x0, x20 + ldr x20, [sp] + ldr x19, [sp, #0x10] + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + bl + mov x0, #0x0 // =0 + ldr x20, [sp] + ldr x19, [sp, #0x10] + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x20 + mov x0, #0x5 // =5 + mov x1, #0x7 // =7 + bl + cmp x0, #0x2a + b.ne + mov x1, #0x0 // =0 + b + mov x1, #0x1 // =1 + mov x0, x1 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/setjmp_value_live_across.x64.asm b/tests/snapshots/asm/setjmp_value_live_across.x64.asm new file mode 100644 index 000000000..20238ed21 --- /dev/null +++ b/tests/snapshots/asm/setjmp_value_live_across.x64.asm @@ -0,0 +1,66 @@ + +setjmp_value_live_across.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + leaq , %rdi + movl $0x1, %esi + xorl %eax, %eax + callq + movzbq %al, %rax + xorq %rax, %rax + popq %rbp + retq + +: + pushq %rbp + movq %rsp, %rbp + subq $0x20, %rsp + movq %rbx, (%rsp) + imulq $0x7, %rdi, %rax + addq %rsi, %rax + movslq %eax, %rbx + leaq , %rdi + xorl %eax, %eax + callq + movslq %eax, %rax + testq %rax, %rax + je + movq %rbx, %rax + movq (%rsp), %rbx + addq $0x20, %rsp + popq %rbp + retq + callq + xorq %rax, %rax + movq (%rsp), %rbx + addq $0x20, %rsp + popq %rbp + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x20, %rsp + movl $0x5, %edi + movl $0x7, %esi + callq + cmpq $0x2a, %rax + jne + xorq %rcx, %rcx + jmp + movl $0x1, %ecx + movq %rcx, %rax + addq $0x20, %rsp + popq %rbp + retq diff --git a/tests/snapshots/asm/shift_result_promoted_type.aarch64.asm b/tests/snapshots/asm/shift_result_promoted_type.aarch64.asm new file mode 100644 index 000000000..d8369d8bc --- /dev/null +++ b/tests/snapshots/asm/shift_result_promoted_type.aarch64.asm @@ -0,0 +1,72 @@ + +shift_result_promoted_type.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x30 + mov x0, #0xfffe00000000 // =281466386776064 + movk x0, #0xffff, lsl #48 + asr x0, x0, #1 + mov x17, #0xffff00000000 // =281470681743360 + movk x17, #0xffff, lsl #48 + cmp x0, x17 + b.eq + mov x0, #0x1 // =1 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #-0x8000000000000000 // =-9223372036854775808 + lsr x0, x0, #63 + cmp x0, #0x1 + b.eq + mov x0, #0x2 // =2 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x80000000 // =2147483648 + lsr x0, x0, #31 + mov x17, #0x1 // =1 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x3 // =3 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xfff0 // =65520 + movk x0, #0xffff, lsl #16 + movk x0, #0xffff, lsl #32 + movk x0, #0xffff, lsl #48 + asr x0, x0, #2 + mov x17, #0xfffc // =65532 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + cmp x0, x17 + b.eq + mov x0, #0x4 // =4 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x80 // =128 + lsr x0, x0, #3 + cmp x0, #0x10 + b.eq + mov x0, #0x5 // =5 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/shift_result_promoted_type.x64.asm b/tests/snapshots/asm/shift_result_promoted_type.x64.asm new file mode 100644 index 000000000..4630c329f --- /dev/null +++ b/tests/snapshots/asm/shift_result_promoted_type.x64.asm @@ -0,0 +1,65 @@ + +shift_result_promoted_type.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x30, %rsp + movabsq $-0x200000000, %rax # imm = 0xFFFFFFFE00000000 + sarq $0x1, %rax + movabsq $-0x100000000, %r11 # imm = 0xFFFFFFFF00000000 + cmpq %r11, %rax + je + movl $0x1, %eax + addq $0x30, %rsp + popq %rbp + retq + movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000 + shrq $0x3f, %rax + cmpq $0x1, %rax + je + movl $0x2, %eax + addq $0x30, %rsp + popq %rbp + retq + movl $0x80000000, %eax # imm = 0x80000000 + shrq $0x1f, %rax + xorq $0x1, %rax + movl %eax, %eax + testq %rax, %rax + je + movl $0x3, %eax + addq $0x30, %rsp + popq %rbp + retq + movabsq $-0x10, %rax + sarq $0x2, %rax + cmpq $-0x4, %rax + je + movl $0x4, %eax + addq $0x30, %rsp + popq %rbp + retq + movl $0x80, %eax + shrq $0x3, %rax + cmpq $0x10, %rax + je + movl $0x5, %eax + addq $0x30, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x30, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/shift_result_type_signedness.x64.asm b/tests/snapshots/asm/shift_result_type_signedness.x64.asm index 149073ea7..57c1cf981 100644 --- a/tests/snapshots/asm/shift_result_type_signedness.x64.asm +++ b/tests/snapshots/asm/shift_result_type_signedness.x64.asm @@ -13,12 +13,16 @@ Disassembly of section .text: : movslq %esi, %rsi movl %edi, %eax + pushq %rcx movq %rsi, %rcx shlq %cl, %rax + popq %rcx movl %eax, %eax movslq %eax, %rax + pushq %rcx movq %rsi, %rcx sarq %cl, %rax + popq %rcx retq
: diff --git a/tests/snapshots/asm/shm_open_mode_arg.aarch64.asm b/tests/snapshots/asm/shm_open_mode_arg.aarch64.asm new file mode 100644 index 000000000..cc6cd1fdf --- /dev/null +++ b/tests/snapshots/asm/shm_open_mode_arg.aarch64.asm @@ -0,0 +1,80 @@ + +shm_open_mode_arg.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x4a0 // =1184 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x120 + str x20, [sp] + str x21, [sp, #0x8] + str x22, [sp, #0x10] + str x19, [sp, #0x20] + mov x22, #0x0 // =0 + sub x20, x29, #0x40 + adrp x21, + add x21, x21, + bl + sxtw x0, w0 + mov x2, x0 + mov x0, x20 + mov x1, x21 + bl + sxtw x0, w0 + sub x0, x29, #0x40 + bl + sxtw x0, w0 + sub x0, x29, #0x40 + mov x1, #0xc2 // =194 + mov x2, #0x180 // =384 + bl + sxtw x0, w0 + mov x20, x0 + sxtw x0, w20 + cmp x0, #0x0 + b.ge + mov x0, #0x1 // =1 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x19, [sp, #0x20] + add sp, sp, #0x120 + ldp x29, x30, [sp], #0x10 + ret + sxtw x0, w20 + sub x1, x29, #0xc0 + bl + sxtw x0, w0 + cmp x0, #0x0 + b.eq + mov x22, #0x2 // =2 + sxtw x0, w20 + bl + sxtw x0, w0 + sub x0, x29, #0x40 + bl + sxtw x0, w0 + sxtw x0, w22 + ldr x20, [sp] + ldr x21, [sp, #0x8] + ldr x22, [sp, #0x10] + ldr x19, [sp, #0x20] + add sp, sp, #0x120 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0xc0 + ldrsw x0, [x0, #0x10] + mov x17, #0x1ff // =511 + and x0, x0, x17 + cmp x0, #0x180 + b.eq + mov x22, #0x3 // =3 + b + b diff --git a/tests/snapshots/asm/shm_open_mode_arg.x64.asm b/tests/snapshots/asm/shm_open_mode_arg.x64.asm new file mode 100644 index 000000000..b5caa9d1e --- /dev/null +++ b/tests/snapshots/asm/shm_open_mode_arg.x64.asm @@ -0,0 +1,84 @@ + +shm_open_mode_arg.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x120, %rsp # imm = 0x120 + movq %rbx, (%rsp) + movq %r12, 0x8(%rsp) + movq %r13, 0x10(%rsp) + xorq %r13, %r13 + leaq -0x40(%rbp), %rbx + leaq , %r12 + xorl %eax, %eax + callq + movslq %eax, %rax + movq %rax, %rdx + movq %rbx, %rdi + movq %r12, %rsi + movb $0x0, %al + callq + movslq %eax, %rax + leaq -0x40(%rbp), %rdi + xorl %eax, %eax + callq + movslq %eax, %rax + leaq -0x40(%rbp), %rdi + movl $0xc2, %esi + movl $0x180, %edx # imm = 0x180 + xorl %eax, %eax + callq + movslq %eax, %rax + movq %rax, %rbx + movslq %ebx, %rax + testq %rax, %rax + jge + movl $0x1, %eax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x120, %rsp # imm = 0x120 + popq %rbp + retq + movslq %ebx, %rdi + leaq -0xd0(%rbp), %rsi + xorl %eax, %eax + callq + movslq %eax, %rax + testq %rax, %rax + je + movl $0x2, %r13d + movslq %ebx, %rdi + xorl %eax, %eax + callq + movslq %eax, %rax + leaq -0x40(%rbp), %rdi + xorl %eax, %eax + callq + movslq %eax, %rax + movslq %r13d, %rax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + addq $0x120, %rsp # imm = 0x120 + popq %rbp + retq + leaq -0xd0(%rbp), %rax + movslq 0x18(%rax), %rax + andq $0x1ff, %rax # imm = 0x1FF + cmpq $0x180, %rax # imm = 0x180 + je + movl $0x3, %r13d + jmp + jmp + addb %al, (%rax) diff --git a/tests/snapshots/asm/slot_coalesce_alloca.aarch64.asm b/tests/snapshots/asm/slot_coalesce_alloca.aarch64.asm index 5b5ffeb23..09efdbb38 100644 --- a/tests/snapshots/asm/slot_coalesce_alloca.aarch64.asm +++ b/tests/snapshots/asm/slot_coalesce_alloca.aarch64.asm @@ -14,8 +14,8 @@ Disassembly of section .text: mov x29, sp sub sp, sp, #0xe0 sxtw x0, w0 - mov x6, #0x0 // =0 - mov x1, x6 + mov x5, #0x0 // =0 + mov x1, x5 sxtw x2, w1 cmp x2, #0x18 b.ge @@ -25,10 +25,12 @@ Disassembly of section .text: b sub x2, x29, #0xc0 sxtw x3, w1 - add x4, x3, #0x1 - sxtw x4, w4 - mul x4, x4, x0 - str x4, [x2, x3, lsl #3] + lsl x4, x3, #3 + add x2, x2, x4 + add x3, x3, #0x1 + sxtw x3, w3 + mul x3, x3, x0 + str x3, [x2] b mov x1, #0x0 // =0 sxtw x0, w1 @@ -40,10 +42,12 @@ Disassembly of section .text: b sub x0, x29, #0xc0 sxtw x2, w1 - ldr x0, [x0, x2, lsl #3] - add x6, x6, x0 + lsl x2, x2, #3 + add x0, x0, x2 + ldr x0, [x0] + add x5, x5, x0 b - mov x0, x6 + mov x0, x5 add sp, sp, #0xe0 ldp x29, x30, [sp], #0x10 ret diff --git a/tests/snapshots/asm/slot_coalesce_alloca.x64.asm b/tests/snapshots/asm/slot_coalesce_alloca.x64.asm index 8b500135a..6bc55e22e 100644 --- a/tests/snapshots/asm/slot_coalesce_alloca.x64.asm +++ b/tests/snapshots/asm/slot_coalesce_alloca.x64.asm @@ -15,8 +15,8 @@ Disassembly of section .text: movq %rsp, %rbp subq $0xe0, %rsp movslq %edi, %rdi - xorq %r9, %r9 - movq %r9, %rax + xorq %r8, %r8 + movq %r8, %rax movslq %eax, %rcx cmpq $0x18, %rcx jge @@ -26,10 +26,13 @@ Disassembly of section .text: jmp leaq -0xc0(%rbp), %rcx movslq %eax, %rdx - leaq 0x1(%rdx), %rsi - movslq %esi, %rsi - imulq %rdi, %rsi - movq %rsi, (%rcx,%rdx,8) + movq %rdx, %rsi + shlq $0x3, %rsi + addq %rsi, %rcx + incq %rdx + movslq %edx, %rdx + imulq %rdi, %rdx + movq %rdx, (%rcx) jmp xorq %rcx, %rcx movslq %ecx, %rax @@ -41,10 +44,12 @@ Disassembly of section .text: jmp leaq -0xc0(%rbp), %rax movslq %ecx, %rdx - movq (%rax,%rdx,8), %rax - addq %rax, %r9 + shlq $0x3, %rdx + addq %rdx, %rax + movq (%rax), %rax + addq %rax, %r8 jmp - movq %r9, %rax + movq %r8, %rax addq $0xe0, %rsp popq %rbp retq @@ -166,4 +171,5 @@ Disassembly of section .text: popq %rbp retq jmp + addb %al, (%rax) addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/snprintf_truncation_c99.aarch64.asm b/tests/snapshots/asm/snprintf_truncation_c99.aarch64.asm new file mode 100644 index 000000000..6a76506f0 --- /dev/null +++ b/tests/snapshots/asm/snprintf_truncation_c99.aarch64.asm @@ -0,0 +1,175 @@ + +snprintf_truncation_c99.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x330 // =816 + movk x1, #0x0, lsl #16 + b + brk #: + sub sp, sp, #0xc0 + str x0, [sp] + str x1, [sp, #0x8] + str x2, [sp, #0x10] + str x3, [sp, #0x18] + str x4, [sp, #0x20] + str x5, [sp, #0x28] + str x6, [sp, #0x30] + str x7, [sp, #0x38] + str d0, [sp, #0x40] + str d1, [sp, #0x50] + str d2, [sp, #0x60] + str d3, [sp, #0x70] + str d4, [sp, #0x80] + str d5, [sp, #0x90] + str d6, [sp, #0xa0] + str d7, [sp, #0xb0] + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x60 + str x19, [sp] + sub x0, x29, #0x20 + add x1, x29, #0x20 + mov x16, x0 + add x17, x29, #0xd0 + str x17, [x16] + add x17, x29, #0x50 + str x17, [x16, #0x8] + add x17, x29, #0xd0 + str x17, [x16, #0x10] + mov x17, #0xffd8 // =65496 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + str w17, [x16, #0x18] + mov x17, #0xff80 // =65408 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + str w17, [x16, #0x1c] + ldur x0, [x29, #0x10] + ldursw x1, [x29, #0x18] + ldur x2, [x29, #0x20] + sub x3, x29, #0x20 + bl + sub x1, x29, #0x20 + sxtw x0, w0 + ldr x19, [sp] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0xc0 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x40 + str x19, [sp] + sub x0, x29, #0x8 + mov x1, #0x41 // =65 + mov x2, #0x8 // =8 + bl + sub x0, x29, #0x8 + mov x1, #0x4 // =4 + adrp x2, + add x2, x2, + mov x3, #0xe240 // =57920 + movk x3, #0x1, lsl #16 + bl + sxtw x0, w0 + cmp x0, #0x6 + b.eq + mov x0, #0x1 // =1 + ldr x19, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x8 + adrp x1, + add x1, x1, + bl + sxtw x0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x2 // =2 + ldr x19, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + adrp x2, + add x2, x2, + adrp x3, + add x3, x3, + mov x1, x0 + bl + sxtw x0, w0 + cmp x0, #0x5 + b.eq + mov x0, #0x3 // =3 + ldr x19, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x8 + mov x1, #0x41 // =65 + mov x2, #0x8 // =8 + bl + sub x0, x29, #0x8 + mov x1, #0x4 // =4 + adrp x2, + add x2, x2, + mov x3, #0x1206 // =4614 + movk x3, #0xf, lsl #16 + bl + cmp x0, #0x6 + b.eq + mov x0, #0x4 // =4 + ldr x19, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x8 + adrp x1, + add x1, x1, + bl + sxtw x0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x5 // =5 + ldr x19, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x8 + mov x1, #0x8 // =8 + adrp x2, + add x2, x2, + mov x3, #0x2a // =42 + bl + sxtw x0, w0 + cmp x0, #0x2 + cset x1, ne + cbnz x1, + sub x0, x29, #0x8 + adrp x1, + add x1, x1, + bl + sxtw x0, w0 + cmp x0, #0x0 + cset x1, ne + cbz x1, + mov x0, #0x6 // =6 + ldr x19, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x19, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + b diff --git a/tests/snapshots/asm/snprintf_truncation_c99.x64.asm b/tests/snapshots/asm/snprintf_truncation_c99.x64.asm new file mode 100644 index 000000000..9b9cd96a9 --- /dev/null +++ b/tests/snapshots/asm/snprintf_truncation_c99.x64.asm @@ -0,0 +1,158 @@ + +snprintf_truncation_c99.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + subq $0xf0, %rsp + movq %rdi, -0xf0(%rbp) + movq %rsi, -0xe8(%rbp) + movq %rdx, -0xe0(%rbp) + movq %rcx, -0xd8(%rbp) + movq %r8, -0xd0(%rbp) + movq %r9, -0xc8(%rbp) + testb %al, %al + je + movsd %xmm0, -0xc0(%rbp,%riz) + movsd %xmm1, -0xb0(%rbp,%riz) + movsd %xmm2, -0xa0(%rbp,%riz) + movsd %xmm3, -0x90(%rbp,%riz) + movsd %xmm4, -0x80(%rbp,%riz) + movsd %xmm5, -0x70(%rbp,%riz) + movsd %xmm6, -0x60(%rbp,%riz) + movsd %xmm7, -0x50(%rbp,%riz) + leaq -0x18(%rbp), %rax + leaq -0xe0(%rbp), %rcx + movl $0x18, (%rax) + movl $0x30, 0x4(%rax) + leaq 0x10(%rbp), %r10 + movq %r10, 0x8(%rax) + leaq -0xf0(%rbp), %r10 + movq %r10, 0x10(%rax) + movq -0xf0(%rbp), %rdi + movslq -0xe8(%rbp), %rsi + movq -0xe0(%rbp), %rdx + leaq -0x18(%rbp), %rcx + xorl %eax, %eax + callq + leaq -0x18(%rbp), %rcx + movslq %eax, %rax + addq $0xf0, %rsp + popq %rbp + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x30, %rsp + leaq -0x8(%rbp), %rdi + movl $0x41, %esi + movl $0x8, %edx + xorl %eax, %eax + callq + leaq -0x8(%rbp), %rdi + movl $0x4, %esi + leaq , %rdx + movl $0x1e240, %ecx # imm = 0x1E240 + movb $0x0, %al + callq + movslq %eax, %rax + cmpq $0x6, %rax + je + movl $0x1, %eax + addq $0x30, %rsp + popq %rbp + retq + leaq -0x8(%rbp), %rdi + leaq , %rsi + xorl %eax, %eax + callq + movslq %eax, %rax + testq %rax, %rax + je + movl $0x2, %eax + addq $0x30, %rsp + popq %rbp + retq + xorq %rdi, %rdi + leaq , %rdx + leaq , %rcx + movq %rdi, %rsi + movb $0x0, %al + callq + movslq %eax, %rax + cmpq $0x5, %rax + je + movl $0x3, %eax + addq $0x30, %rsp + popq %rbp + retq + leaq -0x8(%rbp), %rdi + movl $0x41, %esi + movl $0x8, %edx + xorl %eax, %eax + callq + leaq -0x8(%rbp), %rdi + movl $0x4, %esi + leaq , %rdx + movl $0xf1206, %ecx # imm = 0xF1206 + movb $0x0, %al + callq + cmpq $0x6, %rax + je + movl $0x4, %eax + addq $0x30, %rsp + popq %rbp + retq + leaq -0x8(%rbp), %rdi + leaq , %rsi + xorl %eax, %eax + callq + movslq %eax, %rax + testq %rax, %rax + je + movl $0x5, %eax + addq $0x30, %rsp + popq %rbp + retq + leaq -0x8(%rbp), %rdi + movl $0x8, %esi + leaq , %rdx + movl $0x2a, %ecx + movb $0x0, %al + callq + movslq %eax, %rax + cmpq $0x2, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + jne + leaq -0x8(%rbp), %rdi + leaq , %rsi + xorl %eax, %eax + callq + movslq %eax, %rax + testq %rax, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x6, %eax + addq $0x30, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x30, %rsp + popq %rbp + retq + jmp + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/sqlite_min.aarch64.asm b/tests/snapshots/asm/sqlite_min.aarch64.asm index 4696c0370..daa7312b1 100644 --- a/tests/snapshots/asm/sqlite_min.aarch64.asm +++ b/tests/snapshots/asm/sqlite_min.aarch64.asm @@ -30,10 +30,10 @@ Disassembly of section .text: add x0, x0, mov x2, #0x42 // =66 mov x3, #0x1a4 // =420 - mov x9, x1 str x3, [sp, #-0x10]! str x2, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] @@ -53,9 +53,9 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret mov x1, #0x400 // =1024 - mov x9, x23 str x1, [sp, #-0x10]! str x24, [sp, #-0x10]! + mov x9, x23 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -74,9 +74,9 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret sub x1, x29, #0xb8 - mov x9, x22 str x1, [sp, #-0x10]! str x24, [sp, #-0x10]! + mov x9, x22 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -112,8 +112,8 @@ Disassembly of section .text: add sp, sp, #0x110 ldp x29, x30, [sp], #0x10 ret - mov x9, x20 str x24, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -129,23 +129,7 @@ Disassembly of section .text: ret <__c5_sys_open>: - str x2, [sp, #-0x10]! - str x1, [sp, #-0x10]! - str x0, [sp, #-0x10]! - stp x29, x30, [sp, #-0x10]! - mov x29, sp - sub sp, sp, #0x10 - str x19, [sp] - ldur x0, [x29, #0x10] - ldur x1, [x29, #0x20] - ldur x2, [x29, #0x30] - bl - sxtw x0, w0 - ldr x19, [sp] - add sp, sp, #0x10 - ldp x29, x30, [sp], #0x10 - add sp, sp, #0x30 - ret + b <__c5_sys_close>: str x0, [sp, #-0x10]! @@ -180,23 +164,7 @@ Disassembly of section .text: ret <__c5_sys_fcntl>: - str x2, [sp, #-0x10]! - str x1, [sp, #-0x10]! - str x0, [sp, #-0x10]! - stp x29, x30, [sp, #-0x10]! - mov x29, sp - sub sp, sp, #0x10 - str x19, [sp] - ldur x0, [x29, #0x10] - ldur x1, [x29, #0x20] - ldur x2, [x29, #0x30] - bl - sxtw x0, w0 - ldr x19, [sp] - add sp, sp, #0x10 - ldp x29, x30, [sp], #0x10 - add sp, sp, #0x30 - ret + b <__c5_sys_stat>: str x1, [sp, #-0x10]! diff --git a/tests/snapshots/asm/sqlite_min.x64.asm b/tests/snapshots/asm/sqlite_min.x64.asm index 3243fb3a9..0b510e664 100644 --- a/tests/snapshots/asm/sqlite_min.x64.asm +++ b/tests/snapshots/asm/sqlite_min.x64.asm @@ -106,25 +106,7 @@ Disassembly of section .text: retq <__c5_sys_open>: - popq %r10 - subq $0x30, %rsp - movq %rdi, (%rsp) - movq %rsi, 0x10(%rsp) - movq %rdx, 0x20(%rsp) - pushq %r10 - pushq %rbp - movq %rsp, %rbp - movq 0x10(%rbp), %rdi - movq 0x20(%rbp), %rsi - movq 0x30(%rbp), %rdx - movb $0x0, %al - callq - movslq %eax, %rax - popq %rbp - popq %r11 - addq $0x30, %rsp - pushq %r11 - retq + jmp <__c5_sys_close>: popq %r10 @@ -163,25 +145,7 @@ Disassembly of section .text: retq <__c5_sys_fcntl>: - popq %r10 - subq $0x30, %rsp - movq %rdi, (%rsp) - movq %rsi, 0x10(%rsp) - movq %rdx, 0x20(%rsp) - pushq %r10 - pushq %rbp - movq %rsp, %rbp - movq 0x10(%rbp), %rdi - movq 0x20(%rbp), %rsi - movq 0x30(%rbp), %rdx - xorl %eax, %eax - callq - movslq %eax, %rax - popq %rbp - popq %r11 - addq $0x30, %rsp - pushq %r11 - retq + jmp <__c5_sys_stat>: popq %r10 @@ -220,4 +184,3 @@ Disassembly of section .text: addq $0x20, %rsp pushq %r11 retq - addb %al, (%rax) diff --git a/tests/snapshots/asm/ssa_call_result_spill.x64.asm b/tests/snapshots/asm/ssa_call_result_spill.x64.asm index 1aa597829..d66f9a324 100644 --- a/tests/snapshots/asm/ssa_call_result_spill.x64.asm +++ b/tests/snapshots/asm/ssa_call_result_spill.x64.asm @@ -13,8 +13,10 @@ Disassembly of section .text: : movslq %esi, %rsi movq %rdi, %rax + pushq %rcx movq %rsi, %rcx rorq %cl, %rax + popq %rcx retq : @@ -31,8 +33,10 @@ Disassembly of section .text: movslq %eax, %rax movq %rax, %r10 movq %rdi, %rax + pushq %rcx movq %r10, %rcx rorq %cl, %rax + popq %rcx movl $0x12, %ecx movslq %ecx, %rcx movq %rcx, %r10 diff --git a/tests/snapshots/asm/ssa_va_arg_loop.aarch64.asm b/tests/snapshots/asm/ssa_va_arg_loop.aarch64.asm index 58746eeeb..ab94e97c1 100644 --- a/tests/snapshots/asm/ssa_va_arg_loop.aarch64.asm +++ b/tests/snapshots/asm/ssa_va_arg_loop.aarch64.asm @@ -70,6 +70,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -138,6 +140,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/ssa_va_start_va_copy_aliasing.aarch64.asm b/tests/snapshots/asm/ssa_va_start_va_copy_aliasing.aarch64.asm index 9a05fd0cc..d68375565 100644 --- a/tests/snapshots/asm/ssa_va_start_va_copy_aliasing.aarch64.asm +++ b/tests/snapshots/asm/ssa_va_start_va_copy_aliasing.aarch64.asm @@ -60,6 +60,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -78,6 +80,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -159,6 +163,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -177,6 +183,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/ssa_va_start_va_copy_aliasing.x64.asm b/tests/snapshots/asm/ssa_va_start_va_copy_aliasing.x64.asm index ab20b1bc9..f8ce235e9 100644 --- a/tests/snapshots/asm/ssa_va_start_va_copy_aliasing.x64.asm +++ b/tests/snapshots/asm/ssa_va_start_va_copy_aliasing.x64.asm @@ -99,12 +99,14 @@ Disassembly of section .text: movq %r10, 0x10(%rax) leaq -0x30(%rbp), %rax leaq -0x18(%rbp), %rcx - movq (%rcx), %r10 - movq %r10, (%rax) - movq 0x8(%rcx), %r10 - movq %r10, 0x8(%rax) - movq 0x10(%rcx), %r10 - movq %r10, 0x10(%rax) + pushq %rdx + movq (%rcx), %rdx + movq %rdx, (%rax) + movq 0x8(%rcx), %rdx + movq %rdx, 0x8(%rax) + movq 0x10(%rcx), %rdx + movq %rdx, 0x10(%rax) + popq %rdx leaq -0x18(%rbp), %rax movq %rax, %r11 movl (%r11), %r10d @@ -176,3 +178,4 @@ Disassembly of section .text: addq $0x20, %rsp popq %rbp retq + addb %al, (%rax) diff --git a/tests/snapshots/asm/static_init_cast_funcptr.aarch64.asm b/tests/snapshots/asm/static_init_cast_funcptr.aarch64.asm index 6edf1481a..9043771ae 100644 --- a/tests/snapshots/asm/static_init_cast_funcptr.aarch64.asm +++ b/tests/snapshots/asm/static_init_cast_funcptr.aarch64.asm @@ -33,8 +33,8 @@ Disassembly of section .text: add x20, x20, ldr x0, [x20, #0x8] mov x1, #0x15 // =21 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -49,8 +49,8 @@ Disassembly of section .text: ret ldr x0, [x20, #0x20] mov x1, #0x7 // =7 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -70,8 +70,8 @@ Disassembly of section .text: ldr x0, [x20, #0x10] adrp x1, add x1, x1, - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -87,8 +87,8 @@ Disassembly of section .text: ldr x0, [x20, #0x28] adrp x1, add x1, x1, - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/static_init_paren_relocation.aarch64.asm b/tests/snapshots/asm/static_init_paren_relocation.aarch64.asm index df70a7eaf..c17c47c87 100644 --- a/tests/snapshots/asm/static_init_paren_relocation.aarch64.asm +++ b/tests/snapshots/asm/static_init_paren_relocation.aarch64.asm @@ -23,9 +23,9 @@ Disassembly of section .text: add x20, x20, mov x0, #0x0 // =0 ldr x1, [x20, #0x8] - mov x9, x1 str x0, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -73,9 +73,9 @@ Disassembly of section .text: adrp x1, add x1, x1, ldr x1, [x1] - mov x9, x1 str x0, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x1 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/static_init_struct_fp_call.aarch64.asm b/tests/snapshots/asm/static_init_struct_fp_call.aarch64.asm index 08cf60dd1..d82bcbcb7 100644 --- a/tests/snapshots/asm/static_init_struct_fp_call.aarch64.asm +++ b/tests/snapshots/asm/static_init_struct_fp_call.aarch64.asm @@ -30,9 +30,9 @@ Disassembly of section .text: ldr x0, [x20] mov x1, #0x2 // =2 mov x2, #0x3 // =3 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -49,9 +49,9 @@ Disassembly of section .text: ldr x0, [x20, #0x8] mov x1, #0xa // =10 mov x2, #0x4 // =4 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/static_neg_infinity_init.aarch64.asm b/tests/snapshots/asm/static_neg_infinity_init.aarch64.asm index 89834d649..914159967 100644 --- a/tests/snapshots/asm/static_neg_infinity_init.aarch64.asm +++ b/tests/snapshots/asm/static_neg_infinity_init.aarch64.asm @@ -52,8 +52,7 @@ Disassembly of section .text: ret adrp x0, add x0, x0, - add x0, x0, #0x8 - ldr d0, [x0] + ldr d0, [x0, #0x8] bl cmp x0, #0x0 b.ne diff --git a/tests/snapshots/asm/static_neg_infinity_init.x64.asm b/tests/snapshots/asm/static_neg_infinity_init.x64.asm index 7259dac21..2ad932c0d 100644 --- a/tests/snapshots/asm/static_neg_infinity_init.x64.asm +++ b/tests/snapshots/asm/static_neg_infinity_init.x64.asm @@ -61,8 +61,7 @@ Disassembly of section .text: popq %rbp retq leaq , %rax - addq $0x8, %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rax,%riz), %xmm0 callq testq %rax, %rax jne @@ -105,4 +104,4 @@ Disassembly of section .text: addq $0x10, %rsp popq %rbp retq - addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/strength_reduce_pow2_divmod.aarch64.asm b/tests/snapshots/asm/strength_reduce_pow2_divmod.aarch64.asm index 18f697929..08ac89d65 100644 --- a/tests/snapshots/asm/strength_reduce_pow2_divmod.aarch64.asm +++ b/tests/snapshots/asm/strength_reduce_pow2_divmod.aarch64.asm @@ -17,17 +17,20 @@ Disassembly of section .text: movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 + stur w0, [x29, #-0x8] + ldursw x0, [x29, #-0x8] asr x1, x0, #63 lsr x1, x1, #63 - add x1, x0, x1 - asr x1, x1, #1 + add x0, x0, x1 + asr x0, x0, #1 mov x17, #0xfffd // =65533 movk x17, #0xffff, lsl #16 movk x17, #0xffff, lsl #32 movk x17, #0xffff, lsl #48 - cmp x1, x17 - cset x2, ne - cbnz x2, + cmp x0, x17 + cset x1, ne + cbnz x1, + ldursw x0, [x29, #-0x8] asr x1, x0, #63 lsr x1, x1, #63 add x0, x0, x1 @@ -39,8 +42,8 @@ Disassembly of section .text: movk x17, #0xffff, lsl #32 movk x17, #0xffff, lsl #48 cmp x0, x17 - cset x2, ne - cbz x2, + cset x1, ne + cbz x1, mov x0, #0x1 // =1 add sp, sp, #0xa0 ldp x29, x30, [sp], #0x10 @@ -49,17 +52,20 @@ Disassembly of section .text: movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 + stur w0, [x29, #-0x8] + ldursw x0, [x29, #-0x8] asr x1, x0, #63 lsr x1, x1, #60 - add x1, x0, x1 - asr x1, x1, #4 + add x0, x0, x1 + asr x0, x0, #4 mov x17, #0xffff // =65535 movk x17, #0xffff, lsl #16 movk x17, #0xffff, lsl #32 movk x17, #0xffff, lsl #48 - cmp x1, x17 - cset x2, ne - cbnz x2, + cmp x0, x17 + cset x1, ne + cbnz x1, + ldursw x0, [x29, #-0x8] asr x1, x0, #63 lsr x1, x1, #60 add x0, x0, x1 @@ -67,8 +73,8 @@ Disassembly of section .text: and x0, x0, x17 sub x0, x0, x1 cmp x0, #0x0 - cset x2, ne - cbz x2, + cset x1, ne + cbz x1, mov x0, #0x2 // =2 add sp, sp, #0xa0 ldp x29, x30, [sp], #0x10 @@ -77,17 +83,20 @@ Disassembly of section .text: movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 + stur w0, [x29, #-0x8] + ldursw x0, [x29, #-0x8] asr x1, x0, #63 lsr x1, x1, #60 - add x1, x0, x1 - asr x1, x1, #4 + add x0, x0, x1 + asr x0, x0, #4 mov x17, #0xffff // =65535 movk x17, #0xffff, lsl #16 movk x17, #0xffff, lsl #32 movk x17, #0xffff, lsl #48 - cmp x1, x17 - cset x2, ne - cbnz x2, + cmp x0, x17 + cset x1, ne + cbnz x1, + ldursw x0, [x29, #-0x8] asr x1, x0, #63 lsr x1, x1, #60 add x0, x0, x1 @@ -99,20 +108,23 @@ Disassembly of section .text: movk x17, #0xffff, lsl #32 movk x17, #0xffff, lsl #48 cmp x0, x17 - cset x2, ne - cbz x2, + cset x1, ne + cbz x1, mov x0, #0x3 // =3 add sp, sp, #0xa0 ldp x29, x30, [sp], #0x10 ret mov x0, #0x64 // =100 + stur w0, [x29, #-0x8] + ldursw x0, [x29, #-0x8] asr x1, x0, #63 lsr x1, x1, #61 - add x1, x0, x1 - asr x1, x1, #3 - cmp x1, #0xc - cset x2, ne - cbnz x2, + add x0, x0, x1 + asr x0, x0, #3 + cmp x0, #0xc + cset x1, ne + cbnz x1, + ldursw x0, [x29, #-0x8] asr x1, x0, #63 lsr x1, x1, #61 add x0, x0, x1 @@ -120,8 +132,8 @@ Disassembly of section .text: and x0, x0, x17 sub x0, x0, x1 cmp x0, #0x4 - cset x2, ne - cbz x2, + cset x1, ne + cbz x1, mov x0, #0x4 // =4 add sp, sp, #0xa0 ldp x29, x30, [sp], #0x10 @@ -129,16 +141,19 @@ Disassembly of section .text: mov x0, #0x80000000 // =2147483648 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 + stur w0, [x29, #-0x8] + ldursw x0, [x29, #-0x8] asr x1, x0, #63 lsr x1, x1, #63 - add x1, x0, x1 - asr x1, x1, #1 + add x0, x0, x1 + asr x0, x0, #1 mov x17, #0xc0000000 // =3221225472 movk x17, #0xffff, lsl #32 movk x17, #0xffff, lsl #48 - cmp x1, x17 - cset x2, ne - cbnz x2, + cmp x0, x17 + cset x1, ne + cbnz x1, + ldursw x0, [x29, #-0x8] asr x1, x0, #63 lsr x1, x1, #63 add x0, x0, x1 @@ -146,40 +161,46 @@ Disassembly of section .text: and x0, x0, x17 sub x0, x0, x1 cmp x0, #0x0 - cset x2, ne - cbz x2, + cset x1, ne + cbz x1, mov x0, #0x5 // =5 add sp, sp, #0xa0 ldp x29, x30, [sp], #0x10 ret mov x0, #0xffff // =65535 movk x0, #0xffff, lsl #16 - lsr x1, x0, #1 + stur w0, [x29, #-0x10] + ldur w0, [x29, #-0x10] + lsr x0, x0, #1 mov x17, #0xffff // =65535 movk x17, #0x7fff, lsl #16 - cmp x1, x17 - cset x2, ne - cbnz x2, + cmp x0, x17 + cset x1, ne + cbnz x1, + ldur w0, [x29, #-0x10] mov x17, #0x1 // =1 and x0, x0, x17 cmp x0, #0x1 - cset x2, ne - cbz x2, + cset x1, ne + cbz x1, mov x0, #0x6 // =6 add sp, sp, #0xa0 ldp x29, x30, [sp], #0x10 ret mov x0, #0x80000000 // =2147483648 - lsr x1, x0, #4 + stur w0, [x29, #-0x10] + ldur w0, [x29, #-0x10] + lsr x0, x0, #4 mov x17, #0x8000000 // =134217728 - cmp x1, x17 - cset x2, ne - cbnz x2, + cmp x0, x17 + cset x1, ne + cbnz x1, + ldur w0, [x29, #-0x10] mov x17, #0xf // =15 and x0, x0, x17 cmp x0, #0x0 - cset x2, ne - cbz x2, + cset x1, ne + cbz x1, mov x0, #0x7 // =7 add sp, sp, #0xa0 ldp x29, x30, [sp], #0x10 @@ -188,16 +209,19 @@ Disassembly of section .text: movk x0, #0xffed, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 - asr x1, x0, #63 - lsr x1, x1, #54 - add x1, x0, x1 + stur x0, [x29, #-0x38] + ldur x1, [x29, #-0x38] + asr x2, x1, #63 + lsr x2, x2, #54 + add x1, x1, x2 asr x1, x1, #10 mov x2, #0x3ff // =1023 - add x2, x0, x2 - asr x2, x2, #10 - cmp x1, x2 - cset x2, ne - cbnz x2, + add x0, x0, x2 + asr x0, x0, #10 + cmp x1, x0 + cset x1, ne + cbnz x1, + ldur x0, [x29, #-0x38] asr x1, x0, #63 lsr x1, x1, #54 add x0, x0, x1 @@ -214,21 +238,24 @@ Disassembly of section .text: and x1, x1, x17 sub x1, x1, x2 cmp x0, x1 - cset x2, ne - cbz x2, + cset x1, ne + cbz x1, mov x0, #0x8 // =8 add sp, sp, #0xa0 ldp x29, x30, [sp], #0x10 ret mov x0, #-0x8000000000000000 // =-9223372036854775808 + stur x0, [x29, #-0x38] + ldur x0, [x29, #-0x38] asr x1, x0, #63 lsr x1, x1, #63 - add x1, x0, x1 - asr x1, x1, #1 + add x0, x0, x1 + asr x0, x0, #1 mov x17, #-0x4000000000000000 // =-4611686018427387904 - cmp x1, x17 - cset x2, ne - cbnz x2, + cmp x0, x17 + cset x1, ne + cbnz x1, + ldur x0, [x29, #-0x38] asr x1, x0, #63 lsr x1, x1, #63 add x0, x0, x1 @@ -236,8 +263,8 @@ Disassembly of section .text: and x0, x0, x17 sub x0, x0, x1 cmp x0, #0x0 - cset x2, ne - cbz x2, + cset x1, ne + cbz x1, mov x0, #0x9 // =9 add sp, sp, #0xa0 ldp x29, x30, [sp], #0x10 @@ -246,19 +273,22 @@ Disassembly of section .text: movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 - lsr x1, x0, #1 + stur x0, [x29, #-0x40] + ldur x0, [x29, #-0x40] + lsr x0, x0, #1 mov x17, #0xffff // =65535 movk x17, #0xffff, lsl #16 movk x17, #0xffff, lsl #32 movk x17, #0x7fff, lsl #48 - cmp x1, x17 - cset x2, ne - cbnz x2, + cmp x0, x17 + cset x1, ne + cbnz x1, + ldur x0, [x29, #-0x40] mov x17, #0xff // =255 and x0, x0, x17 cmp x0, #0xff - cset x2, ne - cbz x2, + cset x1, ne + cbz x1, mov x0, #0xa // =10 add sp, sp, #0xa0 ldp x29, x30, [sp], #0x10 @@ -267,6 +297,8 @@ Disassembly of section .text: movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 + stur w0, [x29, #-0x8] + ldursw x0, [x29, #-0x8] mov x17, #0xfffb // =65531 movk x17, #0xffff, lsl #16 movk x17, #0xffff, lsl #32 @@ -274,6 +306,7 @@ Disassembly of section .text: cmp x0, x17 cset x1, ne cbnz x1, + ldursw x0, [x29, #-0x8] mov x1, #0x0 // =0 cbz x1, mov x0, #0xb // =11 diff --git a/tests/snapshots/asm/strength_reduce_pow2_divmod.x64.asm b/tests/snapshots/asm/strength_reduce_pow2_divmod.x64.asm index 130021bbb..3202a769c 100644 --- a/tests/snapshots/asm/strength_reduce_pow2_divmod.x64.asm +++ b/tests/snapshots/asm/strength_reduce_pow2_divmod.x64.asm @@ -15,16 +15,19 @@ Disassembly of section .text: movq %rsp, %rbp subq $0xa0, %rsp movabsq $-0x7, %rax + movl %eax, -0x8(%rbp) + movslq -0x8(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3f, %rcx - addq %rax, %rcx - sarq $0x1, %rcx - cmpq $-0x3, %rcx - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + addq %rcx, %rax + sarq $0x1, %rax + cmpq $-0x3, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx jne + movslq -0x8(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3f, %rcx @@ -32,25 +35,28 @@ Disassembly of section .text: andq $0x1, %rax subq %rcx, %rax cmpq $-0x1, %rax - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx je movl $0x1, %eax addq $0xa0, %rsp popq %rbp retq movabsq $-0x10, %rax + movl %eax, -0x8(%rbp) + movslq -0x8(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3c, %rcx - addq %rax, %rcx - sarq $0x4, %rcx - cmpq $-0x1, %rcx - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + addq %rcx, %rax + sarq $0x4, %rax + cmpq $-0x1, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx jne + movslq -0x8(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3c, %rcx @@ -58,25 +64,28 @@ Disassembly of section .text: andq $0xf, %rax subq %rcx, %rax testq %rax, %rax - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx je movl $0x2, %eax addq $0xa0, %rsp popq %rbp retq movabsq $-0x11, %rax + movl %eax, -0x8(%rbp) + movslq -0x8(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3c, %rcx - addq %rax, %rcx - sarq $0x4, %rcx - cmpq $-0x1, %rcx - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + addq %rcx, %rax + sarq $0x4, %rax + cmpq $-0x1, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx jne + movslq -0x8(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3c, %rcx @@ -84,25 +93,28 @@ Disassembly of section .text: andq $0xf, %rax subq %rcx, %rax cmpq $-0x1, %rax - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx je movl $0x3, %eax addq $0xa0, %rsp popq %rbp retq movl $0x64, %eax + movl %eax, -0x8(%rbp) + movslq -0x8(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3d, %rcx - addq %rax, %rcx - sarq $0x3, %rcx - cmpq $0xc, %rcx - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + addq %rcx, %rax + sarq $0x3, %rax + cmpq $0xc, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx jne + movslq -0x8(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3d, %rcx @@ -110,25 +122,28 @@ Disassembly of section .text: andq $0x7, %rax subq %rcx, %rax cmpq $0x4, %rax - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx je movl $0x4, %eax addq $0xa0, %rsp popq %rbp retq movabsq $-0x80000000, %rax # imm = 0x80000000 + movl %eax, -0x8(%rbp) + movslq -0x8(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3f, %rcx - addq %rax, %rcx - sarq $0x1, %rcx - cmpq $-0x40000000, %rcx # imm = 0xC0000000 - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + addq %rcx, %rax + sarq $0x1, %rax + cmpq $-0x40000000, %rax # imm = 0xC0000000 + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx jne + movslq -0x8(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3f, %rcx @@ -136,64 +151,71 @@ Disassembly of section .text: andq $0x1, %rax subq %rcx, %rax testq %rax, %rax - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx je movl $0x5, %eax addq $0xa0, %rsp popq %rbp retq movl $0xffffffff, %eax # imm = 0xFFFFFFFF - movq %rax, %rcx - shrq $0x1, %rcx - cmpq $0x7fffffff, %rcx # imm = 0x7FFFFFFF - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + movl %eax, -0x10(%rbp) + movl -0x10(%rbp), %eax + shrq $0x1, %rax + cmpq $0x7fffffff, %rax # imm = 0x7FFFFFFF + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx jne + movl -0x10(%rbp), %eax andq $0x1, %rax cmpq $0x1, %rax - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx je movl $0x6, %eax addq $0xa0, %rsp popq %rbp retq movl $0x80000000, %eax # imm = 0x80000000 - movq %rax, %rcx - shrq $0x4, %rcx - cmpq $0x8000000, %rcx # imm = 0x8000000 - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + movl %eax, -0x10(%rbp) + movl -0x10(%rbp), %eax + shrq $0x4, %rax + cmpq $0x8000000, %rax # imm = 0x8000000 + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx jne + movl -0x10(%rbp), %eax andq $0xf, %rax testq %rax, %rax - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx je movl $0x7, %eax addq $0xa0, %rsp popq %rbp retq movabsq $-0x12d687, %rax # imm = 0xFFED2979 - movq %rax, %rcx - sarq $0x3f, %rcx - shrq $0x36, %rcx - addq %rax, %rcx + movq %rax, -0x38(%rbp) + movq -0x38(%rbp), %rcx + movq %rcx, %rdx + sarq $0x3f, %rdx + shrq $0x36, %rdx + addq %rdx, %rcx sarq $0xa, %rcx movl $0x3ff, %edx # imm = 0x3FF - addq %rax, %rdx - sarq $0xa, %rdx - cmpq %rdx, %rcx - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + addq %rdx, %rax + sarq $0xa, %rax + cmpq %rax, %rcx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx jne + movq -0x38(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x36, %rcx @@ -206,27 +228,30 @@ Disassembly of section .text: andq $0x3ff, %rcx # imm = 0x3FF subq %rdx, %rcx cmpq %rcx, %rax - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx je movl $0x8, %eax addq $0xa0, %rsp popq %rbp retq movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000 + movq %rax, -0x38(%rbp) + movq -0x38(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3f, %rcx - addq %rax, %rcx - sarq $0x1, %rcx + addq %rcx, %rax + sarq $0x1, %rax movabsq $-0x4000000000000000, %r11 # imm = 0xC000000000000000 - movq %rcx, %rdx - cmpq %r11, %rcx - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + movq %rax, %rcx + cmpq %r11, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx jne + movq -0x38(%rbp), %rax movq %rax, %rcx sarq $0x3f, %rcx shrq $0x3f, %rcx @@ -234,40 +259,45 @@ Disassembly of section .text: andq $0x1, %rax subq %rcx, %rax testq %rax, %rax - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx je movl $0x9, %eax addq $0xa0, %rsp popq %rbp retq movabsq $-0x1, %rax - movq %rax, %rcx - shrq $0x1, %rcx + movq %rax, -0x40(%rbp) + movq -0x40(%rbp), %rax + shrq $0x1, %rax movabsq $0x7fffffffffffffff, %r11 # imm = 0x7FFFFFFFFFFFFFFF - movq %rcx, %rdx - cmpq %r11, %rcx - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + movq %rax, %rcx + cmpq %r11, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx jne + movq -0x40(%rbp), %rax andq $0xff, %rax cmpq $0xff, %rax - setne %dl - movzbq %dl, %rdx - testq %rdx, %rdx + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx je movl $0xa, %eax addq $0xa0, %rsp popq %rbp retq movabsq $-0x5, %rax + movl %eax, -0x8(%rbp) + movslq -0x8(%rbp), %rax cmpq $-0x5, %rax setne %cl movzbq %cl, %rcx testq %rcx, %rcx jne + movslq -0x8(%rbp), %rax xorq %rcx, %rcx testq %rcx, %rcx je @@ -291,3 +321,4 @@ Disassembly of section .text: jmp jmp addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/strtof_parses_float.aarch64.asm b/tests/snapshots/asm/strtof_parses_float.aarch64.asm new file mode 100644 index 000000000..e30344a8e --- /dev/null +++ b/tests/snapshots/asm/strtof_parses_float.aarch64.asm @@ -0,0 +1,62 @@ + +strtof_parses_float.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x270 // =624 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x30 + str x19, [sp] + adrp x0, + add x0, x0, + sub x1, x29, #0x8 + bl + mov x0, #0x400c000000000000 // =4615063718147915776 + fmov d17, x0 + fcmp d0, d17 + cset x0, ne + cbz x0, + mov x0, #0x1 // =1 + ldr x19, [sp] + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + ldur x0, [x29, #-0x8] + ldrb w0, [x0] + mov x17, #0x78 // =120 + eor x0, x0, x17 + mov w0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x2 // =2 + ldr x19, [sp] + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + mov x1, #0x0 // =0 + bl + mov x0, #0x3fd0000000000000 // =4598175219545276416 + fmov d16, x0 + fneg d1, d16 + fcmp d0, d1 + cset x0, ne + cbz x0, + mov x0, #0x3 // =3 + ldr x19, [sp] + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x19, [sp] + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/strtof_parses_float.x64.asm b/tests/snapshots/asm/strtof_parses_float.x64.asm new file mode 100644 index 000000000..ff657bc78 --- /dev/null +++ b/tests/snapshots/asm/strtof_parses_float.x64.asm @@ -0,0 +1,67 @@ + +strtof_parses_float.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x20, %rsp + leaq , %rdi + leaq -0x8(%rbp), %rsi + xorl %eax, %eax + callq + movabsq $0x400c000000000000, %rax # imm = 0x400C000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x1, %eax + addq $0x20, %rsp + popq %rbp + retq + movq -0x8(%rbp), %rax + movsbq (%rax), %rax + cmpq $0x78, %rax + je + movl $0x2, %eax + addq $0x20, %rsp + popq %rbp + retq + leaq , %rdi + xorq %rsi, %rsi + xorl %eax, %eax + callq + movabsq $0x3fd0000000000000, %rax # imm = 0x3FD0000000000000 + movq %rax, %xmm1 + movabsq $-0x8000000000000000, %r10 # imm = 0x8000000000000000 + movq %r10, %xmm15 + xorpd %xmm15, %xmm1 + ucomisd %xmm1, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x3, %eax + addq $0x20, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x20, %rsp + popq %rbp + retq diff --git a/tests/snapshots/asm/struct_arg_indirect_subscript.aarch64.asm b/tests/snapshots/asm/struct_arg_indirect_subscript.aarch64.asm index 602611d9a..c3147bdf4 100644 --- a/tests/snapshots/asm/struct_arg_indirect_subscript.aarch64.asm +++ b/tests/snapshots/asm/struct_arg_indirect_subscript.aarch64.asm @@ -62,8 +62,7 @@ Disassembly of section .text: ldr d0, [x0] mov x0, #0x4010000000000000 // =4616189618054758400 sub x2, x29, #0x10 - add x2, x2, #0x8 - ldr d1, [x2] + ldr d1, [x2, #0x8] mov x2, #0x4000000000000000 // =4611686018427387904 fmov d17, x2 fmul d1, d1, d17 diff --git a/tests/snapshots/asm/struct_arg_indirect_subscript.x64.asm b/tests/snapshots/asm/struct_arg_indirect_subscript.x64.asm index 215b3b749..8573b6e09 100644 --- a/tests/snapshots/asm/struct_arg_indirect_subscript.x64.asm +++ b/tests/snapshots/asm/struct_arg_indirect_subscript.x64.asm @@ -64,8 +64,7 @@ Disassembly of section .text: movsd (%rax,%riz), %xmm0 movabsq $0x4010000000000000, %rax # imm = 0x4010000000000000 leaq -0x10(%rbp), %rcx - addq $0x8, %rcx - movsd (%rcx,%riz), %xmm1 + movsd 0x8(%rcx,%riz), %xmm1 movabsq $0x4000000000000000, %rcx # imm = 0x4000000000000000 movq %rcx, %xmm15 mulsd %xmm15, %xmm1 @@ -306,3 +305,5 @@ Disassembly of section .text: addq $0xd0, %rsp popq %rbp retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/struct_deref_va_arg.aarch64.asm b/tests/snapshots/asm/struct_deref_va_arg.aarch64.asm index 5d3f2c5e2..ae4927055 100644 --- a/tests/snapshots/asm/struct_deref_va_arg.aarch64.asm +++ b/tests/snapshots/asm/struct_deref_va_arg.aarch64.asm @@ -62,6 +62,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/struct_fn_ptr_field_deref_call.aarch64.asm b/tests/snapshots/asm/struct_fn_ptr_field_deref_call.aarch64.asm index f125dd10c..6c039fc4b 100644 --- a/tests/snapshots/asm/struct_fn_ptr_field_deref_call.aarch64.asm +++ b/tests/snapshots/asm/struct_fn_ptr_field_deref_call.aarch64.asm @@ -34,16 +34,16 @@ Disassembly of section .text: mov x1, #0x0 // =0 str w1, [x20, #0x8] mov x1, #0xa // =10 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 sxtw x21, w0 ldr x0, [x20] mov x1, #0x14 // =20 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -70,16 +70,16 @@ Disassembly of section .text: add x0, x0, str x0, [x20] mov x1, #0x64 // =100 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 sxtw x21, w0 ldr x0, [x20] mov x1, #0xc8 // =200 - mov x9, x0 str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/struct_initializers.aarch64.asm b/tests/snapshots/asm/struct_initializers.aarch64.asm index c9e883efd..cac20dd47 100644 --- a/tests/snapshots/asm/struct_initializers.aarch64.asm +++ b/tests/snapshots/asm/struct_initializers.aarch64.asm @@ -39,9 +39,9 @@ Disassembly of section .text: ldr x0, [x20, #0x8] mov x1, #0x2 // =2 mov x2, #0x3 // =3 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -58,9 +58,9 @@ Disassembly of section .text: ldr x0, [x20, #0x10] mov x1, #0xa // =10 mov x2, #0x4 // =4 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -103,9 +103,9 @@ Disassembly of section .text: ldr x0, [x0, #0x8] mov x1, #0x7 // =7 mov x2, #0x8 // =8 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -149,9 +149,9 @@ Disassembly of section .text: add x0, x0, ldr x0, [x0, #0x8] mov x1, #0x1 // =1 - mov x9, x0 str x1, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -170,9 +170,9 @@ Disassembly of section .text: ldr x0, [x0, #0x10] mov x1, #0x5 // =5 mov x2, #0x1 // =1 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/switch_case_label_promoted.aarch64.asm b/tests/snapshots/asm/switch_case_label_promoted.aarch64.asm new file mode 100644 index 000000000..f0babd65b --- /dev/null +++ b/tests/snapshots/asm/switch_case_label_promoted.aarch64.asm @@ -0,0 +1,91 @@ + +switch_case_label_promoted.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x20 + mov x0, #0x80000000 // =2147483648 + movk x0, #0xffff, lsl #32 + movk x0, #0xffff, lsl #48 + mov x17, #0x80000000 // =2147483648 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + cmp x0, x17 + b.eq + b + sxtw x0, w0 + cmp x0, #0x1 + b.eq + b + mov x0, #0x1 // =1 + b + mov x0, #0x2 // =2 + b + b + mov x0, #0x1 // =1 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xfffe // =65534 + movk x0, #0xffff, lsl #16 + mov x17, #0xfffe // =65534 + movk x17, #0xffff, lsl #16 + cmp x0, x17 + b.eq + b + sxtw x0, w0 + cmp x0, #0x3 + b.eq + b + mov x0, #0x3 // =3 + b + mov x0, #0x4 // =4 + b + b + mov x0, #0x2 // =2 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0xffff00000000 // =281470681743360 + movk x0, #0xffff, lsl #48 + mov x17, #0x80000000 // =2147483648 + cmp x0, x17 + b.lt + b + sxtw x0, w0 + cmp x0, #0x5 + b.eq + b + mov x0, #0x5 // =5 + b + mov x0, #0x6 // =6 + b + mov x0, #0x7 // =7 + b + mov x17, #0xffff00000000 // =281470681743360 + movk x17, #0xffff, lsl #48 + cmp x0, x17 + b.eq + b + mov x17, #0x80000000 // =2147483648 + cmp x0, x17 + b.eq + b + b + mov x0, #0x3 // =3 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/switch_case_label_promoted.x64.asm b/tests/snapshots/asm/switch_case_label_promoted.x64.asm new file mode 100644 index 000000000..159dd2d1f --- /dev/null +++ b/tests/snapshots/asm/switch_case_label_promoted.x64.asm @@ -0,0 +1,86 @@ + +switch_case_label_promoted.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x20, %rsp + movabsq $-0x80000000, %rax # imm = 0x80000000 + cmpq $-0x80000000, %rax # imm = 0x80000000 + je + jmp + movslq %eax, %rax + cmpq $0x1, %rax + je + jmp + movl $0x1, %eax + jmp + movl $0x2, %eax + jmp + jmp + movl $0x1, %eax + addq $0x20, %rsp + popq %rbp + retq + movl $0xfffffffe, %eax # imm = 0xFFFFFFFE + movl $0xfffffffe, %r11d # imm = 0xFFFFFFFE + cmpq %r11, %rax + je + jmp + movslq %eax, %rax + cmpq $0x3, %rax + je + jmp + movl $0x3, %eax + jmp + movl $0x4, %eax + jmp + jmp + movl $0x2, %eax + addq $0x20, %rsp + popq %rbp + retq + movabsq $-0x100000000, %rax # imm = 0xFFFFFFFF00000000 + movl $0x80000000, %r11d # imm = 0x80000000 + movq %rax, %rcx + cmpq %r11, %rax + jl + jmp + movslq %eax, %rax + cmpq $0x5, %rax + je + jmp + movl $0x5, %eax + jmp + movl $0x6, %eax + jmp + movl $0x7, %eax + jmp + movabsq $-0x100000000, %r11 # imm = 0xFFFFFFFF00000000 + cmpq %r11, %rax + je + jmp + movl $0x80000000, %r11d # imm = 0x80000000 + cmpq %r11, %rax + je + jmp + jmp + movl $0x3, %eax + addq $0x20, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x20, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/sxtw_fold_source_liveness.aarch64.asm b/tests/snapshots/asm/sxtw_fold_source_liveness.aarch64.asm new file mode 100644 index 000000000..e812fb190 --- /dev/null +++ b/tests/snapshots/asm/sxtw_fold_source_liveness.aarch64.asm @@ -0,0 +1,34 @@ + +sxtw_fold_source_liveness.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x20 + lsl x2, x0, #32 + add x0, x0, x1 + asr x2, x2, #32 + add x0, x2, x0 + add x0, x0, x1 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + +
: + mov x0, #0x2 // =2 + mov x1, #0x7 // =7 + lsl x2, x0, #32 + add x0, x0, x1 + asr x2, x2, #32 + add x0, x2, x0 + add x0, x0, x1 + sxtw x0, w0 + ret diff --git a/tests/snapshots/asm/sxtw_fold_source_liveness.x64.asm b/tests/snapshots/asm/sxtw_fold_source_liveness.x64.asm new file mode 100644 index 000000000..635b6be10 --- /dev/null +++ b/tests/snapshots/asm/sxtw_fold_source_liveness.x64.asm @@ -0,0 +1,36 @@ + +sxtw_fold_source_liveness.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + subq $0x20, %rsp + leaq (%rdi,%rsi), %rcx + movslq %edi, %rax + addq %rcx, %rax + addq %rsi, %rax + addq $0x20, %rsp + popq %rbp + retq + +
: + movl $0x2, %eax + movl $0x7, %ecx + movq %rax, %rdx + shlq $0x20, %rdx + addq %rcx, %rax + sarq $0x20, %rdx + addq %rdx, %rax + addq %rcx, %rax + movslq %eax, %rax + retq + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/sys_addr_in_static_init.aarch64.asm b/tests/snapshots/asm/sys_addr_in_static_init.aarch64.asm index 98bd8dc9f..e84e66bcc 100644 --- a/tests/snapshots/asm/sys_addr_in_static_init.aarch64.asm +++ b/tests/snapshots/asm/sys_addr_in_static_init.aarch64.asm @@ -23,9 +23,9 @@ Disassembly of section .text: adrp x1, add x1, x1, mov x2, #0x4 // =4 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -45,10 +45,10 @@ Disassembly of section .text: ldr x0, [x20, #0x8] adrp x2, add x2, x2, - mov x9, x0 str x1, [sp, #-0x10]! str x1, [sp, #-0x10]! str x2, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] @@ -68,10 +68,10 @@ Disassembly of section .text: ldr x0, [x20, #0x68] sub x1, x29, #0x48 mov x2, #0x4 // =4 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! str x21, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] @@ -79,8 +79,8 @@ Disassembly of section .text: add sp, sp, #0x30 sxtw x22, w0 ldr x0, [x20, #0x20] - mov x9, x0 str x21, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -104,23 +104,7 @@ Disassembly of section .text: ret <__c5_sys_open>: - str x2, [sp, #-0x10]! - str x1, [sp, #-0x10]! - str x0, [sp, #-0x10]! - stp x29, x30, [sp, #-0x10]! - mov x29, sp - sub sp, sp, #0x10 - str x19, [sp] - ldur x0, [x29, #0x10] - ldur x1, [x29, #0x20] - ldur x2, [x29, #0x30] - bl - sxtw x0, w0 - ldr x19, [sp] - add sp, sp, #0x10 - ldp x29, x30, [sp], #0x10 - add sp, sp, #0x30 - ret + b <__c5_sys_read>: str x2, [sp, #-0x10]! diff --git a/tests/snapshots/asm/sys_addr_in_static_init.x64.asm b/tests/snapshots/asm/sys_addr_in_static_init.x64.asm index 5fe64bb1c..18d38fa39 100644 --- a/tests/snapshots/asm/sys_addr_in_static_init.x64.asm +++ b/tests/snapshots/asm/sys_addr_in_static_init.x64.asm @@ -74,25 +74,7 @@ Disassembly of section .text: retq <__c5_sys_open>: - popq %r10 - subq $0x30, %rsp - movq %rdi, (%rsp) - movq %rsi, 0x10(%rsp) - movq %rdx, 0x20(%rsp) - pushq %r10 - pushq %rbp - movq %rsp, %rbp - movq 0x10(%rbp), %rdi - movq 0x20(%rbp), %rsi - movq 0x30(%rbp), %rdx - movb $0x0, %al - callq - movslq %eax, %rax - popq %rbp - popq %r11 - addq $0x30, %rsp - pushq %r11 - retq + jmp <__c5_sys_read>: popq %r10 @@ -151,4 +133,3 @@ Disassembly of section .text: pushq %r11 retq addb %al, (%rax) - addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/sysv_variadic_host_abi.aarch64.asm b/tests/snapshots/asm/sysv_variadic_host_abi.aarch64.asm index 2221d8f27..2ba9142fd 100644 --- a/tests/snapshots/asm/sysv_variadic_host_abi.aarch64.asm +++ b/tests/snapshots/asm/sysv_variadic_host_abi.aarch64.asm @@ -89,6 +89,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -109,6 +111,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x10 str w16, [x17, #0x1c] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -182,6 +186,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x10 str w16, [x17, #0x1c] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/ternary_arith_common_type.aarch64.asm b/tests/snapshots/asm/ternary_arith_common_type.aarch64.asm new file mode 100644 index 000000000..770b56d7e --- /dev/null +++ b/tests/snapshots/asm/ternary_arith_common_type.aarch64.asm @@ -0,0 +1,78 @@ + +ternary_arith_common_type.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x50 + mov x0, #0x0 // =0 + cmp x0, #0x0 + b.ne + mov x2, #0x1 // =1 + b + mov x2, #0xffff // =65535 + movk x2, #0xffff, lsl #16 + cmp x2, #0x1 + b.eq + mov x0, #0x1 // =1 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret + cmp x0, #0x0 + b.eq + mov x2, #0x1 // =1 + b + mov x2, #0xffff // =65535 + movk x2, #0xffff, lsl #16 + mov x17, #0xffff // =65535 + movk x17, #0xffff, lsl #16 + cmp x2, x17 + b.eq + mov x0, #0x2 // =2 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret + cmp x0, #0x0 + b.ne + mov x2, #0xffff // =65535 + movk x2, #0xffff, lsl #16 + b + mov x2, #0x1 // =1 + mov x17, #0xffff // =65535 + movk x17, #0xffff, lsl #16 + cmp x2, x17 + b.eq + mov x0, #0x3 // =3 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret + cmp x0, #0x0 + b.ne + mov x1, #0xffff // =65535 + movk x1, #0xffff, lsl #16 + movk x1, #0xffff, lsl #32 + movk x1, #0xffff, lsl #48 + b + mov x1, #0x0 // =0 + mov x17, #0xffff // =65535 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + cmp x1, x17 + b.eq + mov x0, #0x4 // =4 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x50 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/ternary_arith_common_type.x64.asm b/tests/snapshots/asm/ternary_arith_common_type.x64.asm new file mode 100644 index 000000000..8c92a0e0f --- /dev/null +++ b/tests/snapshots/asm/ternary_arith_common_type.x64.asm @@ -0,0 +1,70 @@ + +ternary_arith_common_type.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x50, %rsp + xorq %rax, %rax + testq %rax, %rax + jne + movl $0x1, %edx + jmp + movl $0xffffffff, %edx # imm = 0xFFFFFFFF + cmpq $0x1, %rdx + je + movl $0x1, %eax + addq $0x50, %rsp + popq %rbp + retq + testq %rax, %rax + je + movl $0x1, %edx + jmp + movl $0xffffffff, %edx # imm = 0xFFFFFFFF + movl $0xffffffff, %r11d # imm = 0xFFFFFFFF + movq %rdx, %rcx + cmpq %r11, %rdx + je + movl $0x2, %eax + addq $0x50, %rsp + popq %rbp + retq + testq %rax, %rax + jne + movl $0xffffffff, %edx # imm = 0xFFFFFFFF + jmp + movl $0x1, %edx + movl $0xffffffff, %r11d # imm = 0xFFFFFFFF + movq %rdx, %rcx + cmpq %r11, %rdx + je + movl $0x3, %eax + addq $0x50, %rsp + popq %rbp + retq + testq %rax, %rax + jne + movabsq $-0x1, %rcx + jmp + xorq %rcx, %rcx + cmpq $-0x1, %rcx + je + movl $0x4, %eax + addq $0x50, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x50, %rsp + popq %rbp + retq + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/thread_local_per_thread.aarch64.asm b/tests/snapshots/asm/thread_local_per_thread.aarch64.asm index 3864df980..cbbe5a7b3 100644 --- a/tests/snapshots/asm/thread_local_per_thread.aarch64.asm +++ b/tests/snapshots/asm/thread_local_per_thread.aarch64.asm @@ -71,11 +71,11 @@ Disassembly of section .text: sub x0, x29, #0x20 adrp x2, add x2, x2, - mov x9, x23 str x21, [sp, #-0x10]! str x2, [sp, #-0x10]! str x21, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x23 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] @@ -84,9 +84,9 @@ Disassembly of section .text: add sp, sp, #0x40 ldur x0, [x29, #-0x20] sub x1, x29, #0x28 - mov x9, x22 str x1, [sp, #-0x10]! str x0, [sp, #-0x10]! + mov x9, x22 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/two_d_float_array_partial_init.aarch64.asm b/tests/snapshots/asm/two_d_float_array_partial_init.aarch64.asm index f5ef2e85b..2291d318b 100644 --- a/tests/snapshots/asm/two_d_float_array_partial_init.aarch64.asm +++ b/tests/snapshots/asm/two_d_float_array_partial_init.aarch64.asm @@ -153,11 +153,9 @@ Disassembly of section .text: lsl x3, x3, #4 add x2, x2, x3 ldr s1, [x2] - add x3, x2, #0x4 - ldr s2, [x3] + ldr s2, [x2, #0x4] fadd s1, s1, s2 - add x2, x2, #0x8 - ldr s2, [x2] + ldr s2, [x2, #0x8] fadd s1, s1, s2 fadd s0, s0, s1 str s0, [x0] diff --git a/tests/snapshots/asm/two_d_float_array_partial_init.x64.asm b/tests/snapshots/asm/two_d_float_array_partial_init.x64.asm index 6f3b4ba4d..e92d89514 100644 --- a/tests/snapshots/asm/two_d_float_array_partial_init.x64.asm +++ b/tests/snapshots/asm/two_d_float_array_partial_init.x64.asm @@ -147,11 +147,9 @@ Disassembly of section .text: shlq $0x4, %rsi addq %rsi, %rdx movss (%rdx,%riz), %xmm1 - leaq 0x4(%rdx), %rsi - movss (%rsi,%riz), %xmm2 + movss 0x4(%rdx,%riz), %xmm2 addss %xmm2, %xmm1 - addq $0x8, %rdx - movss (%rdx,%riz), %xmm2 + movss 0x8(%rdx,%riz), %xmm2 addss %xmm2, %xmm1 addss %xmm1, %xmm0 movss %xmm0, (%rax,%riz) @@ -190,4 +188,3 @@ Disassembly of section .text: addq $0x50, %rsp popq %rbp retq - addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/two_d_stride_no_leak_across_exprs.aarch64.asm b/tests/snapshots/asm/two_d_stride_no_leak_across_exprs.aarch64.asm index 95ad55da3..457e43b43 100644 --- a/tests/snapshots/asm/two_d_stride_no_leak_across_exprs.aarch64.asm +++ b/tests/snapshots/asm/two_d_stride_no_leak_across_exprs.aarch64.asm @@ -54,8 +54,7 @@ Disassembly of section .text: str s0, [x0] b sub x0, x29, #0x508 - add x0, x0, #0x20 - ldr s0, [x0] + ldr s0, [x0, #0x20] mov x0, #0x4000000000000000 // =4611686018427387904 fcvt d0, s0 fmov d17, x0 diff --git a/tests/snapshots/asm/two_d_stride_no_leak_across_exprs.x64.asm b/tests/snapshots/asm/two_d_stride_no_leak_across_exprs.x64.asm index 3c53b4dd6..89100c389 100644 --- a/tests/snapshots/asm/two_d_stride_no_leak_across_exprs.x64.asm +++ b/tests/snapshots/asm/two_d_stride_no_leak_across_exprs.x64.asm @@ -56,8 +56,7 @@ Disassembly of section .text: movss %xmm0, (%rax,%riz) jmp leaq -0x508(%rbp), %rax - addq $0x20, %rax - movss (%rax,%riz), %xmm0 + movss 0x20(%rax,%riz), %xmm0 movabsq $0x4000000000000000, %rax # imm = 0x4000000000000000 cvtss2sd %xmm0, %xmm0 movq %rax, %xmm15 @@ -98,4 +97,3 @@ Disassembly of section .text: addq $0x520, %rsp # imm = 0x520 popq %rbp retq - addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/typedef_fn_ptr_struct_field.aarch64.asm b/tests/snapshots/asm/typedef_fn_ptr_struct_field.aarch64.asm index 91abf9f90..07e06d215 100644 --- a/tests/snapshots/asm/typedef_fn_ptr_struct_field.aarch64.asm +++ b/tests/snapshots/asm/typedef_fn_ptr_struct_field.aarch64.asm @@ -31,9 +31,9 @@ Disassembly of section .text: ldr x0, [x20] mov x1, #0x3 // =3 mov x2, #0x7 // =7 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -50,9 +50,9 @@ Disassembly of section .text: ldr x0, [x20] mov x1, #0x4 // =4 mov x2, #0x5 // =5 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -70,9 +70,9 @@ Disassembly of section .text: ldr x0, [x0] mov x1, #0x2 // =2 mov x2, #0x9 // =9 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -90,9 +90,9 @@ Disassembly of section .text: ldr x0, [x0] mov x1, #0x6 // =6 mov x2, #0x4 // =4 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 diff --git a/tests/snapshots/asm/unary_plus_init_and_param_shadow.aarch64.asm b/tests/snapshots/asm/unary_plus_init_and_param_shadow.aarch64.asm index ecc77ad57..60b3de606 100644 --- a/tests/snapshots/asm/unary_plus_init_and_param_shadow.aarch64.asm +++ b/tests/snapshots/asm/unary_plus_init_and_param_shadow.aarch64.asm @@ -65,8 +65,7 @@ Disassembly of section .text: add sp, sp, #0x40 ldp x29, x30, [sp], #0x10 ret - add x0, x20, #0x8 - ldr d0, [x0] + ldr d0, [x20, #0x8] mov x0, #0x6666 // =26214 movk x0, #0x6666, lsl #16 movk x0, #0x6666, lsl #32 @@ -80,8 +79,7 @@ Disassembly of section .text: add sp, sp, #0x40 ldp x29, x30, [sp], #0x10 ret - add x0, x20, #0x10 - ldr d0, [x0] + ldr d0, [x20, #0x10] mov x0, #0x3ff0000000000000 // =4607182418800017408 fmov d1, x0 bl @@ -92,8 +90,7 @@ Disassembly of section .text: add sp, sp, #0x40 ldp x29, x30, [sp], #0x10 ret - add x0, x20, #0x18 - ldr d0, [x0] + ldr d0, [x20, #0x18] mov x0, #0x4000000000000000 // =4611686018427387904 fmov d16, x0 fneg d1, d16 diff --git a/tests/snapshots/asm/unary_plus_init_and_param_shadow.x64.asm b/tests/snapshots/asm/unary_plus_init_and_param_shadow.x64.asm index 8a11f486a..a2869f73d 100644 --- a/tests/snapshots/asm/unary_plus_init_and_param_shadow.x64.asm +++ b/tests/snapshots/asm/unary_plus_init_and_param_shadow.x64.asm @@ -68,8 +68,7 @@ Disassembly of section .text: addq $0x40, %rsp popq %rbp retq - leaq 0x8(%rbx), %rax - movsd (%rax,%riz), %xmm0 + movsd 0x8(%rbx,%riz), %xmm0 movabsq $0x3fe6666666666666, %rdi # imm = 0x3FE6666666666666 movq %rdi, %xmm1 callq @@ -80,8 +79,7 @@ Disassembly of section .text: addq $0x40, %rsp popq %rbp retq - leaq 0x10(%rbx), %rax - movsd (%rax,%riz), %xmm0 + movsd 0x10(%rbx,%riz), %xmm0 movabsq $0x3ff0000000000000, %rdi # imm = 0x3FF0000000000000 movq %rdi, %xmm1 callq @@ -92,8 +90,7 @@ Disassembly of section .text: addq $0x40, %rsp popq %rbp retq - leaq 0x18(%rbx), %rax - movsd (%rax,%riz), %xmm0 + movsd 0x18(%rbx,%riz), %xmm0 movabsq $0x4000000000000000, %rax # imm = 0x4000000000000000 movq %rax, %xmm1 movabsq $-0x8000000000000000, %r10 # imm = 0x8000000000000000 diff --git a/tests/snapshots/asm/union_member_unbraced_init.aarch64.asm b/tests/snapshots/asm/union_member_unbraced_init.aarch64.asm new file mode 100644 index 000000000..24d4e7a16 --- /dev/null +++ b/tests/snapshots/asm/union_member_unbraced_init.aarch64.asm @@ -0,0 +1,196 @@ + +union_member_unbraced_init.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x80 + adrp x0, + add x0, x0, + ldr d0, [x0] + mov x1, #0x4008000000000000 // =4613937818241073152 + fmov d17, x1 + fcmp d0, d17 + cset x2, ne + cbnz x2, + ldrsw x1, [x0, #0x10] + cmp x1, #0x2a + cset x2, ne + cbz x2, + mov x0, #0x1 // =1 + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + mov x2, #0x8 // =8 + sxtw x1, w2 + cmp x1, #0x10 + b.ge + b + sxtw x1, w2 + add x2, x1, #0x1 + b + sxtw x1, w2 + add x1, x0, x1 + ldrb w1, [x1] + cmp x1, #0x0 + b.eq + b + adrp x0, + add x0, x0, + ldr d0, [x0] + mov x0, #0x4014000000000000 // =4617315517961601024 + fmov d17, x0 + fcmp d0, d17 + cset x1, ne + cbnz x1, + b + mov x0, #0x2 // =2 + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + b + adrp x0, + add x0, x0, + ldrsw x0, [x0, #0x8] + cmp x0, #0x2b + cset x1, ne + cbz x1, + mov x0, #0x3 // =3 + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + ldrsw x0, [x0] + cmp x0, #0x1 + cset x0, ne + mov x2, #0x1 // =1 + cbnz x0, + adrp x0, + add x0, x0, + ldrsw x0, [x0, #0x4] + cmp x0, #0x2 + cset x0, ne + cmp x0, #0x0 + cset x2, ne + cbnz x2, + adrp x0, + add x0, x0, + ldrsw x0, [x0, #0x8] + cmp x0, #0x9 + cset x2, ne + cbz x2, + mov x0, #0x4 // =4 + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + ldr d0, [x0] + mov x0, #0x4008000000000000 // =4613937818241073152 + fmov d17, x0 + fcmp d0, d17 + cset x1, ne + cbnz x1, + adrp x0, + add x0, x0, + ldrsw x0, [x0, #0x10] + cmp x0, #0x2a + cset x1, ne + cbz x1, + mov x0, #0x5 // =5 + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + adrp x0, + add x0, x0, + ldr d0, [x0, #0x18] + mov x0, #0x4010000000000000 // =4616189618054758400 + fmov d17, x0 + fcmp d0, d17 + cset x1, ne + cbnz x1, + adrp x0, + add x0, x0, + ldrsw x0, [x0, #0x28] + cmp x0, #0x2b + cset x1, ne + cbz x1, + mov x0, #0x6 // =6 + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x20 + adrp x1, + add x1, x1, + str x10, [sp, #-0x10]! + ldr x10, [x1] + str x10, [x0] + ldr x10, [x1, #0x8] + str x10, [x0, #0x8] + ldr x10, [x1, #0x10] + str x10, [x0, #0x10] + ldr x10, [sp], #0x10 + sub x0, x29, #0x20 + ldr d0, [x0] + mov x0, #0x4008000000000000 // =4613937818241073152 + fmov d17, x0 + fcmp d0, d17 + cset x1, ne + cbnz x1, + sub x0, x29, #0x20 + ldrsw x0, [x0, #0x10] + cmp x0, #0x2a + cset x1, ne + cbz x1, + mov x0, #0x7 // =7 + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x38 + adrp x1, + add x1, x1, + str x10, [sp, #-0x10]! + ldr x10, [x1] + str x10, [x0] + ldr x10, [x1, #0x8] + str x10, [x0, #0x8] + ldr x10, [x1, #0x10] + str x10, [x0, #0x10] + ldr x10, [sp], #0x10 + sub x0, x29, #0x38 + ldr d0, [x0] + mov x0, #0x4018000000000000 // =4618441417868443648 + fmov d17, x0 + fcmp d0, d17 + cset x1, ne + cbnz x1, + sub x0, x29, #0x38 + ldrsw x0, [x0, #0x10] + cmp x0, #0x2c + cset x1, ne + cbz x1, + mov x0, #0x8 // =8 + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + b + b + b + b + b + b + b + b diff --git a/tests/snapshots/asm/union_member_unbraced_init.x64.asm b/tests/snapshots/asm/union_member_unbraced_init.x64.asm new file mode 100644 index 000000000..af4978ecd --- /dev/null +++ b/tests/snapshots/asm/union_member_unbraced_init.x64.asm @@ -0,0 +1,235 @@ + +union_member_unbraced_init.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x80, %rsp + leaq , %rax + movsd (%rax,%riz), %xmm0 + movabsq $0x4008000000000000, %rcx # imm = 0x4008000000000000 + movq %rcx, %xmm15 + ucomisd %xmm15, %xmm0 + setne %dl + movzbq %dl, %rdx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rdx + testq %rdx, %rdx + jne + movslq 0x10(%rax), %rcx + cmpq $0x2a, %rcx + setne %dl + movzbq %dl, %rdx + testq %rdx, %rdx + je + movl $0x1, %eax + addq $0x80, %rsp + popq %rbp + retq + movl $0x8, %edx + movslq %edx, %rcx + cmpq $0x10, %rcx + jge + jmp + movslq %edx, %rcx + leaq 0x1(%rcx), %rdx + jmp + movslq %edx, %rcx + addq %rax, %rcx + movsbq (%rcx), %rcx + testq %rcx, %rcx + je + jmp + leaq , %rax + movsd (%rax,%riz), %xmm0 + movabsq $0x4014000000000000, %rax # imm = 0x4014000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %cl + movzbq %cl, %rcx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rcx + testq %rcx, %rcx + jne + jmp + movl $0x2, %eax + addq $0x80, %rsp + popq %rbp + retq + jmp + leaq , %rax + movslq 0x8(%rax), %rax + cmpq $0x2b, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x3, %eax + addq $0x80, %rsp + popq %rbp + retq + leaq , %rax + movslq (%rax), %rax + cmpq $0x1, %rax + setne %al + movzbq %al, %rax + movl $0x1, %edx + testq %rax, %rax + jne + leaq , %rax + movslq 0x4(%rax), %rax + cmpq $0x2, %rax + setne %al + movzbq %al, %rax + testq %rax, %rax + setne %dl + movzbq %dl, %rdx + testq %rdx, %rdx + jne + leaq , %rax + movslq 0x8(%rax), %rax + cmpq $0x9, %rax + setne %dl + movzbq %dl, %rdx + testq %rdx, %rdx + je + movl $0x4, %eax + addq $0x80, %rsp + popq %rbp + retq + leaq , %rax + movsd (%rax,%riz), %xmm0 + movabsq $0x4008000000000000, %rax # imm = 0x4008000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %cl + movzbq %cl, %rcx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rcx + testq %rcx, %rcx + jne + leaq , %rax + movslq 0x10(%rax), %rax + cmpq $0x2a, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x5, %eax + addq $0x80, %rsp + popq %rbp + retq + leaq , %rax + movsd 0x18(%rax,%riz), %xmm0 + movabsq $0x4010000000000000, %rax # imm = 0x4010000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %cl + movzbq %cl, %rcx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rcx + testq %rcx, %rcx + jne + leaq , %rax + movslq 0x28(%rax), %rax + cmpq $0x2b, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x6, %eax + addq $0x80, %rsp + popq %rbp + retq + leaq -0x20(%rbp), %rax + leaq , %rcx + pushq %rdx + movq (%rcx), %rdx + movq %rdx, (%rax) + movq 0x8(%rcx), %rdx + movq %rdx, 0x8(%rax) + movq 0x10(%rcx), %rdx + movq %rdx, 0x10(%rax) + popq %rdx + leaq -0x20(%rbp), %rax + movsd (%rax,%riz), %xmm0 + movabsq $0x4008000000000000, %rax # imm = 0x4008000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %cl + movzbq %cl, %rcx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rcx + testq %rcx, %rcx + jne + leaq -0x20(%rbp), %rax + movslq 0x10(%rax), %rax + cmpq $0x2a, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x7, %eax + addq $0x80, %rsp + popq %rbp + retq + leaq -0x38(%rbp), %rax + leaq , %rcx + pushq %rdx + movq (%rcx), %rdx + movq %rdx, (%rax) + movq 0x8(%rcx), %rdx + movq %rdx, 0x8(%rax) + movq 0x10(%rcx), %rdx + movq %rdx, 0x10(%rax) + popq %rdx + leaq -0x38(%rbp), %rax + movsd (%rax,%riz), %xmm0 + movabsq $0x4018000000000000, %rax # imm = 0x4018000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %cl + movzbq %cl, %rcx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rcx + testq %rcx, %rcx + jne + leaq -0x38(%rbp), %rax + movslq 0x10(%rax), %rax + cmpq $0x2c, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x8, %eax + addq $0x80, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x80, %rsp + popq %rbp + retq + jmp + jmp + jmp + jmp + jmp + jmp + jmp + jmp + addb %al, (%rax) diff --git a/tests/snapshots/asm/va_arg_composite_straddle.aarch64.asm b/tests/snapshots/asm/va_arg_composite_straddle.aarch64.asm new file mode 100644 index 000000000..ef52d20f8 --- /dev/null +++ b/tests/snapshots/asm/va_arg_composite_straddle.aarch64.asm @@ -0,0 +1,192 @@ + +va_arg_composite_straddle.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x230 // =560 + movk x1, #0x0, lsl #16 + b + brk #: + sub sp, sp, #0xc0 + str x0, [sp] + str x1, [sp, #0x8] + str x2, [sp, #0x10] + str x3, [sp, #0x18] + str x4, [sp, #0x20] + str x5, [sp, #0x28] + str x6, [sp, #0x30] + str x7, [sp, #0x38] + str d0, [sp, #0x40] + str d1, [sp, #0x50] + str d2, [sp, #0x60] + str d3, [sp, #0x70] + str d4, [sp, #0x80] + str d5, [sp, #0x90] + str d6, [sp, #0xa0] + str d7, [sp, #0xb0] + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x60 + str x19, [sp] + sub x0, x29, #0x20 + add x1, x29, #0x10 + mov x16, x0 + add x17, x29, #0xd0 + str x17, [x16] + add x17, x29, #0x50 + str x17, [x16, #0x8] + add x17, x29, #0xd0 + str x17, [x16, #0x10] + mov x17, #0xffc8 // =65480 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + str w17, [x16, #0x18] + mov x17, #0xff80 // =65408 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + str w17, [x16, #0x1c] + mov x1, #0x0 // =0 + sxtw x0, w1 + cmp x0, #0x6 + b.ge + b + sxtw x0, w1 + add x1, x0, #0x1 + b + sub x0, x29, #0x20 + mov x17, x0 + str x9, [sp, #-0x10]! + ldrsw x16, [x17, #0x18] + cmp x16, #0x0 + b.ge + ldr x9, [x17, #0x8] + add x9, x9, x16 + add x16, x16, #0x8 + str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt + mov x16, x9 + b + ldr x16, [x17] + add x9, x16, #0x8 + str x9, [x17] + ldr x9, [sp], #0x10 + mov x0, x16 + b + sub x0, x29, #0x20 + mov x17, x0 + str x9, [sp, #-0x10]! + ldrsw x16, [x17, #0x18] + cmp x16, #0x0 + b.ge + ldr x9, [x17, #0x8] + add x9, x9, x16 + add x16, x16, #0x10 + str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt + mov x16, x9 + b + ldr x16, [x17] + add x9, x16, #0x10 + str x9, [x17] + ldr x9, [sp], #0x10 + mov x0, x16 + sub x1, x29, #0x38 + str x10, [sp, #-0x10]! + ldr x10, [x0] + str x10, [x1] + ldr x10, [x0, #0x8] + str x10, [x1, #0x8] + ldr x10, [sp], #0x10 + mov x0, x1 + sub x0, x29, #0x20 + mov x17, x0 + str x9, [sp, #-0x10]! + ldrsw x16, [x17, #0x18] + cmp x16, #0x0 + b.ge + ldr x9, [x17, #0x8] + add x9, x9, x16 + add x16, x16, #0x8 + str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt + mov x16, x9 + b + ldr x16, [x17] + add x9, x16, #0x8 + str x9, [x17] + ldr x9, [sp], #0x10 + mov x0, x16 + ldr x0, [x0] + sub x1, x29, #0x20 + sub x1, x29, #0x38 + ldr x1, [x1] + cmp x1, #0x6f + cset x2, ne + cbnz x2, + sub x1, x29, #0x38 + ldr x1, [x1, #0x8] + cmp x1, #0xde + cset x2, ne + cbz x2, + mov x0, #0x1 // =1 + ldr x19, [sp] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0xc0 + ret + cmp x0, #0x309 + b.eq + mov x0, #0x2 // =2 + ldr x19, [sp] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0xc0 + ret + mov x0, #0x0 // =0 + ldr x19, [sp] + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0xc0 + ret + b + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x60 + sub x0, x29, #0x10 + mov x1, #0x6f // =111 + str x1, [x0] + sub x0, x29, #0x10 + mov x1, #0xde // =222 + str x1, [x0, #0x8] + mov x0, #0x1 // =1 + mov x1, #0x2 // =2 + mov x2, #0x3 // =3 + mov x3, #0x4 // =4 + mov x4, #0x5 // =5 + mov x5, #0x6 // =6 + mov x6, #0x7 // =7 + sub x7, x29, #0x10 + mov x8, #0x309 // =777 + sub sp, sp, #0x20 + str x8, [sp, #0x10] + mov x16, x7 + ldr x17, [x16] + str x17, [sp] + ldr x17, [x16, #0x8] + str x17, [sp, #0x8] + bl + add sp, sp, #0x20 + sxtw x0, w0 + add sp, sp, #0x60 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/va_arg_composite_straddle.x64.asm b/tests/snapshots/asm/va_arg_composite_straddle.x64.asm new file mode 100644 index 000000000..ca809d7fe --- /dev/null +++ b/tests/snapshots/asm/va_arg_composite_straddle.x64.asm @@ -0,0 +1,162 @@ + +va_arg_composite_straddle.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + subq $0xf0, %rsp + movq %rdi, -0xf0(%rbp) + movq %rsi, -0xe8(%rbp) + movq %rdx, -0xe0(%rbp) + movq %rcx, -0xd8(%rbp) + movq %r8, -0xd0(%rbp) + movq %r9, -0xc8(%rbp) + testb %al, %al + je + movsd %xmm0, -0xc0(%rbp,%riz) + movsd %xmm1, -0xb0(%rbp,%riz) + movsd %xmm2, -0xa0(%rbp,%riz) + movsd %xmm3, -0x90(%rbp,%riz) + movsd %xmm4, -0x80(%rbp,%riz) + movsd %xmm5, -0x70(%rbp,%riz) + movsd %xmm6, -0x60(%rbp,%riz) + movsd %xmm7, -0x50(%rbp,%riz) + leaq -0x18(%rbp), %rax + leaq -0xf0(%rbp), %rcx + movl $0x8, (%rax) + movl $0x30, 0x4(%rax) + leaq 0x10(%rbp), %r10 + movq %r10, 0x8(%rax) + leaq -0xf0(%rbp), %r10 + movq %r10, 0x10(%rax) + xorq %rcx, %rcx + movslq %ecx, %rax + cmpq $0x6, %rax + jge + jmp + movslq %ecx, %rax + leaq 0x1(%rax), %rcx + jmp + leaq -0x18(%rbp), %rax + movq %rax, %r11 + movl (%r11), %r10d + cmpq $0x30, %r10 + jae + addq 0x10(%r11), %r10 + addl $0x8, (%r11) + jmp + movq 0x8(%r11), %r10 + addq $0x8, 0x8(%r11) + movq %r10, %rax + jmp + leaq -0x18(%rbp), %rax + movq %rax, %r11 + movl (%r11), %r10d + cmpq $0x28, %r10 + jae + addq 0x10(%r11), %r10 + addl $0x10, (%r11) + jmp + movq 0x8(%r11), %r10 + addq $0x10, 0x8(%r11) + movq %r10, %rax + leaq -0x30(%rbp), %rcx + pushq %rdx + movq (%rax), %rdx + movq %rdx, (%rcx) + movq 0x8(%rax), %rdx + movq %rdx, 0x8(%rcx) + popq %rdx + movq %rcx, %rax + leaq -0x18(%rbp), %rax + movq %rax, %r11 + movl (%r11), %r10d + cmpq $0x30, %r10 + jae + addq 0x10(%r11), %r10 + addl $0x8, (%r11) + jmp + movq 0x8(%r11), %r10 + addq $0x8, 0x8(%r11) + movq %r10, %rax + movq (%rax), %rax + leaq -0x18(%rbp), %rcx + leaq -0x30(%rbp), %rcx + movq (%rcx), %rcx + cmpq $0x6f, %rcx + setne %dl + movzbq %dl, %rdx + testq %rdx, %rdx + jne + leaq -0x30(%rbp), %rcx + movq 0x8(%rcx), %rcx + cmpq $0xde, %rcx + setne %dl + movzbq %dl, %rdx + testq %rdx, %rdx + je + movl $0x1, %eax + addq $0xf0, %rsp + popq %rbp + retq + cmpq $0x309, %rax # imm = 0x309 + je + movl $0x2, %eax + addq $0xf0, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0xf0, %rsp + popq %rbp + retq + jmp + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x70, %rsp + movq %rbx, (%rsp) + movq %r12, 0x8(%rsp) + leaq -0x10(%rbp), %rax + movl $0x6f, %ecx + movq %rcx, (%rax) + leaq -0x10(%rbp), %rax + movl $0xde, %ecx + movq %rcx, 0x8(%rax) + movl $0x1, %edi + movl $0x2, %esi + movl $0x3, %edx + movl $0x4, %ecx + movl $0x5, %r8d + movl $0x6, %r9d + movl $0x7, %eax + leaq -0x10(%rbp), %rbx + movl $0x309, %r12d # imm = 0x309 + subq $0x20, %rsp + movq %rax, (%rsp) + movq %r12, 0x18(%rsp) + movq %rbx, %r10 + movq (%r10), %r11 + movq %r11, 0x8(%rsp) + movq 0x8(%r10), %r11 + movq %r11, 0x10(%rsp) + movb $0x0, %al + callq + addq $0x20, %rsp + movslq %eax, %rax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + addq $0x70, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/va_arg_int_seq.aarch64.asm b/tests/snapshots/asm/va_arg_int_seq.aarch64.asm index cd1a25cb4..9f9eb1889 100644 --- a/tests/snapshots/asm/va_arg_int_seq.aarch64.asm +++ b/tests/snapshots/asm/va_arg_int_seq.aarch64.asm @@ -76,6 +76,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/va_arg_through_pointer.aarch64.asm b/tests/snapshots/asm/va_arg_through_pointer.aarch64.asm index b3745f6fc..a922faf63 100644 --- a/tests/snapshots/asm/va_arg_through_pointer.aarch64.asm +++ b/tests/snapshots/asm/va_arg_through_pointer.aarch64.asm @@ -25,6 +25,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -45,6 +47,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -65,6 +69,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x10 str w16, [x17, #0x1c] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/va_copy.aarch64.asm b/tests/snapshots/asm/va_copy.aarch64.asm index d44b63c1a..aa1d2fe5d 100644 --- a/tests/snapshots/asm/va_copy.aarch64.asm +++ b/tests/snapshots/asm/va_copy.aarch64.asm @@ -78,6 +78,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/va_copy.x64.asm b/tests/snapshots/asm/va_copy.x64.asm index 52e9ac0a5..14ece69be 100644 --- a/tests/snapshots/asm/va_copy.x64.asm +++ b/tests/snapshots/asm/va_copy.x64.asm @@ -40,12 +40,14 @@ Disassembly of section .text: movq %r10, 0x10(%rax) leaq -0x30(%rbp), %rax leaq -0x18(%rbp), %rcx - movq (%rcx), %r10 - movq %r10, (%rax) - movq 0x8(%rcx), %r10 - movq %r10, 0x8(%rax) - movq 0x10(%rcx), %r10 - movq %r10, 0x10(%rax) + pushq %rdx + movq (%rcx), %rdx + movq %rdx, (%rax) + movq 0x8(%rcx), %rdx + movq %rdx, 0x8(%rax) + movq 0x10(%rcx), %rdx + movq %rdx, 0x10(%rax) + popq %rdx xorq %rcx, %rcx movq %rcx, %rax movslq %ecx, %rdx @@ -93,5 +95,4 @@ Disassembly of section .text: xorq %rax, %rax popq %rbp retq - addb %al, (%rax) addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/va_copy_under_pressure.aarch64.asm b/tests/snapshots/asm/va_copy_under_pressure.aarch64.asm new file mode 100644 index 000000000..8dcb6e4ae --- /dev/null +++ b/tests/snapshots/asm/va_copy_under_pressure.aarch64.asm @@ -0,0 +1,168 @@ + +va_copy_under_pressure.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + sub sp, sp, #0xc0 + str x0, [sp] + str x1, [sp, #0x8] + str x2, [sp, #0x10] + str x3, [sp, #0x18] + str x4, [sp, #0x20] + str x5, [sp, #0x28] + str x6, [sp, #0x30] + str x7, [sp, #0x38] + str d0, [sp, #0x40] + str d1, [sp, #0x50] + str d2, [sp, #0x60] + str d3, [sp, #0x70] + str d4, [sp, #0x80] + str d5, [sp, #0x90] + str d6, [sp, #0xa0] + str d7, [sp, #0xb0] + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0xe0 + str x20, [sp] + str x19, [sp, #0x10] + ldur x0, [x29, #0x10] + mov x17, #0x3 // =3 + mul x1, x0, x17 + add x2, x0, #0xb + mov x17, #0x7 // =7 + mul x3, x0, x17 + sub x4, x0, #0x2 + mov x17, #0xd // =13 + mul x5, x0, x17 + add x6, x0, #0x1d + lsl x7, x0, #2 + add x8, x0, #0x29 + mov x17, #0x9 // =9 + mul x9, x0, x17 + add x10, x0, #0x35 + mov x17, #0x5 // =5 + mul x11, x0, x17 + add x12, x0, #0x3d + mov x17, #0xf // =15 + mul x13, x0, x17 + add x0, x0, #0x3 + sub x14, x29, #0x20 + add x15, x29, #0x10 + mov x16, x14 + add x17, x29, #0xd0 + str x17, [x16] + add x17, x29, #0x50 + str x17, [x16, #0x8] + add x17, x29, #0xd0 + str x17, [x16, #0x10] + mov x17, #0xffc8 // =65480 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + str w17, [x16, #0x18] + mov x17, #0xff80 // =65408 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + str w17, [x16, #0x1c] + sub x14, x29, #0x40 + sub x15, x29, #0x20 + str x9, [sp, #-0x10]! + ldr x9, [x15] + str x9, [x14] + ldr x9, [x15, #0x8] + str x9, [x14, #0x8] + ldr x9, [x15, #0x10] + str x9, [x14, #0x10] + ldr x9, [x15, #0x18] + str x9, [x14, #0x18] + ldr x9, [sp], #0x10 + sub x14, x29, #0x40 + mov x17, x14 + str x9, [sp, #-0x10]! + ldrsw x16, [x17, #0x18] + cmp x16, #0x0 + b.ge + ldr x9, [x17, #0x8] + add x9, x9, x16 + add x16, x16, #0x8 + str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt + mov x16, x9 + b + ldr x16, [x17] + add x9, x16, #0x8 + str x9, [x17] + ldr x9, [sp], #0x10 + mov x14, x16 + ldr x14, [x14] + sub x15, x29, #0x40 + mov x17, x15 + str x9, [sp, #-0x10]! + ldrsw x16, [x17, #0x18] + cmp x16, #0x0 + b.ge + ldr x9, [x17, #0x8] + add x9, x9, x16 + add x16, x16, #0x8 + str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt + mov x16, x9 + b + ldr x16, [x17] + add x9, x16, #0x8 + str x9, [x17] + ldr x9, [sp], #0x10 + mov x15, x16 + ldr x15, [x15] + sub x20, x29, #0x40 + sub x20, x29, #0x20 + add x1, x1, x2 + add x1, x1, x3 + add x1, x1, x4 + add x1, x1, x5 + add x1, x1, x6 + add x1, x1, x7 + add x1, x1, x8 + add x1, x1, x9 + add x1, x1, x10 + add x1, x1, x11 + add x1, x1, x12 + add x1, x1, x13 + add x0, x1, x0 + add x0, x0, x14 + add x0, x0, x15 + ldr x20, [sp] + ldr x19, [sp, #0x10] + add sp, sp, #0xe0 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0xc0 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x30 + mov x0, #0x2 // =2 + mov x1, #0xa // =10 + mov x2, #0x14 // =20 + bl + mov x1, #0x160 // =352 + cmp x0, x1 + b.ne + mov x1, #0x0 // =0 + b + mov x1, #0x1 // =1 + mov x0, x1 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/va_copy_under_pressure.x64.asm b/tests/snapshots/asm/va_copy_under_pressure.x64.asm new file mode 100644 index 000000000..764d2443b --- /dev/null +++ b/tests/snapshots/asm/va_copy_under_pressure.x64.asm @@ -0,0 +1,159 @@ + +va_copy_under_pressure.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + subq $0x1c0, %rsp # imm = 0x1C0 + movq %rdi, -0x190(%rbp) + movq %rsi, -0x188(%rbp) + movq %rdx, -0x180(%rbp) + movq %rcx, -0x178(%rbp) + movq %r8, -0x170(%rbp) + movq %r9, -0x168(%rbp) + testb %al, %al + je + movsd %xmm0, -0x160(%rbp,%riz) + movsd %xmm1, -0x150(%rbp,%riz) + movsd %xmm2, -0x140(%rbp,%riz) + movsd %xmm3, -0x130(%rbp,%riz) + movsd %xmm4, -0x120(%rbp,%riz) + movsd %xmm5, -0x110(%rbp,%riz) + movsd %xmm6, -0x100(%rbp,%riz) + movsd %xmm7, -0xf0(%rbp,%riz) + movq %rbx, (%rsp) + movq %r12, 0x8(%rsp) + movq %r13, 0x10(%rsp) + movq %r14, 0x18(%rsp) + movq %r15, 0x20(%rsp) + movq -0x190(%rbp), %rax + leaq (%rax,%rax,2), %rcx + leaq 0xb(%rax), %rdx + imulq $0x7, %rax, %rsi + leaq -0x2(%rax), %rdi + imulq $0xd, %rax, %r8 + leaq 0x1d(%rax), %r9 + movq %rax, %rbx + shlq $0x2, %rbx + leaq 0x29(%rax), %r12 + leaq (%rax,%rax,8), %r13 + leaq 0x35(%rax), %r14 + leaq (%rax,%rax,4), %r15 + leaq 0x3d(%rax), %r10 + movq %r10, 0x108(%rsp) + imulq $0xf, %rax, %r10 + movq %r10, 0x100(%rsp) + addq $0x3, %rax + leaq -0x18(%rbp), %r10 + movq %r10, 0xf8(%rsp) + leaq -0x190(%rbp), %r10 + movq %r10, 0xf0(%rsp) + movq 0xf8(%rsp), %r11 + movl $0x8, (%r11) + movl $0x30, 0x4(%r11) + leaq 0x10(%rbp), %r10 + movq %r10, 0x8(%r11) + leaq -0x190(%rbp), %r10 + movq %r10, 0x10(%r11) + leaq -0x30(%rbp), %r10 + movq %r10, 0xf8(%rsp) + leaq -0x18(%rbp), %r10 + movq %r10, 0xf0(%rsp) + movq 0xf0(%rsp), %r11 + movq 0xf8(%rsp), %r10 + pushq %rax + movq (%r11), %rax + movq %rax, (%r10) + movq 0x8(%r11), %rax + movq %rax, 0x8(%r10) + movq 0x10(%r11), %rax + movq %rax, 0x10(%r10) + popq %rax + leaq -0x30(%rbp), %r10 + movq %r10, 0xf8(%rsp) + movq 0xf8(%rsp), %r11 + movl (%r11), %r10d + cmpq $0x30, %r10 + jae + addq 0x10(%r11), %r10 + addl $0x8, (%r11) + jmp + movq 0x8(%r11), %r10 + addq $0x8, 0x8(%r11) + movq %r10, 0xf8(%rsp) + movq 0xf8(%rsp), %r10 + movq (%r10), %r10 + movq %r10, 0xf8(%rsp) + leaq -0x30(%rbp), %r10 + movq %r10, 0xf0(%rsp) + movq 0xf0(%rsp), %r11 + movl (%r11), %r10d + cmpq $0x30, %r10 + jae + addq 0x10(%r11), %r10 + addl $0x8, (%r11) + jmp + movq 0x8(%r11), %r10 + addq $0x8, 0x8(%r11) + movq %r10, 0xf0(%rsp) + movq 0xf0(%rsp), %r10 + movq (%r10), %r10 + movq %r10, 0xf0(%rsp) + leaq -0x30(%rbp), %r10 + movq %r10, 0xe8(%rsp) + leaq -0x18(%rbp), %r10 + movq %r10, 0xe8(%rsp) + addq %rdx, %rcx + addq %rsi, %rcx + addq %rdi, %rcx + addq %r8, %rcx + addq %r9, %rcx + addq %rbx, %rcx + addq %r12, %rcx + addq %r13, %rcx + addq %r14, %rcx + addq %r15, %rcx + addq 0x108(%rsp), %rcx + addq 0x100(%rsp), %rcx + addq %rcx, %rax + addq 0xf8(%rsp), %rax + addq 0xf0(%rsp), %rax + movq (%rsp), %rbx + movq 0x8(%rsp), %r12 + movq 0x10(%rsp), %r13 + movq 0x18(%rsp), %r14 + movq 0x20(%rsp), %r15 + addq $0x1c0, %rsp # imm = 0x1C0 + popq %rbp + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x30, %rsp + movl $0x2, %edi + movl $0xa, %esi + movl $0x14, %edx + movb $0x0, %al + callq + movl $0x160, %ecx # imm = 0x160 + cmpq %rcx, %rax + jne + xorq %rcx, %rcx + jmp + movl $0x1, %ecx + movq %rcx, %rax + addq $0x30, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/variable_shift_rcx_loop.aarch64.asm b/tests/snapshots/asm/variable_shift_rcx_loop.aarch64.asm new file mode 100644 index 000000000..0bab3eb2d --- /dev/null +++ b/tests/snapshots/asm/variable_shift_rcx_loop.aarch64.asm @@ -0,0 +1,48 @@ + +variable_shift_rcx_loop.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + mov x5, #0x0 // =0 + mov x4, x5 + cmp x4, x0 + b.ge + b + lsl x6, x1, x2 + add x5, x5, x6 + b + add x4, x5, x3 + b + mov x0, x3 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x30 + mov x0, #0x64 // =100 + mov x1, #0x2 // =2 + mov x2, #0x3 // =3 + mov x3, #0x1 // =1 + bl + cmp x0, #0x1 + b.ne + mov x1, #0x0 // =0 + b + mov x1, #0x1 // =1 + mov x0, x1 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/variable_shift_rcx_loop.x64.asm b/tests/snapshots/asm/variable_shift_rcx_loop.x64.asm new file mode 100644 index 000000000..bd95a6d08 --- /dev/null +++ b/tests/snapshots/asm/variable_shift_rcx_loop.x64.asm @@ -0,0 +1,55 @@ + +variable_shift_rcx_loop.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + subq $0x10, %rsp + movq %rcx, %rax + xorq %r8, %r8 + movq %r8, %rcx + cmpq %rdi, %rcx + jge + jmp + movq %rsi, %r9 + pushq %rcx + movq %rdx, %rcx + shlq %cl, %r9 + popq %rcx + addq %r9, %r8 + jmp + leaq (%r8,%rax), %rcx + jmp + addq $0x10, %rsp + popq %rbp + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x30, %rsp + movl $0x64, %edi + movl $0x2, %esi + movl $0x3, %edx + movl $0x1, %ecx + callq + cmpq $0x1, %rax + jne + xorq %rcx, %rcx + jmp + movl $0x1, %ecx + movq %rcx, %rax + addq $0x30, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/variadic_agg_return_classes.aarch64.asm b/tests/snapshots/asm/variadic_agg_return_classes.aarch64.asm new file mode 100644 index 000000000..576e0adb2 --- /dev/null +++ b/tests/snapshots/asm/variadic_agg_return_classes.aarch64.asm @@ -0,0 +1,167 @@ + +variadic_agg_return_classes.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + sub sp, sp, #0xc0 + str x0, [sp] + str x1, [sp, #0x8] + str x2, [sp, #0x10] + str x3, [sp, #0x18] + str x4, [sp, #0x20] + str x5, [sp, #0x28] + str x6, [sp, #0x30] + str x7, [sp, #0x38] + str d0, [sp, #0x40] + str d1, [sp, #0x50] + str d2, [sp, #0x60] + str d3, [sp, #0x70] + str d4, [sp, #0x80] + str d5, [sp, #0x90] + str d6, [sp, #0xa0] + str d7, [sp, #0xb0] + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + sub x0, x29, #0x10 + mov x1, #0x3ff8000000000000 // =4609434218613702656 + ldursw x2, [x29, #0x10] + scvtf d0, x2 + fmov d16, x1 + fmul d0, d16, d0 + str d0, [x0] + sub x0, x29, #0x10 + mov x1, #0x4002000000000000 // =4612248968380809216 + fmov d16, x1 + str d16, [x0, #0x8] + sub x0, x29, #0x10 + mov x16, x0 + ldr d0, [x16] + ldr d1, [x16, #0x8] + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0xc0 + ret + +: + sub sp, sp, #0xc0 + str x0, [sp] + str x1, [sp, #0x8] + str x2, [sp, #0x10] + str x3, [sp, #0x18] + str x4, [sp, #0x20] + str x5, [sp, #0x28] + str x6, [sp, #0x30] + str x7, [sp, #0x38] + str d0, [sp, #0x40] + str d1, [sp, #0x50] + str d2, [sp, #0x60] + str d3, [sp, #0x70] + str d4, [sp, #0x80] + str d5, [sp, #0x90] + str d6, [sp, #0xa0] + str d7, [sp, #0xb0] + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + sub x0, x29, #0x10 + mov x1, #0x3fe0000000000000 // =4602678819172646912 + fmov d16, x1 + str d16, [x0] + sub x0, x29, #0x10 + ldursw x1, [x29, #0x10] + add x1, x1, #0x29 + sxtw x1, w1 + str x1, [x0, #0x8] + sub x0, x29, #0x10 + mov x16, x0 + ldr x1, [x16, #0x8] + ldr x0, [x16] + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0xc0 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x90 + str x20, [sp] + mov x0, #0x2 // =2 + bl + sub x16, x29, #0x58 + str d0, [x16] + str d1, [x16, #0x8] + sub x0, x29, #0x58 + sub x1, x29, #0x10 + str x10, [sp, #-0x10]! + ldr x10, [x0] + str x10, [x1] + ldr x10, [x0, #0x8] + str x10, [x1, #0x8] + ldr x10, [sp], #0x10 + mov x0, x1 + sub x0, x29, #0x10 + ldr d0, [x0] + mov x0, #0x4008000000000000 // =4613937818241073152 + fmov d17, x0 + fcmp d0, d17 + cset x20, ne + cbnz x20, + sub x0, x29, #0x10 + ldr d0, [x0, #0x8] + mov x0, #0x4002000000000000 // =4612248968380809216 + fmov d17, x0 + fcmp d0, d17 + cset x20, ne + cbz x20, + mov x0, #0x1 // =1 + ldr x20, [sp] + add sp, sp, #0x90 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x1 // =1 + bl + sub x16, x29, #0x70 + str x0, [x16] + str x1, [x16, #0x8] + sub x0, x29, #0x70 + sub x1, x29, #0x30 + str x10, [sp, #-0x10]! + ldr x10, [x0] + str x10, [x1] + ldr x10, [x0, #0x8] + str x10, [x1, #0x8] + ldr x10, [sp], #0x10 + mov x0, x1 + sub x0, x29, #0x30 + ldr d0, [x0] + mov x0, #0x3fe0000000000000 // =4602678819172646912 + fmov d17, x0 + fcmp d0, d17 + cset x1, ne + cbnz x1, + sub x0, x29, #0x30 + ldr x0, [x0, #0x8] + cmp x0, #0x2a + cset x1, ne + cbz x1, + mov x0, #0x2 // =2 + ldr x20, [sp] + add sp, sp, #0x90 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x20, [sp] + add sp, sp, #0x90 + ldp x29, x30, [sp], #0x10 + ret + b + b diff --git a/tests/snapshots/asm/variadic_agg_return_classes.x64.asm b/tests/snapshots/asm/variadic_agg_return_classes.x64.asm new file mode 100644 index 000000000..29d7a6db8 --- /dev/null +++ b/tests/snapshots/asm/variadic_agg_return_classes.x64.asm @@ -0,0 +1,182 @@ + +variadic_agg_return_classes.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + subq $0xc0, %rsp + movq %rdi, -0xc0(%rbp) + movq %rsi, -0xb8(%rbp) + movq %rdx, -0xb0(%rbp) + movq %rcx, -0xa8(%rbp) + movq %r8, -0xa0(%rbp) + movq %r9, -0x98(%rbp) + testb %al, %al + je + movsd %xmm0, -0x90(%rbp,%riz) + movsd %xmm1, -0x80(%rbp,%riz) + movsd %xmm2, -0x70(%rbp,%riz) + movsd %xmm3, -0x60(%rbp,%riz) + movsd %xmm4, -0x50(%rbp,%riz) + movsd %xmm5, -0x40(%rbp,%riz) + movsd %xmm6, -0x30(%rbp,%riz) + movsd %xmm7, -0x20(%rbp,%riz) + leaq -0x10(%rbp), %rax + movabsq $0x3ff8000000000000, %rcx # imm = 0x3FF8000000000000 + movslq -0xc0(%rbp), %rdx + cvtsi2sd %rdx, %xmm0 + movapd %xmm0, %xmm15 + movq %rcx, %xmm0 + mulsd %xmm15, %xmm0 + movsd %xmm0, (%rax,%riz) + leaq -0x10(%rbp), %rax + movabsq $0x4002000000000000, %rcx # imm = 0x4002000000000000 + movq %rcx, %xmm14 + movsd %xmm14, 0x8(%rax,%riz) + leaq -0x10(%rbp), %rax + movq %rax, %rcx + movsd (%rcx,%riz), %xmm0 + movsd 0x8(%rcx,%riz), %xmm1 + addq $0xc0, %rsp + popq %rbp + retq + +: + pushq %rbp + movq %rsp, %rbp + subq $0xc0, %rsp + movq %rdi, -0xc0(%rbp) + movq %rsi, -0xb8(%rbp) + movq %rdx, -0xb0(%rbp) + movq %rcx, -0xa8(%rbp) + movq %r8, -0xa0(%rbp) + movq %r9, -0x98(%rbp) + testb %al, %al + je + movsd %xmm0, -0x90(%rbp,%riz) + movsd %xmm1, -0x80(%rbp,%riz) + movsd %xmm2, -0x70(%rbp,%riz) + movsd %xmm3, -0x60(%rbp,%riz) + movsd %xmm4, -0x50(%rbp,%riz) + movsd %xmm5, -0x40(%rbp,%riz) + movsd %xmm6, -0x30(%rbp,%riz) + movsd %xmm7, -0x20(%rbp,%riz) + leaq -0x10(%rbp), %rax + movabsq $0x3fe0000000000000, %rcx # imm = 0x3FE0000000000000 + movq %rcx, %xmm14 + movsd %xmm14, (%rax,%riz) + leaq -0x10(%rbp), %rax + movslq -0xc0(%rbp), %rcx + addq $0x29, %rcx + movslq %ecx, %rcx + movq %rcx, 0x8(%rax) + leaq -0x10(%rbp), %rax + movq %rax, %rcx + movsd (%rcx,%riz), %xmm0 + movq 0x8(%rcx), %rax + addq $0xc0, %rsp + popq %rbp + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x90, %rsp + movq %rbx, (%rsp) + movl $0x2, %edi + movb $0x0, %al + callq + movsd %xmm0, -0x58(%rbp,%riz) + movsd %xmm1, -0x50(%rbp,%riz) + leaq -0x58(%rbp), %rax + leaq -0x10(%rbp), %rcx + pushq %rdx + movq (%rax), %rdx + movq %rdx, (%rcx) + movq 0x8(%rax), %rdx + movq %rdx, 0x8(%rcx) + popq %rdx + movq %rcx, %rax + leaq -0x10(%rbp), %rax + movsd (%rax,%riz), %xmm0 + movabsq $0x4008000000000000, %rax # imm = 0x4008000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %bl + movzbq %bl, %rbx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rbx + testq %rbx, %rbx + jne + leaq -0x10(%rbp), %rax + movsd 0x8(%rax,%riz), %xmm0 + movabsq $0x4002000000000000, %rax # imm = 0x4002000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %bl + movzbq %bl, %rbx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rbx + testq %rbx, %rbx + je + movl $0x1, %eax + movq (%rsp), %rbx + addq $0x90, %rsp + popq %rbp + retq + movl $0x1, %edi + movb $0x0, %al + callq + movsd %xmm0, -0x70(%rbp,%riz) + movq %rax, -0x68(%rbp) + leaq -0x70(%rbp), %rax + leaq -0x30(%rbp), %rcx + pushq %rdx + movq (%rax), %rdx + movq %rdx, (%rcx) + movq 0x8(%rax), %rdx + movq %rdx, 0x8(%rcx) + popq %rdx + movq %rcx, %rax + leaq -0x30(%rbp), %rax + movsd (%rax,%riz), %xmm0 + movabsq $0x3fe0000000000000, %rax # imm = 0x3FE0000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %cl + movzbq %cl, %rcx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rcx + testq %rcx, %rcx + jne + leaq -0x30(%rbp), %rax + movq 0x8(%rax), %rax + cmpq $0x2a, %rax + setne %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movl $0x2, %eax + movq (%rsp), %rbx + addq $0x90, %rsp + popq %rbp + retq + xorq %rax, %rax + movq (%rsp), %rbx + addq $0x90, %rsp + popq %rbp + retq + jmp + jmp diff --git a/tests/snapshots/asm/variadic_cast_fnptr_dispatch.aarch64.asm b/tests/snapshots/asm/variadic_cast_fnptr_dispatch.aarch64.asm new file mode 100644 index 000000000..e2f561d40 --- /dev/null +++ b/tests/snapshots/asm/variadic_cast_fnptr_dispatch.aarch64.asm @@ -0,0 +1,66 @@ + +variadic_cast_fnptr_dispatch.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x2b0 // =688 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x80 + str x19, [sp] + sub x0, x29, #0x20 + mov x1, #0x0 // =0 + strb w1, [x0] + adrp x0, + add x0, x0, + ldr x0, [x0] + sub x1, x29, #0x20 + mov x2, #0x20 // =32 + adrp x3, + add x3, x3, + mov x4, #0x4 // =4 + adrp x5, + add x5, x5, + mov x6, #0x9 // =9 + mov x9, x0 + mov x0, x1 + mov x1, x2 + mov x2, x3 + mov x3, x4 + mov x4, x5 + mov x5, x6 + blr x9 + sxtw x0, w0 + cmp x0, #0x7 + b.eq + mov x0, #0x1 // =1 + ldr x19, [sp] + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + sub x0, x29, #0x20 + adrp x1, + add x1, x1, + bl + sxtw x0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x2 // =2 + ldr x19, [sp] + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x19, [sp] + add sp, sp, #0x80 + ldp x29, x30, [sp], #0x10 + ret + +<__c5_sys_snprintf>: + b diff --git a/tests/snapshots/asm/variadic_cast_fnptr_dispatch.x64.asm b/tests/snapshots/asm/variadic_cast_fnptr_dispatch.x64.asm new file mode 100644 index 000000000..a442df15c --- /dev/null +++ b/tests/snapshots/asm/variadic_cast_fnptr_dispatch.x64.asm @@ -0,0 +1,59 @@ + +variadic_cast_fnptr_dispatch.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x70, %rsp + leaq -0x20(%rbp), %rax + xorq %rcx, %rcx + movb %cl, (%rax) + leaq , %rax + movq (%rax), %rax + leaq -0x20(%rbp), %rdi + movl $0x20, %esi + leaq , %rdx + movl $0x4, %ecx + leaq , %r8 + movl $0x9, %r9d + subq $0x10, %rsp + movq %rax, (%rsp) + movq (%rsp), %r10 + movb $0x0, %al + callq *%r10 + addq $0x10, %rsp + movslq %eax, %rax + cmpq $0x7, %rax + je + movl $0x1, %eax + addq $0x70, %rsp + popq %rbp + retq + leaq -0x20(%rbp), %rdi + leaq , %rsi + xorl %eax, %eax + callq + movslq %eax, %rax + testq %rax, %rax + je + movl $0x2, %eax + addq $0x70, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x70, %rsp + popq %rbp + retq + +<__c5_sys_snprintf>: + jmp + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/variadic_fn_ptr_init.aarch64.asm b/tests/snapshots/asm/variadic_fn_ptr_init.aarch64.asm index a168bb4d7..1e258a00a 100644 --- a/tests/snapshots/asm/variadic_fn_ptr_init.aarch64.asm +++ b/tests/snapshots/asm/variadic_fn_ptr_init.aarch64.asm @@ -70,6 +70,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/variadic_fnptr_proto_erased.aarch64.asm b/tests/snapshots/asm/variadic_fnptr_proto_erased.aarch64.asm index 7bb403366..173e31cd7 100644 --- a/tests/snapshots/asm/variadic_fnptr_proto_erased.aarch64.asm +++ b/tests/snapshots/asm/variadic_fnptr_proto_erased.aarch64.asm @@ -70,6 +70,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/variadic_hfa_struct_arg.aarch64.asm b/tests/snapshots/asm/variadic_hfa_struct_arg.aarch64.asm new file mode 100644 index 000000000..aa3007d4b --- /dev/null +++ b/tests/snapshots/asm/variadic_hfa_struct_arg.aarch64.asm @@ -0,0 +1,120 @@ + +variadic_hfa_struct_arg.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + sub sp, sp, #0xc0 + str x0, [sp] + str x1, [sp, #0x8] + str x2, [sp, #0x10] + str x3, [sp, #0x18] + str x4, [sp, #0x20] + str x5, [sp, #0x28] + str x6, [sp, #0x30] + str x7, [sp, #0x38] + str d0, [sp, #0x40] + str d1, [sp, #0x50] + str d2, [sp, #0x60] + str d3, [sp, #0x70] + str d4, [sp, #0x80] + str d5, [sp, #0x90] + str d6, [sp, #0xa0] + str d7, [sp, #0xb0] + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x40 + str x19, [sp] + sub x0, x29, #0x20 + add x1, x29, #0x10 + mov x16, x0 + add x17, x29, #0xd0 + str x17, [x16] + add x17, x29, #0x50 + str x17, [x16, #0x8] + add x17, x29, #0xd0 + str x17, [x16, #0x10] + mov x17, #0xffc8 // =65480 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + str w17, [x16, #0x18] + mov x17, #0xff80 // =65408 + movk x17, #0xffff, lsl #16 + movk x17, #0xffff, lsl #32 + movk x17, #0xffff, lsl #48 + str w17, [x16, #0x1c] + sub x0, x29, #0x20 + mov x17, x0 + str x9, [sp, #-0x10]! + ldrsw x16, [x17, #0x18] + cmp x16, #0x0 + b.ge + ldr x9, [x17, #0x8] + add x9, x9, x16 + add x16, x16, #0x10 + str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt + mov x16, x9 + b + ldr x16, [x17] + add x9, x16, #0x10 + str x9, [x17] + ldr x9, [sp], #0x10 + mov x0, x16 + sub x1, x29, #0x30 + str x10, [sp, #-0x10]! + ldr x10, [x0] + str x10, [x1] + ldr x10, [x0, #0x8] + str x10, [x1, #0x8] + ldr x10, [sp], #0x10 + mov x0, x1 + sub x0, x29, #0x20 + sub x0, x29, #0x30 + ldr d0, [x0] + sub x0, x29, #0x30 + ldr d1, [x0, #0x8] + fadd d0, d0, d1 + ldr x19, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0xc0 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x30 + sub x0, x29, #0x10 + mov x1, #0x3ff8000000000000 // =4609434218613702656 + fmov d16, x1 + str d16, [x0] + sub x0, x29, #0x10 + mov x1, #0x4002000000000000 // =4612248968380809216 + fmov d16, x1 + str d16, [x0, #0x8] + mov x0, #0x1 // =1 + sub x1, x29, #0x10 + ldr d0, [x1] + ldr d1, [x1, #0x8] + bl + mov x0, #0x400e000000000000 // =4615626668101337088 + fmov d17, x0 + fcmp d0, d17 + cset x0, eq + cbz x0, + mov x1, #0x0 // =0 + b + mov x1, #0x1 // =1 + mov x0, x1 + add sp, sp, #0x30 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/variadic_hfa_struct_arg.x64.asm b/tests/snapshots/asm/variadic_hfa_struct_arg.x64.asm new file mode 100644 index 000000000..c4ec0839c --- /dev/null +++ b/tests/snapshots/asm/variadic_hfa_struct_arg.x64.asm @@ -0,0 +1,106 @@ + +variadic_hfa_struct_arg.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + subq $0xe0, %rsp + movq %rdi, -0xe0(%rbp) + movq %rsi, -0xd8(%rbp) + movq %rdx, -0xd0(%rbp) + movq %rcx, -0xc8(%rbp) + movq %r8, -0xc0(%rbp) + movq %r9, -0xb8(%rbp) + testb %al, %al + je + movsd %xmm0, -0xb0(%rbp,%riz) + movsd %xmm1, -0xa0(%rbp,%riz) + movsd %xmm2, -0x90(%rbp,%riz) + movsd %xmm3, -0x80(%rbp,%riz) + movsd %xmm4, -0x70(%rbp,%riz) + movsd %xmm5, -0x60(%rbp,%riz) + movsd %xmm6, -0x50(%rbp,%riz) + movsd %xmm7, -0x40(%rbp,%riz) + leaq -0x18(%rbp), %rax + leaq -0xe0(%rbp), %rcx + movl $0x8, (%rax) + movl $0x30, 0x4(%rax) + leaq 0x10(%rbp), %r10 + movq %r10, 0x8(%rax) + leaq -0xe0(%rbp), %r10 + movq %r10, 0x10(%rax) + leaq -0x18(%rbp), %rax + movq %rax, %r11 + movl (%r11), %r10d + cmpq $0x28, %r10 + jae + addq 0x10(%r11), %r10 + addl $0x10, (%r11) + jmp + movq 0x8(%r11), %r10 + addq $0x10, 0x8(%r11) + movq %r10, %rax + leaq -0x28(%rbp), %rcx + pushq %rdx + movq (%rax), %rdx + movq %rdx, (%rcx) + movq 0x8(%rax), %rdx + movq %rdx, 0x8(%rcx) + popq %rdx + movq %rcx, %rax + leaq -0x18(%rbp), %rax + leaq -0x28(%rbp), %rax + movsd (%rax,%riz), %xmm0 + leaq -0x28(%rbp), %rax + movsd 0x8(%rax,%riz), %xmm1 + addsd %xmm1, %xmm0 + addq $0xe0, %rsp + popq %rbp + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x30, %rsp + leaq -0x10(%rbp), %rax + movabsq $0x3ff8000000000000, %rcx # imm = 0x3FF8000000000000 + movq %rcx, %xmm14 + movsd %xmm14, (%rax,%riz) + leaq -0x10(%rbp), %rax + movabsq $0x4002000000000000, %rcx # imm = 0x4002000000000000 + movq %rcx, %xmm14 + movsd %xmm14, 0x8(%rax,%riz) + movl $0x1, %edi + leaq -0x10(%rbp), %rsi + movq %rsi, %r10 + movsd (%r10,%riz), %xmm0 + movsd 0x8(%r10,%riz), %xmm1 + movb $0x0, %al + callq + movabsq $0x400e000000000000, %rax # imm = 0x400E000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + sete %al + movzbq %al, %rax + setnp %r10b + movzbq %r10b, %r10 + andq %r10, %rax + testq %rax, %rax + je + xorq %rcx, %rcx + jmp + movl $0x1, %ecx + movq %rcx, %rax + addq $0x30, %rsp + popq %rbp + retq + addb %al, (%rax) diff --git a/tests/snapshots/asm/variadic_libc_fnptr_static_init.aarch64.asm b/tests/snapshots/asm/variadic_libc_fnptr_static_init.aarch64.asm new file mode 100644 index 000000000..737edf560 --- /dev/null +++ b/tests/snapshots/asm/variadic_libc_fnptr_static_init.aarch64.asm @@ -0,0 +1,58 @@ + +variadic_libc_fnptr_static_init.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x2b0 // =688 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0xa0 + str x19, [sp] + sub x0, x29, #0x40 + mov x1, #0x0 // =0 + strb w1, [x0] + adrp x0, + add x0, x0, + ldr x0, [x0, #0x8] + sub x1, x29, #0x40 + mov x2, #0x40 // =64 + adrp x3, + add x3, x3, + mov x4, #0x2a // =42 + adrp x5, + add x5, x5, + mov x6, #0x63 // =99 + mov x9, x0 + mov x0, x1 + mov x1, x2 + mov x2, x3 + mov x3, x4 + mov x4, x5 + mov x5, x6 + blr x9 + sub x0, x29, #0x40 + adrp x1, + add x1, x1, + bl + sxtw x0, w0 + cmp x0, #0x0 + b.eq + mov x0, #0x1 // =1 + ldr x19, [sp] + add sp, sp, #0xa0 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x19, [sp] + add sp, sp, #0xa0 + ldp x29, x30, [sp], #0x10 + ret + +<__c5_sys_snprintf>: + b diff --git a/tests/snapshots/asm/variadic_libc_fnptr_static_init.x64.asm b/tests/snapshots/asm/variadic_libc_fnptr_static_init.x64.asm new file mode 100644 index 000000000..276d0c011 --- /dev/null +++ b/tests/snapshots/asm/variadic_libc_fnptr_static_init.x64.asm @@ -0,0 +1,52 @@ + +variadic_libc_fnptr_static_init.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x90, %rsp + leaq -0x40(%rbp), %rax + xorq %rcx, %rcx + movb %cl, (%rax) + leaq , %rax + movq 0x8(%rax), %rax + leaq -0x40(%rbp), %rdi + movl $0x40, %esi + leaq , %rdx + movl $0x2a, %ecx + leaq , %r8 + movl $0x63, %r9d + subq $0x10, %rsp + movq %rax, (%rsp) + movq (%rsp), %r10 + movb $0x0, %al + callq *%r10 + addq $0x10, %rsp + leaq -0x40(%rbp), %rdi + leaq , %rsi + xorl %eax, %eax + callq + movslq %eax, %rax + testq %rax, %rax + je + movl $0x1, %eax + addq $0x90, %rsp + popq %rbp + retq + xorq %rax, %rax + addq $0x90, %rsp + popq %rbp + retq + +<__c5_sys_snprintf>: + jmp + addb %al, (%rax) diff --git a/tests/snapshots/asm/variadic_optimizer_survives.aarch64.asm b/tests/snapshots/asm/variadic_optimizer_survives.aarch64.asm index 7631c5ec5..e92d515c9 100644 --- a/tests/snapshots/asm/variadic_optimizer_survives.aarch64.asm +++ b/tests/snapshots/asm/variadic_optimizer_survives.aarch64.asm @@ -60,6 +60,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -78,6 +80,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/variadic_struct_arg.aarch64.asm b/tests/snapshots/asm/variadic_struct_arg.aarch64.asm index 71904e3d7..20d726a85 100644 --- a/tests/snapshots/asm/variadic_struct_arg.aarch64.asm +++ b/tests/snapshots/asm/variadic_struct_arg.aarch64.asm @@ -70,6 +70,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/variadic_struct_arg_16b.aarch64.asm b/tests/snapshots/asm/variadic_struct_arg_16b.aarch64.asm index 2263a2674..f12351cae 100644 --- a/tests/snapshots/asm/variadic_struct_arg_16b.aarch64.asm +++ b/tests/snapshots/asm/variadic_struct_arg_16b.aarch64.asm @@ -70,6 +70,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x10 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/variadic_struct_by_value_arg.aarch64.asm b/tests/snapshots/asm/variadic_struct_by_value_arg.aarch64.asm index 9fbc6eead..5f517247b 100644 --- a/tests/snapshots/asm/variadic_struct_by_value_arg.aarch64.asm +++ b/tests/snapshots/asm/variadic_struct_by_value_arg.aarch64.asm @@ -68,6 +68,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/variadic_struct_return.aarch64.asm b/tests/snapshots/asm/variadic_struct_return.aarch64.asm index ddf8c7c2e..149abb4d7 100644 --- a/tests/snapshots/asm/variadic_struct_return.aarch64.asm +++ b/tests/snapshots/asm/variadic_struct_return.aarch64.asm @@ -143,6 +143,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/variadic_union_struct_return.aarch64.asm b/tests/snapshots/asm/variadic_union_struct_return.aarch64.asm index 90b9acab4..e7c98fdca 100644 --- a/tests/snapshots/asm/variadic_union_struct_return.aarch64.asm +++ b/tests/snapshots/asm/variadic_union_struct_return.aarch64.asm @@ -60,6 +60,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -78,6 +80,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/variadic_via_fnptr.aarch64.asm b/tests/snapshots/asm/variadic_via_fnptr.aarch64.asm index 00323c54a..b85a9317e 100644 --- a/tests/snapshots/asm/variadic_via_fnptr.aarch64.asm +++ b/tests/snapshots/asm/variadic_via_fnptr.aarch64.asm @@ -60,6 +60,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -78,6 +80,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] @@ -96,6 +100,8 @@ Disassembly of section .text: add x9, x9, x16 add x16, x16, #0x8 str w16, [x17, #0x18] + cmp x16, #0x0 + b.gt mov x16, x9 b ldr x16, [x17] diff --git a/tests/snapshots/asm/vla_basic_sum.aarch64.asm b/tests/snapshots/asm/vla_basic_sum.aarch64.asm new file mode 100644 index 000000000..03acfe6fb --- /dev/null +++ b/tests/snapshots/asm/vla_basic_sum.aarch64.asm @@ -0,0 +1,98 @@ + +vla_basic_sum.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + str x0, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x2, lsl #12 // =0x2000 + sub sp, sp, #0x40 + str x19, [sp] + sub x16, x29, #0x30 + str x16, [x16] + stur w0, [x29, #0x10] + ldursw x0, [x29, #0x10] + lsl x0, x0, #2 + stur x0, [x29, #-0x10] + add x17, x0, #0xf + and x17, x17, #0xfffffffffffffff0 + sub x16, x29, #0x30 + ldr x0, [x16] + sub x0, x0, x17 + sub x17, x16, #0x2, lsl #12 // =0x2000 + cmp x0, x17 + b.hs + brk #0x1 + str x0, [x16] + stur x0, [x29, #-0x8] + mov x0, #0x0 // =0 + stur w0, [x29, #-0x18] + ldursw x0, [x29, #-0x18] + ldursw x1, [x29, #0x10] + cmp x0, x1 + b.ge + b + ldursw x0, [x29, #-0x18] + add x0, x0, #0x1 + stur w0, [x29, #-0x18] + b + ldur x0, [x29, #-0x8] + ldursw x1, [x29, #-0x18] + lsl x2, x1, #1 + str w2, [x0, x1, lsl #2] + b + mov x0, #0x0 // =0 + stur w0, [x29, #-0x20] + stur w0, [x29, #-0x28] + ldursw x0, [x29, #-0x28] + ldursw x1, [x29, #0x10] + cmp x0, x1 + b.ge + b + ldursw x0, [x29, #-0x28] + add x0, x0, #0x1 + stur w0, [x29, #-0x28] + b + ldursw x0, [x29, #-0x20] + ldur x1, [x29, #-0x8] + ldursw x2, [x29, #-0x28] + ldrsw x1, [x1, x2, lsl #2] + add x0, x0, x1 + stur w0, [x29, #-0x20] + b + ldursw x0, [x29, #-0x20] + ldr x19, [sp] + add sp, sp, #0x2, lsl #12 // =0x2000 + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x10 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + mov x0, #0x5 // =5 + bl + cmp x0, #0x14 + b.eq + mov x0, #0x1 // =1 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x1 // =1 + bl + cmp x0, #0x0 + b.eq + mov x0, #0x2 // =2 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/vla_basic_sum.x64.asm b/tests/snapshots/asm/vla_basic_sum.x64.asm new file mode 100644 index 000000000..50e084120 --- /dev/null +++ b/tests/snapshots/asm/vla_basic_sum.x64.asm @@ -0,0 +1,103 @@ + +vla_basic_sum.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + popq %r10 + subq $0x10, %rsp + movq %rdi, (%rsp) + pushq %r10 + pushq %rbp + movq %rsp, %rbp + subq $0x2030, %rsp # imm = 0x2030 + leaq -0x30(%rbp), %r10 + movq %r10, (%r10) + movl %edi, 0x10(%rbp) + movslq 0x10(%rbp), %rax + shlq $0x2, %rax + movq %rax, -0x10(%rbp) + movq %rax, %r10 + addq $0xf, %r10 + andq $-0x10, %r10 + leaq -0x30(%rbp), %r11 + movq (%r11), %rax + subq %r10, %rax + leaq -0x2000(%r11), %r10 + cmpq %r10, %rax + jae + ud2 + movq %rax, (%r11) + movq %rax, -0x8(%rbp) + xorq %rax, %rax + movl %eax, -0x18(%rbp) + movslq -0x18(%rbp), %rax + movslq 0x10(%rbp), %rcx + cmpq %rcx, %rax + jge + jmp + movslq -0x18(%rbp), %rax + incq %rax + movl %eax, -0x18(%rbp) + jmp + movq -0x8(%rbp), %rax + movslq -0x18(%rbp), %rcx + movq %rcx, %rdx + shlq $0x1, %rdx + movl %edx, (%rax,%rcx,4) + jmp + xorq %rax, %rax + movl %eax, -0x20(%rbp) + movl %eax, -0x28(%rbp) + movslq -0x28(%rbp), %rax + movslq 0x10(%rbp), %rcx + cmpq %rcx, %rax + jge + jmp + movslq -0x28(%rbp), %rax + incq %rax + movl %eax, -0x28(%rbp) + jmp + movslq -0x20(%rbp), %rax + movq -0x8(%rbp), %rcx + movslq -0x28(%rbp), %rdx + movslq (%rcx,%rdx,4), %rcx + addq %rcx, %rax + movl %eax, -0x20(%rbp) + jmp + movslq -0x20(%rbp), %rax + addq $0x2030, %rsp # imm = 0x2030 + popq %rbp + popq %r11 + addq $0x10, %rsp + pushq %r11 + retq + +
: + pushq %rbp + movq %rsp, %rbp + movl $0x5, %edi + callq + cmpq $0x14, %rax + je + movl $0x1, %eax + popq %rbp + retq + movl $0x1, %edi + callq + testq %rax, %rax + je + movl $0x2, %eax + popq %rbp + retq + xorq %rax, %rax + popq %rbp + retq + addb %al, (%rax) diff --git a/tests/snapshots/asm/vla_param_decay.aarch64.asm b/tests/snapshots/asm/vla_param_decay.aarch64.asm new file mode 100644 index 000000000..ead0a86c0 --- /dev/null +++ b/tests/snapshots/asm/vla_param_decay.aarch64.asm @@ -0,0 +1,69 @@ + +vla_param_decay.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + sxtw x0, w0 + mov x4, #0x0 // =0 + mov x3, x4 + sxtw x5, w4 + cmp x5, x0 + b.ge + b + sxtw x4, w4 + add x4, x4, #0x1 + b + sxtw x5, w4 + lsl x5, x5, #2 + add x6, x1, x5 + ldrsw x6, [x6] + add x5, x2, x5 + ldrsw x5, [x5] + mul x5, x6, x5 + add x3, x3, x5 + b + sxtw x0, w3 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x40 + sub x0, x29, #0x10 + adrp x1, + add x1, x1, + str x10, [sp, #-0x10]! + ldr x10, [x1] + str x10, [x0] + ldr x10, [x1, #0x8] + str x10, [x0, #0x8] + ldr x10, [sp], #0x10 + sub x0, x29, #0x20 + adrp x1, + add x1, x1, + str x10, [sp, #-0x10]! + ldr x10, [x1] + str x10, [x0] + ldr x10, [x1, #0x8] + str x10, [x0, #0x8] + ldr x10, [sp], #0x10 + mov x0, #0x4 // =4 + sub x1, x29, #0x10 + sub x2, x29, #0x20 + bl + cmp x0, #0x46 + b.ne + mov x1, #0x0 // =0 + b + mov x1, #0x1 // =1 + mov x0, x1 + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/vla_param_decay.x64.asm b/tests/snapshots/asm/vla_param_decay.x64.asm new file mode 100644 index 000000000..c722865c1 --- /dev/null +++ b/tests/snapshots/asm/vla_param_decay.x64.asm @@ -0,0 +1,77 @@ + +vla_param_decay.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + pushq %rbp + movq %rsp, %rbp + subq $0x10, %rsp + movq %rbx, (%rsp) + movslq %edi, %rdi + xorq %rcx, %rcx + movq %rcx, %rax + movslq %ecx, %r8 + cmpq %rdi, %r8 + jge + jmp + movslq %ecx, %rcx + incq %rcx + jmp + movslq %ecx, %r8 + shlq $0x2, %r8 + leaq (%rsi,%r8), %r9 + movslq (%r9), %r9 + addq %rdx, %r8 + movslq (%r8), %r8 + imulq %r9, %r8 + addq %r8, %rax + jmp + movslq %eax, %rax + movq (%rsp), %rbx + addq $0x10, %rsp + popq %rbp + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x40, %rsp + leaq -0x10(%rbp), %rax + leaq , %rcx + pushq %rdx + movq (%rcx), %rdx + movq %rdx, (%rax) + movq 0x8(%rcx), %rdx + movq %rdx, 0x8(%rax) + popq %rdx + leaq -0x20(%rbp), %rax + leaq , %rcx + pushq %rdx + movq (%rcx), %rdx + movq %rdx, (%rax) + movq 0x8(%rcx), %rdx + movq %rdx, 0x8(%rax) + popq %rdx + movl $0x4, %edi + leaq -0x10(%rbp), %rsi + leaq -0x20(%rbp), %rdx + callq + cmpq $0x46, %rax + jne + xorq %rcx, %rcx + jmp + movl $0x1, %ecx + movq %rcx, %rax + addq $0x40, %rsp + popq %rbp + retq + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/vla_runtime_sizeof.aarch64.asm b/tests/snapshots/asm/vla_runtime_sizeof.aarch64.asm new file mode 100644 index 000000000..f194719ac --- /dev/null +++ b/tests/snapshots/asm/vla_runtime_sizeof.aarch64.asm @@ -0,0 +1,76 @@ + +vla_runtime_sizeof.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x2, lsl #12 // =0x2000 + sub sp, sp, #0x40 + str x19, [sp] + sub x16, x29, #0x28 + str x16, [x16] + mov x0, #0x7 // =7 + stur w0, [x29, #-0x8] + ldursw x0, [x29, #-0x8] + lsl x0, x0, #3 + stur x0, [x29, #-0x18] + add x17, x0, #0xf + and x17, x17, #0xfffffffffffffff0 + sub x16, x29, #0x28 + ldr x0, [x16] + sub x0, x0, x17 + sub x17, x16, #0x2, lsl #12 // =0x2000 + cmp x0, x17 + b.hs + brk #0x1 + str x0, [x16] + stur x0, [x29, #-0x10] + ldur x0, [x29, #-0x18] + stur x0, [x29, #-0x20] + ldur x0, [x29, #-0x20] + ldursw x1, [x29, #-0x8] + lsl x1, x1, #3 + cmp x0, x1 + b.eq + mov x0, #0x1 // =1 + ldr x19, [sp] + add sp, sp, #0x2, lsl #12 // =0x2000 + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + ldur x0, [x29, #-0x20] + lsr x0, x0, #3 + ldursw x1, [x29, #-0x8] + cmp x0, x1 + b.eq + mov x0, #0x2 // =2 + ldr x19, [sp] + add sp, sp, #0x2, lsl #12 // =0x2000 + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x64 // =100 + stur w0, [x29, #-0x8] + ldur x0, [x29, #-0x18] + cmp x0, #0x38 + b.eq + mov x0, #0x3 // =3 + ldr x19, [sp] + add sp, sp, #0x2, lsl #12 // =0x2000 + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x19, [sp] + add sp, sp, #0x2, lsl #12 // =0x2000 + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/vla_runtime_sizeof.x64.asm b/tests/snapshots/asm/vla_runtime_sizeof.x64.asm new file mode 100644 index 000000000..a3fb62f1b --- /dev/null +++ b/tests/snapshots/asm/vla_runtime_sizeof.x64.asm @@ -0,0 +1,69 @@ + +vla_runtime_sizeof.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x2030, %rsp # imm = 0x2030 + leaq -0x28(%rbp), %r10 + movq %r10, (%r10) + movl $0x7, %eax + movl %eax, -0x8(%rbp) + movslq -0x8(%rbp), %rax + shlq $0x3, %rax + movq %rax, -0x18(%rbp) + movq %rax, %r10 + addq $0xf, %r10 + andq $-0x10, %r10 + leaq -0x28(%rbp), %r11 + movq (%r11), %rax + subq %r10, %rax + leaq -0x2000(%r11), %r10 + cmpq %r10, %rax + jae + ud2 + movq %rax, (%r11) + movq %rax, -0x10(%rbp) + movq -0x18(%rbp), %rax + movq %rax, -0x20(%rbp) + movq -0x20(%rbp), %rax + movslq -0x8(%rbp), %rcx + shlq $0x3, %rcx + cmpq %rcx, %rax + je + movl $0x1, %eax + addq $0x2030, %rsp # imm = 0x2030 + popq %rbp + retq + movq -0x20(%rbp), %rax + shrq $0x3, %rax + movslq -0x8(%rbp), %rcx + cmpq %rcx, %rax + je + movl $0x2, %eax + addq $0x2030, %rsp # imm = 0x2030 + popq %rbp + retq + movl $0x64, %eax + movl %eax, -0x8(%rbp) + movq -0x18(%rbp), %rax + cmpq $0x38, %rax + je + movl $0x3, %eax + addq $0x2030, %rsp # imm = 0x2030 + popq %rbp + retq + xorq %rax, %rax + addq $0x2030, %rsp # imm = 0x2030 + popq %rbp + retq + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/vla_scope_reclaim_loop.aarch64.asm b/tests/snapshots/asm/vla_scope_reclaim_loop.aarch64.asm new file mode 100644 index 000000000..98eb3131f --- /dev/null +++ b/tests/snapshots/asm/vla_scope_reclaim_loop.aarch64.asm @@ -0,0 +1,121 @@ + +vla_scope_reclaim_loop.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x2, lsl #12 // =0x2000 + sub sp, sp, #0x70 + str x19, [sp] + sub x16, x29, #0x50 + str x16, [x16] + mov x0, #0x0 // =0 + stur x0, [x29, #-0x8] + stur w0, [x29, #-0x10] + ldursw x0, [x29, #-0x10] + mov x17, #0x86a0 // =34464 + movk x17, #0x1, lsl #16 + cmp x0, x17 + b.ge + b + ldursw x0, [x29, #-0x10] + add x0, x0, #0x1 + stur w0, [x29, #-0x10] + b + sub x17, x29, #0x50 + ldr x0, [x17] + stur x0, [x29, #-0x38] + mov x0, #0x40 // =64 + stur w0, [x29, #-0x18] + ldursw x0, [x29, #-0x18] + lsl x0, x0, #2 + stur x0, [x29, #-0x28] + add x17, x0, #0xf + and x17, x17, #0xfffffffffffffff0 + sub x16, x29, #0x50 + ldr x0, [x16] + sub x0, x0, x17 + sub x17, x16, #0x2, lsl #12 // =0x2000 + cmp x0, x17 + b.hs + brk #0x1 + str x0, [x16] + stur x0, [x29, #-0x20] + mov x0, #0x0 // =0 + stur w0, [x29, #-0x30] + b + mov x0, #0x0 // =0 + stur x0, [x29, #-0x40] + stur w0, [x29, #-0x48] + b + ldursw x0, [x29, #-0x30] + ldursw x1, [x29, #-0x18] + cmp x0, x1 + b.ge + b + ldursw x0, [x29, #-0x30] + add x0, x0, #0x1 + stur w0, [x29, #-0x30] + b + ldur x0, [x29, #-0x20] + ldursw x1, [x29, #-0x30] + str w1, [x0, x1, lsl #2] + b + ldur x0, [x29, #-0x8] + ldur x1, [x29, #-0x20] + ldursw x2, [x29, #-0x10] + mov x17, #0x3f // =63 + and x2, x2, x17 + ldrsw x1, [x1, x2, lsl #2] + add x0, x0, x1 + stur x0, [x29, #-0x8] + ldur x0, [x29, #-0x38] + sub x17, x29, #0x50 + str x0, [x17] + b + ldursw x0, [x29, #-0x48] + mov x17, #0x86a0 // =34464 + movk x17, #0x1, lsl #16 + cmp x0, x17 + b.ge + b + ldursw x0, [x29, #-0x48] + add x0, x0, #0x1 + stur w0, [x29, #-0x48] + b + ldur x0, [x29, #-0x40] + ldursw x1, [x29, #-0x48] + mov x17, #0x3f // =63 + and x1, x1, x17 + add x0, x0, x1 + stur x0, [x29, #-0x40] + b + ldur x0, [x29, #-0x8] + ldur x1, [x29, #-0x40] + cmp x0, x1 + b.ne + mov x0, #0x0 // =0 + sub x17, x29, #0x2, lsl #12 // =0x2000 + sub x17, x17, #0x58 + str x0, [x17] + b + mov x0, #0x1 // =1 + sub x17, x29, #0x2, lsl #12 // =0x2000 + sub x17, x17, #0x58 + str x0, [x17] + sub x16, x29, #0x2, lsl #12 // =0x2000 + sub x16, x16, #0x58 + ldr x0, [x16] + ldr x19, [sp] + add sp, sp, #0x2, lsl #12 // =0x2000 + add sp, sp, #0x70 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/vla_scope_reclaim_loop.x64.asm b/tests/snapshots/asm/vla_scope_reclaim_loop.x64.asm new file mode 100644 index 000000000..fff4edf10 --- /dev/null +++ b/tests/snapshots/asm/vla_scope_reclaim_loop.x64.asm @@ -0,0 +1,106 @@ + +vla_scope_reclaim_loop.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x2060, %rsp # imm = 0x2060 + leaq -0x50(%rbp), %r10 + movq %r10, (%r10) + xorq %rax, %rax + movq %rax, -0x8(%rbp) + movl %eax, -0x10(%rbp) + movslq -0x10(%rbp), %rax + cmpq $0x186a0, %rax # imm = 0x186A0 + jge + jmp + movslq -0x10(%rbp), %rax + incq %rax + movl %eax, -0x10(%rbp) + jmp + movq -0x50(%rbp), %rax + movq %rax, -0x38(%rbp) + movl $0x40, %eax + movl %eax, -0x18(%rbp) + movslq -0x18(%rbp), %rax + shlq $0x2, %rax + movq %rax, -0x28(%rbp) + movq %rax, %r10 + addq $0xf, %r10 + andq $-0x10, %r10 + leaq -0x50(%rbp), %r11 + movq (%r11), %rax + subq %r10, %rax + leaq -0x2000(%r11), %r10 + cmpq %r10, %rax + jae + ud2 + movq %rax, (%r11) + movq %rax, -0x20(%rbp) + xorq %rax, %rax + movl %eax, -0x30(%rbp) + jmp + xorq %rax, %rax + movq %rax, -0x40(%rbp) + movl %eax, -0x48(%rbp) + jmp + movslq -0x30(%rbp), %rax + movslq -0x18(%rbp), %rcx + cmpq %rcx, %rax + jge + jmp + movslq -0x30(%rbp), %rax + incq %rax + movl %eax, -0x30(%rbp) + jmp + movq -0x20(%rbp), %rax + movslq -0x30(%rbp), %rcx + movl %ecx, (%rax,%rcx,4) + jmp + movq -0x8(%rbp), %rax + movq -0x20(%rbp), %rcx + movslq -0x10(%rbp), %rdx + andq $0x3f, %rdx + movslq (%rcx,%rdx,4), %rcx + addq %rcx, %rax + movq %rax, -0x8(%rbp) + movq -0x38(%rbp), %rax + movq %rax, -0x50(%rbp) + jmp + movslq -0x48(%rbp), %rax + cmpq $0x186a0, %rax # imm = 0x186A0 + jge + jmp + movslq -0x48(%rbp), %rax + incq %rax + movl %eax, -0x48(%rbp) + jmp + movq -0x40(%rbp), %rax + movslq -0x48(%rbp), %rcx + andq $0x3f, %rcx + addq %rcx, %rax + movq %rax, -0x40(%rbp) + jmp + movq -0x8(%rbp), %rax + movq -0x40(%rbp), %rcx + cmpq %rcx, %rax + jne + xorq %rax, %rax + movq %rax, -0x2058(%rbp) + jmp + movl $0x1, %eax + movq %rax, -0x2058(%rbp) + movq -0x2058(%rbp), %rax + addq $0x2060, %rsp # imm = 0x2060 + popq %rbp + retq + addb %al, (%rax) diff --git a/tests/snapshots/asm/vla_size_from_arg.aarch64.asm b/tests/snapshots/asm/vla_size_from_arg.aarch64.asm new file mode 100644 index 000000000..6a8b6c376 --- /dev/null +++ b/tests/snapshots/asm/vla_size_from_arg.aarch64.asm @@ -0,0 +1,101 @@ + +vla_size_from_arg.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + str x0, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x2, lsl #12 // =0x2000 + sub sp, sp, #0x40 + str x19, [sp] + sub x16, x29, #0x30 + str x16, [x16] + stur w0, [x29, #0x10] + ldursw x0, [x29, #0x10] + stur x0, [x29, #-0x10] + add x17, x0, #0xf + and x17, x17, #0xfffffffffffffff0 + sub x16, x29, #0x30 + ldr x0, [x16] + sub x0, x0, x17 + sub x17, x16, #0x2, lsl #12 // =0x2000 + cmp x0, x17 + b.hs + brk #0x1 + str x0, [x16] + stur x0, [x29, #-0x8] + mov x0, #0x0 // =0 + stur w0, [x29, #-0x18] + ldursw x0, [x29, #-0x18] + ldursw x1, [x29, #0x10] + cmp x0, x1 + b.ge + b + ldursw x0, [x29, #-0x18] + add x0, x0, #0x1 + stur w0, [x29, #-0x18] + b + ldur x0, [x29, #-0x8] + ldursw x1, [x29, #-0x18] + add x0, x0, x1 + add x1, x1, #0x1 + mov x17, #0xff // =255 + and x1, x1, x17 + strb w1, [x0] + b + mov x0, #0x0 // =0 + stur w0, [x29, #-0x20] + stur w0, [x29, #-0x28] + ldursw x0, [x29, #-0x28] + ldursw x1, [x29, #0x10] + cmp x0, x1 + b.ge + b + ldursw x0, [x29, #-0x28] + add x0, x0, #0x1 + stur w0, [x29, #-0x28] + b + ldursw x0, [x29, #-0x20] + ldur x1, [x29, #-0x8] + ldursw x2, [x29, #-0x28] + add x1, x1, x2 + ldrb w1, [x1] + add x0, x0, x1 + stur w0, [x29, #-0x20] + b + ldursw x0, [x29, #-0x20] + ldr x19, [sp] + add sp, sp, #0x2, lsl #12 // =0x2000 + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x10 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + mov x0, #0xa // =10 + bl + cmp x0, #0x37 + b.eq + mov x0, #0x1 // =1 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x4 // =4 + bl + cmp x0, #0xa + b.eq + mov x0, #0x2 // =2 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/vla_size_from_arg.x64.asm b/tests/snapshots/asm/vla_size_from_arg.x64.asm new file mode 100644 index 000000000..da81a961e --- /dev/null +++ b/tests/snapshots/asm/vla_size_from_arg.x64.asm @@ -0,0 +1,104 @@ + +vla_size_from_arg.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + popq %r10 + subq $0x10, %rsp + movq %rdi, (%rsp) + pushq %r10 + pushq %rbp + movq %rsp, %rbp + subq $0x2030, %rsp # imm = 0x2030 + leaq -0x30(%rbp), %r10 + movq %r10, (%r10) + movl %edi, 0x10(%rbp) + movslq 0x10(%rbp), %rax + movq %rax, -0x10(%rbp) + movq %rax, %r10 + addq $0xf, %r10 + andq $-0x10, %r10 + leaq -0x30(%rbp), %r11 + movq (%r11), %rax + subq %r10, %rax + leaq -0x2000(%r11), %r10 + cmpq %r10, %rax + jae + ud2 + movq %rax, (%r11) + movq %rax, -0x8(%rbp) + xorq %rax, %rax + movl %eax, -0x18(%rbp) + movslq -0x18(%rbp), %rax + movslq 0x10(%rbp), %rcx + cmpq %rcx, %rax + jge + jmp + movslq -0x18(%rbp), %rax + incq %rax + movl %eax, -0x18(%rbp) + jmp + movq -0x8(%rbp), %rax + movslq -0x18(%rbp), %rcx + addq %rcx, %rax + incq %rcx + movslq %ecx, %rdx + movb %dl, (%rax) + jmp + xorq %rax, %rax + movl %eax, -0x20(%rbp) + movl %eax, -0x28(%rbp) + movslq -0x28(%rbp), %rax + movslq 0x10(%rbp), %rcx + cmpq %rcx, %rax + jge + jmp + movslq -0x28(%rbp), %rax + incq %rax + movl %eax, -0x28(%rbp) + jmp + movslq -0x20(%rbp), %rax + movq -0x8(%rbp), %rcx + movslq -0x28(%rbp), %rdx + addq %rdx, %rcx + movsbq (%rcx), %rcx + addq %rcx, %rax + movl %eax, -0x20(%rbp) + jmp + movslq -0x20(%rbp), %rax + addq $0x2030, %rsp # imm = 0x2030 + popq %rbp + popq %r11 + addq $0x10, %rsp + pushq %r11 + retq + +
: + pushq %rbp + movq %rsp, %rbp + movl $0xa, %edi + callq + cmpq $0x37, %rax + je + movl $0x1, %eax + popq %rbp + retq + movl $0x4, %edi + callq + cmpq $0xa, %rax + je + movl $0x2, %eax + popq %rbp + retq + xorq %rax, %rax + popq %rbp + retq + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/void_function_produces_no_value.aarch64.asm b/tests/snapshots/asm/void_function_produces_no_value.aarch64.asm index dafa68e51..3949fcacb 100644 --- a/tests/snapshots/asm/void_function_produces_no_value.aarch64.asm +++ b/tests/snapshots/asm/void_function_produces_no_value.aarch64.asm @@ -37,9 +37,9 @@ Disassembly of section .text: add x0, x0, mov x1, #0x6 // =6 mov x2, #0x7 // =7 - mov x9, x0 str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] blr x9 @@ -63,8 +63,8 @@ Disassembly of section .text: movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 - mov x9, x20 str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] blr x9 add sp, sp, #0x10 @@ -82,8 +82,8 @@ Disassembly of section .text: ldp x29, x30, [sp], #0x10 ret mov x0, #0x5 // =5 - mov x9, x20 str x0, [sp, #-0x10]! + mov x9, x20 ldr x0, [sp] blr x9 add sp, sp, #0x10 diff --git a/tests/snapshots/asm/volatile_param_classes.aarch64.asm b/tests/snapshots/asm/volatile_param_classes.aarch64.asm new file mode 100644 index 000000000..904d6827a --- /dev/null +++ b/tests/snapshots/asm/volatile_param_classes.aarch64.asm @@ -0,0 +1,126 @@ + +volatile_param_classes.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + fmov x16, d0 + str x16, [sp, #-0x10]! + str x0, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + stur x0, [x29, #0x10] + str d0, [x29, #0x20] + ldur x0, [x29, #0x10] + ldr d0, [x0] + sub x17, x29, #0x8 + str d0, [x17] + ldur x0, [x29, #0x10] + sub x16, x29, #0x8 + ldr d0, [x16] + ldr d1, [x29, #0x20] + fadd d0, d0, d1 + str d0, [x0] + mov x0, #0x0 // =0 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + add sp, sp, #0x20 + ret + +: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x10 + sub x17, x29, #0x8 + str s0, [x17] + sub x16, x29, #0x8 + ldr s0, [x16] + fcvt d0, s0 + mov x0, #0x3fe0000000000000 // =4602678819172646912 + fmov d17, x0 + fmul d0, d0, d17 + add sp, sp, #0x10 + ldp x29, x30, [sp], #0x10 + ret + +: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + ldr x1, [x0, #0x8] + add x1, x1, #0x1 + str x1, [x0, #0x8] + bl + mov x0, #0x0 // =0 + ldp x29, x30, [sp], #0x10 + ret + +
: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x40 + str x20, [sp] + sub x0, x29, #0x10 + adrp x1, + add x1, x1, + str x10, [sp, #-0x10]! + ldr x10, [x1] + str x10, [x0] + ldr x10, [x1, #0x8] + str x10, [x0, #0x8] + ldr x10, [sp], #0x10 + sub x0, x29, #0x10 + mov x1, #0x3ff8000000000000 // =4609434218613702656 + fmov d0, x1 + bl + sub x0, x29, #0x10 + mov x1, #0x4004000000000000 // =4612811918334230528 + fmov d0, x1 + bl + sub x0, x29, #0x10 + mov x1, #0x400c000000000000 // =4615063718147915776 + fmov d0, x1 + bl + sub x0, x29, #0x10 + ldr d0, [x0] + mov x0, #0x401e000000000000 // =4620130267728707584 + fmov d17, x0 + fcmp d0, d17 + cset x20, ne + cbnz x20, + sub x0, x29, #0x10 + ldr x0, [x0, #0x8] + cmp x0, #0x3 + cset x20, ne + cbz x20, + mov x0, #0x1 // =1 + ldr x20, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x4014000000000000 // =4617315517961601024 + fmov d16, x0 + fcvt s0, d16 + bl + mov x0, #0x4004000000000000 // =4612811918334230528 + fmov d17, x0 + fcmp d0, d17 + cset x0, ne + cbz x0, + mov x0, #0x2 // =2 + ldr x20, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + mov x0, #0x0 // =0 + ldr x20, [sp] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret + b diff --git a/tests/snapshots/asm/volatile_param_classes.x64.asm b/tests/snapshots/asm/volatile_param_classes.x64.asm new file mode 100644 index 000000000..48e885f7b --- /dev/null +++ b/tests/snapshots/asm/volatile_param_classes.x64.asm @@ -0,0 +1,140 @@ + +volatile_param_classes.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +: + popq %r10 + subq $0x20, %rsp + movq %rdi, (%rsp) + movsd %xmm0, 0x10(%rsp) + pushq %r10 + pushq %rbp + movq %rsp, %rbp + subq $0x10, %rsp + movq %rdi, 0x10(%rbp) + movsd %xmm0, 0x20(%rbp,%riz) + movq 0x10(%rbp), %rax + movsd (%rax,%riz), %xmm0 + movsd %xmm0, -0x8(%rbp,%riz) + movq 0x10(%rbp), %rax + movsd -0x8(%rbp,%riz), %xmm0 + movsd 0x20(%rbp,%riz), %xmm1 + addsd %xmm1, %xmm0 + movsd %xmm0, (%rax,%riz) + xorq %rax, %rax + addq $0x10, %rsp + popq %rbp + popq %r11 + addq $0x20, %rsp + pushq %r11 + retq + +: + pushq %rbp + movq %rsp, %rbp + subq $0x10, %rsp + movss %xmm0, -0x8(%rbp,%riz) + movss -0x8(%rbp,%riz), %xmm0 + cvtss2sd %xmm0, %xmm0 + movabsq $0x3fe0000000000000, %rax # imm = 0x3FE0000000000000 + movq %rax, %xmm15 + mulsd %xmm15, %xmm0 + addq $0x10, %rsp + popq %rbp + retq + +: + pushq %rbp + movq %rsp, %rbp + movq 0x8(%rdi), %rax + incq %rax + movq %rax, 0x8(%rdi) + callq + xorq %rax, %rax + popq %rbp + retq + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x40, %rsp + movq %rbx, (%rsp) + leaq -0x10(%rbp), %rax + leaq , %rcx + pushq %rdx + movq (%rcx), %rdx + movq %rdx, (%rax) + movq 0x8(%rcx), %rdx + movq %rdx, 0x8(%rax) + popq %rdx + leaq -0x10(%rbp), %rdi + movabsq $0x3ff8000000000000, %rsi # imm = 0x3FF8000000000000 + movq %rsi, %xmm0 + callq + leaq -0x10(%rbp), %rdi + movabsq $0x4004000000000000, %rsi # imm = 0x4004000000000000 + movq %rsi, %xmm0 + callq + leaq -0x10(%rbp), %rdi + movabsq $0x400c000000000000, %rsi # imm = 0x400C000000000000 + movq %rsi, %xmm0 + callq + leaq -0x10(%rbp), %rax + movsd (%rax,%riz), %xmm0 + movabsq $0x401e000000000000, %rax # imm = 0x401E000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %bl + movzbq %bl, %rbx + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rbx + testq %rbx, %rbx + jne + leaq -0x10(%rbp), %rax + movq 0x8(%rax), %rax + cmpq $0x3, %rax + setne %bl + movzbq %bl, %rbx + testq %rbx, %rbx + je + movl $0x1, %eax + movq (%rsp), %rbx + addq $0x40, %rsp + popq %rbp + retq + movabsq $0x4014000000000000, %rax # imm = 0x4014000000000000 + movq %rax, %xmm14 + cvtsd2ss %xmm14, %xmm0 + callq + movabsq $0x4004000000000000, %rax # imm = 0x4004000000000000 + movq %rax, %xmm15 + ucomisd %xmm15, %xmm0 + setne %al + movzbq %al, %rax + setp %r10b + movzbq %r10b, %r10 + orq %r10, %rax + testq %rax, %rax + je + movl $0x2, %eax + movq (%rsp), %rbx + addq $0x40, %rsp + popq %rbp + retq + xorq %rax, %rax + movq (%rsp), %rbx + addq $0x40, %rsp + popq %rbp + retq + jmp + addb %al, (%rax) + addb %al, 0x41(%rdx) diff --git a/tests/snapshots/asm/volatile_ptr_alias_loop.aarch64.asm b/tests/snapshots/asm/volatile_ptr_alias_loop.aarch64.asm new file mode 100644 index 000000000..64920fc27 --- /dev/null +++ b/tests/snapshots/asm/volatile_ptr_alias_loop.aarch64.asm @@ -0,0 +1,47 @@ + +volatile_ptr_alias_loop.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x20 + mov x1, #0x0 // =0 + stur w1, [x29, #-0x8] + sub x0, x29, #0x8 + stur x0, [x29, #-0x10] + ldursw x0, [x29, #-0x8] + cmp x0, #0x3 + b.ge + ldur x0, [x29, #-0x10] + ldursw x2, [x29, #-0x8] + add x2, x2, #0x1 + str w2, [x0] + add x1, x1, #0x1 + sxtw x0, w1 + cmp x0, #0xa + b.le + b + sxtw x0, w1 + cmp x0, #0x3 + b.ne + b + mov x0, #0x1 // =1 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + b + mov x1, #0x0 // =0 + b + mov x1, #0x2 // =2 + mov x0, x1 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/volatile_ptr_alias_loop.x64.asm b/tests/snapshots/asm/volatile_ptr_alias_loop.x64.asm new file mode 100644 index 000000000..9380e032e --- /dev/null +++ b/tests/snapshots/asm/volatile_ptr_alias_loop.x64.asm @@ -0,0 +1,48 @@ + +volatile_ptr_alias_loop.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x20, %rsp + xorq %rcx, %rcx + movl %ecx, -0x8(%rbp) + leaq -0x8(%rbp), %rax + movq %rax, -0x10(%rbp) + movslq -0x8(%rbp), %rax + cmpq $0x3, %rax + jge + movq -0x10(%rbp), %rax + movslq -0x8(%rbp), %rdx + incq %rdx + movl %edx, (%rax) + incq %rcx + movslq %ecx, %rax + cmpq $0xa, %rax + jle + jmp + movslq %ecx, %rax + cmpq $0x3, %rax + jne + jmp + movl $0x1, %eax + addq $0x20, %rsp + popq %rbp + retq + jmp + xorq %rcx, %rcx + jmp + movl $0x2, %ecx + movq %rcx, %rax + addq $0x20, %rsp + popq %rbp + retq diff --git a/tests/snapshots/asm/volatile_setjmp_longjmp.aarch64.asm b/tests/snapshots/asm/volatile_setjmp_longjmp.aarch64.asm new file mode 100644 index 000000000..6f3173e21 --- /dev/null +++ b/tests/snapshots/asm/volatile_setjmp_longjmp.aarch64.asm @@ -0,0 +1,44 @@ + +volatile_setjmp_longjmp.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x2a0 // =672 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x40 + str x20, [sp] + str x19, [sp, #0x10] + mov x0, #0x1 // =1 + stur w0, [x29, #-0x8] + adrp x20, + add x20, x20, + mov x0, x20 + bl + sxtw x0, w0 + cmp x0, #0x0 + b.ne + mov x0, #0x2 // =2 + stur w0, [x29, #-0x8] + mov x1, #0x1 // =1 + mov x0, x20 + bl + uxtb w0, w0 + ldursw x0, [x29, #-0x8] + cmp x0, #0x2 + b.ne + mov x1, #0x0 // =0 + b + mov x1, #0x1 // =1 + mov x0, x1 + ldr x20, [sp] + ldr x19, [sp, #0x10] + add sp, sp, #0x40 + ldp x29, x30, [sp], #0x10 + ret diff --git a/tests/snapshots/asm/volatile_setjmp_longjmp.x64.asm b/tests/snapshots/asm/volatile_setjmp_longjmp.x64.asm new file mode 100644 index 000000000..15c66763e --- /dev/null +++ b/tests/snapshots/asm/volatile_setjmp_longjmp.x64.asm @@ -0,0 +1,45 @@ + +volatile_setjmp_longjmp.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x30, %rsp + movq %rbx, (%rsp) + movl $0x1, %eax + movl %eax, -0x8(%rbp) + leaq , %rbx + movq %rbx, %rdi + xorl %eax, %eax + callq + movslq %eax, %rax + testq %rax, %rax + jne + movl $0x2, %eax + movl %eax, -0x8(%rbp) + movl $0x1, %esi + movq %rbx, %rdi + xorl %eax, %eax + callq + movzbq %al, %rax + movslq -0x8(%rbp), %rax + cmpq $0x2, %rax + jne + xorq %rcx, %rcx + jmp + movl $0x1, %ecx + movq (%rsp), %rbx + movq %rcx, %rax + addq $0x30, %rsp + popq %rbp + retq + addb %al, (%rax) diff --git a/tests/snapshots/asm/volatile_unused_read.aarch64.asm b/tests/snapshots/asm/volatile_unused_read.aarch64.asm new file mode 100644 index 000000000..bd6be7743 --- /dev/null +++ b/tests/snapshots/asm/volatile_unused_read.aarch64.asm @@ -0,0 +1,37 @@ + +volatile_unused_read.aarch64: file format elf64-littleaarch64 + +Disassembly of section .text: + +<.text>: + mov x29, #0x0 // =0 + mov x0, sp + mov x1, #0x220 // =544 + movk x1, #0x0, lsl #16 + b + brk #: + stp x29, x30, [sp, #-0x10]! + mov x29, sp + sub sp, sp, #0x20 + adrp x0, + add x0, x0, + ldrsw x1, [x0] + mov x1, #0x7 // =7 + stur w1, [x29, #-0x8] + ldursw x1, [x29, #-0x8] + ldrsw x0, [x0] + cmp x0, #0x5 + cset x1, eq + cbz x1, + ldursw x0, [x29, #-0x8] + cmp x0, #0x7 + cset x1, eq + cbz x1, + mov x1, #0x0 // =0 + b + mov x1, #0x1 // =1 + mov x0, x1 + add sp, sp, #0x20 + ldp x29, x30, [sp], #0x10 + ret + b diff --git a/tests/snapshots/asm/volatile_unused_read.x64.asm b/tests/snapshots/asm/volatile_unused_read.x64.asm new file mode 100644 index 000000000..c216c17cc --- /dev/null +++ b/tests/snapshots/asm/volatile_unused_read.x64.asm @@ -0,0 +1,41 @@ + +volatile_unused_read.x64: file format elf64-x86-64 + +Disassembly of section .text: + +<.text>: + xorl %ebp, %ebp + movq %rsp, %rdi + movl $, %esi + callq + ud2 + +
: + pushq %rbp + movq %rsp, %rbp + subq $0x20, %rsp + leaq , %rax + movslq (%rax), %rcx + movl $0x7, %ecx + movl %ecx, -0x8(%rbp) + movslq -0x8(%rbp), %rcx + movslq (%rax), %rax + cmpq $0x5, %rax + sete %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + movslq -0x8(%rbp), %rax + cmpq $0x7, %rax + sete %cl + movzbq %cl, %rcx + testq %rcx, %rcx + je + xorq %rcx, %rcx + jmp + movl $0x1, %ecx + movq %rcx, %rax + addq $0x20, %rsp + popq %rbp + retq + jmp diff --git a/tests/snapshots/asm/vtable_back_to_back.aarch64.asm b/tests/snapshots/asm/vtable_back_to_back.aarch64.asm index 60ea6c321..4419dc45f 100644 --- a/tests/snapshots/asm/vtable_back_to_back.aarch64.asm +++ b/tests/snapshots/asm/vtable_back_to_back.aarch64.asm @@ -47,11 +47,11 @@ Disassembly of section .text: add x2, x2, mov x3, #0x2a // =42 mov x4, #0x8 // =8 - mov x9, x0 str x4, [sp, #-0x10]! str x3, [sp, #-0x10]! str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] @@ -64,10 +64,10 @@ Disassembly of section .text: sub x1, x29, #0x10 sub x2, x29, #0x40 mov x3, #0x1 // =1 - mov x9, x0 str x3, [sp, #-0x10]! str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] diff --git a/tests/snapshots/asm/vtable_back_to_back_4arg.aarch64.asm b/tests/snapshots/asm/vtable_back_to_back_4arg.aarch64.asm index 0399894c1..f155ae62f 100644 --- a/tests/snapshots/asm/vtable_back_to_back_4arg.aarch64.asm +++ b/tests/snapshots/asm/vtable_back_to_back_4arg.aarch64.asm @@ -49,11 +49,11 @@ Disassembly of section .text: add x2, x2, mov x20, #0x1 // =1 mov x3, #0x64 // =100 - mov x9, x0 str x3, [sp, #-0x10]! str x20, [sp, #-0x10]! str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] @@ -65,10 +65,10 @@ Disassembly of section .text: ldr x0, [x0, #0x8] sub x1, x29, #0x10 sub x2, x29, #0x40 - mov x9, x0 str x20, [sp, #-0x10]! str x2, [sp, #-0x10]! str x1, [sp, #-0x10]! + mov x9, x0 ldr x0, [sp] ldr x1, [sp, #0x10] ldr x2, [sp, #0x20] diff --git a/tests/snapshots/ssa/add_sub_negative_imm.ssa b/tests/snapshots/ssa/add_sub_negative_imm.ssa index 6fc5b4d80..1355c00ca 100644 --- a/tests/snapshots/ssa/add_sub_negative_imm.ssa +++ b/tests/snapshots/ssa/add_sub_negative_imm.ssa @@ -5,69 +5,69 @@ fn ent_pc=0 n_params=0 variadic=false locals=4 block 0 start_pc=0 v0 AllocaInit(0) -> - v1 Imm(10) -> x0 - v2 Imm(0) -> x1 - v3 Imm(1000) -> x1 - v4 Imm(0) -> x2 - v5 LoadLocal { off=-1, kind=I32 } -> x2 - v6 BinopI { op=add, lhs=v1, rhs_imm=-5 } -> x2 - v7 BinopI { op=shl, lhs=v6, rhs_imm=32 } -> x6 - v8 Extend { value=v6, kind=I32 } -> x2 - v9 BinopI { op=ne, lhs=v8, rhs_imm=5 } -> x2 + v2 StoreLocal { off=-1, value=v1, kind=I32, volatile } -> - + v3 Imm(1000) -> x0 + v4 StoreLocal { off=-2, value=v3, kind=I64, volatile } -> - + v5 LoadLocal { off=-1, kind=I32, volatile } -> x0 + v6 BinopI { op=add, lhs=v5, rhs_imm=-5 } -> x0 + v7 BinopI { op=shl, lhs=v6, rhs_imm=32 } -> x1 + v8 Extend { value=v6, kind=I32 } -> x0 + v9 BinopI { op=ne, lhs=v8, rhs_imm=5 } -> x0 terminator Bz { cond=v9, target=b2, fall=b1 } (exit_acc=v9) block 1 start_pc=0 v10 Imm(1) -> x0 terminator Return(v10) (exit_acc=v10) block 2 start_pc=0 - v11 LoadLocal { off=-1, kind=I32 } -> x2 - v12 BinopI { op=add, lhs=v1, rhs_imm=-10 } -> x2 - v13 BinopI { op=shl, lhs=v12, rhs_imm=32 } -> x6 - v14 Extend { value=v12, kind=I32 } -> x2 - v15 BinopI { op=ne, lhs=v14, rhs_imm=0 } -> x2 + v11 LoadLocal { off=-1, kind=I32, volatile } -> x0 + v12 BinopI { op=add, lhs=v11, rhs_imm=-10 } -> x0 + v13 BinopI { op=shl, lhs=v12, rhs_imm=32 } -> x1 + v14 Extend { value=v12, kind=I32 } -> x0 + v15 BinopI { op=ne, lhs=v14, rhs_imm=0 } -> x0 terminator Bz { cond=v15, target=b4, fall=b3 } (exit_acc=v15) block 3 start_pc=0 v16 Imm(2) -> x0 terminator Return(v16) (exit_acc=v16) block 4 start_pc=0 - v17 LoadLocal { off=-1, kind=I32 } -> x2 - v18 BinopI { op=sub, lhs=v1, rhs_imm=-7 } -> x2 - v19 BinopI { op=shl, lhs=v18, rhs_imm=32 } -> x6 - v20 Extend { value=v18, kind=I32 } -> x2 - v21 BinopI { op=ne, lhs=v20, rhs_imm=17 } -> x2 + v17 LoadLocal { off=-1, kind=I32, volatile } -> x0 + v18 BinopI { op=sub, lhs=v17, rhs_imm=-7 } -> x0 + v19 BinopI { op=shl, lhs=v18, rhs_imm=32 } -> x1 + v20 Extend { value=v18, kind=I32 } -> x0 + v21 BinopI { op=ne, lhs=v20, rhs_imm=17 } -> x0 terminator Bz { cond=v21, target=b6, fall=b5 } (exit_acc=v21) block 5 start_pc=0 v22 Imm(3) -> x0 terminator Return(v22) (exit_acc=v22) block 6 start_pc=0 - v23 LoadLocal { off=-2, kind=I64 } -> x2 - v24 BinopI { op=add, lhs=v3, rhs_imm=-100 } -> x2 - v25 BinopI { op=ne, lhs=v24, rhs_imm=900 } -> x2 + v23 LoadLocal { off=-2, kind=I64, volatile } -> x0 + v24 BinopI { op=add, lhs=v23, rhs_imm=-100 } -> x0 + v25 BinopI { op=ne, lhs=v24, rhs_imm=900 } -> x0 terminator Bz { cond=v25, target=b8, fall=b7 } (exit_acc=v25) block 7 start_pc=0 v26 Imm(4) -> x0 terminator Return(v26) (exit_acc=v26) block 8 start_pc=0 - v27 LoadLocal { off=-2, kind=I64 } -> x2 - v28 BinopI { op=sub, lhs=v3, rhs_imm=-100 } -> x1 - v29 BinopI { op=ne, lhs=v28, rhs_imm=1100 } -> x1 + v27 LoadLocal { off=-2, kind=I64, volatile } -> x0 + v28 BinopI { op=sub, lhs=v27, rhs_imm=-100 } -> x0 + v29 BinopI { op=ne, lhs=v28, rhs_imm=1100 } -> x0 terminator Bz { cond=v29, target=b10, fall=b9 } (exit_acc=v29) block 9 start_pc=0 v30 Imm(5) -> x0 terminator Return(v30) (exit_acc=v30) block 10 start_pc=0 - v31 LoadLocal { off=-1, kind=I32 } -> x1 - v32 BinopI { op=add, lhs=v1, rhs_imm=-4095 } -> x1 - v33 BinopI { op=shl, lhs=v32, rhs_imm=32 } -> x2 - v34 Extend { value=v32, kind=I32 } -> x1 - v35 Imm(-4085) -> x2 - v36 Imm(-17544941404160) -> x2 - v37 BinopI { op=ne, lhs=v34, rhs_imm=-4085 } -> x1 + v31 LoadLocal { off=-1, kind=I32, volatile } -> x0 + v32 BinopI { op=add, lhs=v31, rhs_imm=-4095 } -> x0 + v33 BinopI { op=shl, lhs=v32, rhs_imm=32 } -> x1 + v34 Extend { value=v32, kind=I32 } -> x0 + v35 Imm(-4085) -> x1 + v36 Imm(-17544941404160) -> x1 + v37 BinopI { op=ne, lhs=v34, rhs_imm=-4085 } -> x0 terminator Bz { cond=v37, target=b12, fall=b11 } (exit_acc=v37) block 11 start_pc=0 v38 Imm(6) -> x0 terminator Return(v38) (exit_acc=v38) block 12 start_pc=0 - v39 LoadLocal { off=-1, kind=I32 } -> x1 - v40 BinopI { op=add, lhs=v1, rhs_imm=-4096 } -> x0 + v39 LoadLocal { off=-1, kind=I32, volatile } -> x0 + v40 BinopI { op=add, lhs=v39, rhs_imm=-4096 } -> x0 v41 BinopI { op=shl, lhs=v40, rhs_imm=32 } -> x1 v42 Extend { value=v40, kind=I32 } -> x0 v43 Imm(-4086) -> x1 @@ -78,39 +78,38 @@ fn ent_pc=0 n_params=0 variadic=false locals=4 v46 Imm(7) -> x0 terminator Return(v46) (exit_acc=v46) block 14 start_pc=0 - v47 Imm(0) -> x2 + v47 Imm(0) -> x1 v48 Imm(0) -> x0 - v49 Imm(5) -> x1 - v50 Imm(0) -> x0 - terminator Jmp(b15) (exit_acc=v49) + v49 Imm(5) -> x0 + v50 StoreLocal { off=-4, value=v49, kind=I32, volatile } -> - + terminator Jmp(b15) (exit_acc=v50) block 15 start_pc=0 - v51 Phi { incoming=[b14:v49, b16:v56], kind=I64 } -> x1 - v52 Phi { incoming=[b14:v47, b16:v60], kind=I64 } -> x2 - v53 Extend { value=v51, kind=I32 } -> x0 - v54 BinopI { op=gt, lhs=v53, rhs_imm=0 } -> x0 - terminator Bz { cond=v54, target=b18, fall=b17 } (exit_acc=v54) + v51 Phi { incoming=[b14:v47, b16:v59], kind=I64 } -> x1 + v52 LoadLocal { off=-4, kind=I32, volatile } -> x0 + v53 BinopI { op=gt, lhs=v52, rhs_imm=0 } -> x0 + terminator Bz { cond=v53, target=b18, fall=b17 } (exit_acc=v53) block 16 start_pc=0 - v55 Extend { value=v51, kind=I32 } -> x0 - v56 BinopI { op=add, lhs=v55, rhs_imm=-1 } -> x1 - v57 Imm(0) -> x0 + v54 LoadLocal { off=-4, kind=I32, volatile } -> x0 + v55 BinopI { op=add, lhs=v54, rhs_imm=-1 } -> x0 + v56 StoreLocal { off=-4, value=v55, kind=I32, volatile } -> - terminator Jmp(b15) (exit_acc=v56) block 17 start_pc=0 - v58 Extend { value=v52, kind=I32 } -> x0 - v59 Extend { value=v51, kind=I32 } -> x0 - v60 Binop { op=add, lhs=v52, rhs=v51 } -> x2 - v61 Imm(0) -> x0 - v62 Extend { value=v60, kind=I32 } -> x0 - terminator Jmp(b16) (exit_acc=v62) + v57 Extend { value=v51, kind=I32 } -> x0 + v58 LoadLocal { off=-4, kind=I32, volatile } -> x0 + v59 Binop { op=add, lhs=v51, rhs=v58 } -> x1 + v60 Imm(0) -> x0 + v61 Extend { value=v59, kind=I32 } -> x0 + terminator Jmp(b16) (exit_acc=v61) block 18 start_pc=0 - v63 Extend { value=v52, kind=I32 } -> x0 - v64 BinopI { op=ne, lhs=v63, rhs_imm=15 } -> x0 - terminator Bz { cond=v64, target=b20, fall=b19 } (exit_acc=v64) + v62 Extend { value=v51, kind=I32 } -> x0 + v63 BinopI { op=ne, lhs=v62, rhs_imm=15 } -> x0 + terminator Bz { cond=v63, target=b20, fall=b19 } (exit_acc=v63) block 19 start_pc=0 - v65 Imm(8) -> x0 - terminator Return(v65) (exit_acc=v65) + v64 Imm(8) -> x0 + terminator Return(v64) (exit_acc=v64) block 20 start_pc=0 - v66 Imm(0) -> x0 - terminator Return(v66) (exit_acc=v66) + v65 Imm(0) -> x0 + terminator Return(v65) (exit_acc=v65) ; --- SSA dump (ok=true) ent_pc=0 --- ; name=__c5_exit fn ent_pc=0 n_params=1 variadic=false locals=1 diff --git a/tests/snapshots/ssa/add_three_operand_lea.ssa b/tests/snapshots/ssa/add_three_operand_lea.ssa index fcac0d9d9..04dee8856 100644 --- a/tests/snapshots/ssa/add_three_operand_lea.ssa +++ b/tests/snapshots/ssa/add_three_operand_lea.ssa @@ -5,73 +5,74 @@ fn ent_pc=0 n_params=0 variadic=false locals=6 block 0 start_pc=0 v0 AllocaInit(0) -> - v1 Imm(3) -> x0 - v2 Imm(0) -> x1 - v3 Imm(4) -> x1 - v4 Imm(0) -> x2 - v5 Imm(5) -> x2 - v6 Imm(0) -> x6 - v7 LoadLocal { off=-1, kind=I64 } -> x6 - v8 LoadLocal { off=-2, kind=I64 } -> x6 - v9 Binop { op=add, lhs=v1, rhs=v3 } -> x6 - v10 BinopI { op=ne, lhs=v9, rhs_imm=7 } -> x6 + v2 StoreLocal { off=-1, value=v1, kind=I64, volatile } -> - + v3 Imm(4) -> x0 + v4 StoreLocal { off=-2, value=v3, kind=I64, volatile } -> - + v5 Imm(5) -> x0 + v6 StoreLocal { off=-3, value=v5, kind=I64, volatile } -> - + v7 LoadLocal { off=-1, kind=I64, volatile } -> x0 + v8 LoadLocal { off=-2, kind=I64, volatile } -> x1 + v9 Binop { op=add, lhs=v7, rhs=v8 } -> x0 + v10 BinopI { op=ne, lhs=v9, rhs_imm=7 } -> x0 terminator Bz { cond=v10, target=b2, fall=b1 } (exit_acc=v10) block 1 start_pc=0 v11 Imm(1) -> x0 terminator Return(v11) (exit_acc=v11) block 2 start_pc=0 - v12 LoadLocal { off=-1, kind=I64 } -> x6 - v13 LoadLocal { off=-2, kind=I64 } -> x6 - v14 Binop { op=add, lhs=v1, rhs=v3 } -> x6 - v15 LoadLocal { off=-3, kind=I64 } -> x7 - v16 Binop { op=add, lhs=v1, rhs=v5 } -> x0 - v17 Binop { op=add, lhs=v14, rhs=v16 } -> x0 - v18 BinopI { op=ne, lhs=v17, rhs_imm=15 } -> x0 - terminator Bz { cond=v18, target=b4, fall=b3 } (exit_acc=v18) + v12 LoadLocal { off=-1, kind=I64, volatile } -> x0 + v13 LoadLocal { off=-2, kind=I64, volatile } -> x1 + v14 Binop { op=add, lhs=v12, rhs=v13 } -> x0 + v15 LoadLocal { off=-1, kind=I64, volatile } -> x1 + v16 LoadLocal { off=-3, kind=I64, volatile } -> x2 + v17 Binop { op=add, lhs=v15, rhs=v16 } -> x1 + v18 Binop { op=add, lhs=v14, rhs=v17 } -> x0 + v19 BinopI { op=ne, lhs=v18, rhs_imm=15 } -> x0 + terminator Bz { cond=v19, target=b4, fall=b3 } (exit_acc=v19) block 3 start_pc=0 - v19 Imm(2) -> x0 - terminator Return(v19) (exit_acc=v19) + v20 Imm(2) -> x0 + terminator Return(v20) (exit_acc=v20) block 4 start_pc=0 - v20 Imm(-5) -> x0 - v21 Imm(0) -> x2 - v22 LoadLocal { off=-1, kind=I64 } -> x2 - v23 LoadLocal { off=-2, kind=I64 } -> x2 - v24 Binop { op=add, lhs=v20, rhs=v3 } -> x0 - v25 BinopI { op=ne, lhs=v24, rhs_imm=-1 } -> x0 - terminator Bz { cond=v25, target=b6, fall=b5 } (exit_acc=v25) + v21 Imm(-5) -> x0 + v22 StoreLocal { off=-1, value=v21, kind=I64, volatile } -> - + v23 LoadLocal { off=-1, kind=I64, volatile } -> x0 + v24 LoadLocal { off=-2, kind=I64, volatile } -> x1 + v25 Binop { op=add, lhs=v23, rhs=v24 } -> x0 + v26 BinopI { op=ne, lhs=v25, rhs_imm=-1 } -> x0 + terminator Bz { cond=v26, target=b6, fall=b5 } (exit_acc=v26) block 5 start_pc=0 - v26 Imm(3) -> x0 - terminator Return(v26) (exit_acc=v26) + v27 Imm(3) -> x0 + terminator Return(v27) (exit_acc=v27) block 6 start_pc=0 - v27 Imm(2000000000) -> x0 - v28 Imm(0) -> x1 - v29 Imm(0) -> x1 - v30 LoadLocal { off=-4, kind=I32 } -> x1 - v31 LoadLocal { off=-5, kind=I32 } -> x1 - v32 Binop { op=add, lhs=v27, rhs=v27 } -> x0 - v33 BinopI { op=shl, lhs=v32, rhs_imm=32 } -> x1 - v34 Extend { value=v32, kind=I32 } -> x0 - v35 Imm(4000000000) -> x1 - v36 Imm(-1266874889709551616) -> x1 - v37 Imm(-294967296) -> x1 - v38 BinopI { op=ne, lhs=v34, rhs_imm=-294967296 } -> x0 - terminator Bz { cond=v38, target=b8, fall=b7 } (exit_acc=v38) + v28 Imm(2000000000) -> x0 + v29 StoreLocal { off=-4, value=v28, kind=I32, volatile } -> - + v30 StoreLocal { off=-5, value=v28, kind=I32, volatile } -> - + v31 LoadLocal { off=-4, kind=I32, volatile } -> x0 + v32 LoadLocal { off=-5, kind=I32, volatile } -> x1 + v33 Binop { op=add, lhs=v31, rhs=v32 } -> x0 + v34 BinopI { op=shl, lhs=v33, rhs_imm=32 } -> x1 + v35 Extend { value=v33, kind=I32 } -> x0 + v36 Imm(4000000000) -> x1 + v37 Imm(-1266874889709551616) -> x1 + v38 Imm(-294967296) -> x1 + v39 BinopI { op=ne, lhs=v35, rhs_imm=-294967296 } -> x0 + terminator Bz { cond=v39, target=b8, fall=b7 } (exit_acc=v39) block 7 start_pc=0 - v39 Imm(4) -> x0 - terminator Return(v39) (exit_acc=v39) + v40 Imm(4) -> x0 + terminator Return(v40) (exit_acc=v40) block 8 start_pc=0 - v40 Imm(9223372036854775807) -> x0 - v41 Imm(0) -> x1 - v42 LoadLocal { off=-6, kind=I64 } -> x1 - v43 BinopI { op=add, lhs=v40, rhs_imm=1 } -> x0 - v44 Imm(-9223372036854775808) -> x1 - v45 BinopI { op=ne, lhs=v43, rhs_imm=-9223372036854775808 } -> x0 - terminator Bz { cond=v45, target=b10, fall=b9 } (exit_acc=v45) + v41 Imm(9223372036854775807) -> x0 + v42 StoreLocal { off=-6, value=v41, kind=I64, volatile } -> - + v43 LoadLocal { off=-6, kind=I64, volatile } -> x0 + v44 BinopI { op=add, lhs=v43, rhs_imm=1 } -> x0 + v45 Imm(-9223372036854775808) -> x1 + v46 BinopI { op=ne, lhs=v44, rhs_imm=-9223372036854775808 } -> x0 + terminator Bz { cond=v46, target=b10, fall=b9 } (exit_acc=v46) block 9 start_pc=0 - v46 Imm(5) -> x0 - terminator Return(v46) (exit_acc=v46) - block 10 start_pc=0 - v47 Imm(0) -> x0 + v47 Imm(5) -> x0 terminator Return(v47) (exit_acc=v47) + block 10 start_pc=0 + v48 Imm(0) -> x0 + terminator Return(v48) (exit_acc=v48) ; --- SSA dump (ok=true) ent_pc=0 --- ; name=__c5_exit fn ent_pc=0 n_params=1 variadic=false locals=1 diff --git a/tests/snapshots/ssa/anonymous_aggregates.ssa b/tests/snapshots/ssa/anonymous_aggregates.ssa index 7c20bdd04..44e3b135b 100644 --- a/tests/snapshots/ssa/anonymous_aggregates.ssa +++ b/tests/snapshots/ssa/anonymous_aggregates.ssa @@ -123,9 +123,9 @@ fn ent_pc=1 n_params=0 variadic=false locals=11 terminator Return(v74) (exit_acc=v74) block 22 start_pc=0 v75 LocalAddr(-4) -> x0 - v76 BinopI { op=add, lhs=v75, rhs_imm=8 } -> x0 + v76 BinopI { op=add, lhs=v75, rhs_imm=8 } -> x1 v77 Imm(4614253070214989087) -> x1 - v78 Store { addr=v76, disp=0, value=v77, kind=F64 } -> - + v78 Store { addr=v75, disp=8, value=v77, kind=F64 } -> - v79 LocalAddr(-4) -> x0 v80 Load { addr=v79, disp=0, kind=I32 } -> x0 v81 BinopI { op=ne, lhs=v80, rhs_imm=1 } -> x0 diff --git a/tests/snapshots/ssa/array_2d_struct_init.ssa b/tests/snapshots/ssa/array_2d_struct_init.ssa index b735db69c..8633b6d5e 100644 --- a/tests/snapshots/ssa/array_2d_struct_init.ssa +++ b/tests/snapshots/ssa/array_2d_struct_init.ssa @@ -18,7 +18,7 @@ fn ent_pc=0 n_params=0 variadic=false locals=7 v10 Imm(16) -> x1 v11 BinopI { op=add, lhs=v1, rhs_imm=16 } -> x1 v12 BinopI { op=add, lhs=v1, rhs_imm=24 } -> x1 - v13 Load { addr=v12, disp=0, kind=F64 } -> d0 + v13 Load { addr=v1, disp=24, kind=F64 } -> d0 v14 Imm(4) -> x1 v15 FpCast { kind=IntToFp, value=v14 } -> d1 v16 Binop { op=fne, lhs=v13, rhs=v15 } -> x1 @@ -35,8 +35,8 @@ fn ent_pc=0 n_params=0 variadic=false locals=7 v23 ImmData(8) -> x1 v24 Imm(32) -> x1 v25 BinopI { op=add, lhs=v1, rhs_imm=32 } -> x1 - v26 Imm(0) -> x2 - v27 Load { addr=v25, disp=0, kind=F64 } -> d0 + v26 Imm(0) -> x1 + v27 Load { addr=v1, disp=32, kind=F64 } -> d0 v28 Imm(5) -> x1 v29 FpCast { kind=IntToFp, value=v28 } -> d1 v30 Binop { op=fne, lhs=v27, rhs=v29 } -> x1 @@ -54,8 +54,8 @@ fn ent_pc=0 n_params=0 variadic=false locals=7 v38 BinopI { op=add, lhs=v1, rhs_imm=32 } -> x1 v39 Imm(16) -> x1 v40 BinopI { op=add, lhs=v1, rhs_imm=48 } -> x1 - v41 BinopI { op=add, lhs=v1, rhs_imm=56 } -> x0 - v42 Load { addr=v41, disp=0, kind=F64 } -> d0 + v41 BinopI { op=add, lhs=v1, rhs_imm=56 } -> x1 + v42 Load { addr=v1, disp=56, kind=F64 } -> d0 v43 Imm(8) -> x0 v44 FpCast { kind=IntToFp, value=v43 } -> d1 v45 Binop { op=fne, lhs=v42, rhs=v44 } -> x2 @@ -85,8 +85,8 @@ fn ent_pc=0 n_params=0 variadic=false locals=7 v61 BinopI { op=add, lhs=v57, rhs_imm=96 } -> x1 v62 Imm(16) -> x1 v63 BinopI { op=add, lhs=v57, rhs_imm=112 } -> x1 - v64 BinopI { op=add, lhs=v57, rhs_imm=120 } -> x0 - v65 Load { addr=v64, disp=0, kind=F64 } -> d0 + v64 BinopI { op=add, lhs=v57, rhs_imm=120 } -> x1 + v65 Load { addr=v57, disp=120, kind=F64 } -> d0 v66 Imm(8) -> x0 v67 FpCast { kind=IntToFp, value=v66 } -> d1 v68 Binop { op=fne, lhs=v65, rhs=v67 } -> x0 @@ -104,8 +104,8 @@ fn ent_pc=0 n_params=0 variadic=false locals=7 v76 BinopI { op=add, lhs=v74, rhs_imm=64 } -> x1 v77 Imm(0) -> x1 v78 Imm(16) -> x1 - v79 BinopI { op=add, lhs=v74, rhs_imm=80 } -> x0 - v80 Load { addr=v79, disp=0, kind=F64 } -> d0 + v79 BinopI { op=add, lhs=v74, rhs_imm=80 } -> x1 + v80 Load { addr=v74, disp=80, kind=F64 } -> d0 v81 Imm(6) -> x0 v82 FpCast { kind=IntToFp, value=v81 } -> d1 v83 Binop { op=fne, lhs=v80, rhs=v82 } -> x2 @@ -134,8 +134,8 @@ fn ent_pc=0 n_params=0 variadic=false locals=7 v98 BinopI { op=add, lhs=v96, rhs_imm=32 } -> x1 v99 Imm(16) -> x1 v100 BinopI { op=add, lhs=v96, rhs_imm=48 } -> x2 - v101 BinopI { op=add, lhs=v96, rhs_imm=56 } -> x0 - v102 Load { addr=v101, disp=0, kind=F64 } -> d0 + v101 BinopI { op=add, lhs=v96, rhs_imm=56 } -> x2 + v102 Load { addr=v96, disp=56, kind=F64 } -> d0 v103 FpCast { kind=IntToFp, value=v99 } -> d1 v104 Binop { op=fne, lhs=v102, rhs=v103 } -> x0 v105 BinopI { op=ne, lhs=v104, rhs_imm=0 } -> x2 @@ -150,8 +150,8 @@ fn ent_pc=0 n_params=0 variadic=false locals=7 v110 ImmData(200) -> x0 v111 Imm(0) -> x1 v112 Imm(16) -> x1 - v113 BinopI { op=add, lhs=v110, rhs_imm=16 } -> x0 - v114 Load { addr=v113, disp=0, kind=F64 } -> d0 + v113 BinopI { op=add, lhs=v110, rhs_imm=16 } -> x1 + v114 Load { addr=v110, disp=16, kind=F64 } -> d0 v115 Imm(11) -> x0 v116 FpCast { kind=IntToFp, value=v115 } -> d1 v117 Binop { op=fne, lhs=v114, rhs=v116 } -> x2 diff --git a/tests/snapshots/ssa/atomic_operand_in_working_regs.ssa b/tests/snapshots/ssa/atomic_operand_in_working_regs.ssa new file mode 100644 index 000000000..e305ce019 --- /dev/null +++ b/tests/snapshots/ssa/atomic_operand_in_working_regs.ssa @@ -0,0 +1,160 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=f +fn ent_pc=0 n_params=8 variadic=false locals=3 + spill_count=0 gpr_used=[3, 12, 13] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 ParamRef(2, kind=I64) -> x2 + v6 Imm(0) -> x0 + v7 ParamRef(3, kind=I64) -> x1 + v8 Imm(0) -> x0 + v9 ParamRef(4, kind=I64) -> x8 + v10 Imm(0) -> x0 + v11 ParamRef(5, kind=I64) -> x9 + v12 Imm(0) -> x0 + v13 Imm(100) -> x0 + v14 StoreLocal { off=-1, value=v13, kind=I64 } -> - + v15 ImmData(8) -> x0 + v16 LocalAddr(-1) -> x3 + v17 Imm(5) -> x12 + v18 AtomicCas { addr=v15, expected_addr=v16, desired=v17, width=8 } -> x3 + v19 Imm(0) -> x12 + v20 LoadLocal { off=2, kind=I64 } -> x12 + v21 LoadLocal { off=3, kind=I64 } -> x12 + v22 Binop { op=add, lhs=v1, rhs=v3 } -> x12 + v23 AtomicRmw { op=Add, addr=v15, value=v22, width=8 } -> x12 + v24 Imm(0) -> x13 + v25 Extend { value=v18, kind=I32 } -> x3 + v26 BinopI { op=ne, lhs=v25, rhs_imm=0 } -> x3 + terminator Bz { cond=v26, target=b2, fall=b1 } (exit_acc=v26) + block 1 start_pc=0 + v27 Imm(1) -> x0 + terminator Return(v27) (exit_acc=v27) + block 2 start_pc=0 + v28 LoadLocal { off=-1, kind=I64 } -> x3 + v29 BinopI { op=ne, lhs=v28, rhs_imm=9 } -> x3 + terminator Bz { cond=v29, target=b4, fall=b3 } (exit_acc=v29) + block 3 start_pc=0 + v30 Imm(2) -> x0 + terminator Return(v30) (exit_acc=v30) + block 4 start_pc=0 + v31 LoadLocal { off=-3, kind=I64 } -> x3 + v32 BinopI { op=ne, lhs=v23, rhs_imm=9 } -> x3 + terminator Bz { cond=v32, target=b6, fall=b5 } (exit_acc=v32) + block 5 start_pc=0 + v33 Imm(3) -> x0 + terminator Return(v33) (exit_acc=v33) + block 6 start_pc=0 + v34 ImmData(8) -> x3 + v35 Load { addr=v15, disp=0, kind=I64 } -> x0 + v36 Imm(9) -> x3 + v37 LoadLocal { off=2, kind=I64 } -> x3 + v38 BinopI { op=add, lhs=v1, rhs_imm=9 } -> x3 + v39 LoadLocal { off=3, kind=I64 } -> x12 + v40 Binop { op=add, lhs=v38, rhs=v3 } -> x3 + v41 Binop { op=ne, lhs=v35, rhs=v40 } -> x0 + terminator Bz { cond=v41, target=b8, fall=b7 } (exit_acc=v41) + block 7 start_pc=0 + v42 Imm(4) -> x0 + terminator Return(v42) (exit_acc=v42) + block 8 start_pc=0 + v43 LoadLocal { off=2, kind=I64 } -> x0 + v44 LoadLocal { off=3, kind=I64 } -> x0 + v45 Binop { op=add, lhs=v1, rhs=v3 } -> x0 + v46 LoadLocal { off=4, kind=I64 } -> x6 + v47 Binop { op=add, lhs=v45, rhs=v5 } -> x0 + v48 LoadLocal { off=5, kind=I64 } -> x2 + v49 Binop { op=add, lhs=v47, rhs=v7 } -> x0 + v50 LoadLocal { off=6, kind=I64 } -> x1 + v51 Binop { op=add, lhs=v49, rhs=v9 } -> x0 + v52 LoadLocal { off=7, kind=I64 } -> x1 + v53 Binop { op=add, lhs=v51, rhs=v11 } -> x0 + v54 LoadLocal { off=8, kind=I64 } -> x1 + v55 Binop { op=add, lhs=v53, rhs=v54 } -> x0 + v56 LoadLocal { off=9, kind=I64 } -> x1 + v57 Binop { op=add, lhs=v55, rhs=v56 } -> x0 + terminator Return(v57) (exit_acc=v57) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=10 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(1) -> x7 + v2 Imm(2) -> x6 + v3 Imm(3) -> x2 + v4 Imm(4) -> x1 + v5 Imm(5) -> x8 + v6 Imm(6) -> x9 + v7 Imm(7) -> x0 + v8 Imm(8) -> x3 + v9 Call { target_pc=0, args=[v1, v2, v3, v4, v5, v6, v7, v8], fixed_args=8, fp_return=false, fp_arg_mask=0x0 } -> x0 + v10 Imm(0) -> x1 + v11 LoadLocal { off=-1, kind=I64 } -> x1 + v12 BinopI { op=eq, lhs=v9, rhs_imm=36 } -> x1 + terminator Bz { cond=v12, target=b2, fall=b1 } (exit_acc=v12) + block 1 start_pc=0 + v13 Imm(0) -> x1 + v14 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v13) + block 2 start_pc=0 + v15 LoadLocal { off=-1, kind=I64 } -> x1 + v16 BinopI { op=shl, lhs=v9, rhs_imm=32 } -> x1 + v17 Extend { value=v9, kind=I32 } -> x1 + v18 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v17) + block 3 start_pc=0 + v19 Phi { incoming=[b1:v13, b2:v17], kind=I64 } -> x1 + v20 LoadLocal { off=-10, kind=I64 } -> x0 + terminator Return(v19) (exit_acc=v19) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/bitwise_not_mvn.ssa b/tests/snapshots/ssa/bitwise_not_mvn.ssa index 7c03f8fe6..51dc51b79 100644 --- a/tests/snapshots/ssa/bitwise_not_mvn.ssa +++ b/tests/snapshots/ssa/bitwise_not_mvn.ssa @@ -51,86 +51,87 @@ fn ent_pc=3 n_params=0 variadic=false locals=6 block 0 start_pc=0 v0 AllocaInit(0) -> - v1 Imm(81985529216486895) -> x0 - v2 Imm(0) -> x1 - v3 Imm(-81985529216486896) -> x1 - v4 Imm(0) -> x2 - v5 Imm(-6149008514797120171) -> x2 - v6 Imm(0) -> x6 - v7 LoadLocal { off=-1, kind=I64 } -> x6 - v8 Imm(0) -> x6 - v9 BinopI { op=xor, lhs=v1, rhs_imm=-1 } -> x6 - v10 LoadLocal { off=-1, kind=I64 } -> x7 - v11 BinopI { op=xor, lhs=v1, rhs_imm=-1 } -> x7 - v12 Binop { op=ne, lhs=v9, rhs=v11 } -> x6 + v2 StoreLocal { off=-1, value=v1, kind=I64, volatile } -> - + v3 Imm(-81985529216486896) -> x0 + v4 StoreLocal { off=-2, value=v3, kind=I64, volatile } -> - + v5 Imm(-6149008514797120171) -> x0 + v6 StoreLocal { off=-3, value=v5, kind=I64, volatile } -> - + v7 LoadLocal { off=-1, kind=I64, volatile } -> x0 + v8 Imm(0) -> x1 + v9 BinopI { op=xor, lhs=v7, rhs_imm=-1 } -> x0 + v10 LoadLocal { off=-1, kind=I64, volatile } -> x1 + v11 BinopI { op=xor, lhs=v10, rhs_imm=-1 } -> x1 + v12 Binop { op=ne, lhs=v9, rhs=v11 } -> x0 terminator Bz { cond=v12, target=b2, fall=b1 } (exit_acc=v12) block 1 start_pc=0 v13 Imm(1) -> x0 terminator Return(v13) (exit_acc=v13) block 2 start_pc=0 - v14 LoadLocal { off=-1, kind=I64 } -> x6 - v15 LoadLocal { off=-2, kind=I64 } -> x6 - v16 Imm(0) -> x6 - v17 Imm(0) -> x6 - v18 BinopI { op=xor, lhs=v1, rhs_imm=-1 } -> x6 - v19 Binop { op=and, lhs=v18, rhs=v3 } -> x6 - v20 LoadLocal { off=-1, kind=I64 } -> x7 - v21 BinopI { op=xor, lhs=v1, rhs_imm=-1 } -> x7 - v22 LoadLocal { off=-2, kind=I64 } -> x8 - v23 Binop { op=and, lhs=v21, rhs=v3 } -> x7 - v24 Binop { op=ne, lhs=v19, rhs=v23 } -> x6 + v14 LoadLocal { off=-1, kind=I64, volatile } -> x0 + v15 LoadLocal { off=-2, kind=I64, volatile } -> x1 + v16 Imm(0) -> x2 + v17 Imm(0) -> x2 + v18 BinopI { op=xor, lhs=v14, rhs_imm=-1 } -> x0 + v19 Binop { op=and, lhs=v18, rhs=v15 } -> x0 + v20 LoadLocal { off=-1, kind=I64, volatile } -> x1 + v21 BinopI { op=xor, lhs=v20, rhs_imm=-1 } -> x1 + v22 LoadLocal { off=-2, kind=I64, volatile } -> x2 + v23 Binop { op=and, lhs=v21, rhs=v22 } -> x1 + v24 Binop { op=ne, lhs=v19, rhs=v23 } -> x0 terminator Bz { cond=v24, target=b4, fall=b3 } (exit_acc=v24) block 3 start_pc=0 v25 Imm(2) -> x0 terminator Return(v25) (exit_acc=v25) block 4 start_pc=0 - v26 LoadLocal { off=-1, kind=I64 } -> x6 - v27 LoadLocal { off=-2, kind=I64 } -> x6 - v28 LoadLocal { off=-3, kind=I64 } -> x6 + v26 LoadLocal { off=-1, kind=I64, volatile } -> x0 + v27 LoadLocal { off=-2, kind=I64, volatile } -> x1 + v28 LoadLocal { off=-3, kind=I64, volatile } -> x2 v29 Imm(0) -> x6 v30 Imm(0) -> x6 v31 Imm(0) -> x6 - v32 Binop { op=and, lhs=v1, rhs=v3 } -> x6 - v33 BinopI { op=xor, lhs=v1, rhs_imm=-1 } -> x7 - v34 Binop { op=and, lhs=v33, rhs=v5 } -> x7 - v35 Binop { op=xor, lhs=v32, rhs=v34 } -> x6 - v36 LoadLocal { off=-1, kind=I64 } -> x7 - v37 LoadLocal { off=-2, kind=I64 } -> x7 - v38 Binop { op=and, lhs=v1, rhs=v3 } -> x1 - v39 BinopI { op=xor, lhs=v1, rhs_imm=-1 } -> x0 - v40 LoadLocal { off=-3, kind=I64 } -> x7 - v41 Binop { op=and, lhs=v39, rhs=v5 } -> x0 - v42 Binop { op=xor, lhs=v38, rhs=v41 } -> x0 - v43 Binop { op=ne, lhs=v35, rhs=v42 } -> x0 - terminator Bz { cond=v43, target=b6, fall=b5 } (exit_acc=v43) + v32 Binop { op=and, lhs=v26, rhs=v27 } -> x1 + v33 BinopI { op=xor, lhs=v26, rhs_imm=-1 } -> x0 + v34 Binop { op=and, lhs=v33, rhs=v28 } -> x0 + v35 Binop { op=xor, lhs=v32, rhs=v34 } -> x0 + v36 LoadLocal { off=-1, kind=I64, volatile } -> x1 + v37 LoadLocal { off=-2, kind=I64, volatile } -> x2 + v38 Binop { op=and, lhs=v36, rhs=v37 } -> x1 + v39 LoadLocal { off=-1, kind=I64, volatile } -> x2 + v40 BinopI { op=xor, lhs=v39, rhs_imm=-1 } -> x2 + v41 LoadLocal { off=-3, kind=I64, volatile } -> x6 + v42 Binop { op=and, lhs=v40, rhs=v41 } -> x2 + v43 Binop { op=xor, lhs=v38, rhs=v42 } -> x1 + v44 Binop { op=ne, lhs=v35, rhs=v43 } -> x0 + terminator Bz { cond=v44, target=b6, fall=b5 } (exit_acc=v44) block 5 start_pc=0 - v44 Imm(3) -> x0 - terminator Return(v44) (exit_acc=v44) + v45 Imm(3) -> x0 + terminator Return(v45) (exit_acc=v45) block 6 start_pc=0 - v45 Imm(0) -> x0 - v46 Imm(0) -> x1 - v47 LoadLocal { off=-1, kind=I64 } -> x1 - v48 Imm(0) -> x1 - v49 BinopI { op=xor, lhs=v45, rhs_imm=-1 } -> x0 - v50 Imm(-1) -> x1 - v51 BinopI { op=ne, lhs=v49, rhs_imm=-1 } -> x0 - terminator Bz { cond=v51, target=b8, fall=b7 } (exit_acc=v51) + v46 Imm(0) -> x0 + v47 StoreLocal { off=-1, value=v46, kind=I64, volatile } -> - + v48 LoadLocal { off=-1, kind=I64, volatile } -> x0 + v49 Imm(0) -> x1 + v50 BinopI { op=xor, lhs=v48, rhs_imm=-1 } -> x0 + v51 Imm(-1) -> x1 + v52 BinopI { op=ne, lhs=v50, rhs_imm=-1 } -> x0 + terminator Bz { cond=v52, target=b8, fall=b7 } (exit_acc=v52) block 7 start_pc=0 - v52 Imm(4) -> x0 - terminator Return(v52) (exit_acc=v52) + v53 Imm(4) -> x0 + terminator Return(v53) (exit_acc=v53) block 8 start_pc=0 - v53 Imm(-1) -> x0 - v54 Imm(0) -> x1 - v55 LoadLocal { off=-1, kind=I64 } -> x1 - v56 Imm(0) -> x1 - v57 BinopI { op=xor, lhs=v53, rhs_imm=-1 } -> x0 - v58 BinopI { op=ne, lhs=v57, rhs_imm=0 } -> x0 - terminator Bz { cond=v58, target=b10, fall=b9 } (exit_acc=v58) + v54 Imm(-1) -> x0 + v55 StoreLocal { off=-1, value=v54, kind=I64, volatile } -> - + v56 LoadLocal { off=-1, kind=I64, volatile } -> x0 + v57 Imm(0) -> x1 + v58 BinopI { op=xor, lhs=v56, rhs_imm=-1 } -> x0 + v59 BinopI { op=ne, lhs=v58, rhs_imm=0 } -> x0 + terminator Bz { cond=v59, target=b10, fall=b9 } (exit_acc=v59) block 9 start_pc=0 - v59 Imm(5) -> x0 - terminator Return(v59) (exit_acc=v59) - block 10 start_pc=0 - v60 Imm(0) -> x0 + v60 Imm(5) -> x0 terminator Return(v60) (exit_acc=v60) + block 10 start_pc=0 + v61 Imm(0) -> x0 + terminator Return(v61) (exit_acc=v61) ; --- SSA dump (ok=true) ent_pc=0 --- ; name=__c5_exit fn ent_pc=0 n_params=1 variadic=false locals=1 diff --git a/tests/snapshots/ssa/block_scope_typedef_variadic_fnptr.ssa b/tests/snapshots/ssa/block_scope_typedef_variadic_fnptr.ssa new file mode 100644 index 000000000..958c2e6ae --- /dev/null +++ b/tests/snapshots/ssa/block_scope_typedef_variadic_fnptr.ssa @@ -0,0 +1,84 @@ +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=13 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-8) -> x0 + v2 Imm(0) -> x1 + v3 Store { addr=v1, disp=0, value=v2, kind=I8 } -> - + v4 LocalAddr(-8) -> x7 + v5 Imm(64) -> x6 + v6 ImmData(64) -> x2 + v7 Imm(7) -> x1 + v8 ImmData(70) -> x8 + v9 ImmData(56) -> x0 + v10 Load { addr=v9, disp=0, kind=I64 } -> x0 + v11 CallIndirect { target=v10, args=[v4, v5, v6, v7, v8], callee_variadic=true, fixed_args=3, fp_return=false, fp_arg_mask=0x0 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 LocalAddr(-8) -> x7 + v15 ImmData(75) -> x6 + v16 CallExt { binding_idx=62, args=[v14, v15], fp_arg_mask=0x0 } -> x0 + v17 BinopI { op=ne, lhs=v16, rhs_imm=0 } -> x0 + terminator Bz { cond=v17, target=b2, fall=b1 } (exit_acc=v17) + block 1 start_pc=0 + v18 Imm(1) -> x0 + terminator Return(v18) (exit_acc=v18) + block 2 start_pc=0 + v19 Imm(0) -> x0 + terminator Return(v19) (exit_acc=v19) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=__c5_sys_snprintf +fn ent_pc=2 n_params=0 variadic=false locals=0 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + terminator TailExt(3) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/builtin_bit_count.ssa b/tests/snapshots/ssa/builtin_bit_count.ssa index 498db7437..562ed4174 100644 --- a/tests/snapshots/ssa/builtin_bit_count.ssa +++ b/tests/snapshots/ssa/builtin_bit_count.ssa @@ -707,79 +707,79 @@ fn ent_pc=1 n_params=0 variadic=false locals=4 terminator Return(v608) (exit_acc=v608) block 40 start_pc=0 v609 Imm(16711935) -> x0 - v610 Imm(0) -> x1 - v611 LoadLocal { off=-1, kind=U32 } -> x1 - v612 BinopI { op=shru, lhs=v609, rhs_imm=1 } -> x1 + v610 StoreLocal { off=-1, value=v609, kind=I32, volatile } -> - + v611 LoadLocal { off=-1, kind=U32, volatile } -> x0 + v612 BinopI { op=shru, lhs=v611, rhs_imm=1 } -> x1 v613 BinopI { op=and, lhs=v612, rhs_imm=1431655765 } -> x1 - v614 Binop { op=sub, lhs=v609, rhs=v613 } -> x1 - v615 BinopI { op=and, lhs=v614, rhs_imm=858993459 } -> x2 - v616 BinopI { op=shru, lhs=v614, rhs_imm=2 } -> x1 - v617 BinopI { op=and, lhs=v616, rhs_imm=858993459 } -> x1 - v618 Binop { op=add, lhs=v615, rhs=v617 } -> x1 - v619 BinopI { op=shru, lhs=v618, rhs_imm=4 } -> x2 - v620 Binop { op=add, lhs=v618, rhs=v619 } -> x1 - v621 BinopI { op=and, lhs=v620, rhs_imm=252645135 } -> x1 - v622 BinopI { op=shru, lhs=v621, rhs_imm=8 } -> x2 - v623 Binop { op=add, lhs=v621, rhs=v622 } -> x1 - v624 BinopI { op=shru, lhs=v623, rhs_imm=16 } -> x2 - v625 Binop { op=add, lhs=v623, rhs=v624 } -> x1 - v626 BinopI { op=and, lhs=v625, rhs_imm=127 } -> x1 - v627 Imm(16) -> x2 - v628 Extend { value=v626, kind=I32 } -> x1 - v629 Imm(0) -> x6 - v630 Extend { value=v627, kind=I32 } -> x2 - v631 Imm(0) -> x6 - v632 Binop { op=eq, lhs=v628, rhs=v630 } -> x1 - v633 BinopI { op=eq, lhs=v632, rhs_imm=0 } -> x1 + v614 Binop { op=sub, lhs=v611, rhs=v613 } -> x0 + v615 BinopI { op=and, lhs=v614, rhs_imm=858993459 } -> x1 + v616 BinopI { op=shru, lhs=v614, rhs_imm=2 } -> x0 + v617 BinopI { op=and, lhs=v616, rhs_imm=858993459 } -> x0 + v618 Binop { op=add, lhs=v615, rhs=v617 } -> x0 + v619 BinopI { op=shru, lhs=v618, rhs_imm=4 } -> x1 + v620 Binop { op=add, lhs=v618, rhs=v619 } -> x0 + v621 BinopI { op=and, lhs=v620, rhs_imm=252645135 } -> x0 + v622 BinopI { op=shru, lhs=v621, rhs_imm=8 } -> x1 + v623 Binop { op=add, lhs=v621, rhs=v622 } -> x0 + v624 BinopI { op=shru, lhs=v623, rhs_imm=16 } -> x1 + v625 Binop { op=add, lhs=v623, rhs=v624 } -> x0 + v626 BinopI { op=and, lhs=v625, rhs_imm=127 } -> x0 + v627 Imm(16) -> x1 + v628 Extend { value=v626, kind=I32 } -> x0 + v629 Imm(0) -> x2 + v630 Extend { value=v627, kind=I32 } -> x1 + v631 Imm(0) -> x2 + v632 Binop { op=eq, lhs=v628, rhs=v630 } -> x0 + v633 BinopI { op=eq, lhs=v632, rhs_imm=0 } -> x0 terminator Bz { cond=v633, target=b42, fall=b41 } (exit_acc=v633) block 41 start_pc=0 v634 Imm(21) -> x0 terminator Return(v634) (exit_acc=v634) block 42 start_pc=0 - v635 LoadLocal { off=-1, kind=U32 } -> x1 - v636 BinopI { op=shru, lhs=v609, rhs_imm=1 } -> x1 - v637 Binop { op=or, lhs=v609, rhs=v636 } -> x1 - v638 BinopI { op=shru, lhs=v637, rhs_imm=2 } -> x2 - v639 Binop { op=or, lhs=v637, rhs=v638 } -> x1 - v640 BinopI { op=shru, lhs=v639, rhs_imm=4 } -> x2 - v641 Binop { op=or, lhs=v639, rhs=v640 } -> x1 - v642 BinopI { op=shru, lhs=v641, rhs_imm=8 } -> x2 - v643 Binop { op=or, lhs=v641, rhs=v642 } -> x1 - v644 BinopI { op=shru, lhs=v643, rhs_imm=16 } -> x2 - v645 Binop { op=or, lhs=v643, rhs=v644 } -> x1 - v646 BinopI { op=and, lhs=v645, rhs_imm=4294967295 } -> x1 - v647 BinopI { op=shru, lhs=v646, rhs_imm=1 } -> x2 - v648 BinopI { op=and, lhs=v647, rhs_imm=1431655765 } -> x2 - v649 Binop { op=sub, lhs=v646, rhs=v648 } -> x1 - v650 BinopI { op=and, lhs=v649, rhs_imm=858993459 } -> x2 - v651 BinopI { op=shru, lhs=v649, rhs_imm=2 } -> x1 - v652 BinopI { op=and, lhs=v651, rhs_imm=858993459 } -> x1 - v653 Binop { op=add, lhs=v650, rhs=v652 } -> x1 - v654 BinopI { op=shru, lhs=v653, rhs_imm=4 } -> x2 - v655 Binop { op=add, lhs=v653, rhs=v654 } -> x1 - v656 BinopI { op=and, lhs=v655, rhs_imm=252645135 } -> x1 - v657 BinopI { op=shru, lhs=v656, rhs_imm=8 } -> x2 - v658 Binop { op=add, lhs=v656, rhs=v657 } -> x1 - v659 BinopI { op=shru, lhs=v658, rhs_imm=16 } -> x2 - v660 Binop { op=add, lhs=v658, rhs=v659 } -> x1 - v661 BinopI { op=and, lhs=v660, rhs_imm=127 } -> x1 - v662 Imm(32) -> x2 - v663 Binop { op=sub, lhs=v662, rhs=v661 } -> x1 - v664 Imm(8) -> x2 - v665 Extend { value=v663, kind=I32 } -> x1 - v666 Imm(0) -> x6 - v667 Extend { value=v664, kind=I32 } -> x2 - v668 Imm(0) -> x6 - v669 Binop { op=eq, lhs=v665, rhs=v667 } -> x1 - v670 BinopI { op=eq, lhs=v669, rhs_imm=0 } -> x1 + v635 LoadLocal { off=-1, kind=U32, volatile } -> x0 + v636 BinopI { op=shru, lhs=v635, rhs_imm=1 } -> x1 + v637 Binop { op=or, lhs=v635, rhs=v636 } -> x0 + v638 BinopI { op=shru, lhs=v637, rhs_imm=2 } -> x1 + v639 Binop { op=or, lhs=v637, rhs=v638 } -> x0 + v640 BinopI { op=shru, lhs=v639, rhs_imm=4 } -> x1 + v641 Binop { op=or, lhs=v639, rhs=v640 } -> x0 + v642 BinopI { op=shru, lhs=v641, rhs_imm=8 } -> x1 + v643 Binop { op=or, lhs=v641, rhs=v642 } -> x0 + v644 BinopI { op=shru, lhs=v643, rhs_imm=16 } -> x1 + v645 Binop { op=or, lhs=v643, rhs=v644 } -> x0 + v646 BinopI { op=and, lhs=v645, rhs_imm=4294967295 } -> x0 + v647 BinopI { op=shru, lhs=v646, rhs_imm=1 } -> x1 + v648 BinopI { op=and, lhs=v647, rhs_imm=1431655765 } -> x1 + v649 Binop { op=sub, lhs=v646, rhs=v648 } -> x0 + v650 BinopI { op=and, lhs=v649, rhs_imm=858993459 } -> x1 + v651 BinopI { op=shru, lhs=v649, rhs_imm=2 } -> x0 + v652 BinopI { op=and, lhs=v651, rhs_imm=858993459 } -> x0 + v653 Binop { op=add, lhs=v650, rhs=v652 } -> x0 + v654 BinopI { op=shru, lhs=v653, rhs_imm=4 } -> x1 + v655 Binop { op=add, lhs=v653, rhs=v654 } -> x0 + v656 BinopI { op=and, lhs=v655, rhs_imm=252645135 } -> x0 + v657 BinopI { op=shru, lhs=v656, rhs_imm=8 } -> x1 + v658 Binop { op=add, lhs=v656, rhs=v657 } -> x0 + v659 BinopI { op=shru, lhs=v658, rhs_imm=16 } -> x1 + v660 Binop { op=add, lhs=v658, rhs=v659 } -> x0 + v661 BinopI { op=and, lhs=v660, rhs_imm=127 } -> x0 + v662 Imm(32) -> x1 + v663 Binop { op=sub, lhs=v662, rhs=v661 } -> x0 + v664 Imm(8) -> x1 + v665 Extend { value=v663, kind=I32 } -> x0 + v666 Imm(0) -> x2 + v667 Extend { value=v664, kind=I32 } -> x1 + v668 Imm(0) -> x2 + v669 Binop { op=eq, lhs=v665, rhs=v667 } -> x0 + v670 BinopI { op=eq, lhs=v669, rhs_imm=0 } -> x0 terminator Bz { cond=v670, target=b44, fall=b43 } (exit_acc=v670) block 43 start_pc=0 v671 Imm(22) -> x0 terminator Return(v671) (exit_acc=v671) block 44 start_pc=0 - v672 LoadLocal { off=-1, kind=U32 } -> x1 - v673 BinopI { op=sub, lhs=v609, rhs_imm=1 } -> x1 - v674 BinopI { op=xor, lhs=v609, rhs_imm=-1 } -> x0 + v672 LoadLocal { off=-1, kind=U32, volatile } -> x0 + v673 BinopI { op=sub, lhs=v672, rhs_imm=1 } -> x1 + v674 BinopI { op=xor, lhs=v672, rhs_imm=-1 } -> x0 v675 Binop { op=and, lhs=v673, rhs=v674 } -> x0 v676 BinopI { op=and, lhs=v675, rhs_imm=4294967295 } -> x0 v677 BinopI { op=shru, lhs=v676, rhs_imm=1 } -> x1 @@ -934,40 +934,40 @@ fn ent_pc=1 n_params=0 variadic=false locals=4 terminator Return(v807) (exit_acc=v807) block 54 start_pc=0 v808 Imm(16711935) -> x0 - v809 Imm(0) -> x1 - v810 LoadLocal { off=-2, kind=I64 } -> x1 - v811 BinopI { op=shru, lhs=v808, rhs_imm=1 } -> x1 + v809 StoreLocal { off=-2, value=v808, kind=I64, volatile } -> - + v810 LoadLocal { off=-2, kind=I64, volatile } -> x0 + v811 BinopI { op=shru, lhs=v810, rhs_imm=1 } -> x1 v812 BinopI { op=and, lhs=v811, rhs_imm=6148914691236517205 } -> x1 - v813 Binop { op=sub, lhs=v808, rhs=v812 } -> x1 - v814 BinopI { op=and, lhs=v813, rhs_imm=3689348814741910323 } -> x2 - v815 BinopI { op=shru, lhs=v813, rhs_imm=2 } -> x1 - v816 BinopI { op=and, lhs=v815, rhs_imm=3689348814741910323 } -> x1 - v817 Binop { op=add, lhs=v814, rhs=v816 } -> x1 - v818 BinopI { op=shru, lhs=v817, rhs_imm=4 } -> x2 - v819 Binop { op=add, lhs=v817, rhs=v818 } -> x1 - v820 BinopI { op=and, lhs=v819, rhs_imm=1085102592571150095 } -> x1 - v821 BinopI { op=shru, lhs=v820, rhs_imm=8 } -> x2 - v822 Binop { op=add, lhs=v820, rhs=v821 } -> x1 - v823 BinopI { op=shru, lhs=v822, rhs_imm=16 } -> x2 - v824 Binop { op=add, lhs=v822, rhs=v823 } -> x1 - v825 BinopI { op=shru, lhs=v824, rhs_imm=32 } -> x2 - v826 Binop { op=add, lhs=v824, rhs=v825 } -> x1 - v827 BinopI { op=and, lhs=v826, rhs_imm=127 } -> x1 - v828 Imm(16) -> x2 - v829 Extend { value=v827, kind=I32 } -> x1 - v830 Imm(0) -> x6 - v831 Extend { value=v828, kind=I32 } -> x2 - v832 Imm(0) -> x6 - v833 Binop { op=eq, lhs=v829, rhs=v831 } -> x1 - v834 BinopI { op=eq, lhs=v833, rhs_imm=0 } -> x1 + v813 Binop { op=sub, lhs=v810, rhs=v812 } -> x0 + v814 BinopI { op=and, lhs=v813, rhs_imm=3689348814741910323 } -> x1 + v815 BinopI { op=shru, lhs=v813, rhs_imm=2 } -> x0 + v816 BinopI { op=and, lhs=v815, rhs_imm=3689348814741910323 } -> x0 + v817 Binop { op=add, lhs=v814, rhs=v816 } -> x0 + v818 BinopI { op=shru, lhs=v817, rhs_imm=4 } -> x1 + v819 Binop { op=add, lhs=v817, rhs=v818 } -> x0 + v820 BinopI { op=and, lhs=v819, rhs_imm=1085102592571150095 } -> x0 + v821 BinopI { op=shru, lhs=v820, rhs_imm=8 } -> x1 + v822 Binop { op=add, lhs=v820, rhs=v821 } -> x0 + v823 BinopI { op=shru, lhs=v822, rhs_imm=16 } -> x1 + v824 Binop { op=add, lhs=v822, rhs=v823 } -> x0 + v825 BinopI { op=shru, lhs=v824, rhs_imm=32 } -> x1 + v826 Binop { op=add, lhs=v824, rhs=v825 } -> x0 + v827 BinopI { op=and, lhs=v826, rhs_imm=127 } -> x0 + v828 Imm(16) -> x1 + v829 Extend { value=v827, kind=I32 } -> x0 + v830 Imm(0) -> x2 + v831 Extend { value=v828, kind=I32 } -> x1 + v832 Imm(0) -> x2 + v833 Binop { op=eq, lhs=v829, rhs=v831 } -> x0 + v834 BinopI { op=eq, lhs=v833, rhs_imm=0 } -> x0 terminator Bz { cond=v834, target=b56, fall=b55 } (exit_acc=v834) block 55 start_pc=0 v835 Imm(28) -> x0 terminator Return(v835) (exit_acc=v835) block 56 start_pc=0 - v836 LoadLocal { off=-2, kind=I64 } -> x1 - v837 BinopI { op=sub, lhs=v808, rhs_imm=1 } -> x1 - v838 BinopI { op=xor, lhs=v808, rhs_imm=-1 } -> x0 + v836 LoadLocal { off=-2, kind=I64, volatile } -> x0 + v837 BinopI { op=sub, lhs=v836, rhs_imm=1 } -> x1 + v838 BinopI { op=xor, lhs=v836, rhs_imm=-1 } -> x0 v839 Binop { op=and, lhs=v837, rhs=v838 } -> x0 v840 BinopI { op=shru, lhs=v839, rhs_imm=1 } -> x1 v841 BinopI { op=and, lhs=v840, rhs_imm=6148914691236517205 } -> x1 diff --git a/tests/snapshots/ssa/builtin_bswap_expect.ssa b/tests/snapshots/ssa/builtin_bswap_expect.ssa index 2e89e5e6f..e093fa1ad 100644 --- a/tests/snapshots/ssa/builtin_bswap_expect.ssa +++ b/tests/snapshots/ssa/builtin_bswap_expect.ssa @@ -71,19 +71,19 @@ fn ent_pc=0 n_params=0 variadic=false locals=2 terminator Return(v53) (exit_acc=v53) block 6 start_pc=0 v54 Imm(2864434397) -> x0 - v55 Imm(0) -> x1 - v56 LoadLocal { off=-1, kind=U32 } -> x1 - v57 BinopI { op=and, lhs=v54, rhs_imm=255 } -> x1 + v55 StoreLocal { off=-1, value=v54, kind=I32, volatile } -> - + v56 LoadLocal { off=-1, kind=U32, volatile } -> x0 + v57 BinopI { op=and, lhs=v56, rhs_imm=255 } -> x1 v58 BinopI { op=shl, lhs=v57, rhs_imm=24 } -> x1 - v59 BinopI { op=shru, lhs=v54, rhs_imm=8 } -> x2 + v59 BinopI { op=shru, lhs=v56, rhs_imm=8 } -> x2 v60 BinopI { op=and, lhs=v59, rhs_imm=255 } -> x2 v61 BinopI { op=shl, lhs=v60, rhs_imm=16 } -> x2 v62 Binop { op=or, lhs=v58, rhs=v61 } -> x1 - v63 BinopI { op=shru, lhs=v54, rhs_imm=16 } -> x2 + v63 BinopI { op=shru, lhs=v56, rhs_imm=16 } -> x2 v64 BinopI { op=and, lhs=v63, rhs_imm=255 } -> x2 v65 BinopI { op=shl, lhs=v64, rhs_imm=8 } -> x2 v66 Binop { op=or, lhs=v62, rhs=v65 } -> x1 - v67 BinopI { op=shru, lhs=v54, rhs_imm=24 } -> x0 + v67 BinopI { op=shru, lhs=v56, rhs_imm=24 } -> x0 v68 BinopI { op=and, lhs=v67, rhs_imm=255 } -> x0 v69 Binop { op=or, lhs=v66, rhs=v68 } -> x0 v70 BinopI { op=ne, lhs=v69, rhs_imm=3721182122 } -> x0 diff --git a/tests/snapshots/ssa/c11_atomic_specifier.ssa b/tests/snapshots/ssa/c11_atomic_specifier.ssa index 06ae77c33..8bcb10c36 100644 --- a/tests/snapshots/ssa/c11_atomic_specifier.ssa +++ b/tests/snapshots/ssa/c11_atomic_specifier.ssa @@ -73,23 +73,23 @@ fn ent_pc=0 n_params=0 variadic=false locals=9 v43 Imm(99) -> x0 v44 Imm(0) -> x1 v45 Imm(13) -> x1 - v46 Imm(0) -> x2 - v47 LoadLocal { off=-6, kind=I32 } -> x2 - v48 BinopI { op=ne, lhs=v47, rhs_imm=-7 } -> x2 + v46 StoreLocal { off=-8, value=v45, kind=I16, volatile } -> - + v47 LoadLocal { off=-6, kind=I32 } -> x1 + v48 BinopI { op=ne, lhs=v47, rhs_imm=-7 } -> x1 terminator Bz { cond=v48, target=b14, fall=b13 } (exit_acc=v48) block 13 start_pc=0 v49 Imm(7) -> x0 terminator Return(v49) (exit_acc=v49) block 14 start_pc=0 - v50 LoadLocal { off=-7, kind=I64 } -> x2 + v50 LoadLocal { off=-7, kind=I64 } -> x1 v51 BinopI { op=ne, lhs=v43, rhs_imm=99 } -> x0 terminator Bz { cond=v51, target=b16, fall=b15 } (exit_acc=v51) block 15 start_pc=0 v52 Imm(8) -> x0 terminator Return(v52) (exit_acc=v52) block 16 start_pc=0 - v53 LoadLocal { off=-8, kind=I16 } -> x0 - v54 BinopI { op=ne, lhs=v45, rhs_imm=13 } -> x0 + v53 LoadLocal { off=-8, kind=I16, volatile } -> x0 + v54 BinopI { op=ne, lhs=v53, rhs_imm=13 } -> x0 terminator Bz { cond=v54, target=b18, fall=b17 } (exit_acc=v54) block 17 start_pc=0 v55 Imm(9) -> x0 diff --git a/tests/snapshots/ssa/call_sp_adjust_imm12_overflow.ssa b/tests/snapshots/ssa/call_sp_adjust_imm12_overflow.ssa new file mode 100644 index 000000000..f1e940f47 --- /dev/null +++ b/tests/snapshots/ssa/call_sp_adjust_imm12_overflow.ssa @@ -0,0 +1,4835 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=sum_pairs +fn ent_pc=0 n_params=261 variadic=false locals=523 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(0) -> x0 + v2 Imm(0) -> x1 + v3 LoadLocal { off=-523, kind=I64 } -> x1 + v4 LocalAddr(-2) -> x1 + v5 Load { addr=v4, disp=0, kind=I64 } -> x1 + v6 LocalAddr(-2) -> x2 + v7 BinopI { op=add, lhs=v6, rhs_imm=8 } -> x6 + v8 Load { addr=v6, disp=8, kind=I64 } -> x2 + v9 Binop { op=add, lhs=v5, rhs=v8 } -> x1 + v10 Binop { op=add, lhs=v1, rhs=v9 } -> x0 + v11 Imm(0) -> x1 + v12 LoadLocal { off=-523, kind=I64 } -> x1 + v13 LocalAddr(-4) -> x1 + v14 Load { addr=v13, disp=0, kind=I64 } -> x1 + v15 LocalAddr(-4) -> x2 + v16 BinopI { op=add, lhs=v15, rhs_imm=8 } -> x6 + v17 Load { addr=v15, disp=8, kind=I64 } -> x2 + v18 Binop { op=add, lhs=v14, rhs=v17 } -> x1 + v19 Binop { op=add, lhs=v10, rhs=v18 } -> x0 + v20 Imm(0) -> x1 + v21 LoadLocal { off=-523, kind=I64 } -> x1 + v22 LocalAddr(-6) -> x1 + v23 Load { addr=v22, disp=0, kind=I64 } -> x1 + v24 LocalAddr(-6) -> x2 + v25 BinopI { op=add, lhs=v24, rhs_imm=8 } -> x6 + v26 Load { addr=v24, disp=8, kind=I64 } -> x2 + v27 Binop { op=add, lhs=v23, rhs=v26 } -> x1 + v28 Binop { op=add, lhs=v19, rhs=v27 } -> x0 + v29 Imm(0) -> x1 + v30 LoadLocal { off=-523, kind=I64 } -> x1 + v31 LocalAddr(-8) -> x1 + v32 Load { addr=v31, disp=0, kind=I64 } -> x1 + v33 LocalAddr(-8) -> x2 + v34 BinopI { op=add, lhs=v33, rhs_imm=8 } -> x6 + v35 Load { addr=v33, disp=8, kind=I64 } -> x2 + v36 Binop { op=add, lhs=v32, rhs=v35 } -> x1 + v37 Binop { op=add, lhs=v28, rhs=v36 } -> x0 + v38 Imm(0) -> x1 + v39 LoadLocal { off=-523, kind=I64 } -> x1 + v40 LocalAddr(-10) -> x1 + v41 Load { addr=v40, disp=0, kind=I64 } -> x1 + v42 LocalAddr(-10) -> x2 + v43 BinopI { op=add, lhs=v42, rhs_imm=8 } -> x6 + v44 Load { addr=v42, disp=8, kind=I64 } -> x2 + v45 Binop { op=add, lhs=v41, rhs=v44 } -> x1 + v46 Binop { op=add, lhs=v37, rhs=v45 } -> x0 + v47 Imm(0) -> x1 + v48 LoadLocal { off=-523, kind=I64 } -> x1 + v49 LocalAddr(-12) -> x1 + v50 Load { addr=v49, disp=0, kind=I64 } -> x1 + v51 LocalAddr(-12) -> x2 + v52 BinopI { op=add, lhs=v51, rhs_imm=8 } -> x6 + v53 Load { addr=v51, disp=8, kind=I64 } -> x2 + v54 Binop { op=add, lhs=v50, rhs=v53 } -> x1 + v55 Binop { op=add, lhs=v46, rhs=v54 } -> x0 + v56 Imm(0) -> x1 + v57 LoadLocal { off=-523, kind=I64 } -> x1 + v58 LocalAddr(-14) -> x1 + v59 Load { addr=v58, disp=0, kind=I64 } -> x1 + v60 LocalAddr(-14) -> x2 + v61 BinopI { op=add, lhs=v60, rhs_imm=8 } -> x6 + v62 Load { addr=v60, disp=8, kind=I64 } -> x2 + v63 Binop { op=add, lhs=v59, rhs=v62 } -> x1 + v64 Binop { op=add, lhs=v55, rhs=v63 } -> x0 + v65 Imm(0) -> x1 + v66 LoadLocal { off=-523, kind=I64 } -> x1 + v67 LocalAddr(-16) -> x1 + v68 Load { addr=v67, disp=0, kind=I64 } -> x1 + v69 LocalAddr(-16) -> x2 + v70 BinopI { op=add, lhs=v69, rhs_imm=8 } -> x6 + v71 Load { addr=v69, disp=8, kind=I64 } -> x2 + v72 Binop { op=add, lhs=v68, rhs=v71 } -> x1 + v73 Binop { op=add, lhs=v64, rhs=v72 } -> x0 + v74 Imm(0) -> x1 + v75 LoadLocal { off=-523, kind=I64 } -> x1 + v76 LocalAddr(-18) -> x1 + v77 Load { addr=v76, disp=0, kind=I64 } -> x1 + v78 LocalAddr(-18) -> x2 + v79 BinopI { op=add, lhs=v78, rhs_imm=8 } -> x6 + v80 Load { addr=v78, disp=8, kind=I64 } -> x2 + v81 Binop { op=add, lhs=v77, rhs=v80 } -> x1 + v82 Binop { op=add, lhs=v73, rhs=v81 } -> x0 + v83 Imm(0) -> x1 + v84 LoadLocal { off=-523, kind=I64 } -> x1 + v85 LocalAddr(-20) -> x1 + v86 Load { addr=v85, disp=0, kind=I64 } -> x1 + v87 LocalAddr(-20) -> x2 + v88 BinopI { op=add, lhs=v87, rhs_imm=8 } -> x6 + v89 Load { addr=v87, disp=8, kind=I64 } -> x2 + v90 Binop { op=add, lhs=v86, rhs=v89 } -> x1 + v91 Binop { op=add, lhs=v82, rhs=v90 } -> x0 + v92 Imm(0) -> x1 + v93 LoadLocal { off=-523, kind=I64 } -> x1 + v94 LocalAddr(-22) -> x1 + v95 Load { addr=v94, disp=0, kind=I64 } -> x1 + v96 LocalAddr(-22) -> x2 + v97 BinopI { op=add, lhs=v96, rhs_imm=8 } -> x6 + v98 Load { addr=v96, disp=8, kind=I64 } -> x2 + v99 Binop { op=add, lhs=v95, rhs=v98 } -> x1 + v100 Binop { op=add, lhs=v91, rhs=v99 } -> x0 + v101 Imm(0) -> x1 + v102 LoadLocal { off=-523, kind=I64 } -> x1 + v103 LocalAddr(-24) -> x1 + v104 Load { addr=v103, disp=0, kind=I64 } -> x1 + v105 LocalAddr(-24) -> x2 + v106 BinopI { op=add, lhs=v105, rhs_imm=8 } -> x6 + v107 Load { addr=v105, disp=8, kind=I64 } -> x2 + v108 Binop { op=add, lhs=v104, rhs=v107 } -> x1 + v109 Binop { op=add, lhs=v100, rhs=v108 } -> x0 + v110 Imm(0) -> x1 + v111 LoadLocal { off=-523, kind=I64 } -> x1 + v112 LocalAddr(-26) -> x1 + v113 Load { addr=v112, disp=0, kind=I64 } -> x1 + v114 LocalAddr(-26) -> x2 + v115 BinopI { op=add, lhs=v114, rhs_imm=8 } -> x6 + v116 Load { addr=v114, disp=8, kind=I64 } -> x2 + v117 Binop { op=add, lhs=v113, rhs=v116 } -> x1 + v118 Binop { op=add, lhs=v109, rhs=v117 } -> x0 + v119 Imm(0) -> x1 + v120 LoadLocal { off=-523, kind=I64 } -> x1 + v121 LocalAddr(-28) -> x1 + v122 Load { addr=v121, disp=0, kind=I64 } -> x1 + v123 LocalAddr(-28) -> x2 + v124 BinopI { op=add, lhs=v123, rhs_imm=8 } -> x6 + v125 Load { addr=v123, disp=8, kind=I64 } -> x2 + v126 Binop { op=add, lhs=v122, rhs=v125 } -> x1 + v127 Binop { op=add, lhs=v118, rhs=v126 } -> x0 + v128 Imm(0) -> x1 + v129 LoadLocal { off=-523, kind=I64 } -> x1 + v130 LocalAddr(-30) -> x1 + v131 Load { addr=v130, disp=0, kind=I64 } -> x1 + v132 LocalAddr(-30) -> x2 + v133 BinopI { op=add, lhs=v132, rhs_imm=8 } -> x6 + v134 Load { addr=v132, disp=8, kind=I64 } -> x2 + v135 Binop { op=add, lhs=v131, rhs=v134 } -> x1 + v136 Binop { op=add, lhs=v127, rhs=v135 } -> x0 + v137 Imm(0) -> x1 + v138 LoadLocal { off=-523, kind=I64 } -> x1 + v139 LocalAddr(-32) -> x1 + v140 Load { addr=v139, disp=0, kind=I64 } -> x1 + v141 LocalAddr(-32) -> x2 + v142 BinopI { op=add, lhs=v141, rhs_imm=8 } -> x6 + v143 Load { addr=v141, disp=8, kind=I64 } -> x2 + v144 Binop { op=add, lhs=v140, rhs=v143 } -> x1 + v145 Binop { op=add, lhs=v136, rhs=v144 } -> x0 + v146 Imm(0) -> x1 + v147 LoadLocal { off=-523, kind=I64 } -> x1 + v148 LocalAddr(-34) -> x1 + v149 Load { addr=v148, disp=0, kind=I64 } -> x1 + v150 LocalAddr(-34) -> x2 + v151 BinopI { op=add, lhs=v150, rhs_imm=8 } -> x6 + v152 Load { addr=v150, disp=8, kind=I64 } -> x2 + v153 Binop { op=add, lhs=v149, rhs=v152 } -> x1 + v154 Binop { op=add, lhs=v145, rhs=v153 } -> x0 + v155 Imm(0) -> x1 + v156 LoadLocal { off=-523, kind=I64 } -> x1 + v157 LocalAddr(-36) -> x1 + v158 Load { addr=v157, disp=0, kind=I64 } -> x1 + v159 LocalAddr(-36) -> x2 + v160 BinopI { op=add, lhs=v159, rhs_imm=8 } -> x6 + v161 Load { addr=v159, disp=8, kind=I64 } -> x2 + v162 Binop { op=add, lhs=v158, rhs=v161 } -> x1 + v163 Binop { op=add, lhs=v154, rhs=v162 } -> x0 + v164 Imm(0) -> x1 + v165 LoadLocal { off=-523, kind=I64 } -> x1 + v166 LocalAddr(-38) -> x1 + v167 Load { addr=v166, disp=0, kind=I64 } -> x1 + v168 LocalAddr(-38) -> x2 + v169 BinopI { op=add, lhs=v168, rhs_imm=8 } -> x6 + v170 Load { addr=v168, disp=8, kind=I64 } -> x2 + v171 Binop { op=add, lhs=v167, rhs=v170 } -> x1 + v172 Binop { op=add, lhs=v163, rhs=v171 } -> x0 + v173 Imm(0) -> x1 + v174 LoadLocal { off=-523, kind=I64 } -> x1 + v175 LocalAddr(-40) -> x1 + v176 Load { addr=v175, disp=0, kind=I64 } -> x1 + v177 LocalAddr(-40) -> x2 + v178 BinopI { op=add, lhs=v177, rhs_imm=8 } -> x6 + v179 Load { addr=v177, disp=8, kind=I64 } -> x2 + v180 Binop { op=add, lhs=v176, rhs=v179 } -> x1 + v181 Binop { op=add, lhs=v172, rhs=v180 } -> x0 + v182 Imm(0) -> x1 + v183 LoadLocal { off=-523, kind=I64 } -> x1 + v184 LocalAddr(-42) -> x1 + v185 Load { addr=v184, disp=0, kind=I64 } -> x1 + v186 LocalAddr(-42) -> x2 + v187 BinopI { op=add, lhs=v186, rhs_imm=8 } -> x6 + v188 Load { addr=v186, disp=8, kind=I64 } -> x2 + v189 Binop { op=add, lhs=v185, rhs=v188 } -> x1 + v190 Binop { op=add, lhs=v181, rhs=v189 } -> x0 + v191 Imm(0) -> x1 + v192 LoadLocal { off=-523, kind=I64 } -> x1 + v193 LocalAddr(-44) -> x1 + v194 Load { addr=v193, disp=0, kind=I64 } -> x1 + v195 LocalAddr(-44) -> x2 + v196 BinopI { op=add, lhs=v195, rhs_imm=8 } -> x6 + v197 Load { addr=v195, disp=8, kind=I64 } -> x2 + v198 Binop { op=add, lhs=v194, rhs=v197 } -> x1 + v199 Binop { op=add, lhs=v190, rhs=v198 } -> x0 + v200 Imm(0) -> x1 + v201 LoadLocal { off=-523, kind=I64 } -> x1 + v202 LocalAddr(-46) -> x1 + v203 Load { addr=v202, disp=0, kind=I64 } -> x1 + v204 LocalAddr(-46) -> x2 + v205 BinopI { op=add, lhs=v204, rhs_imm=8 } -> x6 + v206 Load { addr=v204, disp=8, kind=I64 } -> x2 + v207 Binop { op=add, lhs=v203, rhs=v206 } -> x1 + v208 Binop { op=add, lhs=v199, rhs=v207 } -> x0 + v209 Imm(0) -> x1 + v210 LoadLocal { off=-523, kind=I64 } -> x1 + v211 LocalAddr(-48) -> x1 + v212 Load { addr=v211, disp=0, kind=I64 } -> x1 + v213 LocalAddr(-48) -> x2 + v214 BinopI { op=add, lhs=v213, rhs_imm=8 } -> x6 + v215 Load { addr=v213, disp=8, kind=I64 } -> x2 + v216 Binop { op=add, lhs=v212, rhs=v215 } -> x1 + v217 Binop { op=add, lhs=v208, rhs=v216 } -> x0 + v218 Imm(0) -> x1 + v219 LoadLocal { off=-523, kind=I64 } -> x1 + v220 LocalAddr(-50) -> x1 + v221 Load { addr=v220, disp=0, kind=I64 } -> x1 + v222 LocalAddr(-50) -> x2 + v223 BinopI { op=add, lhs=v222, rhs_imm=8 } -> x6 + v224 Load { addr=v222, disp=8, kind=I64 } -> x2 + v225 Binop { op=add, lhs=v221, rhs=v224 } -> x1 + v226 Binop { op=add, lhs=v217, rhs=v225 } -> x0 + v227 Imm(0) -> x1 + v228 LoadLocal { off=-523, kind=I64 } -> x1 + v229 LocalAddr(-52) -> x1 + v230 Load { addr=v229, disp=0, kind=I64 } -> x1 + v231 LocalAddr(-52) -> x2 + v232 BinopI { op=add, lhs=v231, rhs_imm=8 } -> x6 + v233 Load { addr=v231, disp=8, kind=I64 } -> x2 + v234 Binop { op=add, lhs=v230, rhs=v233 } -> x1 + v235 Binop { op=add, lhs=v226, rhs=v234 } -> x0 + v236 Imm(0) -> x1 + v237 LoadLocal { off=-523, kind=I64 } -> x1 + v238 LocalAddr(-54) -> x1 + v239 Load { addr=v238, disp=0, kind=I64 } -> x1 + v240 LocalAddr(-54) -> x2 + v241 BinopI { op=add, lhs=v240, rhs_imm=8 } -> x6 + v242 Load { addr=v240, disp=8, kind=I64 } -> x2 + v243 Binop { op=add, lhs=v239, rhs=v242 } -> x1 + v244 Binop { op=add, lhs=v235, rhs=v243 } -> x0 + v245 Imm(0) -> x1 + v246 LoadLocal { off=-523, kind=I64 } -> x1 + v247 LocalAddr(-56) -> x1 + v248 Load { addr=v247, disp=0, kind=I64 } -> x1 + v249 LocalAddr(-56) -> x2 + v250 BinopI { op=add, lhs=v249, rhs_imm=8 } -> x6 + v251 Load { addr=v249, disp=8, kind=I64 } -> x2 + v252 Binop { op=add, lhs=v248, rhs=v251 } -> x1 + v253 Binop { op=add, lhs=v244, rhs=v252 } -> x0 + v254 Imm(0) -> x1 + v255 LoadLocal { off=-523, kind=I64 } -> x1 + v256 LocalAddr(-58) -> x1 + v257 Load { addr=v256, disp=0, kind=I64 } -> x1 + v258 LocalAddr(-58) -> x2 + v259 BinopI { op=add, lhs=v258, rhs_imm=8 } -> x6 + v260 Load { addr=v258, disp=8, kind=I64 } -> x2 + v261 Binop { op=add, lhs=v257, rhs=v260 } -> x1 + v262 Binop { op=add, lhs=v253, rhs=v261 } -> x0 + v263 Imm(0) -> x1 + v264 LoadLocal { off=-523, kind=I64 } -> x1 + v265 LocalAddr(-60) -> x1 + v266 Load { addr=v265, disp=0, kind=I64 } -> x1 + v267 LocalAddr(-60) -> x2 + v268 BinopI { op=add, lhs=v267, rhs_imm=8 } -> x6 + v269 Load { addr=v267, disp=8, kind=I64 } -> x2 + v270 Binop { op=add, lhs=v266, rhs=v269 } -> x1 + v271 Binop { op=add, lhs=v262, rhs=v270 } -> x0 + v272 Imm(0) -> x1 + v273 LoadLocal { off=-523, kind=I64 } -> x1 + v274 LocalAddr(-62) -> x1 + v275 Load { addr=v274, disp=0, kind=I64 } -> x1 + v276 LocalAddr(-62) -> x2 + v277 BinopI { op=add, lhs=v276, rhs_imm=8 } -> x6 + v278 Load { addr=v276, disp=8, kind=I64 } -> x2 + v279 Binop { op=add, lhs=v275, rhs=v278 } -> x1 + v280 Binop { op=add, lhs=v271, rhs=v279 } -> x0 + v281 Imm(0) -> x1 + v282 LoadLocal { off=-523, kind=I64 } -> x1 + v283 LocalAddr(-64) -> x1 + v284 Load { addr=v283, disp=0, kind=I64 } -> x1 + v285 LocalAddr(-64) -> x2 + v286 BinopI { op=add, lhs=v285, rhs_imm=8 } -> x6 + v287 Load { addr=v285, disp=8, kind=I64 } -> x2 + v288 Binop { op=add, lhs=v284, rhs=v287 } -> x1 + v289 Binop { op=add, lhs=v280, rhs=v288 } -> x0 + v290 Imm(0) -> x1 + v291 LoadLocal { off=-523, kind=I64 } -> x1 + v292 LocalAddr(-66) -> x1 + v293 Load { addr=v292, disp=0, kind=I64 } -> x1 + v294 LocalAddr(-66) -> x2 + v295 BinopI { op=add, lhs=v294, rhs_imm=8 } -> x6 + v296 Load { addr=v294, disp=8, kind=I64 } -> x2 + v297 Binop { op=add, lhs=v293, rhs=v296 } -> x1 + v298 Binop { op=add, lhs=v289, rhs=v297 } -> x0 + v299 Imm(0) -> x1 + v300 LoadLocal { off=-523, kind=I64 } -> x1 + v301 LocalAddr(-68) -> x1 + v302 Load { addr=v301, disp=0, kind=I64 } -> x1 + v303 LocalAddr(-68) -> x2 + v304 BinopI { op=add, lhs=v303, rhs_imm=8 } -> x6 + v305 Load { addr=v303, disp=8, kind=I64 } -> x2 + v306 Binop { op=add, lhs=v302, rhs=v305 } -> x1 + v307 Binop { op=add, lhs=v298, rhs=v306 } -> x0 + v308 Imm(0) -> x1 + v309 LoadLocal { off=-523, kind=I64 } -> x1 + v310 LocalAddr(-70) -> x1 + v311 Load { addr=v310, disp=0, kind=I64 } -> x1 + v312 LocalAddr(-70) -> x2 + v313 BinopI { op=add, lhs=v312, rhs_imm=8 } -> x6 + v314 Load { addr=v312, disp=8, kind=I64 } -> x2 + v315 Binop { op=add, lhs=v311, rhs=v314 } -> x1 + v316 Binop { op=add, lhs=v307, rhs=v315 } -> x0 + v317 Imm(0) -> x1 + v318 LoadLocal { off=-523, kind=I64 } -> x1 + v319 LocalAddr(-72) -> x1 + v320 Load { addr=v319, disp=0, kind=I64 } -> x1 + v321 LocalAddr(-72) -> x2 + v322 BinopI { op=add, lhs=v321, rhs_imm=8 } -> x6 + v323 Load { addr=v321, disp=8, kind=I64 } -> x2 + v324 Binop { op=add, lhs=v320, rhs=v323 } -> x1 + v325 Binop { op=add, lhs=v316, rhs=v324 } -> x0 + v326 Imm(0) -> x1 + v327 LoadLocal { off=-523, kind=I64 } -> x1 + v328 LocalAddr(-74) -> x1 + v329 Load { addr=v328, disp=0, kind=I64 } -> x1 + v330 LocalAddr(-74) -> x2 + v331 BinopI { op=add, lhs=v330, rhs_imm=8 } -> x6 + v332 Load { addr=v330, disp=8, kind=I64 } -> x2 + v333 Binop { op=add, lhs=v329, rhs=v332 } -> x1 + v334 Binop { op=add, lhs=v325, rhs=v333 } -> x0 + v335 Imm(0) -> x1 + v336 LoadLocal { off=-523, kind=I64 } -> x1 + v337 LocalAddr(-76) -> x1 + v338 Load { addr=v337, disp=0, kind=I64 } -> x1 + v339 LocalAddr(-76) -> x2 + v340 BinopI { op=add, lhs=v339, rhs_imm=8 } -> x6 + v341 Load { addr=v339, disp=8, kind=I64 } -> x2 + v342 Binop { op=add, lhs=v338, rhs=v341 } -> x1 + v343 Binop { op=add, lhs=v334, rhs=v342 } -> x0 + v344 Imm(0) -> x1 + v345 LoadLocal { off=-523, kind=I64 } -> x1 + v346 LocalAddr(-78) -> x1 + v347 Load { addr=v346, disp=0, kind=I64 } -> x1 + v348 LocalAddr(-78) -> x2 + v349 BinopI { op=add, lhs=v348, rhs_imm=8 } -> x6 + v350 Load { addr=v348, disp=8, kind=I64 } -> x2 + v351 Binop { op=add, lhs=v347, rhs=v350 } -> x1 + v352 Binop { op=add, lhs=v343, rhs=v351 } -> x0 + v353 Imm(0) -> x1 + v354 LoadLocal { off=-523, kind=I64 } -> x1 + v355 LocalAddr(-80) -> x1 + v356 Load { addr=v355, disp=0, kind=I64 } -> x1 + v357 LocalAddr(-80) -> x2 + v358 BinopI { op=add, lhs=v357, rhs_imm=8 } -> x6 + v359 Load { addr=v357, disp=8, kind=I64 } -> x2 + v360 Binop { op=add, lhs=v356, rhs=v359 } -> x1 + v361 Binop { op=add, lhs=v352, rhs=v360 } -> x0 + v362 Imm(0) -> x1 + v363 LoadLocal { off=-523, kind=I64 } -> x1 + v364 LocalAddr(-82) -> x1 + v365 Load { addr=v364, disp=0, kind=I64 } -> x1 + v366 LocalAddr(-82) -> x2 + v367 BinopI { op=add, lhs=v366, rhs_imm=8 } -> x6 + v368 Load { addr=v366, disp=8, kind=I64 } -> x2 + v369 Binop { op=add, lhs=v365, rhs=v368 } -> x1 + v370 Binop { op=add, lhs=v361, rhs=v369 } -> x0 + v371 Imm(0) -> x1 + v372 LoadLocal { off=-523, kind=I64 } -> x1 + v373 LocalAddr(-84) -> x1 + v374 Load { addr=v373, disp=0, kind=I64 } -> x1 + v375 LocalAddr(-84) -> x2 + v376 BinopI { op=add, lhs=v375, rhs_imm=8 } -> x6 + v377 Load { addr=v375, disp=8, kind=I64 } -> x2 + v378 Binop { op=add, lhs=v374, rhs=v377 } -> x1 + v379 Binop { op=add, lhs=v370, rhs=v378 } -> x0 + v380 Imm(0) -> x1 + v381 LoadLocal { off=-523, kind=I64 } -> x1 + v382 LocalAddr(-86) -> x1 + v383 Load { addr=v382, disp=0, kind=I64 } -> x1 + v384 LocalAddr(-86) -> x2 + v385 BinopI { op=add, lhs=v384, rhs_imm=8 } -> x6 + v386 Load { addr=v384, disp=8, kind=I64 } -> x2 + v387 Binop { op=add, lhs=v383, rhs=v386 } -> x1 + v388 Binop { op=add, lhs=v379, rhs=v387 } -> x0 + v389 Imm(0) -> x1 + v390 LoadLocal { off=-523, kind=I64 } -> x1 + v391 LocalAddr(-88) -> x1 + v392 Load { addr=v391, disp=0, kind=I64 } -> x1 + v393 LocalAddr(-88) -> x2 + v394 BinopI { op=add, lhs=v393, rhs_imm=8 } -> x6 + v395 Load { addr=v393, disp=8, kind=I64 } -> x2 + v396 Binop { op=add, lhs=v392, rhs=v395 } -> x1 + v397 Binop { op=add, lhs=v388, rhs=v396 } -> x0 + v398 Imm(0) -> x1 + v399 LoadLocal { off=-523, kind=I64 } -> x1 + v400 LocalAddr(-90) -> x1 + v401 Load { addr=v400, disp=0, kind=I64 } -> x1 + v402 LocalAddr(-90) -> x2 + v403 BinopI { op=add, lhs=v402, rhs_imm=8 } -> x6 + v404 Load { addr=v402, disp=8, kind=I64 } -> x2 + v405 Binop { op=add, lhs=v401, rhs=v404 } -> x1 + v406 Binop { op=add, lhs=v397, rhs=v405 } -> x0 + v407 Imm(0) -> x1 + v408 LoadLocal { off=-523, kind=I64 } -> x1 + v409 LocalAddr(-92) -> x1 + v410 Load { addr=v409, disp=0, kind=I64 } -> x1 + v411 LocalAddr(-92) -> x2 + v412 BinopI { op=add, lhs=v411, rhs_imm=8 } -> x6 + v413 Load { addr=v411, disp=8, kind=I64 } -> x2 + v414 Binop { op=add, lhs=v410, rhs=v413 } -> x1 + v415 Binop { op=add, lhs=v406, rhs=v414 } -> x0 + v416 Imm(0) -> x1 + v417 LoadLocal { off=-523, kind=I64 } -> x1 + v418 LocalAddr(-94) -> x1 + v419 Load { addr=v418, disp=0, kind=I64 } -> x1 + v420 LocalAddr(-94) -> x2 + v421 BinopI { op=add, lhs=v420, rhs_imm=8 } -> x6 + v422 Load { addr=v420, disp=8, kind=I64 } -> x2 + v423 Binop { op=add, lhs=v419, rhs=v422 } -> x1 + v424 Binop { op=add, lhs=v415, rhs=v423 } -> x0 + v425 Imm(0) -> x1 + v426 LoadLocal { off=-523, kind=I64 } -> x1 + v427 LocalAddr(-96) -> x1 + v428 Load { addr=v427, disp=0, kind=I64 } -> x1 + v429 LocalAddr(-96) -> x2 + v430 BinopI { op=add, lhs=v429, rhs_imm=8 } -> x6 + v431 Load { addr=v429, disp=8, kind=I64 } -> x2 + v432 Binop { op=add, lhs=v428, rhs=v431 } -> x1 + v433 Binop { op=add, lhs=v424, rhs=v432 } -> x0 + v434 Imm(0) -> x1 + v435 LoadLocal { off=-523, kind=I64 } -> x1 + v436 LocalAddr(-98) -> x1 + v437 Load { addr=v436, disp=0, kind=I64 } -> x1 + v438 LocalAddr(-98) -> x2 + v439 BinopI { op=add, lhs=v438, rhs_imm=8 } -> x6 + v440 Load { addr=v438, disp=8, kind=I64 } -> x2 + v441 Binop { op=add, lhs=v437, rhs=v440 } -> x1 + v442 Binop { op=add, lhs=v433, rhs=v441 } -> x0 + v443 Imm(0) -> x1 + v444 LoadLocal { off=-523, kind=I64 } -> x1 + v445 LocalAddr(-100) -> x1 + v446 Load { addr=v445, disp=0, kind=I64 } -> x1 + v447 LocalAddr(-100) -> x2 + v448 BinopI { op=add, lhs=v447, rhs_imm=8 } -> x6 + v449 Load { addr=v447, disp=8, kind=I64 } -> x2 + v450 Binop { op=add, lhs=v446, rhs=v449 } -> x1 + v451 Binop { op=add, lhs=v442, rhs=v450 } -> x0 + v452 Imm(0) -> x1 + v453 LoadLocal { off=-523, kind=I64 } -> x1 + v454 LocalAddr(-102) -> x1 + v455 Load { addr=v454, disp=0, kind=I64 } -> x1 + v456 LocalAddr(-102) -> x2 + v457 BinopI { op=add, lhs=v456, rhs_imm=8 } -> x6 + v458 Load { addr=v456, disp=8, kind=I64 } -> x2 + v459 Binop { op=add, lhs=v455, rhs=v458 } -> x1 + v460 Binop { op=add, lhs=v451, rhs=v459 } -> x0 + v461 Imm(0) -> x1 + v462 LoadLocal { off=-523, kind=I64 } -> x1 + v463 LocalAddr(-104) -> x1 + v464 Load { addr=v463, disp=0, kind=I64 } -> x1 + v465 LocalAddr(-104) -> x2 + v466 BinopI { op=add, lhs=v465, rhs_imm=8 } -> x6 + v467 Load { addr=v465, disp=8, kind=I64 } -> x2 + v468 Binop { op=add, lhs=v464, rhs=v467 } -> x1 + v469 Binop { op=add, lhs=v460, rhs=v468 } -> x0 + v470 Imm(0) -> x1 + v471 LoadLocal { off=-523, kind=I64 } -> x1 + v472 LocalAddr(-106) -> x1 + v473 Load { addr=v472, disp=0, kind=I64 } -> x1 + v474 LocalAddr(-106) -> x2 + v475 BinopI { op=add, lhs=v474, rhs_imm=8 } -> x6 + v476 Load { addr=v474, disp=8, kind=I64 } -> x2 + v477 Binop { op=add, lhs=v473, rhs=v476 } -> x1 + v478 Binop { op=add, lhs=v469, rhs=v477 } -> x0 + v479 Imm(0) -> x1 + v480 LoadLocal { off=-523, kind=I64 } -> x1 + v481 LocalAddr(-108) -> x1 + v482 Load { addr=v481, disp=0, kind=I64 } -> x1 + v483 LocalAddr(-108) -> x2 + v484 BinopI { op=add, lhs=v483, rhs_imm=8 } -> x6 + v485 Load { addr=v483, disp=8, kind=I64 } -> x2 + v486 Binop { op=add, lhs=v482, rhs=v485 } -> x1 + v487 Binop { op=add, lhs=v478, rhs=v486 } -> x0 + v488 Imm(0) -> x1 + v489 LoadLocal { off=-523, kind=I64 } -> x1 + v490 LocalAddr(-110) -> x1 + v491 Load { addr=v490, disp=0, kind=I64 } -> x1 + v492 LocalAddr(-110) -> x2 + v493 BinopI { op=add, lhs=v492, rhs_imm=8 } -> x6 + v494 Load { addr=v492, disp=8, kind=I64 } -> x2 + v495 Binop { op=add, lhs=v491, rhs=v494 } -> x1 + v496 Binop { op=add, lhs=v487, rhs=v495 } -> x0 + v497 Imm(0) -> x1 + v498 LoadLocal { off=-523, kind=I64 } -> x1 + v499 LocalAddr(-112) -> x1 + v500 Load { addr=v499, disp=0, kind=I64 } -> x1 + v501 LocalAddr(-112) -> x2 + v502 BinopI { op=add, lhs=v501, rhs_imm=8 } -> x6 + v503 Load { addr=v501, disp=8, kind=I64 } -> x2 + v504 Binop { op=add, lhs=v500, rhs=v503 } -> x1 + v505 Binop { op=add, lhs=v496, rhs=v504 } -> x0 + v506 Imm(0) -> x1 + v507 LoadLocal { off=-523, kind=I64 } -> x1 + v508 LocalAddr(-114) -> x1 + v509 Load { addr=v508, disp=0, kind=I64 } -> x1 + v510 LocalAddr(-114) -> x2 + v511 BinopI { op=add, lhs=v510, rhs_imm=8 } -> x6 + v512 Load { addr=v510, disp=8, kind=I64 } -> x2 + v513 Binop { op=add, lhs=v509, rhs=v512 } -> x1 + v514 Binop { op=add, lhs=v505, rhs=v513 } -> x0 + v515 Imm(0) -> x1 + v516 LoadLocal { off=-523, kind=I64 } -> x1 + v517 LocalAddr(-116) -> x1 + v518 Load { addr=v517, disp=0, kind=I64 } -> x1 + v519 LocalAddr(-116) -> x2 + v520 BinopI { op=add, lhs=v519, rhs_imm=8 } -> x6 + v521 Load { addr=v519, disp=8, kind=I64 } -> x2 + v522 Binop { op=add, lhs=v518, rhs=v521 } -> x1 + v523 Binop { op=add, lhs=v514, rhs=v522 } -> x0 + v524 Imm(0) -> x1 + v525 LoadLocal { off=-523, kind=I64 } -> x1 + v526 LocalAddr(-118) -> x1 + v527 Load { addr=v526, disp=0, kind=I64 } -> x1 + v528 LocalAddr(-118) -> x2 + v529 BinopI { op=add, lhs=v528, rhs_imm=8 } -> x6 + v530 Load { addr=v528, disp=8, kind=I64 } -> x2 + v531 Binop { op=add, lhs=v527, rhs=v530 } -> x1 + v532 Binop { op=add, lhs=v523, rhs=v531 } -> x0 + v533 Imm(0) -> x1 + v534 LoadLocal { off=-523, kind=I64 } -> x1 + v535 LocalAddr(-120) -> x1 + v536 Load { addr=v535, disp=0, kind=I64 } -> x1 + v537 LocalAddr(-120) -> x2 + v538 BinopI { op=add, lhs=v537, rhs_imm=8 } -> x6 + v539 Load { addr=v537, disp=8, kind=I64 } -> x2 + v540 Binop { op=add, lhs=v536, rhs=v539 } -> x1 + v541 Binop { op=add, lhs=v532, rhs=v540 } -> x0 + v542 Imm(0) -> x1 + v543 LoadLocal { off=-523, kind=I64 } -> x1 + v544 LocalAddr(-122) -> x1 + v545 Load { addr=v544, disp=0, kind=I64 } -> x1 + v546 LocalAddr(-122) -> x2 + v547 BinopI { op=add, lhs=v546, rhs_imm=8 } -> x6 + v548 Load { addr=v546, disp=8, kind=I64 } -> x2 + v549 Binop { op=add, lhs=v545, rhs=v548 } -> x1 + v550 Binop { op=add, lhs=v541, rhs=v549 } -> x0 + v551 Imm(0) -> x1 + v552 LoadLocal { off=-523, kind=I64 } -> x1 + v553 LocalAddr(-124) -> x1 + v554 Load { addr=v553, disp=0, kind=I64 } -> x1 + v555 LocalAddr(-124) -> x2 + v556 BinopI { op=add, lhs=v555, rhs_imm=8 } -> x6 + v557 Load { addr=v555, disp=8, kind=I64 } -> x2 + v558 Binop { op=add, lhs=v554, rhs=v557 } -> x1 + v559 Binop { op=add, lhs=v550, rhs=v558 } -> x0 + v560 Imm(0) -> x1 + v561 LoadLocal { off=-523, kind=I64 } -> x1 + v562 LocalAddr(-126) -> x1 + v563 Load { addr=v562, disp=0, kind=I64 } -> x1 + v564 LocalAddr(-126) -> x2 + v565 BinopI { op=add, lhs=v564, rhs_imm=8 } -> x6 + v566 Load { addr=v564, disp=8, kind=I64 } -> x2 + v567 Binop { op=add, lhs=v563, rhs=v566 } -> x1 + v568 Binop { op=add, lhs=v559, rhs=v567 } -> x0 + v569 Imm(0) -> x1 + v570 LoadLocal { off=-523, kind=I64 } -> x1 + v571 LocalAddr(-128) -> x1 + v572 Load { addr=v571, disp=0, kind=I64 } -> x1 + v573 LocalAddr(-128) -> x2 + v574 BinopI { op=add, lhs=v573, rhs_imm=8 } -> x6 + v575 Load { addr=v573, disp=8, kind=I64 } -> x2 + v576 Binop { op=add, lhs=v572, rhs=v575 } -> x1 + v577 Binop { op=add, lhs=v568, rhs=v576 } -> x0 + v578 Imm(0) -> x1 + v579 LoadLocal { off=-523, kind=I64 } -> x1 + v580 LocalAddr(-130) -> x1 + v581 Load { addr=v580, disp=0, kind=I64 } -> x1 + v582 LocalAddr(-130) -> x2 + v583 BinopI { op=add, lhs=v582, rhs_imm=8 } -> x6 + v584 Load { addr=v582, disp=8, kind=I64 } -> x2 + v585 Binop { op=add, lhs=v581, rhs=v584 } -> x1 + v586 Binop { op=add, lhs=v577, rhs=v585 } -> x0 + v587 Imm(0) -> x1 + v588 LoadLocal { off=-523, kind=I64 } -> x1 + v589 LocalAddr(-132) -> x1 + v590 Load { addr=v589, disp=0, kind=I64 } -> x1 + v591 LocalAddr(-132) -> x2 + v592 BinopI { op=add, lhs=v591, rhs_imm=8 } -> x6 + v593 Load { addr=v591, disp=8, kind=I64 } -> x2 + v594 Binop { op=add, lhs=v590, rhs=v593 } -> x1 + v595 Binop { op=add, lhs=v586, rhs=v594 } -> x0 + v596 Imm(0) -> x1 + v597 LoadLocal { off=-523, kind=I64 } -> x1 + v598 LocalAddr(-134) -> x1 + v599 Load { addr=v598, disp=0, kind=I64 } -> x1 + v600 LocalAddr(-134) -> x2 + v601 BinopI { op=add, lhs=v600, rhs_imm=8 } -> x6 + v602 Load { addr=v600, disp=8, kind=I64 } -> x2 + v603 Binop { op=add, lhs=v599, rhs=v602 } -> x1 + v604 Binop { op=add, lhs=v595, rhs=v603 } -> x0 + v605 Imm(0) -> x1 + v606 LoadLocal { off=-523, kind=I64 } -> x1 + v607 LocalAddr(-136) -> x1 + v608 Load { addr=v607, disp=0, kind=I64 } -> x1 + v609 LocalAddr(-136) -> x2 + v610 BinopI { op=add, lhs=v609, rhs_imm=8 } -> x6 + v611 Load { addr=v609, disp=8, kind=I64 } -> x2 + v612 Binop { op=add, lhs=v608, rhs=v611 } -> x1 + v613 Binop { op=add, lhs=v604, rhs=v612 } -> x0 + v614 Imm(0) -> x1 + v615 LoadLocal { off=-523, kind=I64 } -> x1 + v616 LocalAddr(-138) -> x1 + v617 Load { addr=v616, disp=0, kind=I64 } -> x1 + v618 LocalAddr(-138) -> x2 + v619 BinopI { op=add, lhs=v618, rhs_imm=8 } -> x6 + v620 Load { addr=v618, disp=8, kind=I64 } -> x2 + v621 Binop { op=add, lhs=v617, rhs=v620 } -> x1 + v622 Binop { op=add, lhs=v613, rhs=v621 } -> x0 + v623 Imm(0) -> x1 + v624 LoadLocal { off=-523, kind=I64 } -> x1 + v625 LocalAddr(-140) -> x1 + v626 Load { addr=v625, disp=0, kind=I64 } -> x1 + v627 LocalAddr(-140) -> x2 + v628 BinopI { op=add, lhs=v627, rhs_imm=8 } -> x6 + v629 Load { addr=v627, disp=8, kind=I64 } -> x2 + v630 Binop { op=add, lhs=v626, rhs=v629 } -> x1 + v631 Binop { op=add, lhs=v622, rhs=v630 } -> x0 + v632 Imm(0) -> x1 + v633 LoadLocal { off=-523, kind=I64 } -> x1 + v634 LocalAddr(-142) -> x1 + v635 Load { addr=v634, disp=0, kind=I64 } -> x1 + v636 LocalAddr(-142) -> x2 + v637 BinopI { op=add, lhs=v636, rhs_imm=8 } -> x6 + v638 Load { addr=v636, disp=8, kind=I64 } -> x2 + v639 Binop { op=add, lhs=v635, rhs=v638 } -> x1 + v640 Binop { op=add, lhs=v631, rhs=v639 } -> x0 + v641 Imm(0) -> x1 + v642 LoadLocal { off=-523, kind=I64 } -> x1 + v643 LocalAddr(-144) -> x1 + v644 Load { addr=v643, disp=0, kind=I64 } -> x1 + v645 LocalAddr(-144) -> x2 + v646 BinopI { op=add, lhs=v645, rhs_imm=8 } -> x6 + v647 Load { addr=v645, disp=8, kind=I64 } -> x2 + v648 Binop { op=add, lhs=v644, rhs=v647 } -> x1 + v649 Binop { op=add, lhs=v640, rhs=v648 } -> x0 + v650 Imm(0) -> x1 + v651 LoadLocal { off=-523, kind=I64 } -> x1 + v652 LocalAddr(-146) -> x1 + v653 Load { addr=v652, disp=0, kind=I64 } -> x1 + v654 LocalAddr(-146) -> x2 + v655 BinopI { op=add, lhs=v654, rhs_imm=8 } -> x6 + v656 Load { addr=v654, disp=8, kind=I64 } -> x2 + v657 Binop { op=add, lhs=v653, rhs=v656 } -> x1 + v658 Binop { op=add, lhs=v649, rhs=v657 } -> x0 + v659 Imm(0) -> x1 + v660 LoadLocal { off=-523, kind=I64 } -> x1 + v661 LocalAddr(-148) -> x1 + v662 Load { addr=v661, disp=0, kind=I64 } -> x1 + v663 LocalAddr(-148) -> x2 + v664 BinopI { op=add, lhs=v663, rhs_imm=8 } -> x6 + v665 Load { addr=v663, disp=8, kind=I64 } -> x2 + v666 Binop { op=add, lhs=v662, rhs=v665 } -> x1 + v667 Binop { op=add, lhs=v658, rhs=v666 } -> x0 + v668 Imm(0) -> x1 + v669 LoadLocal { off=-523, kind=I64 } -> x1 + v670 LocalAddr(-150) -> x1 + v671 Load { addr=v670, disp=0, kind=I64 } -> x1 + v672 LocalAddr(-150) -> x2 + v673 BinopI { op=add, lhs=v672, rhs_imm=8 } -> x6 + v674 Load { addr=v672, disp=8, kind=I64 } -> x2 + v675 Binop { op=add, lhs=v671, rhs=v674 } -> x1 + v676 Binop { op=add, lhs=v667, rhs=v675 } -> x0 + v677 Imm(0) -> x1 + v678 LoadLocal { off=-523, kind=I64 } -> x1 + v679 LocalAddr(-152) -> x1 + v680 Load { addr=v679, disp=0, kind=I64 } -> x1 + v681 LocalAddr(-152) -> x2 + v682 BinopI { op=add, lhs=v681, rhs_imm=8 } -> x6 + v683 Load { addr=v681, disp=8, kind=I64 } -> x2 + v684 Binop { op=add, lhs=v680, rhs=v683 } -> x1 + v685 Binop { op=add, lhs=v676, rhs=v684 } -> x0 + v686 Imm(0) -> x1 + v687 LoadLocal { off=-523, kind=I64 } -> x1 + v688 LocalAddr(-154) -> x1 + v689 Load { addr=v688, disp=0, kind=I64 } -> x1 + v690 LocalAddr(-154) -> x2 + v691 BinopI { op=add, lhs=v690, rhs_imm=8 } -> x6 + v692 Load { addr=v690, disp=8, kind=I64 } -> x2 + v693 Binop { op=add, lhs=v689, rhs=v692 } -> x1 + v694 Binop { op=add, lhs=v685, rhs=v693 } -> x0 + v695 Imm(0) -> x1 + v696 LoadLocal { off=-523, kind=I64 } -> x1 + v697 LocalAddr(-156) -> x1 + v698 Load { addr=v697, disp=0, kind=I64 } -> x1 + v699 LocalAddr(-156) -> x2 + v700 BinopI { op=add, lhs=v699, rhs_imm=8 } -> x6 + v701 Load { addr=v699, disp=8, kind=I64 } -> x2 + v702 Binop { op=add, lhs=v698, rhs=v701 } -> x1 + v703 Binop { op=add, lhs=v694, rhs=v702 } -> x0 + v704 Imm(0) -> x1 + v705 LoadLocal { off=-523, kind=I64 } -> x1 + v706 LocalAddr(-158) -> x1 + v707 Load { addr=v706, disp=0, kind=I64 } -> x1 + v708 LocalAddr(-158) -> x2 + v709 BinopI { op=add, lhs=v708, rhs_imm=8 } -> x6 + v710 Load { addr=v708, disp=8, kind=I64 } -> x2 + v711 Binop { op=add, lhs=v707, rhs=v710 } -> x1 + v712 Binop { op=add, lhs=v703, rhs=v711 } -> x0 + v713 Imm(0) -> x1 + v714 LoadLocal { off=-523, kind=I64 } -> x1 + v715 LocalAddr(-160) -> x1 + v716 Load { addr=v715, disp=0, kind=I64 } -> x1 + v717 LocalAddr(-160) -> x2 + v718 BinopI { op=add, lhs=v717, rhs_imm=8 } -> x6 + v719 Load { addr=v717, disp=8, kind=I64 } -> x2 + v720 Binop { op=add, lhs=v716, rhs=v719 } -> x1 + v721 Binop { op=add, lhs=v712, rhs=v720 } -> x0 + v722 Imm(0) -> x1 + v723 LoadLocal { off=-523, kind=I64 } -> x1 + v724 LocalAddr(-162) -> x1 + v725 Load { addr=v724, disp=0, kind=I64 } -> x1 + v726 LocalAddr(-162) -> x2 + v727 BinopI { op=add, lhs=v726, rhs_imm=8 } -> x6 + v728 Load { addr=v726, disp=8, kind=I64 } -> x2 + v729 Binop { op=add, lhs=v725, rhs=v728 } -> x1 + v730 Binop { op=add, lhs=v721, rhs=v729 } -> x0 + v731 Imm(0) -> x1 + v732 LoadLocal { off=-523, kind=I64 } -> x1 + v733 LocalAddr(-164) -> x1 + v734 Load { addr=v733, disp=0, kind=I64 } -> x1 + v735 LocalAddr(-164) -> x2 + v736 BinopI { op=add, lhs=v735, rhs_imm=8 } -> x6 + v737 Load { addr=v735, disp=8, kind=I64 } -> x2 + v738 Binop { op=add, lhs=v734, rhs=v737 } -> x1 + v739 Binop { op=add, lhs=v730, rhs=v738 } -> x0 + v740 Imm(0) -> x1 + v741 LoadLocal { off=-523, kind=I64 } -> x1 + v742 LocalAddr(-166) -> x1 + v743 Load { addr=v742, disp=0, kind=I64 } -> x1 + v744 LocalAddr(-166) -> x2 + v745 BinopI { op=add, lhs=v744, rhs_imm=8 } -> x6 + v746 Load { addr=v744, disp=8, kind=I64 } -> x2 + v747 Binop { op=add, lhs=v743, rhs=v746 } -> x1 + v748 Binop { op=add, lhs=v739, rhs=v747 } -> x0 + v749 Imm(0) -> x1 + v750 LoadLocal { off=-523, kind=I64 } -> x1 + v751 LocalAddr(-168) -> x1 + v752 Load { addr=v751, disp=0, kind=I64 } -> x1 + v753 LocalAddr(-168) -> x2 + v754 BinopI { op=add, lhs=v753, rhs_imm=8 } -> x6 + v755 Load { addr=v753, disp=8, kind=I64 } -> x2 + v756 Binop { op=add, lhs=v752, rhs=v755 } -> x1 + v757 Binop { op=add, lhs=v748, rhs=v756 } -> x0 + v758 Imm(0) -> x1 + v759 LoadLocal { off=-523, kind=I64 } -> x1 + v760 LocalAddr(-170) -> x1 + v761 Load { addr=v760, disp=0, kind=I64 } -> x1 + v762 LocalAddr(-170) -> x2 + v763 BinopI { op=add, lhs=v762, rhs_imm=8 } -> x6 + v764 Load { addr=v762, disp=8, kind=I64 } -> x2 + v765 Binop { op=add, lhs=v761, rhs=v764 } -> x1 + v766 Binop { op=add, lhs=v757, rhs=v765 } -> x0 + v767 Imm(0) -> x1 + v768 LoadLocal { off=-523, kind=I64 } -> x1 + v769 LocalAddr(-172) -> x1 + v770 Load { addr=v769, disp=0, kind=I64 } -> x1 + v771 LocalAddr(-172) -> x2 + v772 BinopI { op=add, lhs=v771, rhs_imm=8 } -> x6 + v773 Load { addr=v771, disp=8, kind=I64 } -> x2 + v774 Binop { op=add, lhs=v770, rhs=v773 } -> x1 + v775 Binop { op=add, lhs=v766, rhs=v774 } -> x0 + v776 Imm(0) -> x1 + v777 LoadLocal { off=-523, kind=I64 } -> x1 + v778 LocalAddr(-174) -> x1 + v779 Load { addr=v778, disp=0, kind=I64 } -> x1 + v780 LocalAddr(-174) -> x2 + v781 BinopI { op=add, lhs=v780, rhs_imm=8 } -> x6 + v782 Load { addr=v780, disp=8, kind=I64 } -> x2 + v783 Binop { op=add, lhs=v779, rhs=v782 } -> x1 + v784 Binop { op=add, lhs=v775, rhs=v783 } -> x0 + v785 Imm(0) -> x1 + v786 LoadLocal { off=-523, kind=I64 } -> x1 + v787 LocalAddr(-176) -> x1 + v788 Load { addr=v787, disp=0, kind=I64 } -> x1 + v789 LocalAddr(-176) -> x2 + v790 BinopI { op=add, lhs=v789, rhs_imm=8 } -> x6 + v791 Load { addr=v789, disp=8, kind=I64 } -> x2 + v792 Binop { op=add, lhs=v788, rhs=v791 } -> x1 + v793 Binop { op=add, lhs=v784, rhs=v792 } -> x0 + v794 Imm(0) -> x1 + v795 LoadLocal { off=-523, kind=I64 } -> x1 + v796 LocalAddr(-178) -> x1 + v797 Load { addr=v796, disp=0, kind=I64 } -> x1 + v798 LocalAddr(-178) -> x2 + v799 BinopI { op=add, lhs=v798, rhs_imm=8 } -> x6 + v800 Load { addr=v798, disp=8, kind=I64 } -> x2 + v801 Binop { op=add, lhs=v797, rhs=v800 } -> x1 + v802 Binop { op=add, lhs=v793, rhs=v801 } -> x0 + v803 Imm(0) -> x1 + v804 LoadLocal { off=-523, kind=I64 } -> x1 + v805 LocalAddr(-180) -> x1 + v806 Load { addr=v805, disp=0, kind=I64 } -> x1 + v807 LocalAddr(-180) -> x2 + v808 BinopI { op=add, lhs=v807, rhs_imm=8 } -> x6 + v809 Load { addr=v807, disp=8, kind=I64 } -> x2 + v810 Binop { op=add, lhs=v806, rhs=v809 } -> x1 + v811 Binop { op=add, lhs=v802, rhs=v810 } -> x0 + v812 Imm(0) -> x1 + v813 LoadLocal { off=-523, kind=I64 } -> x1 + v814 LocalAddr(-182) -> x1 + v815 Load { addr=v814, disp=0, kind=I64 } -> x1 + v816 LocalAddr(-182) -> x2 + v817 BinopI { op=add, lhs=v816, rhs_imm=8 } -> x6 + v818 Load { addr=v816, disp=8, kind=I64 } -> x2 + v819 Binop { op=add, lhs=v815, rhs=v818 } -> x1 + v820 Binop { op=add, lhs=v811, rhs=v819 } -> x0 + v821 Imm(0) -> x1 + v822 LoadLocal { off=-523, kind=I64 } -> x1 + v823 LocalAddr(-184) -> x1 + v824 Load { addr=v823, disp=0, kind=I64 } -> x1 + v825 LocalAddr(-184) -> x2 + v826 BinopI { op=add, lhs=v825, rhs_imm=8 } -> x6 + v827 Load { addr=v825, disp=8, kind=I64 } -> x2 + v828 Binop { op=add, lhs=v824, rhs=v827 } -> x1 + v829 Binop { op=add, lhs=v820, rhs=v828 } -> x0 + v830 Imm(0) -> x1 + v831 LoadLocal { off=-523, kind=I64 } -> x1 + v832 LocalAddr(-186) -> x1 + v833 Load { addr=v832, disp=0, kind=I64 } -> x1 + v834 LocalAddr(-186) -> x2 + v835 BinopI { op=add, lhs=v834, rhs_imm=8 } -> x6 + v836 Load { addr=v834, disp=8, kind=I64 } -> x2 + v837 Binop { op=add, lhs=v833, rhs=v836 } -> x1 + v838 Binop { op=add, lhs=v829, rhs=v837 } -> x0 + v839 Imm(0) -> x1 + v840 LoadLocal { off=-523, kind=I64 } -> x1 + v841 LocalAddr(-188) -> x1 + v842 Load { addr=v841, disp=0, kind=I64 } -> x1 + v843 LocalAddr(-188) -> x2 + v844 BinopI { op=add, lhs=v843, rhs_imm=8 } -> x6 + v845 Load { addr=v843, disp=8, kind=I64 } -> x2 + v846 Binop { op=add, lhs=v842, rhs=v845 } -> x1 + v847 Binop { op=add, lhs=v838, rhs=v846 } -> x0 + v848 Imm(0) -> x1 + v849 LoadLocal { off=-523, kind=I64 } -> x1 + v850 LocalAddr(-190) -> x1 + v851 Load { addr=v850, disp=0, kind=I64 } -> x1 + v852 LocalAddr(-190) -> x2 + v853 BinopI { op=add, lhs=v852, rhs_imm=8 } -> x6 + v854 Load { addr=v852, disp=8, kind=I64 } -> x2 + v855 Binop { op=add, lhs=v851, rhs=v854 } -> x1 + v856 Binop { op=add, lhs=v847, rhs=v855 } -> x0 + v857 Imm(0) -> x1 + v858 LoadLocal { off=-523, kind=I64 } -> x1 + v859 LocalAddr(-192) -> x1 + v860 Load { addr=v859, disp=0, kind=I64 } -> x1 + v861 LocalAddr(-192) -> x2 + v862 BinopI { op=add, lhs=v861, rhs_imm=8 } -> x6 + v863 Load { addr=v861, disp=8, kind=I64 } -> x2 + v864 Binop { op=add, lhs=v860, rhs=v863 } -> x1 + v865 Binop { op=add, lhs=v856, rhs=v864 } -> x0 + v866 Imm(0) -> x1 + v867 LoadLocal { off=-523, kind=I64 } -> x1 + v868 LocalAddr(-194) -> x1 + v869 Load { addr=v868, disp=0, kind=I64 } -> x1 + v870 LocalAddr(-194) -> x2 + v871 BinopI { op=add, lhs=v870, rhs_imm=8 } -> x6 + v872 Load { addr=v870, disp=8, kind=I64 } -> x2 + v873 Binop { op=add, lhs=v869, rhs=v872 } -> x1 + v874 Binop { op=add, lhs=v865, rhs=v873 } -> x0 + v875 Imm(0) -> x1 + v876 LoadLocal { off=-523, kind=I64 } -> x1 + v877 LocalAddr(-196) -> x1 + v878 Load { addr=v877, disp=0, kind=I64 } -> x1 + v879 LocalAddr(-196) -> x2 + v880 BinopI { op=add, lhs=v879, rhs_imm=8 } -> x6 + v881 Load { addr=v879, disp=8, kind=I64 } -> x2 + v882 Binop { op=add, lhs=v878, rhs=v881 } -> x1 + v883 Binop { op=add, lhs=v874, rhs=v882 } -> x0 + v884 Imm(0) -> x1 + v885 LoadLocal { off=-523, kind=I64 } -> x1 + v886 LocalAddr(-198) -> x1 + v887 Load { addr=v886, disp=0, kind=I64 } -> x1 + v888 LocalAddr(-198) -> x2 + v889 BinopI { op=add, lhs=v888, rhs_imm=8 } -> x6 + v890 Load { addr=v888, disp=8, kind=I64 } -> x2 + v891 Binop { op=add, lhs=v887, rhs=v890 } -> x1 + v892 Binop { op=add, lhs=v883, rhs=v891 } -> x0 + v893 Imm(0) -> x1 + v894 LoadLocal { off=-523, kind=I64 } -> x1 + v895 LocalAddr(-200) -> x1 + v896 Load { addr=v895, disp=0, kind=I64 } -> x1 + v897 LocalAddr(-200) -> x2 + v898 BinopI { op=add, lhs=v897, rhs_imm=8 } -> x6 + v899 Load { addr=v897, disp=8, kind=I64 } -> x2 + v900 Binop { op=add, lhs=v896, rhs=v899 } -> x1 + v901 Binop { op=add, lhs=v892, rhs=v900 } -> x0 + v902 Imm(0) -> x1 + v903 LoadLocal { off=-523, kind=I64 } -> x1 + v904 LocalAddr(-202) -> x1 + v905 Load { addr=v904, disp=0, kind=I64 } -> x1 + v906 LocalAddr(-202) -> x2 + v907 BinopI { op=add, lhs=v906, rhs_imm=8 } -> x6 + v908 Load { addr=v906, disp=8, kind=I64 } -> x2 + v909 Binop { op=add, lhs=v905, rhs=v908 } -> x1 + v910 Binop { op=add, lhs=v901, rhs=v909 } -> x0 + v911 Imm(0) -> x1 + v912 LoadLocal { off=-523, kind=I64 } -> x1 + v913 LocalAddr(-204) -> x1 + v914 Load { addr=v913, disp=0, kind=I64 } -> x1 + v915 LocalAddr(-204) -> x2 + v916 BinopI { op=add, lhs=v915, rhs_imm=8 } -> x6 + v917 Load { addr=v915, disp=8, kind=I64 } -> x2 + v918 Binop { op=add, lhs=v914, rhs=v917 } -> x1 + v919 Binop { op=add, lhs=v910, rhs=v918 } -> x0 + v920 Imm(0) -> x1 + v921 LoadLocal { off=-523, kind=I64 } -> x1 + v922 LocalAddr(-206) -> x1 + v923 Load { addr=v922, disp=0, kind=I64 } -> x1 + v924 LocalAddr(-206) -> x2 + v925 BinopI { op=add, lhs=v924, rhs_imm=8 } -> x6 + v926 Load { addr=v924, disp=8, kind=I64 } -> x2 + v927 Binop { op=add, lhs=v923, rhs=v926 } -> x1 + v928 Binop { op=add, lhs=v919, rhs=v927 } -> x0 + v929 Imm(0) -> x1 + v930 LoadLocal { off=-523, kind=I64 } -> x1 + v931 LocalAddr(-208) -> x1 + v932 Load { addr=v931, disp=0, kind=I64 } -> x1 + v933 LocalAddr(-208) -> x2 + v934 BinopI { op=add, lhs=v933, rhs_imm=8 } -> x6 + v935 Load { addr=v933, disp=8, kind=I64 } -> x2 + v936 Binop { op=add, lhs=v932, rhs=v935 } -> x1 + v937 Binop { op=add, lhs=v928, rhs=v936 } -> x0 + v938 Imm(0) -> x1 + v939 LoadLocal { off=-523, kind=I64 } -> x1 + v940 LocalAddr(-210) -> x1 + v941 Load { addr=v940, disp=0, kind=I64 } -> x1 + v942 LocalAddr(-210) -> x2 + v943 BinopI { op=add, lhs=v942, rhs_imm=8 } -> x6 + v944 Load { addr=v942, disp=8, kind=I64 } -> x2 + v945 Binop { op=add, lhs=v941, rhs=v944 } -> x1 + v946 Binop { op=add, lhs=v937, rhs=v945 } -> x0 + v947 Imm(0) -> x1 + v948 LoadLocal { off=-523, kind=I64 } -> x1 + v949 LocalAddr(-212) -> x1 + v950 Load { addr=v949, disp=0, kind=I64 } -> x1 + v951 LocalAddr(-212) -> x2 + v952 BinopI { op=add, lhs=v951, rhs_imm=8 } -> x6 + v953 Load { addr=v951, disp=8, kind=I64 } -> x2 + v954 Binop { op=add, lhs=v950, rhs=v953 } -> x1 + v955 Binop { op=add, lhs=v946, rhs=v954 } -> x0 + v956 Imm(0) -> x1 + v957 LoadLocal { off=-523, kind=I64 } -> x1 + v958 LocalAddr(-214) -> x1 + v959 Load { addr=v958, disp=0, kind=I64 } -> x1 + v960 LocalAddr(-214) -> x2 + v961 BinopI { op=add, lhs=v960, rhs_imm=8 } -> x6 + v962 Load { addr=v960, disp=8, kind=I64 } -> x2 + v963 Binop { op=add, lhs=v959, rhs=v962 } -> x1 + v964 Binop { op=add, lhs=v955, rhs=v963 } -> x0 + v965 Imm(0) -> x1 + v966 LoadLocal { off=-523, kind=I64 } -> x1 + v967 LocalAddr(-216) -> x1 + v968 Load { addr=v967, disp=0, kind=I64 } -> x1 + v969 LocalAddr(-216) -> x2 + v970 BinopI { op=add, lhs=v969, rhs_imm=8 } -> x6 + v971 Load { addr=v969, disp=8, kind=I64 } -> x2 + v972 Binop { op=add, lhs=v968, rhs=v971 } -> x1 + v973 Binop { op=add, lhs=v964, rhs=v972 } -> x0 + v974 Imm(0) -> x1 + v975 LoadLocal { off=-523, kind=I64 } -> x1 + v976 LocalAddr(-218) -> x1 + v977 Load { addr=v976, disp=0, kind=I64 } -> x1 + v978 LocalAddr(-218) -> x2 + v979 BinopI { op=add, lhs=v978, rhs_imm=8 } -> x6 + v980 Load { addr=v978, disp=8, kind=I64 } -> x2 + v981 Binop { op=add, lhs=v977, rhs=v980 } -> x1 + v982 Binop { op=add, lhs=v973, rhs=v981 } -> x0 + v983 Imm(0) -> x1 + v984 LoadLocal { off=-523, kind=I64 } -> x1 + v985 LocalAddr(-220) -> x1 + v986 Load { addr=v985, disp=0, kind=I64 } -> x1 + v987 LocalAddr(-220) -> x2 + v988 BinopI { op=add, lhs=v987, rhs_imm=8 } -> x6 + v989 Load { addr=v987, disp=8, kind=I64 } -> x2 + v990 Binop { op=add, lhs=v986, rhs=v989 } -> x1 + v991 Binop { op=add, lhs=v982, rhs=v990 } -> x0 + v992 Imm(0) -> x1 + v993 LoadLocal { off=-523, kind=I64 } -> x1 + v994 LocalAddr(-222) -> x1 + v995 Load { addr=v994, disp=0, kind=I64 } -> x1 + v996 LocalAddr(-222) -> x2 + v997 BinopI { op=add, lhs=v996, rhs_imm=8 } -> x6 + v998 Load { addr=v996, disp=8, kind=I64 } -> x2 + v999 Binop { op=add, lhs=v995, rhs=v998 } -> x1 + v1000 Binop { op=add, lhs=v991, rhs=v999 } -> x0 + v1001 Imm(0) -> x1 + v1002 LoadLocal { off=-523, kind=I64 } -> x1 + v1003 LocalAddr(-224) -> x1 + v1004 Load { addr=v1003, disp=0, kind=I64 } -> x1 + v1005 LocalAddr(-224) -> x2 + v1006 BinopI { op=add, lhs=v1005, rhs_imm=8 } -> x6 + v1007 Load { addr=v1005, disp=8, kind=I64 } -> x2 + v1008 Binop { op=add, lhs=v1004, rhs=v1007 } -> x1 + v1009 Binop { op=add, lhs=v1000, rhs=v1008 } -> x0 + v1010 Imm(0) -> x1 + v1011 LoadLocal { off=-523, kind=I64 } -> x1 + v1012 LocalAddr(-226) -> x1 + v1013 Load { addr=v1012, disp=0, kind=I64 } -> x1 + v1014 LocalAddr(-226) -> x2 + v1015 BinopI { op=add, lhs=v1014, rhs_imm=8 } -> x6 + v1016 Load { addr=v1014, disp=8, kind=I64 } -> x2 + v1017 Binop { op=add, lhs=v1013, rhs=v1016 } -> x1 + v1018 Binop { op=add, lhs=v1009, rhs=v1017 } -> x0 + v1019 Imm(0) -> x1 + v1020 LoadLocal { off=-523, kind=I64 } -> x1 + v1021 LocalAddr(-228) -> x1 + v1022 Load { addr=v1021, disp=0, kind=I64 } -> x1 + v1023 LocalAddr(-228) -> x2 + v1024 BinopI { op=add, lhs=v1023, rhs_imm=8 } -> x6 + v1025 Load { addr=v1023, disp=8, kind=I64 } -> x2 + v1026 Binop { op=add, lhs=v1022, rhs=v1025 } -> x1 + v1027 Binop { op=add, lhs=v1018, rhs=v1026 } -> x0 + v1028 Imm(0) -> x1 + v1029 LoadLocal { off=-523, kind=I64 } -> x1 + v1030 LocalAddr(-230) -> x1 + v1031 Load { addr=v1030, disp=0, kind=I64 } -> x1 + v1032 LocalAddr(-230) -> x2 + v1033 BinopI { op=add, lhs=v1032, rhs_imm=8 } -> x6 + v1034 Load { addr=v1032, disp=8, kind=I64 } -> x2 + v1035 Binop { op=add, lhs=v1031, rhs=v1034 } -> x1 + v1036 Binop { op=add, lhs=v1027, rhs=v1035 } -> x0 + v1037 Imm(0) -> x1 + v1038 LoadLocal { off=-523, kind=I64 } -> x1 + v1039 LocalAddr(-232) -> x1 + v1040 Load { addr=v1039, disp=0, kind=I64 } -> x1 + v1041 LocalAddr(-232) -> x2 + v1042 BinopI { op=add, lhs=v1041, rhs_imm=8 } -> x6 + v1043 Load { addr=v1041, disp=8, kind=I64 } -> x2 + v1044 Binop { op=add, lhs=v1040, rhs=v1043 } -> x1 + v1045 Binop { op=add, lhs=v1036, rhs=v1044 } -> x0 + v1046 Imm(0) -> x1 + v1047 LoadLocal { off=-523, kind=I64 } -> x1 + v1048 LocalAddr(-234) -> x1 + v1049 Load { addr=v1048, disp=0, kind=I64 } -> x1 + v1050 LocalAddr(-234) -> x2 + v1051 BinopI { op=add, lhs=v1050, rhs_imm=8 } -> x6 + v1052 Load { addr=v1050, disp=8, kind=I64 } -> x2 + v1053 Binop { op=add, lhs=v1049, rhs=v1052 } -> x1 + v1054 Binop { op=add, lhs=v1045, rhs=v1053 } -> x0 + v1055 Imm(0) -> x1 + v1056 LoadLocal { off=-523, kind=I64 } -> x1 + v1057 LocalAddr(-236) -> x1 + v1058 Load { addr=v1057, disp=0, kind=I64 } -> x1 + v1059 LocalAddr(-236) -> x2 + v1060 BinopI { op=add, lhs=v1059, rhs_imm=8 } -> x6 + v1061 Load { addr=v1059, disp=8, kind=I64 } -> x2 + v1062 Binop { op=add, lhs=v1058, rhs=v1061 } -> x1 + v1063 Binop { op=add, lhs=v1054, rhs=v1062 } -> x0 + v1064 Imm(0) -> x1 + v1065 LoadLocal { off=-523, kind=I64 } -> x1 + v1066 LocalAddr(-238) -> x1 + v1067 Load { addr=v1066, disp=0, kind=I64 } -> x1 + v1068 LocalAddr(-238) -> x2 + v1069 BinopI { op=add, lhs=v1068, rhs_imm=8 } -> x6 + v1070 Load { addr=v1068, disp=8, kind=I64 } -> x2 + v1071 Binop { op=add, lhs=v1067, rhs=v1070 } -> x1 + v1072 Binop { op=add, lhs=v1063, rhs=v1071 } -> x0 + v1073 Imm(0) -> x1 + v1074 LoadLocal { off=-523, kind=I64 } -> x1 + v1075 LocalAddr(-240) -> x1 + v1076 Load { addr=v1075, disp=0, kind=I64 } -> x1 + v1077 LocalAddr(-240) -> x2 + v1078 BinopI { op=add, lhs=v1077, rhs_imm=8 } -> x6 + v1079 Load { addr=v1077, disp=8, kind=I64 } -> x2 + v1080 Binop { op=add, lhs=v1076, rhs=v1079 } -> x1 + v1081 Binop { op=add, lhs=v1072, rhs=v1080 } -> x0 + v1082 Imm(0) -> x1 + v1083 LoadLocal { off=-523, kind=I64 } -> x1 + v1084 LocalAddr(-242) -> x1 + v1085 Load { addr=v1084, disp=0, kind=I64 } -> x1 + v1086 LocalAddr(-242) -> x2 + v1087 BinopI { op=add, lhs=v1086, rhs_imm=8 } -> x6 + v1088 Load { addr=v1086, disp=8, kind=I64 } -> x2 + v1089 Binop { op=add, lhs=v1085, rhs=v1088 } -> x1 + v1090 Binop { op=add, lhs=v1081, rhs=v1089 } -> x0 + v1091 Imm(0) -> x1 + v1092 LoadLocal { off=-523, kind=I64 } -> x1 + v1093 LocalAddr(-244) -> x1 + v1094 Load { addr=v1093, disp=0, kind=I64 } -> x1 + v1095 LocalAddr(-244) -> x2 + v1096 BinopI { op=add, lhs=v1095, rhs_imm=8 } -> x6 + v1097 Load { addr=v1095, disp=8, kind=I64 } -> x2 + v1098 Binop { op=add, lhs=v1094, rhs=v1097 } -> x1 + v1099 Binop { op=add, lhs=v1090, rhs=v1098 } -> x0 + v1100 Imm(0) -> x1 + v1101 LoadLocal { off=-523, kind=I64 } -> x1 + v1102 LocalAddr(-246) -> x1 + v1103 Load { addr=v1102, disp=0, kind=I64 } -> x1 + v1104 LocalAddr(-246) -> x2 + v1105 BinopI { op=add, lhs=v1104, rhs_imm=8 } -> x6 + v1106 Load { addr=v1104, disp=8, kind=I64 } -> x2 + v1107 Binop { op=add, lhs=v1103, rhs=v1106 } -> x1 + v1108 Binop { op=add, lhs=v1099, rhs=v1107 } -> x0 + v1109 Imm(0) -> x1 + v1110 LoadLocal { off=-523, kind=I64 } -> x1 + v1111 LocalAddr(-248) -> x1 + v1112 Load { addr=v1111, disp=0, kind=I64 } -> x1 + v1113 LocalAddr(-248) -> x2 + v1114 BinopI { op=add, lhs=v1113, rhs_imm=8 } -> x6 + v1115 Load { addr=v1113, disp=8, kind=I64 } -> x2 + v1116 Binop { op=add, lhs=v1112, rhs=v1115 } -> x1 + v1117 Binop { op=add, lhs=v1108, rhs=v1116 } -> x0 + v1118 Imm(0) -> x1 + v1119 LoadLocal { off=-523, kind=I64 } -> x1 + v1120 LocalAddr(-250) -> x1 + v1121 Load { addr=v1120, disp=0, kind=I64 } -> x1 + v1122 LocalAddr(-250) -> x2 + v1123 BinopI { op=add, lhs=v1122, rhs_imm=8 } -> x6 + v1124 Load { addr=v1122, disp=8, kind=I64 } -> x2 + v1125 Binop { op=add, lhs=v1121, rhs=v1124 } -> x1 + v1126 Binop { op=add, lhs=v1117, rhs=v1125 } -> x0 + v1127 Imm(0) -> x1 + v1128 LoadLocal { off=-523, kind=I64 } -> x1 + v1129 LocalAddr(-252) -> x1 + v1130 Load { addr=v1129, disp=0, kind=I64 } -> x1 + v1131 LocalAddr(-252) -> x2 + v1132 BinopI { op=add, lhs=v1131, rhs_imm=8 } -> x6 + v1133 Load { addr=v1131, disp=8, kind=I64 } -> x2 + v1134 Binop { op=add, lhs=v1130, rhs=v1133 } -> x1 + v1135 Binop { op=add, lhs=v1126, rhs=v1134 } -> x0 + v1136 Imm(0) -> x1 + v1137 LoadLocal { off=-523, kind=I64 } -> x1 + v1138 LocalAddr(-254) -> x1 + v1139 Load { addr=v1138, disp=0, kind=I64 } -> x1 + v1140 LocalAddr(-254) -> x2 + v1141 BinopI { op=add, lhs=v1140, rhs_imm=8 } -> x6 + v1142 Load { addr=v1140, disp=8, kind=I64 } -> x2 + v1143 Binop { op=add, lhs=v1139, rhs=v1142 } -> x1 + v1144 Binop { op=add, lhs=v1135, rhs=v1143 } -> x0 + v1145 Imm(0) -> x1 + v1146 LoadLocal { off=-523, kind=I64 } -> x1 + v1147 LocalAddr(-256) -> x1 + v1148 Load { addr=v1147, disp=0, kind=I64 } -> x1 + v1149 LocalAddr(-256) -> x2 + v1150 BinopI { op=add, lhs=v1149, rhs_imm=8 } -> x6 + v1151 Load { addr=v1149, disp=8, kind=I64 } -> x2 + v1152 Binop { op=add, lhs=v1148, rhs=v1151 } -> x1 + v1153 Binop { op=add, lhs=v1144, rhs=v1152 } -> x0 + v1154 Imm(0) -> x1 + v1155 LoadLocal { off=-523, kind=I64 } -> x1 + v1156 LocalAddr(-258) -> x1 + v1157 Load { addr=v1156, disp=0, kind=I64 } -> x1 + v1158 LocalAddr(-258) -> x2 + v1159 BinopI { op=add, lhs=v1158, rhs_imm=8 } -> x6 + v1160 Load { addr=v1158, disp=8, kind=I64 } -> x2 + v1161 Binop { op=add, lhs=v1157, rhs=v1160 } -> x1 + v1162 Binop { op=add, lhs=v1153, rhs=v1161 } -> x0 + v1163 Imm(0) -> x1 + v1164 LoadLocal { off=-523, kind=I64 } -> x1 + v1165 LocalAddr(-260) -> x1 + v1166 Load { addr=v1165, disp=0, kind=I64 } -> x1 + v1167 LocalAddr(-260) -> x2 + v1168 BinopI { op=add, lhs=v1167, rhs_imm=8 } -> x6 + v1169 Load { addr=v1167, disp=8, kind=I64 } -> x2 + v1170 Binop { op=add, lhs=v1166, rhs=v1169 } -> x1 + v1171 Binop { op=add, lhs=v1162, rhs=v1170 } -> x0 + v1172 Imm(0) -> x1 + v1173 LoadLocal { off=-523, kind=I64 } -> x1 + v1174 LocalAddr(-262) -> x1 + v1175 Load { addr=v1174, disp=0, kind=I64 } -> x1 + v1176 LocalAddr(-262) -> x2 + v1177 BinopI { op=add, lhs=v1176, rhs_imm=8 } -> x6 + v1178 Load { addr=v1176, disp=8, kind=I64 } -> x2 + v1179 Binop { op=add, lhs=v1175, rhs=v1178 } -> x1 + v1180 Binop { op=add, lhs=v1171, rhs=v1179 } -> x0 + v1181 Imm(0) -> x1 + v1182 LoadLocal { off=-523, kind=I64 } -> x1 + v1183 LocalAddr(-264) -> x1 + v1184 Load { addr=v1183, disp=0, kind=I64 } -> x1 + v1185 LocalAddr(-264) -> x2 + v1186 BinopI { op=add, lhs=v1185, rhs_imm=8 } -> x6 + v1187 Load { addr=v1185, disp=8, kind=I64 } -> x2 + v1188 Binop { op=add, lhs=v1184, rhs=v1187 } -> x1 + v1189 Binop { op=add, lhs=v1180, rhs=v1188 } -> x0 + v1190 Imm(0) -> x1 + v1191 LoadLocal { off=-523, kind=I64 } -> x1 + v1192 LocalAddr(-266) -> x1 + v1193 Load { addr=v1192, disp=0, kind=I64 } -> x1 + v1194 LocalAddr(-266) -> x2 + v1195 BinopI { op=add, lhs=v1194, rhs_imm=8 } -> x6 + v1196 Load { addr=v1194, disp=8, kind=I64 } -> x2 + v1197 Binop { op=add, lhs=v1193, rhs=v1196 } -> x1 + v1198 Binop { op=add, lhs=v1189, rhs=v1197 } -> x0 + v1199 Imm(0) -> x1 + v1200 LoadLocal { off=-523, kind=I64 } -> x1 + v1201 LocalAddr(-268) -> x1 + v1202 Load { addr=v1201, disp=0, kind=I64 } -> x1 + v1203 LocalAddr(-268) -> x2 + v1204 BinopI { op=add, lhs=v1203, rhs_imm=8 } -> x6 + v1205 Load { addr=v1203, disp=8, kind=I64 } -> x2 + v1206 Binop { op=add, lhs=v1202, rhs=v1205 } -> x1 + v1207 Binop { op=add, lhs=v1198, rhs=v1206 } -> x0 + v1208 Imm(0) -> x1 + v1209 LoadLocal { off=-523, kind=I64 } -> x1 + v1210 LocalAddr(-270) -> x1 + v1211 Load { addr=v1210, disp=0, kind=I64 } -> x1 + v1212 LocalAddr(-270) -> x2 + v1213 BinopI { op=add, lhs=v1212, rhs_imm=8 } -> x6 + v1214 Load { addr=v1212, disp=8, kind=I64 } -> x2 + v1215 Binop { op=add, lhs=v1211, rhs=v1214 } -> x1 + v1216 Binop { op=add, lhs=v1207, rhs=v1215 } -> x0 + v1217 Imm(0) -> x1 + v1218 LoadLocal { off=-523, kind=I64 } -> x1 + v1219 LocalAddr(-272) -> x1 + v1220 Load { addr=v1219, disp=0, kind=I64 } -> x1 + v1221 LocalAddr(-272) -> x2 + v1222 BinopI { op=add, lhs=v1221, rhs_imm=8 } -> x6 + v1223 Load { addr=v1221, disp=8, kind=I64 } -> x2 + v1224 Binop { op=add, lhs=v1220, rhs=v1223 } -> x1 + v1225 Binop { op=add, lhs=v1216, rhs=v1224 } -> x0 + v1226 Imm(0) -> x1 + v1227 LoadLocal { off=-523, kind=I64 } -> x1 + v1228 LocalAddr(-274) -> x1 + v1229 Load { addr=v1228, disp=0, kind=I64 } -> x1 + v1230 LocalAddr(-274) -> x2 + v1231 BinopI { op=add, lhs=v1230, rhs_imm=8 } -> x6 + v1232 Load { addr=v1230, disp=8, kind=I64 } -> x2 + v1233 Binop { op=add, lhs=v1229, rhs=v1232 } -> x1 + v1234 Binop { op=add, lhs=v1225, rhs=v1233 } -> x0 + v1235 Imm(0) -> x1 + v1236 LoadLocal { off=-523, kind=I64 } -> x1 + v1237 LocalAddr(-276) -> x1 + v1238 Load { addr=v1237, disp=0, kind=I64 } -> x1 + v1239 LocalAddr(-276) -> x2 + v1240 BinopI { op=add, lhs=v1239, rhs_imm=8 } -> x6 + v1241 Load { addr=v1239, disp=8, kind=I64 } -> x2 + v1242 Binop { op=add, lhs=v1238, rhs=v1241 } -> x1 + v1243 Binop { op=add, lhs=v1234, rhs=v1242 } -> x0 + v1244 Imm(0) -> x1 + v1245 LoadLocal { off=-523, kind=I64 } -> x1 + v1246 LocalAddr(-278) -> x1 + v1247 Load { addr=v1246, disp=0, kind=I64 } -> x1 + v1248 LocalAddr(-278) -> x2 + v1249 BinopI { op=add, lhs=v1248, rhs_imm=8 } -> x6 + v1250 Load { addr=v1248, disp=8, kind=I64 } -> x2 + v1251 Binop { op=add, lhs=v1247, rhs=v1250 } -> x1 + v1252 Binop { op=add, lhs=v1243, rhs=v1251 } -> x0 + v1253 Imm(0) -> x1 + v1254 LoadLocal { off=-523, kind=I64 } -> x1 + v1255 LocalAddr(-280) -> x1 + v1256 Load { addr=v1255, disp=0, kind=I64 } -> x1 + v1257 LocalAddr(-280) -> x2 + v1258 BinopI { op=add, lhs=v1257, rhs_imm=8 } -> x6 + v1259 Load { addr=v1257, disp=8, kind=I64 } -> x2 + v1260 Binop { op=add, lhs=v1256, rhs=v1259 } -> x1 + v1261 Binop { op=add, lhs=v1252, rhs=v1260 } -> x0 + v1262 Imm(0) -> x1 + v1263 LoadLocal { off=-523, kind=I64 } -> x1 + v1264 LocalAddr(-282) -> x1 + v1265 Load { addr=v1264, disp=0, kind=I64 } -> x1 + v1266 LocalAddr(-282) -> x2 + v1267 BinopI { op=add, lhs=v1266, rhs_imm=8 } -> x6 + v1268 Load { addr=v1266, disp=8, kind=I64 } -> x2 + v1269 Binop { op=add, lhs=v1265, rhs=v1268 } -> x1 + v1270 Binop { op=add, lhs=v1261, rhs=v1269 } -> x0 + v1271 Imm(0) -> x1 + v1272 LoadLocal { off=-523, kind=I64 } -> x1 + v1273 LocalAddr(-284) -> x1 + v1274 Load { addr=v1273, disp=0, kind=I64 } -> x1 + v1275 LocalAddr(-284) -> x2 + v1276 BinopI { op=add, lhs=v1275, rhs_imm=8 } -> x6 + v1277 Load { addr=v1275, disp=8, kind=I64 } -> x2 + v1278 Binop { op=add, lhs=v1274, rhs=v1277 } -> x1 + v1279 Binop { op=add, lhs=v1270, rhs=v1278 } -> x0 + v1280 Imm(0) -> x1 + v1281 LoadLocal { off=-523, kind=I64 } -> x1 + v1282 LocalAddr(-286) -> x1 + v1283 Load { addr=v1282, disp=0, kind=I64 } -> x1 + v1284 LocalAddr(-286) -> x2 + v1285 BinopI { op=add, lhs=v1284, rhs_imm=8 } -> x6 + v1286 Load { addr=v1284, disp=8, kind=I64 } -> x2 + v1287 Binop { op=add, lhs=v1283, rhs=v1286 } -> x1 + v1288 Binop { op=add, lhs=v1279, rhs=v1287 } -> x0 + v1289 Imm(0) -> x1 + v1290 LoadLocal { off=-523, kind=I64 } -> x1 + v1291 LocalAddr(-288) -> x1 + v1292 Load { addr=v1291, disp=0, kind=I64 } -> x1 + v1293 LocalAddr(-288) -> x2 + v1294 BinopI { op=add, lhs=v1293, rhs_imm=8 } -> x6 + v1295 Load { addr=v1293, disp=8, kind=I64 } -> x2 + v1296 Binop { op=add, lhs=v1292, rhs=v1295 } -> x1 + v1297 Binop { op=add, lhs=v1288, rhs=v1296 } -> x0 + v1298 Imm(0) -> x1 + v1299 LoadLocal { off=-523, kind=I64 } -> x1 + v1300 LocalAddr(-290) -> x1 + v1301 Load { addr=v1300, disp=0, kind=I64 } -> x1 + v1302 LocalAddr(-290) -> x2 + v1303 BinopI { op=add, lhs=v1302, rhs_imm=8 } -> x6 + v1304 Load { addr=v1302, disp=8, kind=I64 } -> x2 + v1305 Binop { op=add, lhs=v1301, rhs=v1304 } -> x1 + v1306 Binop { op=add, lhs=v1297, rhs=v1305 } -> x0 + v1307 Imm(0) -> x1 + v1308 LoadLocal { off=-523, kind=I64 } -> x1 + v1309 LocalAddr(-292) -> x1 + v1310 Load { addr=v1309, disp=0, kind=I64 } -> x1 + v1311 LocalAddr(-292) -> x2 + v1312 BinopI { op=add, lhs=v1311, rhs_imm=8 } -> x6 + v1313 Load { addr=v1311, disp=8, kind=I64 } -> x2 + v1314 Binop { op=add, lhs=v1310, rhs=v1313 } -> x1 + v1315 Binop { op=add, lhs=v1306, rhs=v1314 } -> x0 + v1316 Imm(0) -> x1 + v1317 LoadLocal { off=-523, kind=I64 } -> x1 + v1318 LocalAddr(-294) -> x1 + v1319 Load { addr=v1318, disp=0, kind=I64 } -> x1 + v1320 LocalAddr(-294) -> x2 + v1321 BinopI { op=add, lhs=v1320, rhs_imm=8 } -> x6 + v1322 Load { addr=v1320, disp=8, kind=I64 } -> x2 + v1323 Binop { op=add, lhs=v1319, rhs=v1322 } -> x1 + v1324 Binop { op=add, lhs=v1315, rhs=v1323 } -> x0 + v1325 Imm(0) -> x1 + v1326 LoadLocal { off=-523, kind=I64 } -> x1 + v1327 LocalAddr(-296) -> x1 + v1328 Load { addr=v1327, disp=0, kind=I64 } -> x1 + v1329 LocalAddr(-296) -> x2 + v1330 BinopI { op=add, lhs=v1329, rhs_imm=8 } -> x6 + v1331 Load { addr=v1329, disp=8, kind=I64 } -> x2 + v1332 Binop { op=add, lhs=v1328, rhs=v1331 } -> x1 + v1333 Binop { op=add, lhs=v1324, rhs=v1332 } -> x0 + v1334 Imm(0) -> x1 + v1335 LoadLocal { off=-523, kind=I64 } -> x1 + v1336 LocalAddr(-298) -> x1 + v1337 Load { addr=v1336, disp=0, kind=I64 } -> x1 + v1338 LocalAddr(-298) -> x2 + v1339 BinopI { op=add, lhs=v1338, rhs_imm=8 } -> x6 + v1340 Load { addr=v1338, disp=8, kind=I64 } -> x2 + v1341 Binop { op=add, lhs=v1337, rhs=v1340 } -> x1 + v1342 Binop { op=add, lhs=v1333, rhs=v1341 } -> x0 + v1343 Imm(0) -> x1 + v1344 LoadLocal { off=-523, kind=I64 } -> x1 + v1345 LocalAddr(-300) -> x1 + v1346 Load { addr=v1345, disp=0, kind=I64 } -> x1 + v1347 LocalAddr(-300) -> x2 + v1348 BinopI { op=add, lhs=v1347, rhs_imm=8 } -> x6 + v1349 Load { addr=v1347, disp=8, kind=I64 } -> x2 + v1350 Binop { op=add, lhs=v1346, rhs=v1349 } -> x1 + v1351 Binop { op=add, lhs=v1342, rhs=v1350 } -> x0 + v1352 Imm(0) -> x1 + v1353 LoadLocal { off=-523, kind=I64 } -> x1 + v1354 LocalAddr(-302) -> x1 + v1355 Load { addr=v1354, disp=0, kind=I64 } -> x1 + v1356 LocalAddr(-302) -> x2 + v1357 BinopI { op=add, lhs=v1356, rhs_imm=8 } -> x6 + v1358 Load { addr=v1356, disp=8, kind=I64 } -> x2 + v1359 Binop { op=add, lhs=v1355, rhs=v1358 } -> x1 + v1360 Binop { op=add, lhs=v1351, rhs=v1359 } -> x0 + v1361 Imm(0) -> x1 + v1362 LoadLocal { off=-523, kind=I64 } -> x1 + v1363 LocalAddr(-304) -> x1 + v1364 Load { addr=v1363, disp=0, kind=I64 } -> x1 + v1365 LocalAddr(-304) -> x2 + v1366 BinopI { op=add, lhs=v1365, rhs_imm=8 } -> x6 + v1367 Load { addr=v1365, disp=8, kind=I64 } -> x2 + v1368 Binop { op=add, lhs=v1364, rhs=v1367 } -> x1 + v1369 Binop { op=add, lhs=v1360, rhs=v1368 } -> x0 + v1370 Imm(0) -> x1 + v1371 LoadLocal { off=-523, kind=I64 } -> x1 + v1372 LocalAddr(-306) -> x1 + v1373 Load { addr=v1372, disp=0, kind=I64 } -> x1 + v1374 LocalAddr(-306) -> x2 + v1375 BinopI { op=add, lhs=v1374, rhs_imm=8 } -> x6 + v1376 Load { addr=v1374, disp=8, kind=I64 } -> x2 + v1377 Binop { op=add, lhs=v1373, rhs=v1376 } -> x1 + v1378 Binop { op=add, lhs=v1369, rhs=v1377 } -> x0 + v1379 Imm(0) -> x1 + v1380 LoadLocal { off=-523, kind=I64 } -> x1 + v1381 LocalAddr(-308) -> x1 + v1382 Load { addr=v1381, disp=0, kind=I64 } -> x1 + v1383 LocalAddr(-308) -> x2 + v1384 BinopI { op=add, lhs=v1383, rhs_imm=8 } -> x6 + v1385 Load { addr=v1383, disp=8, kind=I64 } -> x2 + v1386 Binop { op=add, lhs=v1382, rhs=v1385 } -> x1 + v1387 Binop { op=add, lhs=v1378, rhs=v1386 } -> x0 + v1388 Imm(0) -> x1 + v1389 LoadLocal { off=-523, kind=I64 } -> x1 + v1390 LocalAddr(-310) -> x1 + v1391 Load { addr=v1390, disp=0, kind=I64 } -> x1 + v1392 LocalAddr(-310) -> x2 + v1393 BinopI { op=add, lhs=v1392, rhs_imm=8 } -> x6 + v1394 Load { addr=v1392, disp=8, kind=I64 } -> x2 + v1395 Binop { op=add, lhs=v1391, rhs=v1394 } -> x1 + v1396 Binop { op=add, lhs=v1387, rhs=v1395 } -> x0 + v1397 Imm(0) -> x1 + v1398 LoadLocal { off=-523, kind=I64 } -> x1 + v1399 LocalAddr(-312) -> x1 + v1400 Load { addr=v1399, disp=0, kind=I64 } -> x1 + v1401 LocalAddr(-312) -> x2 + v1402 BinopI { op=add, lhs=v1401, rhs_imm=8 } -> x6 + v1403 Load { addr=v1401, disp=8, kind=I64 } -> x2 + v1404 Binop { op=add, lhs=v1400, rhs=v1403 } -> x1 + v1405 Binop { op=add, lhs=v1396, rhs=v1404 } -> x0 + v1406 Imm(0) -> x1 + v1407 LoadLocal { off=-523, kind=I64 } -> x1 + v1408 LocalAddr(-314) -> x1 + v1409 Load { addr=v1408, disp=0, kind=I64 } -> x1 + v1410 LocalAddr(-314) -> x2 + v1411 BinopI { op=add, lhs=v1410, rhs_imm=8 } -> x6 + v1412 Load { addr=v1410, disp=8, kind=I64 } -> x2 + v1413 Binop { op=add, lhs=v1409, rhs=v1412 } -> x1 + v1414 Binop { op=add, lhs=v1405, rhs=v1413 } -> x0 + v1415 Imm(0) -> x1 + v1416 LoadLocal { off=-523, kind=I64 } -> x1 + v1417 LocalAddr(-316) -> x1 + v1418 Load { addr=v1417, disp=0, kind=I64 } -> x1 + v1419 LocalAddr(-316) -> x2 + v1420 BinopI { op=add, lhs=v1419, rhs_imm=8 } -> x6 + v1421 Load { addr=v1419, disp=8, kind=I64 } -> x2 + v1422 Binop { op=add, lhs=v1418, rhs=v1421 } -> x1 + v1423 Binop { op=add, lhs=v1414, rhs=v1422 } -> x0 + v1424 Imm(0) -> x1 + v1425 LoadLocal { off=-523, kind=I64 } -> x1 + v1426 LocalAddr(-318) -> x1 + v1427 Load { addr=v1426, disp=0, kind=I64 } -> x1 + v1428 LocalAddr(-318) -> x2 + v1429 BinopI { op=add, lhs=v1428, rhs_imm=8 } -> x6 + v1430 Load { addr=v1428, disp=8, kind=I64 } -> x2 + v1431 Binop { op=add, lhs=v1427, rhs=v1430 } -> x1 + v1432 Binop { op=add, lhs=v1423, rhs=v1431 } -> x0 + v1433 Imm(0) -> x1 + v1434 LoadLocal { off=-523, kind=I64 } -> x1 + v1435 LocalAddr(-320) -> x1 + v1436 Load { addr=v1435, disp=0, kind=I64 } -> x1 + v1437 LocalAddr(-320) -> x2 + v1438 BinopI { op=add, lhs=v1437, rhs_imm=8 } -> x6 + v1439 Load { addr=v1437, disp=8, kind=I64 } -> x2 + v1440 Binop { op=add, lhs=v1436, rhs=v1439 } -> x1 + v1441 Binop { op=add, lhs=v1432, rhs=v1440 } -> x0 + v1442 Imm(0) -> x1 + v1443 LoadLocal { off=-523, kind=I64 } -> x1 + v1444 LocalAddr(-322) -> x1 + v1445 Load { addr=v1444, disp=0, kind=I64 } -> x1 + v1446 LocalAddr(-322) -> x2 + v1447 BinopI { op=add, lhs=v1446, rhs_imm=8 } -> x6 + v1448 Load { addr=v1446, disp=8, kind=I64 } -> x2 + v1449 Binop { op=add, lhs=v1445, rhs=v1448 } -> x1 + v1450 Binop { op=add, lhs=v1441, rhs=v1449 } -> x0 + v1451 Imm(0) -> x1 + v1452 LoadLocal { off=-523, kind=I64 } -> x1 + v1453 LocalAddr(-324) -> x1 + v1454 Load { addr=v1453, disp=0, kind=I64 } -> x1 + v1455 LocalAddr(-324) -> x2 + v1456 BinopI { op=add, lhs=v1455, rhs_imm=8 } -> x6 + v1457 Load { addr=v1455, disp=8, kind=I64 } -> x2 + v1458 Binop { op=add, lhs=v1454, rhs=v1457 } -> x1 + v1459 Binop { op=add, lhs=v1450, rhs=v1458 } -> x0 + v1460 Imm(0) -> x1 + v1461 LoadLocal { off=-523, kind=I64 } -> x1 + v1462 LocalAddr(-326) -> x1 + v1463 Load { addr=v1462, disp=0, kind=I64 } -> x1 + v1464 LocalAddr(-326) -> x2 + v1465 BinopI { op=add, lhs=v1464, rhs_imm=8 } -> x6 + v1466 Load { addr=v1464, disp=8, kind=I64 } -> x2 + v1467 Binop { op=add, lhs=v1463, rhs=v1466 } -> x1 + v1468 Binop { op=add, lhs=v1459, rhs=v1467 } -> x0 + v1469 Imm(0) -> x1 + v1470 LoadLocal { off=-523, kind=I64 } -> x1 + v1471 LocalAddr(-328) -> x1 + v1472 Load { addr=v1471, disp=0, kind=I64 } -> x1 + v1473 LocalAddr(-328) -> x2 + v1474 BinopI { op=add, lhs=v1473, rhs_imm=8 } -> x6 + v1475 Load { addr=v1473, disp=8, kind=I64 } -> x2 + v1476 Binop { op=add, lhs=v1472, rhs=v1475 } -> x1 + v1477 Binop { op=add, lhs=v1468, rhs=v1476 } -> x0 + v1478 Imm(0) -> x1 + v1479 LoadLocal { off=-523, kind=I64 } -> x1 + v1480 LocalAddr(-330) -> x1 + v1481 Load { addr=v1480, disp=0, kind=I64 } -> x1 + v1482 LocalAddr(-330) -> x2 + v1483 BinopI { op=add, lhs=v1482, rhs_imm=8 } -> x6 + v1484 Load { addr=v1482, disp=8, kind=I64 } -> x2 + v1485 Binop { op=add, lhs=v1481, rhs=v1484 } -> x1 + v1486 Binop { op=add, lhs=v1477, rhs=v1485 } -> x0 + v1487 Imm(0) -> x1 + v1488 LoadLocal { off=-523, kind=I64 } -> x1 + v1489 LocalAddr(-332) -> x1 + v1490 Load { addr=v1489, disp=0, kind=I64 } -> x1 + v1491 LocalAddr(-332) -> x2 + v1492 BinopI { op=add, lhs=v1491, rhs_imm=8 } -> x6 + v1493 Load { addr=v1491, disp=8, kind=I64 } -> x2 + v1494 Binop { op=add, lhs=v1490, rhs=v1493 } -> x1 + v1495 Binop { op=add, lhs=v1486, rhs=v1494 } -> x0 + v1496 Imm(0) -> x1 + v1497 LoadLocal { off=-523, kind=I64 } -> x1 + v1498 LocalAddr(-334) -> x1 + v1499 Load { addr=v1498, disp=0, kind=I64 } -> x1 + v1500 LocalAddr(-334) -> x2 + v1501 BinopI { op=add, lhs=v1500, rhs_imm=8 } -> x6 + v1502 Load { addr=v1500, disp=8, kind=I64 } -> x2 + v1503 Binop { op=add, lhs=v1499, rhs=v1502 } -> x1 + v1504 Binop { op=add, lhs=v1495, rhs=v1503 } -> x0 + v1505 Imm(0) -> x1 + v1506 LoadLocal { off=-523, kind=I64 } -> x1 + v1507 LocalAddr(-336) -> x1 + v1508 Load { addr=v1507, disp=0, kind=I64 } -> x1 + v1509 LocalAddr(-336) -> x2 + v1510 BinopI { op=add, lhs=v1509, rhs_imm=8 } -> x6 + v1511 Load { addr=v1509, disp=8, kind=I64 } -> x2 + v1512 Binop { op=add, lhs=v1508, rhs=v1511 } -> x1 + v1513 Binop { op=add, lhs=v1504, rhs=v1512 } -> x0 + v1514 Imm(0) -> x1 + v1515 LoadLocal { off=-523, kind=I64 } -> x1 + v1516 LocalAddr(-338) -> x1 + v1517 Load { addr=v1516, disp=0, kind=I64 } -> x1 + v1518 LocalAddr(-338) -> x2 + v1519 BinopI { op=add, lhs=v1518, rhs_imm=8 } -> x6 + v1520 Load { addr=v1518, disp=8, kind=I64 } -> x2 + v1521 Binop { op=add, lhs=v1517, rhs=v1520 } -> x1 + v1522 Binop { op=add, lhs=v1513, rhs=v1521 } -> x0 + v1523 Imm(0) -> x1 + v1524 LoadLocal { off=-523, kind=I64 } -> x1 + v1525 LocalAddr(-340) -> x1 + v1526 Load { addr=v1525, disp=0, kind=I64 } -> x1 + v1527 LocalAddr(-340) -> x2 + v1528 BinopI { op=add, lhs=v1527, rhs_imm=8 } -> x6 + v1529 Load { addr=v1527, disp=8, kind=I64 } -> x2 + v1530 Binop { op=add, lhs=v1526, rhs=v1529 } -> x1 + v1531 Binop { op=add, lhs=v1522, rhs=v1530 } -> x0 + v1532 Imm(0) -> x1 + v1533 LoadLocal { off=-523, kind=I64 } -> x1 + v1534 LocalAddr(-342) -> x1 + v1535 Load { addr=v1534, disp=0, kind=I64 } -> x1 + v1536 LocalAddr(-342) -> x2 + v1537 BinopI { op=add, lhs=v1536, rhs_imm=8 } -> x6 + v1538 Load { addr=v1536, disp=8, kind=I64 } -> x2 + v1539 Binop { op=add, lhs=v1535, rhs=v1538 } -> x1 + v1540 Binop { op=add, lhs=v1531, rhs=v1539 } -> x0 + v1541 Imm(0) -> x1 + v1542 LoadLocal { off=-523, kind=I64 } -> x1 + v1543 LocalAddr(-344) -> x1 + v1544 Load { addr=v1543, disp=0, kind=I64 } -> x1 + v1545 LocalAddr(-344) -> x2 + v1546 BinopI { op=add, lhs=v1545, rhs_imm=8 } -> x6 + v1547 Load { addr=v1545, disp=8, kind=I64 } -> x2 + v1548 Binop { op=add, lhs=v1544, rhs=v1547 } -> x1 + v1549 Binop { op=add, lhs=v1540, rhs=v1548 } -> x0 + v1550 Imm(0) -> x1 + v1551 LoadLocal { off=-523, kind=I64 } -> x1 + v1552 LocalAddr(-346) -> x1 + v1553 Load { addr=v1552, disp=0, kind=I64 } -> x1 + v1554 LocalAddr(-346) -> x2 + v1555 BinopI { op=add, lhs=v1554, rhs_imm=8 } -> x6 + v1556 Load { addr=v1554, disp=8, kind=I64 } -> x2 + v1557 Binop { op=add, lhs=v1553, rhs=v1556 } -> x1 + v1558 Binop { op=add, lhs=v1549, rhs=v1557 } -> x0 + v1559 Imm(0) -> x1 + v1560 LoadLocal { off=-523, kind=I64 } -> x1 + v1561 LocalAddr(-348) -> x1 + v1562 Load { addr=v1561, disp=0, kind=I64 } -> x1 + v1563 LocalAddr(-348) -> x2 + v1564 BinopI { op=add, lhs=v1563, rhs_imm=8 } -> x6 + v1565 Load { addr=v1563, disp=8, kind=I64 } -> x2 + v1566 Binop { op=add, lhs=v1562, rhs=v1565 } -> x1 + v1567 Binop { op=add, lhs=v1558, rhs=v1566 } -> x0 + v1568 Imm(0) -> x1 + v1569 LoadLocal { off=-523, kind=I64 } -> x1 + v1570 LocalAddr(-350) -> x1 + v1571 Load { addr=v1570, disp=0, kind=I64 } -> x1 + v1572 LocalAddr(-350) -> x2 + v1573 BinopI { op=add, lhs=v1572, rhs_imm=8 } -> x6 + v1574 Load { addr=v1572, disp=8, kind=I64 } -> x2 + v1575 Binop { op=add, lhs=v1571, rhs=v1574 } -> x1 + v1576 Binop { op=add, lhs=v1567, rhs=v1575 } -> x0 + v1577 Imm(0) -> x1 + v1578 LoadLocal { off=-523, kind=I64 } -> x1 + v1579 LocalAddr(-352) -> x1 + v1580 Load { addr=v1579, disp=0, kind=I64 } -> x1 + v1581 LocalAddr(-352) -> x2 + v1582 BinopI { op=add, lhs=v1581, rhs_imm=8 } -> x6 + v1583 Load { addr=v1581, disp=8, kind=I64 } -> x2 + v1584 Binop { op=add, lhs=v1580, rhs=v1583 } -> x1 + v1585 Binop { op=add, lhs=v1576, rhs=v1584 } -> x0 + v1586 Imm(0) -> x1 + v1587 LoadLocal { off=-523, kind=I64 } -> x1 + v1588 LocalAddr(-354) -> x1 + v1589 Load { addr=v1588, disp=0, kind=I64 } -> x1 + v1590 LocalAddr(-354) -> x2 + v1591 BinopI { op=add, lhs=v1590, rhs_imm=8 } -> x6 + v1592 Load { addr=v1590, disp=8, kind=I64 } -> x2 + v1593 Binop { op=add, lhs=v1589, rhs=v1592 } -> x1 + v1594 Binop { op=add, lhs=v1585, rhs=v1593 } -> x0 + v1595 Imm(0) -> x1 + v1596 LoadLocal { off=-523, kind=I64 } -> x1 + v1597 LocalAddr(-356) -> x1 + v1598 Load { addr=v1597, disp=0, kind=I64 } -> x1 + v1599 LocalAddr(-356) -> x2 + v1600 BinopI { op=add, lhs=v1599, rhs_imm=8 } -> x6 + v1601 Load { addr=v1599, disp=8, kind=I64 } -> x2 + v1602 Binop { op=add, lhs=v1598, rhs=v1601 } -> x1 + v1603 Binop { op=add, lhs=v1594, rhs=v1602 } -> x0 + v1604 Imm(0) -> x1 + v1605 LoadLocal { off=-523, kind=I64 } -> x1 + v1606 LocalAddr(-358) -> x1 + v1607 Load { addr=v1606, disp=0, kind=I64 } -> x1 + v1608 LocalAddr(-358) -> x2 + v1609 BinopI { op=add, lhs=v1608, rhs_imm=8 } -> x6 + v1610 Load { addr=v1608, disp=8, kind=I64 } -> x2 + v1611 Binop { op=add, lhs=v1607, rhs=v1610 } -> x1 + v1612 Binop { op=add, lhs=v1603, rhs=v1611 } -> x0 + v1613 Imm(0) -> x1 + v1614 LoadLocal { off=-523, kind=I64 } -> x1 + v1615 LocalAddr(-360) -> x1 + v1616 Load { addr=v1615, disp=0, kind=I64 } -> x1 + v1617 LocalAddr(-360) -> x2 + v1618 BinopI { op=add, lhs=v1617, rhs_imm=8 } -> x6 + v1619 Load { addr=v1617, disp=8, kind=I64 } -> x2 + v1620 Binop { op=add, lhs=v1616, rhs=v1619 } -> x1 + v1621 Binop { op=add, lhs=v1612, rhs=v1620 } -> x0 + v1622 Imm(0) -> x1 + v1623 LoadLocal { off=-523, kind=I64 } -> x1 + v1624 LocalAddr(-362) -> x1 + v1625 Load { addr=v1624, disp=0, kind=I64 } -> x1 + v1626 LocalAddr(-362) -> x2 + v1627 BinopI { op=add, lhs=v1626, rhs_imm=8 } -> x6 + v1628 Load { addr=v1626, disp=8, kind=I64 } -> x2 + v1629 Binop { op=add, lhs=v1625, rhs=v1628 } -> x1 + v1630 Binop { op=add, lhs=v1621, rhs=v1629 } -> x0 + v1631 Imm(0) -> x1 + v1632 LoadLocal { off=-523, kind=I64 } -> x1 + v1633 LocalAddr(-364) -> x1 + v1634 Load { addr=v1633, disp=0, kind=I64 } -> x1 + v1635 LocalAddr(-364) -> x2 + v1636 BinopI { op=add, lhs=v1635, rhs_imm=8 } -> x6 + v1637 Load { addr=v1635, disp=8, kind=I64 } -> x2 + v1638 Binop { op=add, lhs=v1634, rhs=v1637 } -> x1 + v1639 Binop { op=add, lhs=v1630, rhs=v1638 } -> x0 + v1640 Imm(0) -> x1 + v1641 LoadLocal { off=-523, kind=I64 } -> x1 + v1642 LocalAddr(-366) -> x1 + v1643 Load { addr=v1642, disp=0, kind=I64 } -> x1 + v1644 LocalAddr(-366) -> x2 + v1645 BinopI { op=add, lhs=v1644, rhs_imm=8 } -> x6 + v1646 Load { addr=v1644, disp=8, kind=I64 } -> x2 + v1647 Binop { op=add, lhs=v1643, rhs=v1646 } -> x1 + v1648 Binop { op=add, lhs=v1639, rhs=v1647 } -> x0 + v1649 Imm(0) -> x1 + v1650 LoadLocal { off=-523, kind=I64 } -> x1 + v1651 LocalAddr(-368) -> x1 + v1652 Load { addr=v1651, disp=0, kind=I64 } -> x1 + v1653 LocalAddr(-368) -> x2 + v1654 BinopI { op=add, lhs=v1653, rhs_imm=8 } -> x6 + v1655 Load { addr=v1653, disp=8, kind=I64 } -> x2 + v1656 Binop { op=add, lhs=v1652, rhs=v1655 } -> x1 + v1657 Binop { op=add, lhs=v1648, rhs=v1656 } -> x0 + v1658 Imm(0) -> x1 + v1659 LoadLocal { off=-523, kind=I64 } -> x1 + v1660 LocalAddr(-370) -> x1 + v1661 Load { addr=v1660, disp=0, kind=I64 } -> x1 + v1662 LocalAddr(-370) -> x2 + v1663 BinopI { op=add, lhs=v1662, rhs_imm=8 } -> x6 + v1664 Load { addr=v1662, disp=8, kind=I64 } -> x2 + v1665 Binop { op=add, lhs=v1661, rhs=v1664 } -> x1 + v1666 Binop { op=add, lhs=v1657, rhs=v1665 } -> x0 + v1667 Imm(0) -> x1 + v1668 LoadLocal { off=-523, kind=I64 } -> x1 + v1669 LocalAddr(-372) -> x1 + v1670 Load { addr=v1669, disp=0, kind=I64 } -> x1 + v1671 LocalAddr(-372) -> x2 + v1672 BinopI { op=add, lhs=v1671, rhs_imm=8 } -> x6 + v1673 Load { addr=v1671, disp=8, kind=I64 } -> x2 + v1674 Binop { op=add, lhs=v1670, rhs=v1673 } -> x1 + v1675 Binop { op=add, lhs=v1666, rhs=v1674 } -> x0 + v1676 Imm(0) -> x1 + v1677 LoadLocal { off=-523, kind=I64 } -> x1 + v1678 LocalAddr(-374) -> x1 + v1679 Load { addr=v1678, disp=0, kind=I64 } -> x1 + v1680 LocalAddr(-374) -> x2 + v1681 BinopI { op=add, lhs=v1680, rhs_imm=8 } -> x6 + v1682 Load { addr=v1680, disp=8, kind=I64 } -> x2 + v1683 Binop { op=add, lhs=v1679, rhs=v1682 } -> x1 + v1684 Binop { op=add, lhs=v1675, rhs=v1683 } -> x0 + v1685 Imm(0) -> x1 + v1686 LoadLocal { off=-523, kind=I64 } -> x1 + v1687 LocalAddr(-376) -> x1 + v1688 Load { addr=v1687, disp=0, kind=I64 } -> x1 + v1689 LocalAddr(-376) -> x2 + v1690 BinopI { op=add, lhs=v1689, rhs_imm=8 } -> x6 + v1691 Load { addr=v1689, disp=8, kind=I64 } -> x2 + v1692 Binop { op=add, lhs=v1688, rhs=v1691 } -> x1 + v1693 Binop { op=add, lhs=v1684, rhs=v1692 } -> x0 + v1694 Imm(0) -> x1 + v1695 LoadLocal { off=-523, kind=I64 } -> x1 + v1696 LocalAddr(-378) -> x1 + v1697 Load { addr=v1696, disp=0, kind=I64 } -> x1 + v1698 LocalAddr(-378) -> x2 + v1699 BinopI { op=add, lhs=v1698, rhs_imm=8 } -> x6 + v1700 Load { addr=v1698, disp=8, kind=I64 } -> x2 + v1701 Binop { op=add, lhs=v1697, rhs=v1700 } -> x1 + v1702 Binop { op=add, lhs=v1693, rhs=v1701 } -> x0 + v1703 Imm(0) -> x1 + v1704 LoadLocal { off=-523, kind=I64 } -> x1 + v1705 LocalAddr(-380) -> x1 + v1706 Load { addr=v1705, disp=0, kind=I64 } -> x1 + v1707 LocalAddr(-380) -> x2 + v1708 BinopI { op=add, lhs=v1707, rhs_imm=8 } -> x6 + v1709 Load { addr=v1707, disp=8, kind=I64 } -> x2 + v1710 Binop { op=add, lhs=v1706, rhs=v1709 } -> x1 + v1711 Binop { op=add, lhs=v1702, rhs=v1710 } -> x0 + v1712 Imm(0) -> x1 + v1713 LoadLocal { off=-523, kind=I64 } -> x1 + v1714 LocalAddr(-382) -> x1 + v1715 Load { addr=v1714, disp=0, kind=I64 } -> x1 + v1716 LocalAddr(-382) -> x2 + v1717 BinopI { op=add, lhs=v1716, rhs_imm=8 } -> x6 + v1718 Load { addr=v1716, disp=8, kind=I64 } -> x2 + v1719 Binop { op=add, lhs=v1715, rhs=v1718 } -> x1 + v1720 Binop { op=add, lhs=v1711, rhs=v1719 } -> x0 + v1721 Imm(0) -> x1 + v1722 LoadLocal { off=-523, kind=I64 } -> x1 + v1723 LocalAddr(-384) -> x1 + v1724 Load { addr=v1723, disp=0, kind=I64 } -> x1 + v1725 LocalAddr(-384) -> x2 + v1726 BinopI { op=add, lhs=v1725, rhs_imm=8 } -> x6 + v1727 Load { addr=v1725, disp=8, kind=I64 } -> x2 + v1728 Binop { op=add, lhs=v1724, rhs=v1727 } -> x1 + v1729 Binop { op=add, lhs=v1720, rhs=v1728 } -> x0 + v1730 Imm(0) -> x1 + v1731 LoadLocal { off=-523, kind=I64 } -> x1 + v1732 LocalAddr(-386) -> x1 + v1733 Load { addr=v1732, disp=0, kind=I64 } -> x1 + v1734 LocalAddr(-386) -> x2 + v1735 BinopI { op=add, lhs=v1734, rhs_imm=8 } -> x6 + v1736 Load { addr=v1734, disp=8, kind=I64 } -> x2 + v1737 Binop { op=add, lhs=v1733, rhs=v1736 } -> x1 + v1738 Binop { op=add, lhs=v1729, rhs=v1737 } -> x0 + v1739 Imm(0) -> x1 + v1740 LoadLocal { off=-523, kind=I64 } -> x1 + v1741 LocalAddr(-388) -> x1 + v1742 Load { addr=v1741, disp=0, kind=I64 } -> x1 + v1743 LocalAddr(-388) -> x2 + v1744 BinopI { op=add, lhs=v1743, rhs_imm=8 } -> x6 + v1745 Load { addr=v1743, disp=8, kind=I64 } -> x2 + v1746 Binop { op=add, lhs=v1742, rhs=v1745 } -> x1 + v1747 Binop { op=add, lhs=v1738, rhs=v1746 } -> x0 + v1748 Imm(0) -> x1 + v1749 LoadLocal { off=-523, kind=I64 } -> x1 + v1750 LocalAddr(-390) -> x1 + v1751 Load { addr=v1750, disp=0, kind=I64 } -> x1 + v1752 LocalAddr(-390) -> x2 + v1753 BinopI { op=add, lhs=v1752, rhs_imm=8 } -> x6 + v1754 Load { addr=v1752, disp=8, kind=I64 } -> x2 + v1755 Binop { op=add, lhs=v1751, rhs=v1754 } -> x1 + v1756 Binop { op=add, lhs=v1747, rhs=v1755 } -> x0 + v1757 Imm(0) -> x1 + v1758 LoadLocal { off=-523, kind=I64 } -> x1 + v1759 LocalAddr(-392) -> x1 + v1760 Load { addr=v1759, disp=0, kind=I64 } -> x1 + v1761 LocalAddr(-392) -> x2 + v1762 BinopI { op=add, lhs=v1761, rhs_imm=8 } -> x6 + v1763 Load { addr=v1761, disp=8, kind=I64 } -> x2 + v1764 Binop { op=add, lhs=v1760, rhs=v1763 } -> x1 + v1765 Binop { op=add, lhs=v1756, rhs=v1764 } -> x0 + v1766 Imm(0) -> x1 + v1767 LoadLocal { off=-523, kind=I64 } -> x1 + v1768 LocalAddr(-394) -> x1 + v1769 Load { addr=v1768, disp=0, kind=I64 } -> x1 + v1770 LocalAddr(-394) -> x2 + v1771 BinopI { op=add, lhs=v1770, rhs_imm=8 } -> x6 + v1772 Load { addr=v1770, disp=8, kind=I64 } -> x2 + v1773 Binop { op=add, lhs=v1769, rhs=v1772 } -> x1 + v1774 Binop { op=add, lhs=v1765, rhs=v1773 } -> x0 + v1775 Imm(0) -> x1 + v1776 LoadLocal { off=-523, kind=I64 } -> x1 + v1777 LocalAddr(-396) -> x1 + v1778 Load { addr=v1777, disp=0, kind=I64 } -> x1 + v1779 LocalAddr(-396) -> x2 + v1780 BinopI { op=add, lhs=v1779, rhs_imm=8 } -> x6 + v1781 Load { addr=v1779, disp=8, kind=I64 } -> x2 + v1782 Binop { op=add, lhs=v1778, rhs=v1781 } -> x1 + v1783 Binop { op=add, lhs=v1774, rhs=v1782 } -> x0 + v1784 Imm(0) -> x1 + v1785 LoadLocal { off=-523, kind=I64 } -> x1 + v1786 LocalAddr(-398) -> x1 + v1787 Load { addr=v1786, disp=0, kind=I64 } -> x1 + v1788 LocalAddr(-398) -> x2 + v1789 BinopI { op=add, lhs=v1788, rhs_imm=8 } -> x6 + v1790 Load { addr=v1788, disp=8, kind=I64 } -> x2 + v1791 Binop { op=add, lhs=v1787, rhs=v1790 } -> x1 + v1792 Binop { op=add, lhs=v1783, rhs=v1791 } -> x0 + v1793 Imm(0) -> x1 + v1794 LoadLocal { off=-523, kind=I64 } -> x1 + v1795 LocalAddr(-400) -> x1 + v1796 Load { addr=v1795, disp=0, kind=I64 } -> x1 + v1797 LocalAddr(-400) -> x2 + v1798 BinopI { op=add, lhs=v1797, rhs_imm=8 } -> x6 + v1799 Load { addr=v1797, disp=8, kind=I64 } -> x2 + v1800 Binop { op=add, lhs=v1796, rhs=v1799 } -> x1 + v1801 Binop { op=add, lhs=v1792, rhs=v1800 } -> x0 + v1802 Imm(0) -> x1 + v1803 LoadLocal { off=-523, kind=I64 } -> x1 + v1804 LocalAddr(-402) -> x1 + v1805 Load { addr=v1804, disp=0, kind=I64 } -> x1 + v1806 LocalAddr(-402) -> x2 + v1807 BinopI { op=add, lhs=v1806, rhs_imm=8 } -> x6 + v1808 Load { addr=v1806, disp=8, kind=I64 } -> x2 + v1809 Binop { op=add, lhs=v1805, rhs=v1808 } -> x1 + v1810 Binop { op=add, lhs=v1801, rhs=v1809 } -> x0 + v1811 Imm(0) -> x1 + v1812 LoadLocal { off=-523, kind=I64 } -> x1 + v1813 LocalAddr(-404) -> x1 + v1814 Load { addr=v1813, disp=0, kind=I64 } -> x1 + v1815 LocalAddr(-404) -> x2 + v1816 BinopI { op=add, lhs=v1815, rhs_imm=8 } -> x6 + v1817 Load { addr=v1815, disp=8, kind=I64 } -> x2 + v1818 Binop { op=add, lhs=v1814, rhs=v1817 } -> x1 + v1819 Binop { op=add, lhs=v1810, rhs=v1818 } -> x0 + v1820 Imm(0) -> x1 + v1821 LoadLocal { off=-523, kind=I64 } -> x1 + v1822 LocalAddr(-406) -> x1 + v1823 Load { addr=v1822, disp=0, kind=I64 } -> x1 + v1824 LocalAddr(-406) -> x2 + v1825 BinopI { op=add, lhs=v1824, rhs_imm=8 } -> x6 + v1826 Load { addr=v1824, disp=8, kind=I64 } -> x2 + v1827 Binop { op=add, lhs=v1823, rhs=v1826 } -> x1 + v1828 Binop { op=add, lhs=v1819, rhs=v1827 } -> x0 + v1829 Imm(0) -> x1 + v1830 LoadLocal { off=-523, kind=I64 } -> x1 + v1831 LocalAddr(-408) -> x1 + v1832 Load { addr=v1831, disp=0, kind=I64 } -> x1 + v1833 LocalAddr(-408) -> x2 + v1834 BinopI { op=add, lhs=v1833, rhs_imm=8 } -> x6 + v1835 Load { addr=v1833, disp=8, kind=I64 } -> x2 + v1836 Binop { op=add, lhs=v1832, rhs=v1835 } -> x1 + v1837 Binop { op=add, lhs=v1828, rhs=v1836 } -> x0 + v1838 Imm(0) -> x1 + v1839 LoadLocal { off=-523, kind=I64 } -> x1 + v1840 LocalAddr(-410) -> x1 + v1841 Load { addr=v1840, disp=0, kind=I64 } -> x1 + v1842 LocalAddr(-410) -> x2 + v1843 BinopI { op=add, lhs=v1842, rhs_imm=8 } -> x6 + v1844 Load { addr=v1842, disp=8, kind=I64 } -> x2 + v1845 Binop { op=add, lhs=v1841, rhs=v1844 } -> x1 + v1846 Binop { op=add, lhs=v1837, rhs=v1845 } -> x0 + v1847 Imm(0) -> x1 + v1848 LoadLocal { off=-523, kind=I64 } -> x1 + v1849 LocalAddr(-412) -> x1 + v1850 Load { addr=v1849, disp=0, kind=I64 } -> x1 + v1851 LocalAddr(-412) -> x2 + v1852 BinopI { op=add, lhs=v1851, rhs_imm=8 } -> x6 + v1853 Load { addr=v1851, disp=8, kind=I64 } -> x2 + v1854 Binop { op=add, lhs=v1850, rhs=v1853 } -> x1 + v1855 Binop { op=add, lhs=v1846, rhs=v1854 } -> x0 + v1856 Imm(0) -> x1 + v1857 LoadLocal { off=-523, kind=I64 } -> x1 + v1858 LocalAddr(-414) -> x1 + v1859 Load { addr=v1858, disp=0, kind=I64 } -> x1 + v1860 LocalAddr(-414) -> x2 + v1861 BinopI { op=add, lhs=v1860, rhs_imm=8 } -> x6 + v1862 Load { addr=v1860, disp=8, kind=I64 } -> x2 + v1863 Binop { op=add, lhs=v1859, rhs=v1862 } -> x1 + v1864 Binop { op=add, lhs=v1855, rhs=v1863 } -> x0 + v1865 Imm(0) -> x1 + v1866 LoadLocal { off=-523, kind=I64 } -> x1 + v1867 LocalAddr(-416) -> x1 + v1868 Load { addr=v1867, disp=0, kind=I64 } -> x1 + v1869 LocalAddr(-416) -> x2 + v1870 BinopI { op=add, lhs=v1869, rhs_imm=8 } -> x6 + v1871 Load { addr=v1869, disp=8, kind=I64 } -> x2 + v1872 Binop { op=add, lhs=v1868, rhs=v1871 } -> x1 + v1873 Binop { op=add, lhs=v1864, rhs=v1872 } -> x0 + v1874 Imm(0) -> x1 + v1875 LoadLocal { off=-523, kind=I64 } -> x1 + v1876 LocalAddr(-418) -> x1 + v1877 Load { addr=v1876, disp=0, kind=I64 } -> x1 + v1878 LocalAddr(-418) -> x2 + v1879 BinopI { op=add, lhs=v1878, rhs_imm=8 } -> x6 + v1880 Load { addr=v1878, disp=8, kind=I64 } -> x2 + v1881 Binop { op=add, lhs=v1877, rhs=v1880 } -> x1 + v1882 Binop { op=add, lhs=v1873, rhs=v1881 } -> x0 + v1883 Imm(0) -> x1 + v1884 LoadLocal { off=-523, kind=I64 } -> x1 + v1885 LocalAddr(-420) -> x1 + v1886 Load { addr=v1885, disp=0, kind=I64 } -> x1 + v1887 LocalAddr(-420) -> x2 + v1888 BinopI { op=add, lhs=v1887, rhs_imm=8 } -> x6 + v1889 Load { addr=v1887, disp=8, kind=I64 } -> x2 + v1890 Binop { op=add, lhs=v1886, rhs=v1889 } -> x1 + v1891 Binop { op=add, lhs=v1882, rhs=v1890 } -> x0 + v1892 Imm(0) -> x1 + v1893 LoadLocal { off=-523, kind=I64 } -> x1 + v1894 LocalAddr(-422) -> x1 + v1895 Load { addr=v1894, disp=0, kind=I64 } -> x1 + v1896 LocalAddr(-422) -> x2 + v1897 BinopI { op=add, lhs=v1896, rhs_imm=8 } -> x6 + v1898 Load { addr=v1896, disp=8, kind=I64 } -> x2 + v1899 Binop { op=add, lhs=v1895, rhs=v1898 } -> x1 + v1900 Binop { op=add, lhs=v1891, rhs=v1899 } -> x0 + v1901 Imm(0) -> x1 + v1902 LoadLocal { off=-523, kind=I64 } -> x1 + v1903 LocalAddr(-424) -> x1 + v1904 Load { addr=v1903, disp=0, kind=I64 } -> x1 + v1905 LocalAddr(-424) -> x2 + v1906 BinopI { op=add, lhs=v1905, rhs_imm=8 } -> x6 + v1907 Load { addr=v1905, disp=8, kind=I64 } -> x2 + v1908 Binop { op=add, lhs=v1904, rhs=v1907 } -> x1 + v1909 Binop { op=add, lhs=v1900, rhs=v1908 } -> x0 + v1910 Imm(0) -> x1 + v1911 LoadLocal { off=-523, kind=I64 } -> x1 + v1912 LocalAddr(-426) -> x1 + v1913 Load { addr=v1912, disp=0, kind=I64 } -> x1 + v1914 LocalAddr(-426) -> x2 + v1915 BinopI { op=add, lhs=v1914, rhs_imm=8 } -> x6 + v1916 Load { addr=v1914, disp=8, kind=I64 } -> x2 + v1917 Binop { op=add, lhs=v1913, rhs=v1916 } -> x1 + v1918 Binop { op=add, lhs=v1909, rhs=v1917 } -> x0 + v1919 Imm(0) -> x1 + v1920 LoadLocal { off=-523, kind=I64 } -> x1 + v1921 LocalAddr(-428) -> x1 + v1922 Load { addr=v1921, disp=0, kind=I64 } -> x1 + v1923 LocalAddr(-428) -> x2 + v1924 BinopI { op=add, lhs=v1923, rhs_imm=8 } -> x6 + v1925 Load { addr=v1923, disp=8, kind=I64 } -> x2 + v1926 Binop { op=add, lhs=v1922, rhs=v1925 } -> x1 + v1927 Binop { op=add, lhs=v1918, rhs=v1926 } -> x0 + v1928 Imm(0) -> x1 + v1929 LoadLocal { off=-523, kind=I64 } -> x1 + v1930 LocalAddr(-430) -> x1 + v1931 Load { addr=v1930, disp=0, kind=I64 } -> x1 + v1932 LocalAddr(-430) -> x2 + v1933 BinopI { op=add, lhs=v1932, rhs_imm=8 } -> x6 + v1934 Load { addr=v1932, disp=8, kind=I64 } -> x2 + v1935 Binop { op=add, lhs=v1931, rhs=v1934 } -> x1 + v1936 Binop { op=add, lhs=v1927, rhs=v1935 } -> x0 + v1937 Imm(0) -> x1 + v1938 LoadLocal { off=-523, kind=I64 } -> x1 + v1939 LocalAddr(-432) -> x1 + v1940 Load { addr=v1939, disp=0, kind=I64 } -> x1 + v1941 LocalAddr(-432) -> x2 + v1942 BinopI { op=add, lhs=v1941, rhs_imm=8 } -> x6 + v1943 Load { addr=v1941, disp=8, kind=I64 } -> x2 + v1944 Binop { op=add, lhs=v1940, rhs=v1943 } -> x1 + v1945 Binop { op=add, lhs=v1936, rhs=v1944 } -> x0 + v1946 Imm(0) -> x1 + v1947 LoadLocal { off=-523, kind=I64 } -> x1 + v1948 LocalAddr(-434) -> x1 + v1949 Load { addr=v1948, disp=0, kind=I64 } -> x1 + v1950 LocalAddr(-434) -> x2 + v1951 BinopI { op=add, lhs=v1950, rhs_imm=8 } -> x6 + v1952 Load { addr=v1950, disp=8, kind=I64 } -> x2 + v1953 Binop { op=add, lhs=v1949, rhs=v1952 } -> x1 + v1954 Binop { op=add, lhs=v1945, rhs=v1953 } -> x0 + v1955 Imm(0) -> x1 + v1956 LoadLocal { off=-523, kind=I64 } -> x1 + v1957 LocalAddr(-436) -> x1 + v1958 Load { addr=v1957, disp=0, kind=I64 } -> x1 + v1959 LocalAddr(-436) -> x2 + v1960 BinopI { op=add, lhs=v1959, rhs_imm=8 } -> x6 + v1961 Load { addr=v1959, disp=8, kind=I64 } -> x2 + v1962 Binop { op=add, lhs=v1958, rhs=v1961 } -> x1 + v1963 Binop { op=add, lhs=v1954, rhs=v1962 } -> x0 + v1964 Imm(0) -> x1 + v1965 LoadLocal { off=-523, kind=I64 } -> x1 + v1966 LocalAddr(-438) -> x1 + v1967 Load { addr=v1966, disp=0, kind=I64 } -> x1 + v1968 LocalAddr(-438) -> x2 + v1969 BinopI { op=add, lhs=v1968, rhs_imm=8 } -> x6 + v1970 Load { addr=v1968, disp=8, kind=I64 } -> x2 + v1971 Binop { op=add, lhs=v1967, rhs=v1970 } -> x1 + v1972 Binop { op=add, lhs=v1963, rhs=v1971 } -> x0 + v1973 Imm(0) -> x1 + v1974 LoadLocal { off=-523, kind=I64 } -> x1 + v1975 LocalAddr(-440) -> x1 + v1976 Load { addr=v1975, disp=0, kind=I64 } -> x1 + v1977 LocalAddr(-440) -> x2 + v1978 BinopI { op=add, lhs=v1977, rhs_imm=8 } -> x6 + v1979 Load { addr=v1977, disp=8, kind=I64 } -> x2 + v1980 Binop { op=add, lhs=v1976, rhs=v1979 } -> x1 + v1981 Binop { op=add, lhs=v1972, rhs=v1980 } -> x0 + v1982 Imm(0) -> x1 + v1983 LoadLocal { off=-523, kind=I64 } -> x1 + v1984 LocalAddr(-442) -> x1 + v1985 Load { addr=v1984, disp=0, kind=I64 } -> x1 + v1986 LocalAddr(-442) -> x2 + v1987 BinopI { op=add, lhs=v1986, rhs_imm=8 } -> x6 + v1988 Load { addr=v1986, disp=8, kind=I64 } -> x2 + v1989 Binop { op=add, lhs=v1985, rhs=v1988 } -> x1 + v1990 Binop { op=add, lhs=v1981, rhs=v1989 } -> x0 + v1991 Imm(0) -> x1 + v1992 LoadLocal { off=-523, kind=I64 } -> x1 + v1993 LocalAddr(-444) -> x1 + v1994 Load { addr=v1993, disp=0, kind=I64 } -> x1 + v1995 LocalAddr(-444) -> x2 + v1996 BinopI { op=add, lhs=v1995, rhs_imm=8 } -> x6 + v1997 Load { addr=v1995, disp=8, kind=I64 } -> x2 + v1998 Binop { op=add, lhs=v1994, rhs=v1997 } -> x1 + v1999 Binop { op=add, lhs=v1990, rhs=v1998 } -> x0 + v2000 Imm(0) -> x1 + v2001 LoadLocal { off=-523, kind=I64 } -> x1 + v2002 LocalAddr(-446) -> x1 + v2003 Load { addr=v2002, disp=0, kind=I64 } -> x1 + v2004 LocalAddr(-446) -> x2 + v2005 BinopI { op=add, lhs=v2004, rhs_imm=8 } -> x6 + v2006 Load { addr=v2004, disp=8, kind=I64 } -> x2 + v2007 Binop { op=add, lhs=v2003, rhs=v2006 } -> x1 + v2008 Binop { op=add, lhs=v1999, rhs=v2007 } -> x0 + v2009 Imm(0) -> x1 + v2010 LoadLocal { off=-523, kind=I64 } -> x1 + v2011 LocalAddr(-448) -> x1 + v2012 Load { addr=v2011, disp=0, kind=I64 } -> x1 + v2013 LocalAddr(-448) -> x2 + v2014 BinopI { op=add, lhs=v2013, rhs_imm=8 } -> x6 + v2015 Load { addr=v2013, disp=8, kind=I64 } -> x2 + v2016 Binop { op=add, lhs=v2012, rhs=v2015 } -> x1 + v2017 Binop { op=add, lhs=v2008, rhs=v2016 } -> x0 + v2018 Imm(0) -> x1 + v2019 LoadLocal { off=-523, kind=I64 } -> x1 + v2020 LocalAddr(-450) -> x1 + v2021 Load { addr=v2020, disp=0, kind=I64 } -> x1 + v2022 LocalAddr(-450) -> x2 + v2023 BinopI { op=add, lhs=v2022, rhs_imm=8 } -> x6 + v2024 Load { addr=v2022, disp=8, kind=I64 } -> x2 + v2025 Binop { op=add, lhs=v2021, rhs=v2024 } -> x1 + v2026 Binop { op=add, lhs=v2017, rhs=v2025 } -> x0 + v2027 Imm(0) -> x1 + v2028 LoadLocal { off=-523, kind=I64 } -> x1 + v2029 LocalAddr(-452) -> x1 + v2030 Load { addr=v2029, disp=0, kind=I64 } -> x1 + v2031 LocalAddr(-452) -> x2 + v2032 BinopI { op=add, lhs=v2031, rhs_imm=8 } -> x6 + v2033 Load { addr=v2031, disp=8, kind=I64 } -> x2 + v2034 Binop { op=add, lhs=v2030, rhs=v2033 } -> x1 + v2035 Binop { op=add, lhs=v2026, rhs=v2034 } -> x0 + v2036 Imm(0) -> x1 + v2037 LoadLocal { off=-523, kind=I64 } -> x1 + v2038 LocalAddr(-454) -> x1 + v2039 Load { addr=v2038, disp=0, kind=I64 } -> x1 + v2040 LocalAddr(-454) -> x2 + v2041 BinopI { op=add, lhs=v2040, rhs_imm=8 } -> x6 + v2042 Load { addr=v2040, disp=8, kind=I64 } -> x2 + v2043 Binop { op=add, lhs=v2039, rhs=v2042 } -> x1 + v2044 Binop { op=add, lhs=v2035, rhs=v2043 } -> x0 + v2045 Imm(0) -> x1 + v2046 LoadLocal { off=-523, kind=I64 } -> x1 + v2047 LocalAddr(-456) -> x1 + v2048 Load { addr=v2047, disp=0, kind=I64 } -> x1 + v2049 LocalAddr(-456) -> x2 + v2050 BinopI { op=add, lhs=v2049, rhs_imm=8 } -> x6 + v2051 Load { addr=v2049, disp=8, kind=I64 } -> x2 + v2052 Binop { op=add, lhs=v2048, rhs=v2051 } -> x1 + v2053 Binop { op=add, lhs=v2044, rhs=v2052 } -> x0 + v2054 Imm(0) -> x1 + v2055 LoadLocal { off=-523, kind=I64 } -> x1 + v2056 LocalAddr(-458) -> x1 + v2057 Load { addr=v2056, disp=0, kind=I64 } -> x1 + v2058 LocalAddr(-458) -> x2 + v2059 BinopI { op=add, lhs=v2058, rhs_imm=8 } -> x6 + v2060 Load { addr=v2058, disp=8, kind=I64 } -> x2 + v2061 Binop { op=add, lhs=v2057, rhs=v2060 } -> x1 + v2062 Binop { op=add, lhs=v2053, rhs=v2061 } -> x0 + v2063 Imm(0) -> x1 + v2064 LoadLocal { off=-523, kind=I64 } -> x1 + v2065 LocalAddr(-460) -> x1 + v2066 Load { addr=v2065, disp=0, kind=I64 } -> x1 + v2067 LocalAddr(-460) -> x2 + v2068 BinopI { op=add, lhs=v2067, rhs_imm=8 } -> x6 + v2069 Load { addr=v2067, disp=8, kind=I64 } -> x2 + v2070 Binop { op=add, lhs=v2066, rhs=v2069 } -> x1 + v2071 Binop { op=add, lhs=v2062, rhs=v2070 } -> x0 + v2072 Imm(0) -> x1 + v2073 LoadLocal { off=-523, kind=I64 } -> x1 + v2074 LocalAddr(-462) -> x1 + v2075 Load { addr=v2074, disp=0, kind=I64 } -> x1 + v2076 LocalAddr(-462) -> x2 + v2077 BinopI { op=add, lhs=v2076, rhs_imm=8 } -> x6 + v2078 Load { addr=v2076, disp=8, kind=I64 } -> x2 + v2079 Binop { op=add, lhs=v2075, rhs=v2078 } -> x1 + v2080 Binop { op=add, lhs=v2071, rhs=v2079 } -> x0 + v2081 Imm(0) -> x1 + v2082 LoadLocal { off=-523, kind=I64 } -> x1 + v2083 LocalAddr(-464) -> x1 + v2084 Load { addr=v2083, disp=0, kind=I64 } -> x1 + v2085 LocalAddr(-464) -> x2 + v2086 BinopI { op=add, lhs=v2085, rhs_imm=8 } -> x6 + v2087 Load { addr=v2085, disp=8, kind=I64 } -> x2 + v2088 Binop { op=add, lhs=v2084, rhs=v2087 } -> x1 + v2089 Binop { op=add, lhs=v2080, rhs=v2088 } -> x0 + v2090 Imm(0) -> x1 + v2091 LoadLocal { off=-523, kind=I64 } -> x1 + v2092 LocalAddr(-466) -> x1 + v2093 Load { addr=v2092, disp=0, kind=I64 } -> x1 + v2094 LocalAddr(-466) -> x2 + v2095 BinopI { op=add, lhs=v2094, rhs_imm=8 } -> x6 + v2096 Load { addr=v2094, disp=8, kind=I64 } -> x2 + v2097 Binop { op=add, lhs=v2093, rhs=v2096 } -> x1 + v2098 Binop { op=add, lhs=v2089, rhs=v2097 } -> x0 + v2099 Imm(0) -> x1 + v2100 LoadLocal { off=-523, kind=I64 } -> x1 + v2101 LocalAddr(-468) -> x1 + v2102 Load { addr=v2101, disp=0, kind=I64 } -> x1 + v2103 LocalAddr(-468) -> x2 + v2104 BinopI { op=add, lhs=v2103, rhs_imm=8 } -> x6 + v2105 Load { addr=v2103, disp=8, kind=I64 } -> x2 + v2106 Binop { op=add, lhs=v2102, rhs=v2105 } -> x1 + v2107 Binop { op=add, lhs=v2098, rhs=v2106 } -> x0 + v2108 Imm(0) -> x1 + v2109 LoadLocal { off=-523, kind=I64 } -> x1 + v2110 LocalAddr(-470) -> x1 + v2111 Load { addr=v2110, disp=0, kind=I64 } -> x1 + v2112 LocalAddr(-470) -> x2 + v2113 BinopI { op=add, lhs=v2112, rhs_imm=8 } -> x6 + v2114 Load { addr=v2112, disp=8, kind=I64 } -> x2 + v2115 Binop { op=add, lhs=v2111, rhs=v2114 } -> x1 + v2116 Binop { op=add, lhs=v2107, rhs=v2115 } -> x0 + v2117 Imm(0) -> x1 + v2118 LoadLocal { off=-523, kind=I64 } -> x1 + v2119 LocalAddr(-472) -> x1 + v2120 Load { addr=v2119, disp=0, kind=I64 } -> x1 + v2121 LocalAddr(-472) -> x2 + v2122 BinopI { op=add, lhs=v2121, rhs_imm=8 } -> x6 + v2123 Load { addr=v2121, disp=8, kind=I64 } -> x2 + v2124 Binop { op=add, lhs=v2120, rhs=v2123 } -> x1 + v2125 Binop { op=add, lhs=v2116, rhs=v2124 } -> x0 + v2126 Imm(0) -> x1 + v2127 LoadLocal { off=-523, kind=I64 } -> x1 + v2128 LocalAddr(-474) -> x1 + v2129 Load { addr=v2128, disp=0, kind=I64 } -> x1 + v2130 LocalAddr(-474) -> x2 + v2131 BinopI { op=add, lhs=v2130, rhs_imm=8 } -> x6 + v2132 Load { addr=v2130, disp=8, kind=I64 } -> x2 + v2133 Binop { op=add, lhs=v2129, rhs=v2132 } -> x1 + v2134 Binop { op=add, lhs=v2125, rhs=v2133 } -> x0 + v2135 Imm(0) -> x1 + v2136 LoadLocal { off=-523, kind=I64 } -> x1 + v2137 LocalAddr(-476) -> x1 + v2138 Load { addr=v2137, disp=0, kind=I64 } -> x1 + v2139 LocalAddr(-476) -> x2 + v2140 BinopI { op=add, lhs=v2139, rhs_imm=8 } -> x6 + v2141 Load { addr=v2139, disp=8, kind=I64 } -> x2 + v2142 Binop { op=add, lhs=v2138, rhs=v2141 } -> x1 + v2143 Binop { op=add, lhs=v2134, rhs=v2142 } -> x0 + v2144 Imm(0) -> x1 + v2145 LoadLocal { off=-523, kind=I64 } -> x1 + v2146 LocalAddr(-478) -> x1 + v2147 Load { addr=v2146, disp=0, kind=I64 } -> x1 + v2148 LocalAddr(-478) -> x2 + v2149 BinopI { op=add, lhs=v2148, rhs_imm=8 } -> x6 + v2150 Load { addr=v2148, disp=8, kind=I64 } -> x2 + v2151 Binop { op=add, lhs=v2147, rhs=v2150 } -> x1 + v2152 Binop { op=add, lhs=v2143, rhs=v2151 } -> x0 + v2153 Imm(0) -> x1 + v2154 LoadLocal { off=-523, kind=I64 } -> x1 + v2155 LocalAddr(-480) -> x1 + v2156 Load { addr=v2155, disp=0, kind=I64 } -> x1 + v2157 LocalAddr(-480) -> x2 + v2158 BinopI { op=add, lhs=v2157, rhs_imm=8 } -> x6 + v2159 Load { addr=v2157, disp=8, kind=I64 } -> x2 + v2160 Binop { op=add, lhs=v2156, rhs=v2159 } -> x1 + v2161 Binop { op=add, lhs=v2152, rhs=v2160 } -> x0 + v2162 Imm(0) -> x1 + v2163 LoadLocal { off=-523, kind=I64 } -> x1 + v2164 LocalAddr(-482) -> x1 + v2165 Load { addr=v2164, disp=0, kind=I64 } -> x1 + v2166 LocalAddr(-482) -> x2 + v2167 BinopI { op=add, lhs=v2166, rhs_imm=8 } -> x6 + v2168 Load { addr=v2166, disp=8, kind=I64 } -> x2 + v2169 Binop { op=add, lhs=v2165, rhs=v2168 } -> x1 + v2170 Binop { op=add, lhs=v2161, rhs=v2169 } -> x0 + v2171 Imm(0) -> x1 + v2172 LoadLocal { off=-523, kind=I64 } -> x1 + v2173 LocalAddr(-484) -> x1 + v2174 Load { addr=v2173, disp=0, kind=I64 } -> x1 + v2175 LocalAddr(-484) -> x2 + v2176 BinopI { op=add, lhs=v2175, rhs_imm=8 } -> x6 + v2177 Load { addr=v2175, disp=8, kind=I64 } -> x2 + v2178 Binop { op=add, lhs=v2174, rhs=v2177 } -> x1 + v2179 Binop { op=add, lhs=v2170, rhs=v2178 } -> x0 + v2180 Imm(0) -> x1 + v2181 LoadLocal { off=-523, kind=I64 } -> x1 + v2182 LocalAddr(-486) -> x1 + v2183 Load { addr=v2182, disp=0, kind=I64 } -> x1 + v2184 LocalAddr(-486) -> x2 + v2185 BinopI { op=add, lhs=v2184, rhs_imm=8 } -> x6 + v2186 Load { addr=v2184, disp=8, kind=I64 } -> x2 + v2187 Binop { op=add, lhs=v2183, rhs=v2186 } -> x1 + v2188 Binop { op=add, lhs=v2179, rhs=v2187 } -> x0 + v2189 Imm(0) -> x1 + v2190 LoadLocal { off=-523, kind=I64 } -> x1 + v2191 LocalAddr(-488) -> x1 + v2192 Load { addr=v2191, disp=0, kind=I64 } -> x1 + v2193 LocalAddr(-488) -> x2 + v2194 BinopI { op=add, lhs=v2193, rhs_imm=8 } -> x6 + v2195 Load { addr=v2193, disp=8, kind=I64 } -> x2 + v2196 Binop { op=add, lhs=v2192, rhs=v2195 } -> x1 + v2197 Binop { op=add, lhs=v2188, rhs=v2196 } -> x0 + v2198 Imm(0) -> x1 + v2199 LoadLocal { off=-523, kind=I64 } -> x1 + v2200 LocalAddr(-490) -> x1 + v2201 Load { addr=v2200, disp=0, kind=I64 } -> x1 + v2202 LocalAddr(-490) -> x2 + v2203 BinopI { op=add, lhs=v2202, rhs_imm=8 } -> x6 + v2204 Load { addr=v2202, disp=8, kind=I64 } -> x2 + v2205 Binop { op=add, lhs=v2201, rhs=v2204 } -> x1 + v2206 Binop { op=add, lhs=v2197, rhs=v2205 } -> x0 + v2207 Imm(0) -> x1 + v2208 LoadLocal { off=-523, kind=I64 } -> x1 + v2209 LocalAddr(-492) -> x1 + v2210 Load { addr=v2209, disp=0, kind=I64 } -> x1 + v2211 LocalAddr(-492) -> x2 + v2212 BinopI { op=add, lhs=v2211, rhs_imm=8 } -> x6 + v2213 Load { addr=v2211, disp=8, kind=I64 } -> x2 + v2214 Binop { op=add, lhs=v2210, rhs=v2213 } -> x1 + v2215 Binop { op=add, lhs=v2206, rhs=v2214 } -> x0 + v2216 Imm(0) -> x1 + v2217 LoadLocal { off=-523, kind=I64 } -> x1 + v2218 LocalAddr(-494) -> x1 + v2219 Load { addr=v2218, disp=0, kind=I64 } -> x1 + v2220 LocalAddr(-494) -> x2 + v2221 BinopI { op=add, lhs=v2220, rhs_imm=8 } -> x6 + v2222 Load { addr=v2220, disp=8, kind=I64 } -> x2 + v2223 Binop { op=add, lhs=v2219, rhs=v2222 } -> x1 + v2224 Binop { op=add, lhs=v2215, rhs=v2223 } -> x0 + v2225 Imm(0) -> x1 + v2226 LoadLocal { off=-523, kind=I64 } -> x1 + v2227 LocalAddr(-496) -> x1 + v2228 Load { addr=v2227, disp=0, kind=I64 } -> x1 + v2229 LocalAddr(-496) -> x2 + v2230 BinopI { op=add, lhs=v2229, rhs_imm=8 } -> x6 + v2231 Load { addr=v2229, disp=8, kind=I64 } -> x2 + v2232 Binop { op=add, lhs=v2228, rhs=v2231 } -> x1 + v2233 Binop { op=add, lhs=v2224, rhs=v2232 } -> x0 + v2234 Imm(0) -> x1 + v2235 LoadLocal { off=-523, kind=I64 } -> x1 + v2236 LocalAddr(-498) -> x1 + v2237 Load { addr=v2236, disp=0, kind=I64 } -> x1 + v2238 LocalAddr(-498) -> x2 + v2239 BinopI { op=add, lhs=v2238, rhs_imm=8 } -> x6 + v2240 Load { addr=v2238, disp=8, kind=I64 } -> x2 + v2241 Binop { op=add, lhs=v2237, rhs=v2240 } -> x1 + v2242 Binop { op=add, lhs=v2233, rhs=v2241 } -> x0 + v2243 Imm(0) -> x1 + v2244 LoadLocal { off=-523, kind=I64 } -> x1 + v2245 LocalAddr(-500) -> x1 + v2246 Load { addr=v2245, disp=0, kind=I64 } -> x1 + v2247 LocalAddr(-500) -> x2 + v2248 BinopI { op=add, lhs=v2247, rhs_imm=8 } -> x6 + v2249 Load { addr=v2247, disp=8, kind=I64 } -> x2 + v2250 Binop { op=add, lhs=v2246, rhs=v2249 } -> x1 + v2251 Binop { op=add, lhs=v2242, rhs=v2250 } -> x0 + v2252 Imm(0) -> x1 + v2253 LoadLocal { off=-523, kind=I64 } -> x1 + v2254 LocalAddr(-502) -> x1 + v2255 Load { addr=v2254, disp=0, kind=I64 } -> x1 + v2256 LocalAddr(-502) -> x2 + v2257 BinopI { op=add, lhs=v2256, rhs_imm=8 } -> x6 + v2258 Load { addr=v2256, disp=8, kind=I64 } -> x2 + v2259 Binop { op=add, lhs=v2255, rhs=v2258 } -> x1 + v2260 Binop { op=add, lhs=v2251, rhs=v2259 } -> x0 + v2261 Imm(0) -> x1 + v2262 LoadLocal { off=-523, kind=I64 } -> x1 + v2263 LocalAddr(-504) -> x1 + v2264 Load { addr=v2263, disp=0, kind=I64 } -> x1 + v2265 LocalAddr(-504) -> x2 + v2266 BinopI { op=add, lhs=v2265, rhs_imm=8 } -> x6 + v2267 Load { addr=v2265, disp=8, kind=I64 } -> x2 + v2268 Binop { op=add, lhs=v2264, rhs=v2267 } -> x1 + v2269 Binop { op=add, lhs=v2260, rhs=v2268 } -> x0 + v2270 Imm(0) -> x1 + v2271 LoadLocal { off=-523, kind=I64 } -> x1 + v2272 LocalAddr(-506) -> x1 + v2273 Load { addr=v2272, disp=0, kind=I64 } -> x1 + v2274 LocalAddr(-506) -> x2 + v2275 BinopI { op=add, lhs=v2274, rhs_imm=8 } -> x6 + v2276 Load { addr=v2274, disp=8, kind=I64 } -> x2 + v2277 Binop { op=add, lhs=v2273, rhs=v2276 } -> x1 + v2278 Binop { op=add, lhs=v2269, rhs=v2277 } -> x0 + v2279 Imm(0) -> x1 + v2280 LoadLocal { off=-523, kind=I64 } -> x1 + v2281 LocalAddr(-508) -> x1 + v2282 Load { addr=v2281, disp=0, kind=I64 } -> x1 + v2283 LocalAddr(-508) -> x2 + v2284 BinopI { op=add, lhs=v2283, rhs_imm=8 } -> x6 + v2285 Load { addr=v2283, disp=8, kind=I64 } -> x2 + v2286 Binop { op=add, lhs=v2282, rhs=v2285 } -> x1 + v2287 Binop { op=add, lhs=v2278, rhs=v2286 } -> x0 + v2288 Imm(0) -> x1 + v2289 LoadLocal { off=-523, kind=I64 } -> x1 + v2290 LocalAddr(-510) -> x1 + v2291 Load { addr=v2290, disp=0, kind=I64 } -> x1 + v2292 LocalAddr(-510) -> x2 + v2293 BinopI { op=add, lhs=v2292, rhs_imm=8 } -> x6 + v2294 Load { addr=v2292, disp=8, kind=I64 } -> x2 + v2295 Binop { op=add, lhs=v2291, rhs=v2294 } -> x1 + v2296 Binop { op=add, lhs=v2287, rhs=v2295 } -> x0 + v2297 Imm(0) -> x1 + v2298 LoadLocal { off=-523, kind=I64 } -> x1 + v2299 LocalAddr(-512) -> x1 + v2300 Load { addr=v2299, disp=0, kind=I64 } -> x1 + v2301 LocalAddr(-512) -> x2 + v2302 BinopI { op=add, lhs=v2301, rhs_imm=8 } -> x6 + v2303 Load { addr=v2301, disp=8, kind=I64 } -> x2 + v2304 Binop { op=add, lhs=v2300, rhs=v2303 } -> x1 + v2305 Binop { op=add, lhs=v2296, rhs=v2304 } -> x0 + v2306 Imm(0) -> x1 + v2307 LoadLocal { off=-523, kind=I64 } -> x1 + v2308 LocalAddr(-514) -> x1 + v2309 Load { addr=v2308, disp=0, kind=I64 } -> x1 + v2310 LocalAddr(-514) -> x2 + v2311 BinopI { op=add, lhs=v2310, rhs_imm=8 } -> x6 + v2312 Load { addr=v2310, disp=8, kind=I64 } -> x2 + v2313 Binop { op=add, lhs=v2309, rhs=v2312 } -> x1 + v2314 Binop { op=add, lhs=v2305, rhs=v2313 } -> x0 + v2315 Imm(0) -> x1 + v2316 LoadLocal { off=-523, kind=I64 } -> x1 + v2317 LocalAddr(-516) -> x1 + v2318 Load { addr=v2317, disp=0, kind=I64 } -> x1 + v2319 LocalAddr(-516) -> x2 + v2320 BinopI { op=add, lhs=v2319, rhs_imm=8 } -> x6 + v2321 Load { addr=v2319, disp=8, kind=I64 } -> x2 + v2322 Binop { op=add, lhs=v2318, rhs=v2321 } -> x1 + v2323 Binop { op=add, lhs=v2314, rhs=v2322 } -> x0 + v2324 Imm(0) -> x1 + v2325 LoadLocal { off=-523, kind=I64 } -> x1 + v2326 LocalAddr(-518) -> x1 + v2327 Load { addr=v2326, disp=0, kind=I64 } -> x1 + v2328 LocalAddr(-518) -> x2 + v2329 BinopI { op=add, lhs=v2328, rhs_imm=8 } -> x6 + v2330 Load { addr=v2328, disp=8, kind=I64 } -> x2 + v2331 Binop { op=add, lhs=v2327, rhs=v2330 } -> x1 + v2332 Binop { op=add, lhs=v2323, rhs=v2331 } -> x0 + v2333 Imm(0) -> x1 + v2334 LoadLocal { off=-523, kind=I64 } -> x1 + v2335 LocalAddr(-520) -> x1 + v2336 Load { addr=v2335, disp=0, kind=I64 } -> x1 + v2337 LocalAddr(-520) -> x2 + v2338 BinopI { op=add, lhs=v2337, rhs_imm=8 } -> x6 + v2339 Load { addr=v2337, disp=8, kind=I64 } -> x2 + v2340 Binop { op=add, lhs=v2336, rhs=v2339 } -> x1 + v2341 Binop { op=add, lhs=v2332, rhs=v2340 } -> x0 + v2342 Imm(0) -> x1 + v2343 LoadLocal { off=-523, kind=I64 } -> x1 + v2344 LocalAddr(-522) -> x1 + v2345 Load { addr=v2344, disp=0, kind=I64 } -> x1 + v2346 LocalAddr(-522) -> x2 + v2347 BinopI { op=add, lhs=v2346, rhs_imm=8 } -> x6 + v2348 Load { addr=v2346, disp=8, kind=I64 } -> x2 + v2349 Binop { op=add, lhs=v2345, rhs=v2348 } -> x1 + v2350 Binop { op=add, lhs=v2341, rhs=v2349 } -> x0 + v2351 Imm(0) -> x1 + v2352 LoadLocal { off=-523, kind=I64 } -> x1 + terminator Return(v2350) (exit_acc=v2350) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=sum_longs +fn ent_pc=1 n_params=260 variadic=false locals=1 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 ParamRef(2, kind=I64) -> x2 + v6 Imm(0) -> x0 + v7 ParamRef(3, kind=I64) -> x1 + v8 Imm(0) -> x0 + v9 ParamRef(4, kind=I64) -> x8 + v10 Imm(0) -> x0 + v11 ParamRef(5, kind=I64) -> x9 + v12 Imm(0) -> x0 + v13 Imm(0) -> x0 + v14 Imm(0) -> x3 + v15 LoadLocal { off=-1, kind=I64 } -> x3 + v16 LoadLocal { off=2, kind=I64 } -> x3 + v17 Binop { op=add, lhs=v13, rhs=v1 } -> x0 + v18 Imm(0) -> x7 + v19 LoadLocal { off=-1, kind=I64 } -> x7 + v20 LoadLocal { off=3, kind=I64 } -> x7 + v21 Binop { op=add, lhs=v17, rhs=v3 } -> x0 + v22 Imm(0) -> x6 + v23 LoadLocal { off=-1, kind=I64 } -> x6 + v24 LoadLocal { off=4, kind=I64 } -> x6 + v25 Binop { op=add, lhs=v21, rhs=v5 } -> x0 + v26 Imm(0) -> x2 + v27 LoadLocal { off=-1, kind=I64 } -> x2 + v28 LoadLocal { off=5, kind=I64 } -> x2 + v29 Binop { op=add, lhs=v25, rhs=v7 } -> x0 + v30 Imm(0) -> x1 + v31 LoadLocal { off=-1, kind=I64 } -> x1 + v32 LoadLocal { off=6, kind=I64 } -> x1 + v33 Binop { op=add, lhs=v29, rhs=v9 } -> x0 + v34 Imm(0) -> x1 + v35 LoadLocal { off=-1, kind=I64 } -> x1 + v36 LoadLocal { off=7, kind=I64 } -> x1 + v37 Binop { op=add, lhs=v33, rhs=v11 } -> x0 + v38 Imm(0) -> x1 + v39 LoadLocal { off=-1, kind=I64 } -> x1 + v40 LoadLocal { off=8, kind=I64 } -> x1 + v41 Binop { op=add, lhs=v37, rhs=v40 } -> x0 + v42 Imm(0) -> x1 + v43 LoadLocal { off=-1, kind=I64 } -> x1 + v44 LoadLocal { off=9, kind=I64 } -> x1 + v45 Binop { op=add, lhs=v41, rhs=v44 } -> x0 + v46 Imm(0) -> x1 + v47 LoadLocal { off=-1, kind=I64 } -> x1 + v48 LoadLocal { off=10, kind=I64 } -> x1 + v49 Binop { op=add, lhs=v45, rhs=v48 } -> x0 + v50 Imm(0) -> x1 + v51 LoadLocal { off=-1, kind=I64 } -> x1 + v52 LoadLocal { off=11, kind=I64 } -> x1 + v53 Binop { op=add, lhs=v49, rhs=v52 } -> x0 + v54 Imm(0) -> x1 + v55 LoadLocal { off=-1, kind=I64 } -> x1 + v56 LoadLocal { off=12, kind=I64 } -> x1 + v57 Binop { op=add, lhs=v53, rhs=v56 } -> x0 + v58 Imm(0) -> x1 + v59 LoadLocal { off=-1, kind=I64 } -> x1 + v60 LoadLocal { off=13, kind=I64 } -> x1 + v61 Binop { op=add, lhs=v57, rhs=v60 } -> x0 + v62 Imm(0) -> x1 + v63 LoadLocal { off=-1, kind=I64 } -> x1 + v64 LoadLocal { off=14, kind=I64 } -> x1 + v65 Binop { op=add, lhs=v61, rhs=v64 } -> x0 + v66 Imm(0) -> x1 + v67 LoadLocal { off=-1, kind=I64 } -> x1 + v68 LoadLocal { off=15, kind=I64 } -> x1 + v69 Binop { op=add, lhs=v65, rhs=v68 } -> x0 + v70 Imm(0) -> x1 + v71 LoadLocal { off=-1, kind=I64 } -> x1 + v72 LoadLocal { off=16, kind=I64 } -> x1 + v73 Binop { op=add, lhs=v69, rhs=v72 } -> x0 + v74 Imm(0) -> x1 + v75 LoadLocal { off=-1, kind=I64 } -> x1 + v76 LoadLocal { off=17, kind=I64 } -> x1 + v77 Binop { op=add, lhs=v73, rhs=v76 } -> x0 + v78 Imm(0) -> x1 + v79 LoadLocal { off=-1, kind=I64 } -> x1 + v80 LoadLocal { off=18, kind=I64 } -> x1 + v81 Binop { op=add, lhs=v77, rhs=v80 } -> x0 + v82 Imm(0) -> x1 + v83 LoadLocal { off=-1, kind=I64 } -> x1 + v84 LoadLocal { off=19, kind=I64 } -> x1 + v85 Binop { op=add, lhs=v81, rhs=v84 } -> x0 + v86 Imm(0) -> x1 + v87 LoadLocal { off=-1, kind=I64 } -> x1 + v88 LoadLocal { off=20, kind=I64 } -> x1 + v89 Binop { op=add, lhs=v85, rhs=v88 } -> x0 + v90 Imm(0) -> x1 + v91 LoadLocal { off=-1, kind=I64 } -> x1 + v92 LoadLocal { off=21, kind=I64 } -> x1 + v93 Binop { op=add, lhs=v89, rhs=v92 } -> x0 + v94 Imm(0) -> x1 + v95 LoadLocal { off=-1, kind=I64 } -> x1 + v96 LoadLocal { off=22, kind=I64 } -> x1 + v97 Binop { op=add, lhs=v93, rhs=v96 } -> x0 + v98 Imm(0) -> x1 + v99 LoadLocal { off=-1, kind=I64 } -> x1 + v100 LoadLocal { off=23, kind=I64 } -> x1 + v101 Binop { op=add, lhs=v97, rhs=v100 } -> x0 + v102 Imm(0) -> x1 + v103 LoadLocal { off=-1, kind=I64 } -> x1 + v104 LoadLocal { off=24, kind=I64 } -> x1 + v105 Binop { op=add, lhs=v101, rhs=v104 } -> x0 + v106 Imm(0) -> x1 + v107 LoadLocal { off=-1, kind=I64 } -> x1 + v108 LoadLocal { off=25, kind=I64 } -> x1 + v109 Binop { op=add, lhs=v105, rhs=v108 } -> x0 + v110 Imm(0) -> x1 + v111 LoadLocal { off=-1, kind=I64 } -> x1 + v112 LoadLocal { off=26, kind=I64 } -> x1 + v113 Binop { op=add, lhs=v109, rhs=v112 } -> x0 + v114 Imm(0) -> x1 + v115 LoadLocal { off=-1, kind=I64 } -> x1 + v116 LoadLocal { off=27, kind=I64 } -> x1 + v117 Binop { op=add, lhs=v113, rhs=v116 } -> x0 + v118 Imm(0) -> x1 + v119 LoadLocal { off=-1, kind=I64 } -> x1 + v120 LoadLocal { off=28, kind=I64 } -> x1 + v121 Binop { op=add, lhs=v117, rhs=v120 } -> x0 + v122 Imm(0) -> x1 + v123 LoadLocal { off=-1, kind=I64 } -> x1 + v124 LoadLocal { off=29, kind=I64 } -> x1 + v125 Binop { op=add, lhs=v121, rhs=v124 } -> x0 + v126 Imm(0) -> x1 + v127 LoadLocal { off=-1, kind=I64 } -> x1 + v128 LoadLocal { off=30, kind=I64 } -> x1 + v129 Binop { op=add, lhs=v125, rhs=v128 } -> x0 + v130 Imm(0) -> x1 + v131 LoadLocal { off=-1, kind=I64 } -> x1 + v132 LoadLocal { off=31, kind=I64 } -> x1 + v133 Binop { op=add, lhs=v129, rhs=v132 } -> x0 + v134 Imm(0) -> x1 + v135 LoadLocal { off=-1, kind=I64 } -> x1 + v136 LoadLocal { off=32, kind=I64 } -> x1 + v137 Binop { op=add, lhs=v133, rhs=v136 } -> x0 + v138 Imm(0) -> x1 + v139 LoadLocal { off=-1, kind=I64 } -> x1 + v140 LoadLocal { off=33, kind=I64 } -> x1 + v141 Binop { op=add, lhs=v137, rhs=v140 } -> x0 + v142 Imm(0) -> x1 + v143 LoadLocal { off=-1, kind=I64 } -> x1 + v144 LoadLocal { off=34, kind=I64 } -> x1 + v145 Binop { op=add, lhs=v141, rhs=v144 } -> x0 + v146 Imm(0) -> x1 + v147 LoadLocal { off=-1, kind=I64 } -> x1 + v148 LoadLocal { off=35, kind=I64 } -> x1 + v149 Binop { op=add, lhs=v145, rhs=v148 } -> x0 + v150 Imm(0) -> x1 + v151 LoadLocal { off=-1, kind=I64 } -> x1 + v152 LoadLocal { off=36, kind=I64 } -> x1 + v153 Binop { op=add, lhs=v149, rhs=v152 } -> x0 + v154 Imm(0) -> x1 + v155 LoadLocal { off=-1, kind=I64 } -> x1 + v156 LoadLocal { off=37, kind=I64 } -> x1 + v157 Binop { op=add, lhs=v153, rhs=v156 } -> x0 + v158 Imm(0) -> x1 + v159 LoadLocal { off=-1, kind=I64 } -> x1 + v160 LoadLocal { off=38, kind=I64 } -> x1 + v161 Binop { op=add, lhs=v157, rhs=v160 } -> x0 + v162 Imm(0) -> x1 + v163 LoadLocal { off=-1, kind=I64 } -> x1 + v164 LoadLocal { off=39, kind=I64 } -> x1 + v165 Binop { op=add, lhs=v161, rhs=v164 } -> x0 + v166 Imm(0) -> x1 + v167 LoadLocal { off=-1, kind=I64 } -> x1 + v168 LoadLocal { off=40, kind=I64 } -> x1 + v169 Binop { op=add, lhs=v165, rhs=v168 } -> x0 + v170 Imm(0) -> x1 + v171 LoadLocal { off=-1, kind=I64 } -> x1 + v172 LoadLocal { off=41, kind=I64 } -> x1 + v173 Binop { op=add, lhs=v169, rhs=v172 } -> x0 + v174 Imm(0) -> x1 + v175 LoadLocal { off=-1, kind=I64 } -> x1 + v176 LoadLocal { off=42, kind=I64 } -> x1 + v177 Binop { op=add, lhs=v173, rhs=v176 } -> x0 + v178 Imm(0) -> x1 + v179 LoadLocal { off=-1, kind=I64 } -> x1 + v180 LoadLocal { off=43, kind=I64 } -> x1 + v181 Binop { op=add, lhs=v177, rhs=v180 } -> x0 + v182 Imm(0) -> x1 + v183 LoadLocal { off=-1, kind=I64 } -> x1 + v184 LoadLocal { off=44, kind=I64 } -> x1 + v185 Binop { op=add, lhs=v181, rhs=v184 } -> x0 + v186 Imm(0) -> x1 + v187 LoadLocal { off=-1, kind=I64 } -> x1 + v188 LoadLocal { off=45, kind=I64 } -> x1 + v189 Binop { op=add, lhs=v185, rhs=v188 } -> x0 + v190 Imm(0) -> x1 + v191 LoadLocal { off=-1, kind=I64 } -> x1 + v192 LoadLocal { off=46, kind=I64 } -> x1 + v193 Binop { op=add, lhs=v189, rhs=v192 } -> x0 + v194 Imm(0) -> x1 + v195 LoadLocal { off=-1, kind=I64 } -> x1 + v196 LoadLocal { off=47, kind=I64 } -> x1 + v197 Binop { op=add, lhs=v193, rhs=v196 } -> x0 + v198 Imm(0) -> x1 + v199 LoadLocal { off=-1, kind=I64 } -> x1 + v200 LoadLocal { off=48, kind=I64 } -> x1 + v201 Binop { op=add, lhs=v197, rhs=v200 } -> x0 + v202 Imm(0) -> x1 + v203 LoadLocal { off=-1, kind=I64 } -> x1 + v204 LoadLocal { off=49, kind=I64 } -> x1 + v205 Binop { op=add, lhs=v201, rhs=v204 } -> x0 + v206 Imm(0) -> x1 + v207 LoadLocal { off=-1, kind=I64 } -> x1 + v208 LoadLocal { off=50, kind=I64 } -> x1 + v209 Binop { op=add, lhs=v205, rhs=v208 } -> x0 + v210 Imm(0) -> x1 + v211 LoadLocal { off=-1, kind=I64 } -> x1 + v212 LoadLocal { off=51, kind=I64 } -> x1 + v213 Binop { op=add, lhs=v209, rhs=v212 } -> x0 + v214 Imm(0) -> x1 + v215 LoadLocal { off=-1, kind=I64 } -> x1 + v216 LoadLocal { off=52, kind=I64 } -> x1 + v217 Binop { op=add, lhs=v213, rhs=v216 } -> x0 + v218 Imm(0) -> x1 + v219 LoadLocal { off=-1, kind=I64 } -> x1 + v220 LoadLocal { off=53, kind=I64 } -> x1 + v221 Binop { op=add, lhs=v217, rhs=v220 } -> x0 + v222 Imm(0) -> x1 + v223 LoadLocal { off=-1, kind=I64 } -> x1 + v224 LoadLocal { off=54, kind=I64 } -> x1 + v225 Binop { op=add, lhs=v221, rhs=v224 } -> x0 + v226 Imm(0) -> x1 + v227 LoadLocal { off=-1, kind=I64 } -> x1 + v228 LoadLocal { off=55, kind=I64 } -> x1 + v229 Binop { op=add, lhs=v225, rhs=v228 } -> x0 + v230 Imm(0) -> x1 + v231 LoadLocal { off=-1, kind=I64 } -> x1 + v232 LoadLocal { off=56, kind=I64 } -> x1 + v233 Binop { op=add, lhs=v229, rhs=v232 } -> x0 + v234 Imm(0) -> x1 + v235 LoadLocal { off=-1, kind=I64 } -> x1 + v236 LoadLocal { off=57, kind=I64 } -> x1 + v237 Binop { op=add, lhs=v233, rhs=v236 } -> x0 + v238 Imm(0) -> x1 + v239 LoadLocal { off=-1, kind=I64 } -> x1 + v240 LoadLocal { off=58, kind=I64 } -> x1 + v241 Binop { op=add, lhs=v237, rhs=v240 } -> x0 + v242 Imm(0) -> x1 + v243 LoadLocal { off=-1, kind=I64 } -> x1 + v244 LoadLocal { off=59, kind=I64 } -> x1 + v245 Binop { op=add, lhs=v241, rhs=v244 } -> x0 + v246 Imm(0) -> x1 + v247 LoadLocal { off=-1, kind=I64 } -> x1 + v248 LoadLocal { off=60, kind=I64 } -> x1 + v249 Binop { op=add, lhs=v245, rhs=v248 } -> x0 + v250 Imm(0) -> x1 + v251 LoadLocal { off=-1, kind=I64 } -> x1 + v252 LoadLocal { off=61, kind=I64 } -> x1 + v253 Binop { op=add, lhs=v249, rhs=v252 } -> x0 + v254 Imm(0) -> x1 + v255 LoadLocal { off=-1, kind=I64 } -> x1 + v256 LoadLocal { off=62, kind=I64 } -> x1 + v257 Binop { op=add, lhs=v253, rhs=v256 } -> x0 + v258 Imm(0) -> x1 + v259 LoadLocal { off=-1, kind=I64 } -> x1 + v260 LoadLocal { off=63, kind=I64 } -> x1 + v261 Binop { op=add, lhs=v257, rhs=v260 } -> x0 + v262 Imm(0) -> x1 + v263 LoadLocal { off=-1, kind=I64 } -> x1 + v264 LoadLocal { off=64, kind=I64 } -> x1 + v265 Binop { op=add, lhs=v261, rhs=v264 } -> x0 + v266 Imm(0) -> x1 + v267 LoadLocal { off=-1, kind=I64 } -> x1 + v268 LoadLocal { off=65, kind=I64 } -> x1 + v269 Binop { op=add, lhs=v265, rhs=v268 } -> x0 + v270 Imm(0) -> x1 + v271 LoadLocal { off=-1, kind=I64 } -> x1 + v272 LoadLocal { off=66, kind=I64 } -> x1 + v273 Binop { op=add, lhs=v269, rhs=v272 } -> x0 + v274 Imm(0) -> x1 + v275 LoadLocal { off=-1, kind=I64 } -> x1 + v276 LoadLocal { off=67, kind=I64 } -> x1 + v277 Binop { op=add, lhs=v273, rhs=v276 } -> x0 + v278 Imm(0) -> x1 + v279 LoadLocal { off=-1, kind=I64 } -> x1 + v280 LoadLocal { off=68, kind=I64 } -> x1 + v281 Binop { op=add, lhs=v277, rhs=v280 } -> x0 + v282 Imm(0) -> x1 + v283 LoadLocal { off=-1, kind=I64 } -> x1 + v284 LoadLocal { off=69, kind=I64 } -> x1 + v285 Binop { op=add, lhs=v281, rhs=v284 } -> x0 + v286 Imm(0) -> x1 + v287 LoadLocal { off=-1, kind=I64 } -> x1 + v288 LoadLocal { off=70, kind=I64 } -> x1 + v289 Binop { op=add, lhs=v285, rhs=v288 } -> x0 + v290 Imm(0) -> x1 + v291 LoadLocal { off=-1, kind=I64 } -> x1 + v292 LoadLocal { off=71, kind=I64 } -> x1 + v293 Binop { op=add, lhs=v289, rhs=v292 } -> x0 + v294 Imm(0) -> x1 + v295 LoadLocal { off=-1, kind=I64 } -> x1 + v296 LoadLocal { off=72, kind=I64 } -> x1 + v297 Binop { op=add, lhs=v293, rhs=v296 } -> x0 + v298 Imm(0) -> x1 + v299 LoadLocal { off=-1, kind=I64 } -> x1 + v300 LoadLocal { off=73, kind=I64 } -> x1 + v301 Binop { op=add, lhs=v297, rhs=v300 } -> x0 + v302 Imm(0) -> x1 + v303 LoadLocal { off=-1, kind=I64 } -> x1 + v304 LoadLocal { off=74, kind=I64 } -> x1 + v305 Binop { op=add, lhs=v301, rhs=v304 } -> x0 + v306 Imm(0) -> x1 + v307 LoadLocal { off=-1, kind=I64 } -> x1 + v308 LoadLocal { off=75, kind=I64 } -> x1 + v309 Binop { op=add, lhs=v305, rhs=v308 } -> x0 + v310 Imm(0) -> x1 + v311 LoadLocal { off=-1, kind=I64 } -> x1 + v312 LoadLocal { off=76, kind=I64 } -> x1 + v313 Binop { op=add, lhs=v309, rhs=v312 } -> x0 + v314 Imm(0) -> x1 + v315 LoadLocal { off=-1, kind=I64 } -> x1 + v316 LoadLocal { off=77, kind=I64 } -> x1 + v317 Binop { op=add, lhs=v313, rhs=v316 } -> x0 + v318 Imm(0) -> x1 + v319 LoadLocal { off=-1, kind=I64 } -> x1 + v320 LoadLocal { off=78, kind=I64 } -> x1 + v321 Binop { op=add, lhs=v317, rhs=v320 } -> x0 + v322 Imm(0) -> x1 + v323 LoadLocal { off=-1, kind=I64 } -> x1 + v324 LoadLocal { off=79, kind=I64 } -> x1 + v325 Binop { op=add, lhs=v321, rhs=v324 } -> x0 + v326 Imm(0) -> x1 + v327 LoadLocal { off=-1, kind=I64 } -> x1 + v328 LoadLocal { off=80, kind=I64 } -> x1 + v329 Binop { op=add, lhs=v325, rhs=v328 } -> x0 + v330 Imm(0) -> x1 + v331 LoadLocal { off=-1, kind=I64 } -> x1 + v332 LoadLocal { off=81, kind=I64 } -> x1 + v333 Binop { op=add, lhs=v329, rhs=v332 } -> x0 + v334 Imm(0) -> x1 + v335 LoadLocal { off=-1, kind=I64 } -> x1 + v336 LoadLocal { off=82, kind=I64 } -> x1 + v337 Binop { op=add, lhs=v333, rhs=v336 } -> x0 + v338 Imm(0) -> x1 + v339 LoadLocal { off=-1, kind=I64 } -> x1 + v340 LoadLocal { off=83, kind=I64 } -> x1 + v341 Binop { op=add, lhs=v337, rhs=v340 } -> x0 + v342 Imm(0) -> x1 + v343 LoadLocal { off=-1, kind=I64 } -> x1 + v344 LoadLocal { off=84, kind=I64 } -> x1 + v345 Binop { op=add, lhs=v341, rhs=v344 } -> x0 + v346 Imm(0) -> x1 + v347 LoadLocal { off=-1, kind=I64 } -> x1 + v348 LoadLocal { off=85, kind=I64 } -> x1 + v349 Binop { op=add, lhs=v345, rhs=v348 } -> x0 + v350 Imm(0) -> x1 + v351 LoadLocal { off=-1, kind=I64 } -> x1 + v352 LoadLocal { off=86, kind=I64 } -> x1 + v353 Binop { op=add, lhs=v349, rhs=v352 } -> x0 + v354 Imm(0) -> x1 + v355 LoadLocal { off=-1, kind=I64 } -> x1 + v356 LoadLocal { off=87, kind=I64 } -> x1 + v357 Binop { op=add, lhs=v353, rhs=v356 } -> x0 + v358 Imm(0) -> x1 + v359 LoadLocal { off=-1, kind=I64 } -> x1 + v360 LoadLocal { off=88, kind=I64 } -> x1 + v361 Binop { op=add, lhs=v357, rhs=v360 } -> x0 + v362 Imm(0) -> x1 + v363 LoadLocal { off=-1, kind=I64 } -> x1 + v364 LoadLocal { off=89, kind=I64 } -> x1 + v365 Binop { op=add, lhs=v361, rhs=v364 } -> x0 + v366 Imm(0) -> x1 + v367 LoadLocal { off=-1, kind=I64 } -> x1 + v368 LoadLocal { off=90, kind=I64 } -> x1 + v369 Binop { op=add, lhs=v365, rhs=v368 } -> x0 + v370 Imm(0) -> x1 + v371 LoadLocal { off=-1, kind=I64 } -> x1 + v372 LoadLocal { off=91, kind=I64 } -> x1 + v373 Binop { op=add, lhs=v369, rhs=v372 } -> x0 + v374 Imm(0) -> x1 + v375 LoadLocal { off=-1, kind=I64 } -> x1 + v376 LoadLocal { off=92, kind=I64 } -> x1 + v377 Binop { op=add, lhs=v373, rhs=v376 } -> x0 + v378 Imm(0) -> x1 + v379 LoadLocal { off=-1, kind=I64 } -> x1 + v380 LoadLocal { off=93, kind=I64 } -> x1 + v381 Binop { op=add, lhs=v377, rhs=v380 } -> x0 + v382 Imm(0) -> x1 + v383 LoadLocal { off=-1, kind=I64 } -> x1 + v384 LoadLocal { off=94, kind=I64 } -> x1 + v385 Binop { op=add, lhs=v381, rhs=v384 } -> x0 + v386 Imm(0) -> x1 + v387 LoadLocal { off=-1, kind=I64 } -> x1 + v388 LoadLocal { off=95, kind=I64 } -> x1 + v389 Binop { op=add, lhs=v385, rhs=v388 } -> x0 + v390 Imm(0) -> x1 + v391 LoadLocal { off=-1, kind=I64 } -> x1 + v392 LoadLocal { off=96, kind=I64 } -> x1 + v393 Binop { op=add, lhs=v389, rhs=v392 } -> x0 + v394 Imm(0) -> x1 + v395 LoadLocal { off=-1, kind=I64 } -> x1 + v396 LoadLocal { off=97, kind=I64 } -> x1 + v397 Binop { op=add, lhs=v393, rhs=v396 } -> x0 + v398 Imm(0) -> x1 + v399 LoadLocal { off=-1, kind=I64 } -> x1 + v400 LoadLocal { off=98, kind=I64 } -> x1 + v401 Binop { op=add, lhs=v397, rhs=v400 } -> x0 + v402 Imm(0) -> x1 + v403 LoadLocal { off=-1, kind=I64 } -> x1 + v404 LoadLocal { off=99, kind=I64 } -> x1 + v405 Binop { op=add, lhs=v401, rhs=v404 } -> x0 + v406 Imm(0) -> x1 + v407 LoadLocal { off=-1, kind=I64 } -> x1 + v408 LoadLocal { off=100, kind=I64 } -> x1 + v409 Binop { op=add, lhs=v405, rhs=v408 } -> x0 + v410 Imm(0) -> x1 + v411 LoadLocal { off=-1, kind=I64 } -> x1 + v412 LoadLocal { off=101, kind=I64 } -> x1 + v413 Binop { op=add, lhs=v409, rhs=v412 } -> x0 + v414 Imm(0) -> x1 + v415 LoadLocal { off=-1, kind=I64 } -> x1 + v416 LoadLocal { off=102, kind=I64 } -> x1 + v417 Binop { op=add, lhs=v413, rhs=v416 } -> x0 + v418 Imm(0) -> x1 + v419 LoadLocal { off=-1, kind=I64 } -> x1 + v420 LoadLocal { off=103, kind=I64 } -> x1 + v421 Binop { op=add, lhs=v417, rhs=v420 } -> x0 + v422 Imm(0) -> x1 + v423 LoadLocal { off=-1, kind=I64 } -> x1 + v424 LoadLocal { off=104, kind=I64 } -> x1 + v425 Binop { op=add, lhs=v421, rhs=v424 } -> x0 + v426 Imm(0) -> x1 + v427 LoadLocal { off=-1, kind=I64 } -> x1 + v428 LoadLocal { off=105, kind=I64 } -> x1 + v429 Binop { op=add, lhs=v425, rhs=v428 } -> x0 + v430 Imm(0) -> x1 + v431 LoadLocal { off=-1, kind=I64 } -> x1 + v432 LoadLocal { off=106, kind=I64 } -> x1 + v433 Binop { op=add, lhs=v429, rhs=v432 } -> x0 + v434 Imm(0) -> x1 + v435 LoadLocal { off=-1, kind=I64 } -> x1 + v436 LoadLocal { off=107, kind=I64 } -> x1 + v437 Binop { op=add, lhs=v433, rhs=v436 } -> x0 + v438 Imm(0) -> x1 + v439 LoadLocal { off=-1, kind=I64 } -> x1 + v440 LoadLocal { off=108, kind=I64 } -> x1 + v441 Binop { op=add, lhs=v437, rhs=v440 } -> x0 + v442 Imm(0) -> x1 + v443 LoadLocal { off=-1, kind=I64 } -> x1 + v444 LoadLocal { off=109, kind=I64 } -> x1 + v445 Binop { op=add, lhs=v441, rhs=v444 } -> x0 + v446 Imm(0) -> x1 + v447 LoadLocal { off=-1, kind=I64 } -> x1 + v448 LoadLocal { off=110, kind=I64 } -> x1 + v449 Binop { op=add, lhs=v445, rhs=v448 } -> x0 + v450 Imm(0) -> x1 + v451 LoadLocal { off=-1, kind=I64 } -> x1 + v452 LoadLocal { off=111, kind=I64 } -> x1 + v453 Binop { op=add, lhs=v449, rhs=v452 } -> x0 + v454 Imm(0) -> x1 + v455 LoadLocal { off=-1, kind=I64 } -> x1 + v456 LoadLocal { off=112, kind=I64 } -> x1 + v457 Binop { op=add, lhs=v453, rhs=v456 } -> x0 + v458 Imm(0) -> x1 + v459 LoadLocal { off=-1, kind=I64 } -> x1 + v460 LoadLocal { off=113, kind=I64 } -> x1 + v461 Binop { op=add, lhs=v457, rhs=v460 } -> x0 + v462 Imm(0) -> x1 + v463 LoadLocal { off=-1, kind=I64 } -> x1 + v464 LoadLocal { off=114, kind=I64 } -> x1 + v465 Binop { op=add, lhs=v461, rhs=v464 } -> x0 + v466 Imm(0) -> x1 + v467 LoadLocal { off=-1, kind=I64 } -> x1 + v468 LoadLocal { off=115, kind=I64 } -> x1 + v469 Binop { op=add, lhs=v465, rhs=v468 } -> x0 + v470 Imm(0) -> x1 + v471 LoadLocal { off=-1, kind=I64 } -> x1 + v472 LoadLocal { off=116, kind=I64 } -> x1 + v473 Binop { op=add, lhs=v469, rhs=v472 } -> x0 + v474 Imm(0) -> x1 + v475 LoadLocal { off=-1, kind=I64 } -> x1 + v476 LoadLocal { off=117, kind=I64 } -> x1 + v477 Binop { op=add, lhs=v473, rhs=v476 } -> x0 + v478 Imm(0) -> x1 + v479 LoadLocal { off=-1, kind=I64 } -> x1 + v480 LoadLocal { off=118, kind=I64 } -> x1 + v481 Binop { op=add, lhs=v477, rhs=v480 } -> x0 + v482 Imm(0) -> x1 + v483 LoadLocal { off=-1, kind=I64 } -> x1 + v484 LoadLocal { off=119, kind=I64 } -> x1 + v485 Binop { op=add, lhs=v481, rhs=v484 } -> x0 + v486 Imm(0) -> x1 + v487 LoadLocal { off=-1, kind=I64 } -> x1 + v488 LoadLocal { off=120, kind=I64 } -> x1 + v489 Binop { op=add, lhs=v485, rhs=v488 } -> x0 + v490 Imm(0) -> x1 + v491 LoadLocal { off=-1, kind=I64 } -> x1 + v492 LoadLocal { off=121, kind=I64 } -> x1 + v493 Binop { op=add, lhs=v489, rhs=v492 } -> x0 + v494 Imm(0) -> x1 + v495 LoadLocal { off=-1, kind=I64 } -> x1 + v496 LoadLocal { off=122, kind=I64 } -> x1 + v497 Binop { op=add, lhs=v493, rhs=v496 } -> x0 + v498 Imm(0) -> x1 + v499 LoadLocal { off=-1, kind=I64 } -> x1 + v500 LoadLocal { off=123, kind=I64 } -> x1 + v501 Binop { op=add, lhs=v497, rhs=v500 } -> x0 + v502 Imm(0) -> x1 + v503 LoadLocal { off=-1, kind=I64 } -> x1 + v504 LoadLocal { off=124, kind=I64 } -> x1 + v505 Binop { op=add, lhs=v501, rhs=v504 } -> x0 + v506 Imm(0) -> x1 + v507 LoadLocal { off=-1, kind=I64 } -> x1 + v508 LoadLocal { off=125, kind=I64 } -> x1 + v509 Binop { op=add, lhs=v505, rhs=v508 } -> x0 + v510 Imm(0) -> x1 + v511 LoadLocal { off=-1, kind=I64 } -> x1 + v512 LoadLocal { off=126, kind=I64 } -> x1 + v513 Binop { op=add, lhs=v509, rhs=v512 } -> x0 + v514 Imm(0) -> x1 + v515 LoadLocal { off=-1, kind=I64 } -> x1 + v516 LoadLocal { off=127, kind=I64 } -> x1 + v517 Binop { op=add, lhs=v513, rhs=v516 } -> x0 + v518 Imm(0) -> x1 + v519 LoadLocal { off=-1, kind=I64 } -> x1 + v520 LoadLocal { off=128, kind=I64 } -> x1 + v521 Binop { op=add, lhs=v517, rhs=v520 } -> x0 + v522 Imm(0) -> x1 + v523 LoadLocal { off=-1, kind=I64 } -> x1 + v524 LoadLocal { off=129, kind=I64 } -> x1 + v525 Binop { op=add, lhs=v521, rhs=v524 } -> x0 + v526 Imm(0) -> x1 + v527 LoadLocal { off=-1, kind=I64 } -> x1 + v528 LoadLocal { off=130, kind=I64 } -> x1 + v529 Binop { op=add, lhs=v525, rhs=v528 } -> x0 + v530 Imm(0) -> x1 + v531 LoadLocal { off=-1, kind=I64 } -> x1 + v532 LoadLocal { off=131, kind=I64 } -> x1 + v533 Binop { op=add, lhs=v529, rhs=v532 } -> x0 + v534 Imm(0) -> x1 + v535 LoadLocal { off=-1, kind=I64 } -> x1 + v536 LoadLocal { off=132, kind=I64 } -> x1 + v537 Binop { op=add, lhs=v533, rhs=v536 } -> x0 + v538 Imm(0) -> x1 + v539 LoadLocal { off=-1, kind=I64 } -> x1 + v540 LoadLocal { off=133, kind=I64 } -> x1 + v541 Binop { op=add, lhs=v537, rhs=v540 } -> x0 + v542 Imm(0) -> x1 + v543 LoadLocal { off=-1, kind=I64 } -> x1 + v544 LoadLocal { off=134, kind=I64 } -> x1 + v545 Binop { op=add, lhs=v541, rhs=v544 } -> x0 + v546 Imm(0) -> x1 + v547 LoadLocal { off=-1, kind=I64 } -> x1 + v548 LoadLocal { off=135, kind=I64 } -> x1 + v549 Binop { op=add, lhs=v545, rhs=v548 } -> x0 + v550 Imm(0) -> x1 + v551 LoadLocal { off=-1, kind=I64 } -> x1 + v552 LoadLocal { off=136, kind=I64 } -> x1 + v553 Binop { op=add, lhs=v549, rhs=v552 } -> x0 + v554 Imm(0) -> x1 + v555 LoadLocal { off=-1, kind=I64 } -> x1 + v556 LoadLocal { off=137, kind=I64 } -> x1 + v557 Binop { op=add, lhs=v553, rhs=v556 } -> x0 + v558 Imm(0) -> x1 + v559 LoadLocal { off=-1, kind=I64 } -> x1 + v560 LoadLocal { off=138, kind=I64 } -> x1 + v561 Binop { op=add, lhs=v557, rhs=v560 } -> x0 + v562 Imm(0) -> x1 + v563 LoadLocal { off=-1, kind=I64 } -> x1 + v564 LoadLocal { off=139, kind=I64 } -> x1 + v565 Binop { op=add, lhs=v561, rhs=v564 } -> x0 + v566 Imm(0) -> x1 + v567 LoadLocal { off=-1, kind=I64 } -> x1 + v568 LoadLocal { off=140, kind=I64 } -> x1 + v569 Binop { op=add, lhs=v565, rhs=v568 } -> x0 + v570 Imm(0) -> x1 + v571 LoadLocal { off=-1, kind=I64 } -> x1 + v572 LoadLocal { off=141, kind=I64 } -> x1 + v573 Binop { op=add, lhs=v569, rhs=v572 } -> x0 + v574 Imm(0) -> x1 + v575 LoadLocal { off=-1, kind=I64 } -> x1 + v576 LoadLocal { off=142, kind=I64 } -> x1 + v577 Binop { op=add, lhs=v573, rhs=v576 } -> x0 + v578 Imm(0) -> x1 + v579 LoadLocal { off=-1, kind=I64 } -> x1 + v580 LoadLocal { off=143, kind=I64 } -> x1 + v581 Binop { op=add, lhs=v577, rhs=v580 } -> x0 + v582 Imm(0) -> x1 + v583 LoadLocal { off=-1, kind=I64 } -> x1 + v584 LoadLocal { off=144, kind=I64 } -> x1 + v585 Binop { op=add, lhs=v581, rhs=v584 } -> x0 + v586 Imm(0) -> x1 + v587 LoadLocal { off=-1, kind=I64 } -> x1 + v588 LoadLocal { off=145, kind=I64 } -> x1 + v589 Binop { op=add, lhs=v585, rhs=v588 } -> x0 + v590 Imm(0) -> x1 + v591 LoadLocal { off=-1, kind=I64 } -> x1 + v592 LoadLocal { off=146, kind=I64 } -> x1 + v593 Binop { op=add, lhs=v589, rhs=v592 } -> x0 + v594 Imm(0) -> x1 + v595 LoadLocal { off=-1, kind=I64 } -> x1 + v596 LoadLocal { off=147, kind=I64 } -> x1 + v597 Binop { op=add, lhs=v593, rhs=v596 } -> x0 + v598 Imm(0) -> x1 + v599 LoadLocal { off=-1, kind=I64 } -> x1 + v600 LoadLocal { off=148, kind=I64 } -> x1 + v601 Binop { op=add, lhs=v597, rhs=v600 } -> x0 + v602 Imm(0) -> x1 + v603 LoadLocal { off=-1, kind=I64 } -> x1 + v604 LoadLocal { off=149, kind=I64 } -> x1 + v605 Binop { op=add, lhs=v601, rhs=v604 } -> x0 + v606 Imm(0) -> x1 + v607 LoadLocal { off=-1, kind=I64 } -> x1 + v608 LoadLocal { off=150, kind=I64 } -> x1 + v609 Binop { op=add, lhs=v605, rhs=v608 } -> x0 + v610 Imm(0) -> x1 + v611 LoadLocal { off=-1, kind=I64 } -> x1 + v612 LoadLocal { off=151, kind=I64 } -> x1 + v613 Binop { op=add, lhs=v609, rhs=v612 } -> x0 + v614 Imm(0) -> x1 + v615 LoadLocal { off=-1, kind=I64 } -> x1 + v616 LoadLocal { off=152, kind=I64 } -> x1 + v617 Binop { op=add, lhs=v613, rhs=v616 } -> x0 + v618 Imm(0) -> x1 + v619 LoadLocal { off=-1, kind=I64 } -> x1 + v620 LoadLocal { off=153, kind=I64 } -> x1 + v621 Binop { op=add, lhs=v617, rhs=v620 } -> x0 + v622 Imm(0) -> x1 + v623 LoadLocal { off=-1, kind=I64 } -> x1 + v624 LoadLocal { off=154, kind=I64 } -> x1 + v625 Binop { op=add, lhs=v621, rhs=v624 } -> x0 + v626 Imm(0) -> x1 + v627 LoadLocal { off=-1, kind=I64 } -> x1 + v628 LoadLocal { off=155, kind=I64 } -> x1 + v629 Binop { op=add, lhs=v625, rhs=v628 } -> x0 + v630 Imm(0) -> x1 + v631 LoadLocal { off=-1, kind=I64 } -> x1 + v632 LoadLocal { off=156, kind=I64 } -> x1 + v633 Binop { op=add, lhs=v629, rhs=v632 } -> x0 + v634 Imm(0) -> x1 + v635 LoadLocal { off=-1, kind=I64 } -> x1 + v636 LoadLocal { off=157, kind=I64 } -> x1 + v637 Binop { op=add, lhs=v633, rhs=v636 } -> x0 + v638 Imm(0) -> x1 + v639 LoadLocal { off=-1, kind=I64 } -> x1 + v640 LoadLocal { off=158, kind=I64 } -> x1 + v641 Binop { op=add, lhs=v637, rhs=v640 } -> x0 + v642 Imm(0) -> x1 + v643 LoadLocal { off=-1, kind=I64 } -> x1 + v644 LoadLocal { off=159, kind=I64 } -> x1 + v645 Binop { op=add, lhs=v641, rhs=v644 } -> x0 + v646 Imm(0) -> x1 + v647 LoadLocal { off=-1, kind=I64 } -> x1 + v648 LoadLocal { off=160, kind=I64 } -> x1 + v649 Binop { op=add, lhs=v645, rhs=v648 } -> x0 + v650 Imm(0) -> x1 + v651 LoadLocal { off=-1, kind=I64 } -> x1 + v652 LoadLocal { off=161, kind=I64 } -> x1 + v653 Binop { op=add, lhs=v649, rhs=v652 } -> x0 + v654 Imm(0) -> x1 + v655 LoadLocal { off=-1, kind=I64 } -> x1 + v656 LoadLocal { off=162, kind=I64 } -> x1 + v657 Binop { op=add, lhs=v653, rhs=v656 } -> x0 + v658 Imm(0) -> x1 + v659 LoadLocal { off=-1, kind=I64 } -> x1 + v660 LoadLocal { off=163, kind=I64 } -> x1 + v661 Binop { op=add, lhs=v657, rhs=v660 } -> x0 + v662 Imm(0) -> x1 + v663 LoadLocal { off=-1, kind=I64 } -> x1 + v664 LoadLocal { off=164, kind=I64 } -> x1 + v665 Binop { op=add, lhs=v661, rhs=v664 } -> x0 + v666 Imm(0) -> x1 + v667 LoadLocal { off=-1, kind=I64 } -> x1 + v668 LoadLocal { off=165, kind=I64 } -> x1 + v669 Binop { op=add, lhs=v665, rhs=v668 } -> x0 + v670 Imm(0) -> x1 + v671 LoadLocal { off=-1, kind=I64 } -> x1 + v672 LoadLocal { off=166, kind=I64 } -> x1 + v673 Binop { op=add, lhs=v669, rhs=v672 } -> x0 + v674 Imm(0) -> x1 + v675 LoadLocal { off=-1, kind=I64 } -> x1 + v676 LoadLocal { off=167, kind=I64 } -> x1 + v677 Binop { op=add, lhs=v673, rhs=v676 } -> x0 + v678 Imm(0) -> x1 + v679 LoadLocal { off=-1, kind=I64 } -> x1 + v680 LoadLocal { off=168, kind=I64 } -> x1 + v681 Binop { op=add, lhs=v677, rhs=v680 } -> x0 + v682 Imm(0) -> x1 + v683 LoadLocal { off=-1, kind=I64 } -> x1 + v684 LoadLocal { off=169, kind=I64 } -> x1 + v685 Binop { op=add, lhs=v681, rhs=v684 } -> x0 + v686 Imm(0) -> x1 + v687 LoadLocal { off=-1, kind=I64 } -> x1 + v688 LoadLocal { off=170, kind=I64 } -> x1 + v689 Binop { op=add, lhs=v685, rhs=v688 } -> x0 + v690 Imm(0) -> x1 + v691 LoadLocal { off=-1, kind=I64 } -> x1 + v692 LoadLocal { off=171, kind=I64 } -> x1 + v693 Binop { op=add, lhs=v689, rhs=v692 } -> x0 + v694 Imm(0) -> x1 + v695 LoadLocal { off=-1, kind=I64 } -> x1 + v696 LoadLocal { off=172, kind=I64 } -> x1 + v697 Binop { op=add, lhs=v693, rhs=v696 } -> x0 + v698 Imm(0) -> x1 + v699 LoadLocal { off=-1, kind=I64 } -> x1 + v700 LoadLocal { off=173, kind=I64 } -> x1 + v701 Binop { op=add, lhs=v697, rhs=v700 } -> x0 + v702 Imm(0) -> x1 + v703 LoadLocal { off=-1, kind=I64 } -> x1 + v704 LoadLocal { off=174, kind=I64 } -> x1 + v705 Binop { op=add, lhs=v701, rhs=v704 } -> x0 + v706 Imm(0) -> x1 + v707 LoadLocal { off=-1, kind=I64 } -> x1 + v708 LoadLocal { off=175, kind=I64 } -> x1 + v709 Binop { op=add, lhs=v705, rhs=v708 } -> x0 + v710 Imm(0) -> x1 + v711 LoadLocal { off=-1, kind=I64 } -> x1 + v712 LoadLocal { off=176, kind=I64 } -> x1 + v713 Binop { op=add, lhs=v709, rhs=v712 } -> x0 + v714 Imm(0) -> x1 + v715 LoadLocal { off=-1, kind=I64 } -> x1 + v716 LoadLocal { off=177, kind=I64 } -> x1 + v717 Binop { op=add, lhs=v713, rhs=v716 } -> x0 + v718 Imm(0) -> x1 + v719 LoadLocal { off=-1, kind=I64 } -> x1 + v720 LoadLocal { off=178, kind=I64 } -> x1 + v721 Binop { op=add, lhs=v717, rhs=v720 } -> x0 + v722 Imm(0) -> x1 + v723 LoadLocal { off=-1, kind=I64 } -> x1 + v724 LoadLocal { off=179, kind=I64 } -> x1 + v725 Binop { op=add, lhs=v721, rhs=v724 } -> x0 + v726 Imm(0) -> x1 + v727 LoadLocal { off=-1, kind=I64 } -> x1 + v728 LoadLocal { off=180, kind=I64 } -> x1 + v729 Binop { op=add, lhs=v725, rhs=v728 } -> x0 + v730 Imm(0) -> x1 + v731 LoadLocal { off=-1, kind=I64 } -> x1 + v732 LoadLocal { off=181, kind=I64 } -> x1 + v733 Binop { op=add, lhs=v729, rhs=v732 } -> x0 + v734 Imm(0) -> x1 + v735 LoadLocal { off=-1, kind=I64 } -> x1 + v736 LoadLocal { off=182, kind=I64 } -> x1 + v737 Binop { op=add, lhs=v733, rhs=v736 } -> x0 + v738 Imm(0) -> x1 + v739 LoadLocal { off=-1, kind=I64 } -> x1 + v740 LoadLocal { off=183, kind=I64 } -> x1 + v741 Binop { op=add, lhs=v737, rhs=v740 } -> x0 + v742 Imm(0) -> x1 + v743 LoadLocal { off=-1, kind=I64 } -> x1 + v744 LoadLocal { off=184, kind=I64 } -> x1 + v745 Binop { op=add, lhs=v741, rhs=v744 } -> x0 + v746 Imm(0) -> x1 + v747 LoadLocal { off=-1, kind=I64 } -> x1 + v748 LoadLocal { off=185, kind=I64 } -> x1 + v749 Binop { op=add, lhs=v745, rhs=v748 } -> x0 + v750 Imm(0) -> x1 + v751 LoadLocal { off=-1, kind=I64 } -> x1 + v752 LoadLocal { off=186, kind=I64 } -> x1 + v753 Binop { op=add, lhs=v749, rhs=v752 } -> x0 + v754 Imm(0) -> x1 + v755 LoadLocal { off=-1, kind=I64 } -> x1 + v756 LoadLocal { off=187, kind=I64 } -> x1 + v757 Binop { op=add, lhs=v753, rhs=v756 } -> x0 + v758 Imm(0) -> x1 + v759 LoadLocal { off=-1, kind=I64 } -> x1 + v760 LoadLocal { off=188, kind=I64 } -> x1 + v761 Binop { op=add, lhs=v757, rhs=v760 } -> x0 + v762 Imm(0) -> x1 + v763 LoadLocal { off=-1, kind=I64 } -> x1 + v764 LoadLocal { off=189, kind=I64 } -> x1 + v765 Binop { op=add, lhs=v761, rhs=v764 } -> x0 + v766 Imm(0) -> x1 + v767 LoadLocal { off=-1, kind=I64 } -> x1 + v768 LoadLocal { off=190, kind=I64 } -> x1 + v769 Binop { op=add, lhs=v765, rhs=v768 } -> x0 + v770 Imm(0) -> x1 + v771 LoadLocal { off=-1, kind=I64 } -> x1 + v772 LoadLocal { off=191, kind=I64 } -> x1 + v773 Binop { op=add, lhs=v769, rhs=v772 } -> x0 + v774 Imm(0) -> x1 + v775 LoadLocal { off=-1, kind=I64 } -> x1 + v776 LoadLocal { off=192, kind=I64 } -> x1 + v777 Binop { op=add, lhs=v773, rhs=v776 } -> x0 + v778 Imm(0) -> x1 + v779 LoadLocal { off=-1, kind=I64 } -> x1 + v780 LoadLocal { off=193, kind=I64 } -> x1 + v781 Binop { op=add, lhs=v777, rhs=v780 } -> x0 + v782 Imm(0) -> x1 + v783 LoadLocal { off=-1, kind=I64 } -> x1 + v784 LoadLocal { off=194, kind=I64 } -> x1 + v785 Binop { op=add, lhs=v781, rhs=v784 } -> x0 + v786 Imm(0) -> x1 + v787 LoadLocal { off=-1, kind=I64 } -> x1 + v788 LoadLocal { off=195, kind=I64 } -> x1 + v789 Binop { op=add, lhs=v785, rhs=v788 } -> x0 + v790 Imm(0) -> x1 + v791 LoadLocal { off=-1, kind=I64 } -> x1 + v792 LoadLocal { off=196, kind=I64 } -> x1 + v793 Binop { op=add, lhs=v789, rhs=v792 } -> x0 + v794 Imm(0) -> x1 + v795 LoadLocal { off=-1, kind=I64 } -> x1 + v796 LoadLocal { off=197, kind=I64 } -> x1 + v797 Binop { op=add, lhs=v793, rhs=v796 } -> x0 + v798 Imm(0) -> x1 + v799 LoadLocal { off=-1, kind=I64 } -> x1 + v800 LoadLocal { off=198, kind=I64 } -> x1 + v801 Binop { op=add, lhs=v797, rhs=v800 } -> x0 + v802 Imm(0) -> x1 + v803 LoadLocal { off=-1, kind=I64 } -> x1 + v804 LoadLocal { off=199, kind=I64 } -> x1 + v805 Binop { op=add, lhs=v801, rhs=v804 } -> x0 + v806 Imm(0) -> x1 + v807 LoadLocal { off=-1, kind=I64 } -> x1 + v808 LoadLocal { off=200, kind=I64 } -> x1 + v809 Binop { op=add, lhs=v805, rhs=v808 } -> x0 + v810 Imm(0) -> x1 + v811 LoadLocal { off=-1, kind=I64 } -> x1 + v812 LoadLocal { off=201, kind=I64 } -> x1 + v813 Binop { op=add, lhs=v809, rhs=v812 } -> x0 + v814 Imm(0) -> x1 + v815 LoadLocal { off=-1, kind=I64 } -> x1 + v816 LoadLocal { off=202, kind=I64 } -> x1 + v817 Binop { op=add, lhs=v813, rhs=v816 } -> x0 + v818 Imm(0) -> x1 + v819 LoadLocal { off=-1, kind=I64 } -> x1 + v820 LoadLocal { off=203, kind=I64 } -> x1 + v821 Binop { op=add, lhs=v817, rhs=v820 } -> x0 + v822 Imm(0) -> x1 + v823 LoadLocal { off=-1, kind=I64 } -> x1 + v824 LoadLocal { off=204, kind=I64 } -> x1 + v825 Binop { op=add, lhs=v821, rhs=v824 } -> x0 + v826 Imm(0) -> x1 + v827 LoadLocal { off=-1, kind=I64 } -> x1 + v828 LoadLocal { off=205, kind=I64 } -> x1 + v829 Binop { op=add, lhs=v825, rhs=v828 } -> x0 + v830 Imm(0) -> x1 + v831 LoadLocal { off=-1, kind=I64 } -> x1 + v832 LoadLocal { off=206, kind=I64 } -> x1 + v833 Binop { op=add, lhs=v829, rhs=v832 } -> x0 + v834 Imm(0) -> x1 + v835 LoadLocal { off=-1, kind=I64 } -> x1 + v836 LoadLocal { off=207, kind=I64 } -> x1 + v837 Binop { op=add, lhs=v833, rhs=v836 } -> x0 + v838 Imm(0) -> x1 + v839 LoadLocal { off=-1, kind=I64 } -> x1 + v840 LoadLocal { off=208, kind=I64 } -> x1 + v841 Binop { op=add, lhs=v837, rhs=v840 } -> x0 + v842 Imm(0) -> x1 + v843 LoadLocal { off=-1, kind=I64 } -> x1 + v844 LoadLocal { off=209, kind=I64 } -> x1 + v845 Binop { op=add, lhs=v841, rhs=v844 } -> x0 + v846 Imm(0) -> x1 + v847 LoadLocal { off=-1, kind=I64 } -> x1 + v848 LoadLocal { off=210, kind=I64 } -> x1 + v849 Binop { op=add, lhs=v845, rhs=v848 } -> x0 + v850 Imm(0) -> x1 + v851 LoadLocal { off=-1, kind=I64 } -> x1 + v852 LoadLocal { off=211, kind=I64 } -> x1 + v853 Binop { op=add, lhs=v849, rhs=v852 } -> x0 + v854 Imm(0) -> x1 + v855 LoadLocal { off=-1, kind=I64 } -> x1 + v856 LoadLocal { off=212, kind=I64 } -> x1 + v857 Binop { op=add, lhs=v853, rhs=v856 } -> x0 + v858 Imm(0) -> x1 + v859 LoadLocal { off=-1, kind=I64 } -> x1 + v860 LoadLocal { off=213, kind=I64 } -> x1 + v861 Binop { op=add, lhs=v857, rhs=v860 } -> x0 + v862 Imm(0) -> x1 + v863 LoadLocal { off=-1, kind=I64 } -> x1 + v864 LoadLocal { off=214, kind=I64 } -> x1 + v865 Binop { op=add, lhs=v861, rhs=v864 } -> x0 + v866 Imm(0) -> x1 + v867 LoadLocal { off=-1, kind=I64 } -> x1 + v868 LoadLocal { off=215, kind=I64 } -> x1 + v869 Binop { op=add, lhs=v865, rhs=v868 } -> x0 + v870 Imm(0) -> x1 + v871 LoadLocal { off=-1, kind=I64 } -> x1 + v872 LoadLocal { off=216, kind=I64 } -> x1 + v873 Binop { op=add, lhs=v869, rhs=v872 } -> x0 + v874 Imm(0) -> x1 + v875 LoadLocal { off=-1, kind=I64 } -> x1 + v876 LoadLocal { off=217, kind=I64 } -> x1 + v877 Binop { op=add, lhs=v873, rhs=v876 } -> x0 + v878 Imm(0) -> x1 + v879 LoadLocal { off=-1, kind=I64 } -> x1 + v880 LoadLocal { off=218, kind=I64 } -> x1 + v881 Binop { op=add, lhs=v877, rhs=v880 } -> x0 + v882 Imm(0) -> x1 + v883 LoadLocal { off=-1, kind=I64 } -> x1 + v884 LoadLocal { off=219, kind=I64 } -> x1 + v885 Binop { op=add, lhs=v881, rhs=v884 } -> x0 + v886 Imm(0) -> x1 + v887 LoadLocal { off=-1, kind=I64 } -> x1 + v888 LoadLocal { off=220, kind=I64 } -> x1 + v889 Binop { op=add, lhs=v885, rhs=v888 } -> x0 + v890 Imm(0) -> x1 + v891 LoadLocal { off=-1, kind=I64 } -> x1 + v892 LoadLocal { off=221, kind=I64 } -> x1 + v893 Binop { op=add, lhs=v889, rhs=v892 } -> x0 + v894 Imm(0) -> x1 + v895 LoadLocal { off=-1, kind=I64 } -> x1 + v896 LoadLocal { off=222, kind=I64 } -> x1 + v897 Binop { op=add, lhs=v893, rhs=v896 } -> x0 + v898 Imm(0) -> x1 + v899 LoadLocal { off=-1, kind=I64 } -> x1 + v900 LoadLocal { off=223, kind=I64 } -> x1 + v901 Binop { op=add, lhs=v897, rhs=v900 } -> x0 + v902 Imm(0) -> x1 + v903 LoadLocal { off=-1, kind=I64 } -> x1 + v904 LoadLocal { off=224, kind=I64 } -> x1 + v905 Binop { op=add, lhs=v901, rhs=v904 } -> x0 + v906 Imm(0) -> x1 + v907 LoadLocal { off=-1, kind=I64 } -> x1 + v908 LoadLocal { off=225, kind=I64 } -> x1 + v909 Binop { op=add, lhs=v905, rhs=v908 } -> x0 + v910 Imm(0) -> x1 + v911 LoadLocal { off=-1, kind=I64 } -> x1 + v912 LoadLocal { off=226, kind=I64 } -> x1 + v913 Binop { op=add, lhs=v909, rhs=v912 } -> x0 + v914 Imm(0) -> x1 + v915 LoadLocal { off=-1, kind=I64 } -> x1 + v916 LoadLocal { off=227, kind=I64 } -> x1 + v917 Binop { op=add, lhs=v913, rhs=v916 } -> x0 + v918 Imm(0) -> x1 + v919 LoadLocal { off=-1, kind=I64 } -> x1 + v920 LoadLocal { off=228, kind=I64 } -> x1 + v921 Binop { op=add, lhs=v917, rhs=v920 } -> x0 + v922 Imm(0) -> x1 + v923 LoadLocal { off=-1, kind=I64 } -> x1 + v924 LoadLocal { off=229, kind=I64 } -> x1 + v925 Binop { op=add, lhs=v921, rhs=v924 } -> x0 + v926 Imm(0) -> x1 + v927 LoadLocal { off=-1, kind=I64 } -> x1 + v928 LoadLocal { off=230, kind=I64 } -> x1 + v929 Binop { op=add, lhs=v925, rhs=v928 } -> x0 + v930 Imm(0) -> x1 + v931 LoadLocal { off=-1, kind=I64 } -> x1 + v932 LoadLocal { off=231, kind=I64 } -> x1 + v933 Binop { op=add, lhs=v929, rhs=v932 } -> x0 + v934 Imm(0) -> x1 + v935 LoadLocal { off=-1, kind=I64 } -> x1 + v936 LoadLocal { off=232, kind=I64 } -> x1 + v937 Binop { op=add, lhs=v933, rhs=v936 } -> x0 + v938 Imm(0) -> x1 + v939 LoadLocal { off=-1, kind=I64 } -> x1 + v940 LoadLocal { off=233, kind=I64 } -> x1 + v941 Binop { op=add, lhs=v937, rhs=v940 } -> x0 + v942 Imm(0) -> x1 + v943 LoadLocal { off=-1, kind=I64 } -> x1 + v944 LoadLocal { off=234, kind=I64 } -> x1 + v945 Binop { op=add, lhs=v941, rhs=v944 } -> x0 + v946 Imm(0) -> x1 + v947 LoadLocal { off=-1, kind=I64 } -> x1 + v948 LoadLocal { off=235, kind=I64 } -> x1 + v949 Binop { op=add, lhs=v945, rhs=v948 } -> x0 + v950 Imm(0) -> x1 + v951 LoadLocal { off=-1, kind=I64 } -> x1 + v952 LoadLocal { off=236, kind=I64 } -> x1 + v953 Binop { op=add, lhs=v949, rhs=v952 } -> x0 + v954 Imm(0) -> x1 + v955 LoadLocal { off=-1, kind=I64 } -> x1 + v956 LoadLocal { off=237, kind=I64 } -> x1 + v957 Binop { op=add, lhs=v953, rhs=v956 } -> x0 + v958 Imm(0) -> x1 + v959 LoadLocal { off=-1, kind=I64 } -> x1 + v960 LoadLocal { off=238, kind=I64 } -> x1 + v961 Binop { op=add, lhs=v957, rhs=v960 } -> x0 + v962 Imm(0) -> x1 + v963 LoadLocal { off=-1, kind=I64 } -> x1 + v964 LoadLocal { off=239, kind=I64 } -> x1 + v965 Binop { op=add, lhs=v961, rhs=v964 } -> x0 + v966 Imm(0) -> x1 + v967 LoadLocal { off=-1, kind=I64 } -> x1 + v968 LoadLocal { off=240, kind=I64 } -> x1 + v969 Binop { op=add, lhs=v965, rhs=v968 } -> x0 + v970 Imm(0) -> x1 + v971 LoadLocal { off=-1, kind=I64 } -> x1 + v972 LoadLocal { off=241, kind=I64 } -> x1 + v973 Binop { op=add, lhs=v969, rhs=v972 } -> x0 + v974 Imm(0) -> x1 + v975 LoadLocal { off=-1, kind=I64 } -> x1 + v976 LoadLocal { off=242, kind=I64 } -> x1 + v977 Binop { op=add, lhs=v973, rhs=v976 } -> x0 + v978 Imm(0) -> x1 + v979 LoadLocal { off=-1, kind=I64 } -> x1 + v980 LoadLocal { off=243, kind=I64 } -> x1 + v981 Binop { op=add, lhs=v977, rhs=v980 } -> x0 + v982 Imm(0) -> x1 + v983 LoadLocal { off=-1, kind=I64 } -> x1 + v984 LoadLocal { off=244, kind=I64 } -> x1 + v985 Binop { op=add, lhs=v981, rhs=v984 } -> x0 + v986 Imm(0) -> x1 + v987 LoadLocal { off=-1, kind=I64 } -> x1 + v988 LoadLocal { off=245, kind=I64 } -> x1 + v989 Binop { op=add, lhs=v985, rhs=v988 } -> x0 + v990 Imm(0) -> x1 + v991 LoadLocal { off=-1, kind=I64 } -> x1 + v992 LoadLocal { off=246, kind=I64 } -> x1 + v993 Binop { op=add, lhs=v989, rhs=v992 } -> x0 + v994 Imm(0) -> x1 + v995 LoadLocal { off=-1, kind=I64 } -> x1 + v996 LoadLocal { off=247, kind=I64 } -> x1 + v997 Binop { op=add, lhs=v993, rhs=v996 } -> x0 + v998 Imm(0) -> x1 + v999 LoadLocal { off=-1, kind=I64 } -> x1 + v1000 LoadLocal { off=248, kind=I64 } -> x1 + v1001 Binop { op=add, lhs=v997, rhs=v1000 } -> x0 + v1002 Imm(0) -> x1 + v1003 LoadLocal { off=-1, kind=I64 } -> x1 + v1004 LoadLocal { off=249, kind=I64 } -> x1 + v1005 Binop { op=add, lhs=v1001, rhs=v1004 } -> x0 + v1006 Imm(0) -> x1 + v1007 LoadLocal { off=-1, kind=I64 } -> x1 + v1008 LoadLocal { off=250, kind=I64 } -> x1 + v1009 Binop { op=add, lhs=v1005, rhs=v1008 } -> x0 + v1010 Imm(0) -> x1 + v1011 LoadLocal { off=-1, kind=I64 } -> x1 + v1012 LoadLocal { off=251, kind=I64 } -> x1 + v1013 Binop { op=add, lhs=v1009, rhs=v1012 } -> x0 + v1014 Imm(0) -> x1 + v1015 LoadLocal { off=-1, kind=I64 } -> x1 + v1016 LoadLocal { off=252, kind=I64 } -> x1 + v1017 Binop { op=add, lhs=v1013, rhs=v1016 } -> x0 + v1018 Imm(0) -> x1 + v1019 LoadLocal { off=-1, kind=I64 } -> x1 + v1020 LoadLocal { off=253, kind=I64 } -> x1 + v1021 Binop { op=add, lhs=v1017, rhs=v1020 } -> x0 + v1022 Imm(0) -> x1 + v1023 LoadLocal { off=-1, kind=I64 } -> x1 + v1024 LoadLocal { off=254, kind=I64 } -> x1 + v1025 Binop { op=add, lhs=v1021, rhs=v1024 } -> x0 + v1026 Imm(0) -> x1 + v1027 LoadLocal { off=-1, kind=I64 } -> x1 + v1028 LoadLocal { off=255, kind=I64 } -> x1 + v1029 Binop { op=add, lhs=v1025, rhs=v1028 } -> x0 + v1030 Imm(0) -> x1 + v1031 LoadLocal { off=-1, kind=I64 } -> x1 + v1032 LoadLocal { off=256, kind=I64 } -> x1 + v1033 Binop { op=add, lhs=v1029, rhs=v1032 } -> x0 + v1034 Imm(0) -> x1 + v1035 LoadLocal { off=-1, kind=I64 } -> x1 + v1036 LoadLocal { off=257, kind=I64 } -> x1 + v1037 Binop { op=add, lhs=v1033, rhs=v1036 } -> x0 + v1038 Imm(0) -> x1 + v1039 LoadLocal { off=-1, kind=I64 } -> x1 + v1040 LoadLocal { off=258, kind=I64 } -> x1 + v1041 Binop { op=add, lhs=v1037, rhs=v1040 } -> x0 + v1042 Imm(0) -> x1 + v1043 LoadLocal { off=-1, kind=I64 } -> x1 + v1044 LoadLocal { off=259, kind=I64 } -> x1 + v1045 Binop { op=add, lhs=v1041, rhs=v1044 } -> x0 + v1046 Imm(0) -> x1 + v1047 LoadLocal { off=-1, kind=I64 } -> x1 + v1048 LoadLocal { off=260, kind=I64 } -> x1 + v1049 Binop { op=add, lhs=v1045, rhs=v1048 } -> x0 + v1050 Imm(0) -> x1 + v1051 LoadLocal { off=-1, kind=I64 } -> x1 + v1052 LoadLocal { off=261, kind=I64 } -> x1 + v1053 Binop { op=add, lhs=v1049, rhs=v1052 } -> x0 + v1054 Imm(0) -> x1 + v1055 LoadLocal { off=-1, kind=I64 } -> x1 + terminator Return(v1053) (exit_acc=v1053) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=main +fn ent_pc=2 n_params=0 variadic=false locals=264 + spill_count=251 gpr_used=[3, 12, 13, 14, 15] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ImmCode(ent_pc=1) -> x3 + v2 Imm(0) -> x0 + v3 ImmCode(ent_pc=0) -> x12 + v4 Imm(0) -> x0 + v5 Imm(0) -> x1 + v6 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v5) + block 1 start_pc=0 + v7 Phi { incoming=[b0:v5, b2:v11], kind=I64 } -> x1 + v8 LoadLocal { off=-3, kind=I64 } -> x0 + v9 BinopI { op=lt, lhs=v7, rhs_imm=261 } -> x0 + terminator Bz { cond=v9, target=b4, fall=b3 } (exit_acc=v9) + block 2 start_pc=0 + v10 LoadLocal { off=-3, kind=I64 } -> x0 + v11 BinopI { op=add, lhs=v7, rhs_imm=1 } -> x1 + v12 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v11) + block 3 start_pc=0 + v13 ImmData(24) -> x0 + v14 LoadLocal { off=-3, kind=I64 } -> x2 + v15 BinopI { op=shl, lhs=v7, rhs_imm=4 } -> x2 + v16 Binop { op=add, lhs=v13, rhs=v15 } -> x2 + v17 Store { addr=v16, disp=0, value=v7, kind=I64 } -> - + v18 LoadLocal { off=-3, kind=I64 } -> x2 + v19 BinopI { op=shl, lhs=v7, rhs_imm=4 } -> x2 + v20 Binop { op=add, lhs=v13, rhs=v19 } -> x0 + v21 BinopI { op=add, lhs=v20, rhs_imm=8 } -> x2 + v22 Imm(2) -> x2 + v23 BinopI { op=shl, lhs=v7, rhs_imm=1 } -> x2 + v24 Store { addr=v20, disp=8, value=v23, kind=I64 } -> - + terminator Jmp(b2) (exit_acc=v24) + block 4 start_pc=0 + v25 ImmData(24) -> x7 + v26 Imm(0) -> x0 + v27 Imm(16) -> x0 + v28 BinopI { op=add, lhs=v25, rhs_imm=16 } -> x6 + v29 Imm(32) -> x0 + v30 BinopI { op=add, lhs=v25, rhs_imm=32 } -> x2 + v31 Imm(48) -> x0 + v32 BinopI { op=add, lhs=v25, rhs_imm=48 } -> x1 + v33 Imm(64) -> x0 + v34 BinopI { op=add, lhs=v25, rhs_imm=64 } -> x8 + v35 Imm(80) -> x0 + v36 BinopI { op=add, lhs=v25, rhs_imm=80 } -> x9 + v37 Imm(96) -> x0 + v38 BinopI { op=add, lhs=v25, rhs_imm=96 } -> x0 + v39 Imm(112) -> x13 + v40 BinopI { op=add, lhs=v25, rhs_imm=112 } -> x13 + v41 Imm(128) -> x14 + v42 BinopI { op=add, lhs=v25, rhs_imm=128 } -> x14 + v43 Imm(144) -> x15 + v44 BinopI { op=add, lhs=v25, rhs_imm=144 } -> x15 + v45 Imm(160) -> [spill 0] + v46 BinopI { op=add, lhs=v25, rhs_imm=160 } -> [spill 0] + v47 Imm(176) -> [spill 1] + v48 BinopI { op=add, lhs=v25, rhs_imm=176 } -> [spill 1] + v49 Imm(192) -> [spill 2] + v50 BinopI { op=add, lhs=v25, rhs_imm=192 } -> [spill 2] + v51 Imm(208) -> [spill 3] + v52 BinopI { op=add, lhs=v25, rhs_imm=208 } -> [spill 3] + v53 Imm(224) -> [spill 4] + v54 BinopI { op=add, lhs=v25, rhs_imm=224 } -> [spill 4] + v55 Imm(240) -> [spill 5] + v56 BinopI { op=add, lhs=v25, rhs_imm=240 } -> [spill 5] + v57 Imm(256) -> [spill 6] + v58 BinopI { op=add, lhs=v25, rhs_imm=256 } -> [spill 6] + v59 Imm(272) -> [spill 7] + v60 BinopI { op=add, lhs=v25, rhs_imm=272 } -> [spill 7] + v61 Imm(288) -> [spill 8] + v62 BinopI { op=add, lhs=v25, rhs_imm=288 } -> [spill 8] + v63 Imm(304) -> [spill 9] + v64 BinopI { op=add, lhs=v25, rhs_imm=304 } -> [spill 9] + v65 Imm(320) -> [spill 10] + v66 BinopI { op=add, lhs=v25, rhs_imm=320 } -> [spill 10] + v67 Imm(336) -> [spill 11] + v68 BinopI { op=add, lhs=v25, rhs_imm=336 } -> [spill 11] + v69 Imm(352) -> [spill 12] + v70 BinopI { op=add, lhs=v25, rhs_imm=352 } -> [spill 12] + v71 Imm(368) -> [spill 13] + v72 BinopI { op=add, lhs=v25, rhs_imm=368 } -> [spill 13] + v73 Imm(384) -> [spill 14] + v74 BinopI { op=add, lhs=v25, rhs_imm=384 } -> [spill 14] + v75 Imm(400) -> [spill 15] + v76 BinopI { op=add, lhs=v25, rhs_imm=400 } -> [spill 15] + v77 Imm(416) -> [spill 16] + v78 BinopI { op=add, lhs=v25, rhs_imm=416 } -> [spill 16] + v79 Imm(432) -> [spill 17] + v80 BinopI { op=add, lhs=v25, rhs_imm=432 } -> [spill 17] + v81 Imm(448) -> [spill 18] + v82 BinopI { op=add, lhs=v25, rhs_imm=448 } -> [spill 18] + v83 Imm(464) -> [spill 19] + v84 BinopI { op=add, lhs=v25, rhs_imm=464 } -> [spill 19] + v85 Imm(480) -> [spill 20] + v86 BinopI { op=add, lhs=v25, rhs_imm=480 } -> [spill 20] + v87 Imm(496) -> [spill 21] + v88 BinopI { op=add, lhs=v25, rhs_imm=496 } -> [spill 21] + v89 Imm(512) -> [spill 22] + v90 BinopI { op=add, lhs=v25, rhs_imm=512 } -> [spill 22] + v91 Imm(528) -> [spill 23] + v92 BinopI { op=add, lhs=v25, rhs_imm=528 } -> [spill 23] + v93 Imm(544) -> [spill 24] + v94 BinopI { op=add, lhs=v25, rhs_imm=544 } -> [spill 24] + v95 Imm(560) -> [spill 25] + v96 BinopI { op=add, lhs=v25, rhs_imm=560 } -> [spill 25] + v97 Imm(576) -> [spill 26] + v98 BinopI { op=add, lhs=v25, rhs_imm=576 } -> [spill 26] + v99 Imm(592) -> [spill 27] + v100 BinopI { op=add, lhs=v25, rhs_imm=592 } -> [spill 27] + v101 Imm(608) -> [spill 28] + v102 BinopI { op=add, lhs=v25, rhs_imm=608 } -> [spill 28] + v103 Imm(624) -> [spill 29] + v104 BinopI { op=add, lhs=v25, rhs_imm=624 } -> [spill 29] + v105 Imm(640) -> [spill 30] + v106 BinopI { op=add, lhs=v25, rhs_imm=640 } -> [spill 30] + v107 Imm(656) -> [spill 31] + v108 BinopI { op=add, lhs=v25, rhs_imm=656 } -> [spill 31] + v109 Imm(672) -> [spill 32] + v110 BinopI { op=add, lhs=v25, rhs_imm=672 } -> [spill 32] + v111 Imm(688) -> [spill 33] + v112 BinopI { op=add, lhs=v25, rhs_imm=688 } -> [spill 33] + v113 Imm(704) -> [spill 34] + v114 BinopI { op=add, lhs=v25, rhs_imm=704 } -> [spill 34] + v115 Imm(720) -> [spill 35] + v116 BinopI { op=add, lhs=v25, rhs_imm=720 } -> [spill 35] + v117 Imm(736) -> [spill 36] + v118 BinopI { op=add, lhs=v25, rhs_imm=736 } -> [spill 36] + v119 Imm(752) -> [spill 37] + v120 BinopI { op=add, lhs=v25, rhs_imm=752 } -> [spill 37] + v121 Imm(768) -> [spill 38] + v122 BinopI { op=add, lhs=v25, rhs_imm=768 } -> [spill 38] + v123 Imm(784) -> [spill 39] + v124 BinopI { op=add, lhs=v25, rhs_imm=784 } -> [spill 39] + v125 Imm(800) -> [spill 40] + v126 BinopI { op=add, lhs=v25, rhs_imm=800 } -> [spill 40] + v127 Imm(816) -> [spill 41] + v128 BinopI { op=add, lhs=v25, rhs_imm=816 } -> [spill 41] + v129 Imm(832) -> [spill 42] + v130 BinopI { op=add, lhs=v25, rhs_imm=832 } -> [spill 42] + v131 Imm(848) -> [spill 43] + v132 BinopI { op=add, lhs=v25, rhs_imm=848 } -> [spill 43] + v133 Imm(864) -> [spill 44] + v134 BinopI { op=add, lhs=v25, rhs_imm=864 } -> [spill 44] + v135 Imm(880) -> [spill 45] + v136 BinopI { op=add, lhs=v25, rhs_imm=880 } -> [spill 45] + v137 Imm(896) -> [spill 46] + v138 BinopI { op=add, lhs=v25, rhs_imm=896 } -> [spill 46] + v139 Imm(912) -> [spill 47] + v140 BinopI { op=add, lhs=v25, rhs_imm=912 } -> [spill 47] + v141 Imm(928) -> [spill 48] + v142 BinopI { op=add, lhs=v25, rhs_imm=928 } -> [spill 48] + v143 Imm(944) -> [spill 49] + v144 BinopI { op=add, lhs=v25, rhs_imm=944 } -> [spill 49] + v145 Imm(960) -> [spill 50] + v146 BinopI { op=add, lhs=v25, rhs_imm=960 } -> [spill 50] + v147 Imm(976) -> [spill 51] + v148 BinopI { op=add, lhs=v25, rhs_imm=976 } -> [spill 51] + v149 Imm(992) -> [spill 52] + v150 BinopI { op=add, lhs=v25, rhs_imm=992 } -> [spill 52] + v151 Imm(1008) -> [spill 53] + v152 BinopI { op=add, lhs=v25, rhs_imm=1008 } -> [spill 53] + v153 Imm(1024) -> [spill 54] + v154 BinopI { op=add, lhs=v25, rhs_imm=1024 } -> [spill 54] + v155 Imm(1040) -> [spill 55] + v156 BinopI { op=add, lhs=v25, rhs_imm=1040 } -> [spill 55] + v157 Imm(1056) -> [spill 56] + v158 BinopI { op=add, lhs=v25, rhs_imm=1056 } -> [spill 56] + v159 Imm(1072) -> [spill 57] + v160 BinopI { op=add, lhs=v25, rhs_imm=1072 } -> [spill 57] + v161 Imm(1088) -> [spill 58] + v162 BinopI { op=add, lhs=v25, rhs_imm=1088 } -> [spill 58] + v163 Imm(1104) -> [spill 59] + v164 BinopI { op=add, lhs=v25, rhs_imm=1104 } -> [spill 59] + v165 Imm(1120) -> [spill 60] + v166 BinopI { op=add, lhs=v25, rhs_imm=1120 } -> [spill 60] + v167 Imm(1136) -> [spill 61] + v168 BinopI { op=add, lhs=v25, rhs_imm=1136 } -> [spill 61] + v169 Imm(1152) -> [spill 62] + v170 BinopI { op=add, lhs=v25, rhs_imm=1152 } -> [spill 62] + v171 Imm(1168) -> [spill 63] + v172 BinopI { op=add, lhs=v25, rhs_imm=1168 } -> [spill 63] + v173 Imm(1184) -> [spill 64] + v174 BinopI { op=add, lhs=v25, rhs_imm=1184 } -> [spill 64] + v175 Imm(1200) -> [spill 65] + v176 BinopI { op=add, lhs=v25, rhs_imm=1200 } -> [spill 65] + v177 Imm(1216) -> [spill 66] + v178 BinopI { op=add, lhs=v25, rhs_imm=1216 } -> [spill 66] + v179 Imm(1232) -> [spill 67] + v180 BinopI { op=add, lhs=v25, rhs_imm=1232 } -> [spill 67] + v181 Imm(1248) -> [spill 68] + v182 BinopI { op=add, lhs=v25, rhs_imm=1248 } -> [spill 68] + v183 Imm(1264) -> [spill 69] + v184 BinopI { op=add, lhs=v25, rhs_imm=1264 } -> [spill 69] + v185 Imm(1280) -> [spill 70] + v186 BinopI { op=add, lhs=v25, rhs_imm=1280 } -> [spill 70] + v187 Imm(1296) -> [spill 71] + v188 BinopI { op=add, lhs=v25, rhs_imm=1296 } -> [spill 71] + v189 Imm(1312) -> [spill 72] + v190 BinopI { op=add, lhs=v25, rhs_imm=1312 } -> [spill 72] + v191 Imm(1328) -> [spill 73] + v192 BinopI { op=add, lhs=v25, rhs_imm=1328 } -> [spill 73] + v193 Imm(1344) -> [spill 74] + v194 BinopI { op=add, lhs=v25, rhs_imm=1344 } -> [spill 74] + v195 Imm(1360) -> [spill 75] + v196 BinopI { op=add, lhs=v25, rhs_imm=1360 } -> [spill 75] + v197 Imm(1376) -> [spill 76] + v198 BinopI { op=add, lhs=v25, rhs_imm=1376 } -> [spill 76] + v199 Imm(1392) -> [spill 77] + v200 BinopI { op=add, lhs=v25, rhs_imm=1392 } -> [spill 77] + v201 Imm(1408) -> [spill 78] + v202 BinopI { op=add, lhs=v25, rhs_imm=1408 } -> [spill 78] + v203 Imm(1424) -> [spill 79] + v204 BinopI { op=add, lhs=v25, rhs_imm=1424 } -> [spill 79] + v205 Imm(1440) -> [spill 80] + v206 BinopI { op=add, lhs=v25, rhs_imm=1440 } -> [spill 80] + v207 Imm(1456) -> [spill 81] + v208 BinopI { op=add, lhs=v25, rhs_imm=1456 } -> [spill 81] + v209 Imm(1472) -> [spill 82] + v210 BinopI { op=add, lhs=v25, rhs_imm=1472 } -> [spill 82] + v211 Imm(1488) -> [spill 83] + v212 BinopI { op=add, lhs=v25, rhs_imm=1488 } -> [spill 83] + v213 Imm(1504) -> [spill 84] + v214 BinopI { op=add, lhs=v25, rhs_imm=1504 } -> [spill 84] + v215 Imm(1520) -> [spill 85] + v216 BinopI { op=add, lhs=v25, rhs_imm=1520 } -> [spill 85] + v217 Imm(1536) -> [spill 86] + v218 BinopI { op=add, lhs=v25, rhs_imm=1536 } -> [spill 86] + v219 Imm(1552) -> [spill 87] + v220 BinopI { op=add, lhs=v25, rhs_imm=1552 } -> [spill 87] + v221 Imm(1568) -> [spill 88] + v222 BinopI { op=add, lhs=v25, rhs_imm=1568 } -> [spill 88] + v223 Imm(1584) -> [spill 89] + v224 BinopI { op=add, lhs=v25, rhs_imm=1584 } -> [spill 89] + v225 Imm(1600) -> [spill 90] + v226 BinopI { op=add, lhs=v25, rhs_imm=1600 } -> [spill 90] + v227 Imm(1616) -> [spill 91] + v228 BinopI { op=add, lhs=v25, rhs_imm=1616 } -> [spill 91] + v229 Imm(1632) -> [spill 92] + v230 BinopI { op=add, lhs=v25, rhs_imm=1632 } -> [spill 92] + v231 Imm(1648) -> [spill 93] + v232 BinopI { op=add, lhs=v25, rhs_imm=1648 } -> [spill 93] + v233 Imm(1664) -> [spill 94] + v234 BinopI { op=add, lhs=v25, rhs_imm=1664 } -> [spill 94] + v235 Imm(1680) -> [spill 95] + v236 BinopI { op=add, lhs=v25, rhs_imm=1680 } -> [spill 95] + v237 Imm(1696) -> [spill 96] + v238 BinopI { op=add, lhs=v25, rhs_imm=1696 } -> [spill 96] + v239 Imm(1712) -> [spill 97] + v240 BinopI { op=add, lhs=v25, rhs_imm=1712 } -> [spill 97] + v241 Imm(1728) -> [spill 98] + v242 BinopI { op=add, lhs=v25, rhs_imm=1728 } -> [spill 98] + v243 Imm(1744) -> [spill 99] + v244 BinopI { op=add, lhs=v25, rhs_imm=1744 } -> [spill 99] + v245 Imm(1760) -> [spill 100] + v246 BinopI { op=add, lhs=v25, rhs_imm=1760 } -> [spill 100] + v247 Imm(1776) -> [spill 101] + v248 BinopI { op=add, lhs=v25, rhs_imm=1776 } -> [spill 101] + v249 Imm(1792) -> [spill 102] + v250 BinopI { op=add, lhs=v25, rhs_imm=1792 } -> [spill 102] + v251 Imm(1808) -> [spill 103] + v252 BinopI { op=add, lhs=v25, rhs_imm=1808 } -> [spill 103] + v253 Imm(1824) -> [spill 104] + v254 BinopI { op=add, lhs=v25, rhs_imm=1824 } -> [spill 104] + v255 Imm(1840) -> [spill 105] + v256 BinopI { op=add, lhs=v25, rhs_imm=1840 } -> [spill 105] + v257 Imm(1856) -> [spill 106] + v258 BinopI { op=add, lhs=v25, rhs_imm=1856 } -> [spill 106] + v259 Imm(1872) -> [spill 107] + v260 BinopI { op=add, lhs=v25, rhs_imm=1872 } -> [spill 107] + v261 Imm(1888) -> [spill 108] + v262 BinopI { op=add, lhs=v25, rhs_imm=1888 } -> [spill 108] + v263 Imm(1904) -> [spill 109] + v264 BinopI { op=add, lhs=v25, rhs_imm=1904 } -> [spill 109] + v265 Imm(1920) -> [spill 110] + v266 BinopI { op=add, lhs=v25, rhs_imm=1920 } -> [spill 110] + v267 Imm(1936) -> [spill 111] + v268 BinopI { op=add, lhs=v25, rhs_imm=1936 } -> [spill 111] + v269 Imm(1952) -> [spill 112] + v270 BinopI { op=add, lhs=v25, rhs_imm=1952 } -> [spill 112] + v271 Imm(1968) -> [spill 113] + v272 BinopI { op=add, lhs=v25, rhs_imm=1968 } -> [spill 113] + v273 Imm(1984) -> [spill 114] + v274 BinopI { op=add, lhs=v25, rhs_imm=1984 } -> [spill 114] + v275 Imm(2000) -> [spill 115] + v276 BinopI { op=add, lhs=v25, rhs_imm=2000 } -> [spill 115] + v277 Imm(2016) -> [spill 116] + v278 BinopI { op=add, lhs=v25, rhs_imm=2016 } -> [spill 116] + v279 Imm(2032) -> [spill 117] + v280 BinopI { op=add, lhs=v25, rhs_imm=2032 } -> [spill 117] + v281 Imm(2048) -> [spill 118] + v282 BinopI { op=add, lhs=v25, rhs_imm=2048 } -> [spill 118] + v283 Imm(2064) -> [spill 119] + v284 BinopI { op=add, lhs=v25, rhs_imm=2064 } -> [spill 119] + v285 Imm(2080) -> [spill 120] + v286 BinopI { op=add, lhs=v25, rhs_imm=2080 } -> [spill 120] + v287 Imm(2096) -> [spill 121] + v288 BinopI { op=add, lhs=v25, rhs_imm=2096 } -> [spill 121] + v289 Imm(2112) -> [spill 122] + v290 BinopI { op=add, lhs=v25, rhs_imm=2112 } -> [spill 122] + v291 Imm(2128) -> [spill 123] + v292 BinopI { op=add, lhs=v25, rhs_imm=2128 } -> [spill 123] + v293 Imm(2144) -> [spill 124] + v294 BinopI { op=add, lhs=v25, rhs_imm=2144 } -> [spill 124] + v295 Imm(2160) -> [spill 125] + v296 BinopI { op=add, lhs=v25, rhs_imm=2160 } -> [spill 125] + v297 Imm(2176) -> [spill 126] + v298 BinopI { op=add, lhs=v25, rhs_imm=2176 } -> [spill 126] + v299 Imm(2192) -> [spill 127] + v300 BinopI { op=add, lhs=v25, rhs_imm=2192 } -> [spill 127] + v301 Imm(2208) -> [spill 128] + v302 BinopI { op=add, lhs=v25, rhs_imm=2208 } -> [spill 128] + v303 Imm(2224) -> [spill 129] + v304 BinopI { op=add, lhs=v25, rhs_imm=2224 } -> [spill 129] + v305 Imm(2240) -> [spill 130] + v306 BinopI { op=add, lhs=v25, rhs_imm=2240 } -> [spill 130] + v307 Imm(2256) -> [spill 131] + v308 BinopI { op=add, lhs=v25, rhs_imm=2256 } -> [spill 131] + v309 Imm(2272) -> [spill 132] + v310 BinopI { op=add, lhs=v25, rhs_imm=2272 } -> [spill 132] + v311 Imm(2288) -> [spill 133] + v312 BinopI { op=add, lhs=v25, rhs_imm=2288 } -> [spill 133] + v313 Imm(2304) -> [spill 134] + v314 BinopI { op=add, lhs=v25, rhs_imm=2304 } -> [spill 134] + v315 Imm(2320) -> [spill 135] + v316 BinopI { op=add, lhs=v25, rhs_imm=2320 } -> [spill 135] + v317 Imm(2336) -> [spill 136] + v318 BinopI { op=add, lhs=v25, rhs_imm=2336 } -> [spill 136] + v319 Imm(2352) -> [spill 137] + v320 BinopI { op=add, lhs=v25, rhs_imm=2352 } -> [spill 137] + v321 Imm(2368) -> [spill 138] + v322 BinopI { op=add, lhs=v25, rhs_imm=2368 } -> [spill 138] + v323 Imm(2384) -> [spill 139] + v324 BinopI { op=add, lhs=v25, rhs_imm=2384 } -> [spill 139] + v325 Imm(2400) -> [spill 140] + v326 BinopI { op=add, lhs=v25, rhs_imm=2400 } -> [spill 140] + v327 Imm(2416) -> [spill 141] + v328 BinopI { op=add, lhs=v25, rhs_imm=2416 } -> [spill 141] + v329 Imm(2432) -> [spill 142] + v330 BinopI { op=add, lhs=v25, rhs_imm=2432 } -> [spill 142] + v331 Imm(2448) -> [spill 143] + v332 BinopI { op=add, lhs=v25, rhs_imm=2448 } -> [spill 143] + v333 Imm(2464) -> [spill 144] + v334 BinopI { op=add, lhs=v25, rhs_imm=2464 } -> [spill 144] + v335 Imm(2480) -> [spill 145] + v336 BinopI { op=add, lhs=v25, rhs_imm=2480 } -> [spill 145] + v337 Imm(2496) -> [spill 146] + v338 BinopI { op=add, lhs=v25, rhs_imm=2496 } -> [spill 146] + v339 Imm(2512) -> [spill 147] + v340 BinopI { op=add, lhs=v25, rhs_imm=2512 } -> [spill 147] + v341 Imm(2528) -> [spill 148] + v342 BinopI { op=add, lhs=v25, rhs_imm=2528 } -> [spill 148] + v343 Imm(2544) -> [spill 149] + v344 BinopI { op=add, lhs=v25, rhs_imm=2544 } -> [spill 149] + v345 Imm(2560) -> [spill 150] + v346 BinopI { op=add, lhs=v25, rhs_imm=2560 } -> [spill 150] + v347 Imm(2576) -> [spill 151] + v348 BinopI { op=add, lhs=v25, rhs_imm=2576 } -> [spill 151] + v349 Imm(2592) -> [spill 152] + v350 BinopI { op=add, lhs=v25, rhs_imm=2592 } -> [spill 152] + v351 Imm(2608) -> [spill 153] + v352 BinopI { op=add, lhs=v25, rhs_imm=2608 } -> [spill 153] + v353 Imm(2624) -> [spill 154] + v354 BinopI { op=add, lhs=v25, rhs_imm=2624 } -> [spill 154] + v355 Imm(2640) -> [spill 155] + v356 BinopI { op=add, lhs=v25, rhs_imm=2640 } -> [spill 155] + v357 Imm(2656) -> [spill 156] + v358 BinopI { op=add, lhs=v25, rhs_imm=2656 } -> [spill 156] + v359 Imm(2672) -> [spill 157] + v360 BinopI { op=add, lhs=v25, rhs_imm=2672 } -> [spill 157] + v361 Imm(2688) -> [spill 158] + v362 BinopI { op=add, lhs=v25, rhs_imm=2688 } -> [spill 158] + v363 Imm(2704) -> [spill 159] + v364 BinopI { op=add, lhs=v25, rhs_imm=2704 } -> [spill 159] + v365 Imm(2720) -> [spill 160] + v366 BinopI { op=add, lhs=v25, rhs_imm=2720 } -> [spill 160] + v367 Imm(2736) -> [spill 161] + v368 BinopI { op=add, lhs=v25, rhs_imm=2736 } -> [spill 161] + v369 Imm(2752) -> [spill 162] + v370 BinopI { op=add, lhs=v25, rhs_imm=2752 } -> [spill 162] + v371 Imm(2768) -> [spill 163] + v372 BinopI { op=add, lhs=v25, rhs_imm=2768 } -> [spill 163] + v373 Imm(2784) -> [spill 164] + v374 BinopI { op=add, lhs=v25, rhs_imm=2784 } -> [spill 164] + v375 Imm(2800) -> [spill 165] + v376 BinopI { op=add, lhs=v25, rhs_imm=2800 } -> [spill 165] + v377 Imm(2816) -> [spill 166] + v378 BinopI { op=add, lhs=v25, rhs_imm=2816 } -> [spill 166] + v379 Imm(2832) -> [spill 167] + v380 BinopI { op=add, lhs=v25, rhs_imm=2832 } -> [spill 167] + v381 Imm(2848) -> [spill 168] + v382 BinopI { op=add, lhs=v25, rhs_imm=2848 } -> [spill 168] + v383 Imm(2864) -> [spill 169] + v384 BinopI { op=add, lhs=v25, rhs_imm=2864 } -> [spill 169] + v385 Imm(2880) -> [spill 170] + v386 BinopI { op=add, lhs=v25, rhs_imm=2880 } -> [spill 170] + v387 Imm(2896) -> [spill 171] + v388 BinopI { op=add, lhs=v25, rhs_imm=2896 } -> [spill 171] + v389 Imm(2912) -> [spill 172] + v390 BinopI { op=add, lhs=v25, rhs_imm=2912 } -> [spill 172] + v391 Imm(2928) -> [spill 173] + v392 BinopI { op=add, lhs=v25, rhs_imm=2928 } -> [spill 173] + v393 Imm(2944) -> [spill 174] + v394 BinopI { op=add, lhs=v25, rhs_imm=2944 } -> [spill 174] + v395 Imm(2960) -> [spill 175] + v396 BinopI { op=add, lhs=v25, rhs_imm=2960 } -> [spill 175] + v397 Imm(2976) -> [spill 176] + v398 BinopI { op=add, lhs=v25, rhs_imm=2976 } -> [spill 176] + v399 Imm(2992) -> [spill 177] + v400 BinopI { op=add, lhs=v25, rhs_imm=2992 } -> [spill 177] + v401 Imm(3008) -> [spill 178] + v402 BinopI { op=add, lhs=v25, rhs_imm=3008 } -> [spill 178] + v403 Imm(3024) -> [spill 179] + v404 BinopI { op=add, lhs=v25, rhs_imm=3024 } -> [spill 179] + v405 Imm(3040) -> [spill 180] + v406 BinopI { op=add, lhs=v25, rhs_imm=3040 } -> [spill 180] + v407 Imm(3056) -> [spill 181] + v408 BinopI { op=add, lhs=v25, rhs_imm=3056 } -> [spill 181] + v409 Imm(3072) -> [spill 182] + v410 BinopI { op=add, lhs=v25, rhs_imm=3072 } -> [spill 182] + v411 Imm(3088) -> [spill 183] + v412 BinopI { op=add, lhs=v25, rhs_imm=3088 } -> [spill 183] + v413 Imm(3104) -> [spill 184] + v414 BinopI { op=add, lhs=v25, rhs_imm=3104 } -> [spill 184] + v415 Imm(3120) -> [spill 185] + v416 BinopI { op=add, lhs=v25, rhs_imm=3120 } -> [spill 185] + v417 Imm(3136) -> [spill 186] + v418 BinopI { op=add, lhs=v25, rhs_imm=3136 } -> [spill 186] + v419 Imm(3152) -> [spill 187] + v420 BinopI { op=add, lhs=v25, rhs_imm=3152 } -> [spill 187] + v421 Imm(3168) -> [spill 188] + v422 BinopI { op=add, lhs=v25, rhs_imm=3168 } -> [spill 188] + v423 Imm(3184) -> [spill 189] + v424 BinopI { op=add, lhs=v25, rhs_imm=3184 } -> [spill 189] + v425 Imm(3200) -> [spill 190] + v426 BinopI { op=add, lhs=v25, rhs_imm=3200 } -> [spill 190] + v427 Imm(3216) -> [spill 191] + v428 BinopI { op=add, lhs=v25, rhs_imm=3216 } -> [spill 191] + v429 Imm(3232) -> [spill 192] + v430 BinopI { op=add, lhs=v25, rhs_imm=3232 } -> [spill 192] + v431 Imm(3248) -> [spill 193] + v432 BinopI { op=add, lhs=v25, rhs_imm=3248 } -> [spill 193] + v433 Imm(3264) -> [spill 194] + v434 BinopI { op=add, lhs=v25, rhs_imm=3264 } -> [spill 194] + v435 Imm(3280) -> [spill 195] + v436 BinopI { op=add, lhs=v25, rhs_imm=3280 } -> [spill 195] + v437 Imm(3296) -> [spill 196] + v438 BinopI { op=add, lhs=v25, rhs_imm=3296 } -> [spill 196] + v439 Imm(3312) -> [spill 197] + v440 BinopI { op=add, lhs=v25, rhs_imm=3312 } -> [spill 197] + v441 Imm(3328) -> [spill 198] + v442 BinopI { op=add, lhs=v25, rhs_imm=3328 } -> [spill 198] + v443 Imm(3344) -> [spill 199] + v444 BinopI { op=add, lhs=v25, rhs_imm=3344 } -> [spill 199] + v445 Imm(3360) -> [spill 200] + v446 BinopI { op=add, lhs=v25, rhs_imm=3360 } -> [spill 200] + v447 Imm(3376) -> [spill 201] + v448 BinopI { op=add, lhs=v25, rhs_imm=3376 } -> [spill 201] + v449 Imm(3392) -> [spill 202] + v450 BinopI { op=add, lhs=v25, rhs_imm=3392 } -> [spill 202] + v451 Imm(3408) -> [spill 203] + v452 BinopI { op=add, lhs=v25, rhs_imm=3408 } -> [spill 203] + v453 Imm(3424) -> [spill 204] + v454 BinopI { op=add, lhs=v25, rhs_imm=3424 } -> [spill 204] + v455 Imm(3440) -> [spill 205] + v456 BinopI { op=add, lhs=v25, rhs_imm=3440 } -> [spill 205] + v457 Imm(3456) -> [spill 206] + v458 BinopI { op=add, lhs=v25, rhs_imm=3456 } -> [spill 206] + v459 Imm(3472) -> [spill 207] + v460 BinopI { op=add, lhs=v25, rhs_imm=3472 } -> [spill 207] + v461 Imm(3488) -> [spill 208] + v462 BinopI { op=add, lhs=v25, rhs_imm=3488 } -> [spill 208] + v463 Imm(3504) -> [spill 209] + v464 BinopI { op=add, lhs=v25, rhs_imm=3504 } -> [spill 209] + v465 Imm(3520) -> [spill 210] + v466 BinopI { op=add, lhs=v25, rhs_imm=3520 } -> [spill 210] + v467 Imm(3536) -> [spill 211] + v468 BinopI { op=add, lhs=v25, rhs_imm=3536 } -> [spill 211] + v469 Imm(3552) -> [spill 212] + v470 BinopI { op=add, lhs=v25, rhs_imm=3552 } -> [spill 212] + v471 Imm(3568) -> [spill 213] + v472 BinopI { op=add, lhs=v25, rhs_imm=3568 } -> [spill 213] + v473 Imm(3584) -> [spill 214] + v474 BinopI { op=add, lhs=v25, rhs_imm=3584 } -> [spill 214] + v475 Imm(3600) -> [spill 215] + v476 BinopI { op=add, lhs=v25, rhs_imm=3600 } -> [spill 215] + v477 Imm(3616) -> [spill 216] + v478 BinopI { op=add, lhs=v25, rhs_imm=3616 } -> [spill 216] + v479 Imm(3632) -> [spill 217] + v480 BinopI { op=add, lhs=v25, rhs_imm=3632 } -> [spill 217] + v481 Imm(3648) -> [spill 218] + v482 BinopI { op=add, lhs=v25, rhs_imm=3648 } -> [spill 218] + v483 Imm(3664) -> [spill 219] + v484 BinopI { op=add, lhs=v25, rhs_imm=3664 } -> [spill 219] + v485 Imm(3680) -> [spill 220] + v486 BinopI { op=add, lhs=v25, rhs_imm=3680 } -> [spill 220] + v487 Imm(3696) -> [spill 221] + v488 BinopI { op=add, lhs=v25, rhs_imm=3696 } -> [spill 221] + v489 Imm(3712) -> [spill 222] + v490 BinopI { op=add, lhs=v25, rhs_imm=3712 } -> [spill 222] + v491 Imm(3728) -> [spill 223] + v492 BinopI { op=add, lhs=v25, rhs_imm=3728 } -> [spill 223] + v493 Imm(3744) -> [spill 224] + v494 BinopI { op=add, lhs=v25, rhs_imm=3744 } -> [spill 224] + v495 Imm(3760) -> [spill 225] + v496 BinopI { op=add, lhs=v25, rhs_imm=3760 } -> [spill 225] + v497 Imm(3776) -> [spill 226] + v498 BinopI { op=add, lhs=v25, rhs_imm=3776 } -> [spill 226] + v499 Imm(3792) -> [spill 227] + v500 BinopI { op=add, lhs=v25, rhs_imm=3792 } -> [spill 227] + v501 Imm(3808) -> [spill 228] + v502 BinopI { op=add, lhs=v25, rhs_imm=3808 } -> [spill 228] + v503 Imm(3824) -> [spill 229] + v504 BinopI { op=add, lhs=v25, rhs_imm=3824 } -> [spill 229] + v505 Imm(3840) -> [spill 230] + v506 BinopI { op=add, lhs=v25, rhs_imm=3840 } -> [spill 230] + v507 Imm(3856) -> [spill 231] + v508 BinopI { op=add, lhs=v25, rhs_imm=3856 } -> [spill 231] + v509 Imm(3872) -> [spill 232] + v510 BinopI { op=add, lhs=v25, rhs_imm=3872 } -> [spill 232] + v511 Imm(3888) -> [spill 233] + v512 BinopI { op=add, lhs=v25, rhs_imm=3888 } -> [spill 233] + v513 Imm(3904) -> [spill 234] + v514 BinopI { op=add, lhs=v25, rhs_imm=3904 } -> [spill 234] + v515 Imm(3920) -> [spill 235] + v516 BinopI { op=add, lhs=v25, rhs_imm=3920 } -> [spill 235] + v517 Imm(3936) -> [spill 236] + v518 BinopI { op=add, lhs=v25, rhs_imm=3936 } -> [spill 236] + v519 Imm(3952) -> [spill 237] + v520 BinopI { op=add, lhs=v25, rhs_imm=3952 } -> [spill 237] + v521 Imm(3968) -> [spill 238] + v522 BinopI { op=add, lhs=v25, rhs_imm=3968 } -> [spill 238] + v523 Imm(3984) -> [spill 239] + v524 BinopI { op=add, lhs=v25, rhs_imm=3984 } -> [spill 239] + v525 Imm(4000) -> [spill 240] + v526 BinopI { op=add, lhs=v25, rhs_imm=4000 } -> [spill 240] + v527 Imm(4016) -> [spill 241] + v528 BinopI { op=add, lhs=v25, rhs_imm=4016 } -> [spill 241] + v529 Imm(4032) -> [spill 242] + v530 BinopI { op=add, lhs=v25, rhs_imm=4032 } -> [spill 242] + v531 Imm(4048) -> [spill 243] + v532 BinopI { op=add, lhs=v25, rhs_imm=4048 } -> [spill 243] + v533 Imm(4064) -> [spill 244] + v534 BinopI { op=add, lhs=v25, rhs_imm=4064 } -> [spill 244] + v535 Imm(4080) -> [spill 245] + v536 BinopI { op=add, lhs=v25, rhs_imm=4080 } -> [spill 245] + v537 Imm(4096) -> [spill 246] + v538 BinopI { op=add, lhs=v25, rhs_imm=4096 } -> [spill 246] + v539 Imm(4112) -> [spill 247] + v540 BinopI { op=add, lhs=v25, rhs_imm=4112 } -> [spill 247] + v541 Imm(4128) -> [spill 248] + v542 BinopI { op=add, lhs=v25, rhs_imm=4128 } -> [spill 248] + v543 Imm(4144) -> [spill 249] + v544 BinopI { op=add, lhs=v25, rhs_imm=4144 } -> [spill 249] + v545 Imm(4160) -> [spill 250] + v546 BinopI { op=add, lhs=v25, rhs_imm=4160 } -> [spill 250] + v547 Call { target_pc=0, args=[v25, v28, v30, v32, v34, v36, v38, v40, v42, v44, v46, v48, v50, v52, v54, v56, v58, v60, v62, v64, v66, v68, v70, v72, v74, v76, v78, v80, v82, v84, v86, v88, v90, v92, v94, v96, v98, v100, v102, v104, v106, v108, v110, v112, v114, v116, v118, v120, v122, v124, v126, v128, v130, v132, v134, v136, v138, v140, v142, v144, v146, v148, v150, v152, v154, v156, v158, v160, v162, v164, v166, v168, v170, v172, v174, v176, v178, v180, v182, v184, v186, v188, v190, v192, v194, v196, v198, v200, v202, v204, v206, v208, v210, v212, v214, v216, v218, v220, v222, v224, v226, v228, v230, v232, v234, v236, v238, v240, v242, v244, v246, v248, v250, v252, v254, v256, v258, v260, v262, v264, v266, v268, v270, v272, v274, v276, v278, v280, v282, v284, v286, v288, v290, v292, v294, v296, v298, v300, v302, v304, v306, v308, v310, v312, v314, v316, v318, v320, v322, v324, v326, v328, v330, v332, v334, v336, v338, v340, v342, v344, v346, v348, v350, v352, v354, v356, v358, v360, v362, v364, v366, v368, v370, v372, v374, v376, v378, v380, v382, v384, v386, v388, v390, v392, v394, v396, v398, v400, v402, v404, v406, v408, v410, v412, v414, v416, v418, v420, v422, v424, v426, v428, v430, v432, v434, v436, v438, v440, v442, v444, v446, v448, v450, v452, v454, v456, v458, v460, v462, v464, v466, v468, v470, v472, v474, v476, v478, v480, v482, v484, v486, v488, v490, v492, v494, v496, v498, v500, v502, v504, v506, v508, v510, v512, v514, v516, v518, v520, v522, v524, v526, v528, v530, v532, v534, v536, v538, v540, v542, v544, v546], fixed_args=261, fp_return=false, fp_arg_mask=0x0 } -> x0 + v548 BinopI { op=ne, lhs=v547, rhs_imm=101790 } -> x0 + terminator Bz { cond=v548, target=b6, fall=b5 } (exit_acc=v548) + block 5 start_pc=0 + v549 Imm(1) -> x0 + terminator Return(v549) (exit_acc=v549) + block 6 start_pc=0 + v550 Imm(1) -> x7 + v551 Imm(2) -> x6 + v552 Imm(3) -> x2 + v553 Imm(4) -> x1 + v554 Imm(5) -> x8 + v555 Imm(6) -> x9 + v556 Imm(7) -> x0 + v557 Imm(8) -> x13 + v558 Imm(9) -> x14 + v559 Imm(10) -> x15 + v560 Imm(11) -> [spill 0] + v561 Imm(12) -> [spill 1] + v562 Imm(13) -> [spill 2] + v563 Imm(14) -> [spill 3] + v564 Imm(15) -> [spill 4] + v565 Imm(16) -> [spill 5] + v566 Imm(17) -> [spill 6] + v567 Imm(18) -> [spill 7] + v568 Imm(19) -> [spill 8] + v569 Imm(20) -> [spill 9] + v570 Imm(21) -> [spill 10] + v571 Imm(22) -> [spill 11] + v572 Imm(23) -> [spill 12] + v573 Imm(24) -> [spill 13] + v574 Imm(25) -> [spill 14] + v575 Imm(26) -> [spill 15] + v576 Imm(27) -> [spill 16] + v577 Imm(28) -> [spill 17] + v578 Imm(29) -> [spill 18] + v579 Imm(30) -> [spill 19] + v580 Imm(31) -> [spill 20] + v581 Imm(32) -> [spill 21] + v582 Imm(33) -> [spill 22] + v583 Imm(34) -> [spill 23] + v584 Imm(35) -> [spill 24] + v585 Imm(36) -> [spill 25] + v586 Imm(37) -> [spill 26] + v587 Imm(38) -> [spill 27] + v588 Imm(39) -> [spill 28] + v589 Imm(40) -> [spill 29] + v590 Imm(41) -> [spill 30] + v591 Imm(42) -> [spill 31] + v592 Imm(43) -> [spill 32] + v593 Imm(44) -> [spill 33] + v594 Imm(45) -> [spill 34] + v595 Imm(46) -> [spill 35] + v596 Imm(47) -> [spill 36] + v597 Imm(48) -> [spill 37] + v598 Imm(49) -> [spill 38] + v599 Imm(50) -> [spill 39] + v600 Imm(51) -> [spill 40] + v601 Imm(52) -> [spill 41] + v602 Imm(53) -> [spill 42] + v603 Imm(54) -> [spill 43] + v604 Imm(55) -> [spill 44] + v605 Imm(56) -> [spill 45] + v606 Imm(57) -> [spill 46] + v607 Imm(58) -> [spill 47] + v608 Imm(59) -> [spill 48] + v609 Imm(60) -> [spill 49] + v610 Imm(61) -> [spill 50] + v611 Imm(62) -> [spill 51] + v612 Imm(63) -> [spill 52] + v613 Imm(64) -> [spill 53] + v614 Imm(65) -> [spill 54] + v615 Imm(66) -> [spill 55] + v616 Imm(67) -> [spill 56] + v617 Imm(68) -> [spill 57] + v618 Imm(69) -> [spill 58] + v619 Imm(70) -> [spill 59] + v620 Imm(71) -> [spill 60] + v621 Imm(72) -> [spill 61] + v622 Imm(73) -> [spill 62] + v623 Imm(74) -> [spill 63] + v624 Imm(75) -> [spill 64] + v625 Imm(76) -> [spill 65] + v626 Imm(77) -> [spill 66] + v627 Imm(78) -> [spill 67] + v628 Imm(79) -> [spill 68] + v629 Imm(80) -> [spill 69] + v630 Imm(81) -> [spill 70] + v631 Imm(82) -> [spill 71] + v632 Imm(83) -> [spill 72] + v633 Imm(84) -> [spill 73] + v634 Imm(85) -> [spill 74] + v635 Imm(86) -> [spill 75] + v636 Imm(87) -> [spill 76] + v637 Imm(88) -> [spill 77] + v638 Imm(89) -> [spill 78] + v639 Imm(90) -> [spill 79] + v640 Imm(91) -> [spill 80] + v641 Imm(92) -> [spill 81] + v642 Imm(93) -> [spill 82] + v643 Imm(94) -> [spill 83] + v644 Imm(95) -> [spill 84] + v645 Imm(96) -> [spill 85] + v646 Imm(97) -> [spill 86] + v647 Imm(98) -> [spill 87] + v648 Imm(99) -> [spill 88] + v649 Imm(100) -> [spill 89] + v650 Imm(101) -> [spill 90] + v651 Imm(102) -> [spill 91] + v652 Imm(103) -> [spill 92] + v653 Imm(104) -> [spill 93] + v654 Imm(105) -> [spill 94] + v655 Imm(106) -> [spill 95] + v656 Imm(107) -> [spill 96] + v657 Imm(108) -> [spill 97] + v658 Imm(109) -> [spill 98] + v659 Imm(110) -> [spill 99] + v660 Imm(111) -> [spill 100] + v661 Imm(112) -> [spill 101] + v662 Imm(113) -> [spill 102] + v663 Imm(114) -> [spill 103] + v664 Imm(115) -> [spill 104] + v665 Imm(116) -> [spill 105] + v666 Imm(117) -> [spill 106] + v667 Imm(118) -> [spill 107] + v668 Imm(119) -> [spill 108] + v669 Imm(120) -> [spill 109] + v670 Imm(121) -> [spill 110] + v671 Imm(122) -> [spill 111] + v672 Imm(123) -> [spill 112] + v673 Imm(124) -> [spill 113] + v674 Imm(125) -> [spill 114] + v675 Imm(126) -> [spill 115] + v676 Imm(127) -> [spill 116] + v677 Imm(128) -> [spill 117] + v678 Imm(129) -> [spill 118] + v679 Imm(130) -> [spill 119] + v680 Imm(131) -> [spill 120] + v681 Imm(132) -> [spill 121] + v682 Imm(133) -> [spill 122] + v683 Imm(134) -> [spill 123] + v684 Imm(135) -> [spill 124] + v685 Imm(136) -> [spill 125] + v686 Imm(137) -> [spill 126] + v687 Imm(138) -> [spill 127] + v688 Imm(139) -> [spill 128] + v689 Imm(140) -> [spill 129] + v690 Imm(141) -> [spill 130] + v691 Imm(142) -> [spill 131] + v692 Imm(143) -> [spill 132] + v693 Imm(144) -> [spill 133] + v694 Imm(145) -> [spill 134] + v695 Imm(146) -> [spill 135] + v696 Imm(147) -> [spill 136] + v697 Imm(148) -> [spill 137] + v698 Imm(149) -> [spill 138] + v699 Imm(150) -> [spill 139] + v700 Imm(151) -> [spill 140] + v701 Imm(152) -> [spill 141] + v702 Imm(153) -> [spill 142] + v703 Imm(154) -> [spill 143] + v704 Imm(155) -> [spill 144] + v705 Imm(156) -> [spill 145] + v706 Imm(157) -> [spill 146] + v707 Imm(158) -> [spill 147] + v708 Imm(159) -> [spill 148] + v709 Imm(160) -> [spill 149] + v710 Imm(161) -> [spill 150] + v711 Imm(162) -> [spill 151] + v712 Imm(163) -> [spill 152] + v713 Imm(164) -> [spill 153] + v714 Imm(165) -> [spill 154] + v715 Imm(166) -> [spill 155] + v716 Imm(167) -> [spill 156] + v717 Imm(168) -> [spill 157] + v718 Imm(169) -> [spill 158] + v719 Imm(170) -> [spill 159] + v720 Imm(171) -> [spill 160] + v721 Imm(172) -> [spill 161] + v722 Imm(173) -> [spill 162] + v723 Imm(174) -> [spill 163] + v724 Imm(175) -> [spill 164] + v725 Imm(176) -> [spill 165] + v726 Imm(177) -> [spill 166] + v727 Imm(178) -> [spill 167] + v728 Imm(179) -> [spill 168] + v729 Imm(180) -> [spill 169] + v730 Imm(181) -> [spill 170] + v731 Imm(182) -> [spill 171] + v732 Imm(183) -> [spill 172] + v733 Imm(184) -> [spill 173] + v734 Imm(185) -> [spill 174] + v735 Imm(186) -> [spill 175] + v736 Imm(187) -> [spill 176] + v737 Imm(188) -> [spill 177] + v738 Imm(189) -> [spill 178] + v739 Imm(190) -> [spill 179] + v740 Imm(191) -> [spill 180] + v741 Imm(192) -> [spill 181] + v742 Imm(193) -> [spill 182] + v743 Imm(194) -> [spill 183] + v744 Imm(195) -> [spill 184] + v745 Imm(196) -> [spill 185] + v746 Imm(197) -> [spill 186] + v747 Imm(198) -> [spill 187] + v748 Imm(199) -> [spill 188] + v749 Imm(200) -> [spill 189] + v750 Imm(201) -> [spill 190] + v751 Imm(202) -> [spill 191] + v752 Imm(203) -> [spill 192] + v753 Imm(204) -> [spill 193] + v754 Imm(205) -> [spill 194] + v755 Imm(206) -> [spill 195] + v756 Imm(207) -> [spill 196] + v757 Imm(208) -> [spill 197] + v758 Imm(209) -> [spill 198] + v759 Imm(210) -> [spill 199] + v760 Imm(211) -> [spill 200] + v761 Imm(212) -> [spill 201] + v762 Imm(213) -> [spill 202] + v763 Imm(214) -> [spill 203] + v764 Imm(215) -> [spill 204] + v765 Imm(216) -> [spill 205] + v766 Imm(217) -> [spill 206] + v767 Imm(218) -> [spill 207] + v768 Imm(219) -> [spill 208] + v769 Imm(220) -> [spill 209] + v770 Imm(221) -> [spill 210] + v771 Imm(222) -> [spill 211] + v772 Imm(223) -> [spill 212] + v773 Imm(224) -> [spill 213] + v774 Imm(225) -> [spill 214] + v775 Imm(226) -> [spill 215] + v776 Imm(227) -> [spill 216] + v777 Imm(228) -> [spill 217] + v778 Imm(229) -> [spill 218] + v779 Imm(230) -> [spill 219] + v780 Imm(231) -> [spill 220] + v781 Imm(232) -> [spill 221] + v782 Imm(233) -> [spill 222] + v783 Imm(234) -> [spill 223] + v784 Imm(235) -> [spill 224] + v785 Imm(236) -> [spill 225] + v786 Imm(237) -> [spill 226] + v787 Imm(238) -> [spill 227] + v788 Imm(239) -> [spill 228] + v789 Imm(240) -> [spill 229] + v790 Imm(241) -> [spill 230] + v791 Imm(242) -> [spill 231] + v792 Imm(243) -> [spill 232] + v793 Imm(244) -> [spill 233] + v794 Imm(245) -> [spill 234] + v795 Imm(246) -> [spill 235] + v796 Imm(247) -> [spill 236] + v797 Imm(248) -> [spill 237] + v798 Imm(249) -> [spill 238] + v799 Imm(250) -> [spill 239] + v800 Imm(251) -> [spill 240] + v801 Imm(252) -> [spill 241] + v802 Imm(253) -> [spill 242] + v803 Imm(254) -> [spill 243] + v804 Imm(255) -> [spill 244] + v805 Imm(256) -> [spill 245] + v806 Imm(257) -> [spill 246] + v807 Imm(258) -> [spill 247] + v808 Imm(259) -> [spill 248] + v809 Imm(260) -> [spill 249] + v810 LoadLocal { off=-1, kind=I64 } -> [spill 250] + v811 CallIndirect { target=v1, args=[v550, v551, v552, v553, v554, v555, v556, v557, v558, v559, v560, v561, v562, v563, v564, v565, v566, v567, v568, v569, v570, v571, v572, v573, v574, v575, v576, v577, v578, v579, v580, v581, v582, v583, v584, v585, v586, v587, v588, v589, v590, v591, v592, v593, v594, v595, v596, v597, v598, v599, v600, v601, v602, v603, v604, v605, v606, v607, v608, v609, v610, v611, v612, v613, v614, v615, v616, v617, v618, v619, v620, v621, v622, v623, v624, v625, v626, v627, v628, v629, v630, v631, v632, v633, v634, v635, v636, v637, v638, v639, v640, v641, v642, v643, v644, v645, v646, v647, v648, v649, v650, v651, v652, v653, v654, v655, v656, v657, v658, v659, v660, v661, v662, v663, v664, v665, v666, v667, v668, v669, v670, v671, v672, v673, v674, v675, v676, v677, v678, v679, v680, v681, v682, v683, v684, v685, v686, v687, v688, v689, v690, v691, v692, v693, v694, v695, v696, v697, v698, v699, v700, v701, v702, v703, v704, v705, v706, v707, v708, v709, v710, v711, v712, v713, v714, v715, v716, v717, v718, v719, v720, v721, v722, v723, v724, v725, v726, v727, v728, v729, v730, v731, v732, v733, v734, v735, v736, v737, v738, v739, v740, v741, v742, v743, v744, v745, v746, v747, v748, v749, v750, v751, v752, v753, v754, v755, v756, v757, v758, v759, v760, v761, v762, v763, v764, v765, v766, v767, v768, v769, v770, v771, v772, v773, v774, v775, v776, v777, v778, v779, v780, v781, v782, v783, v784, v785, v786, v787, v788, v789, v790, v791, v792, v793, v794, v795, v796, v797, v798, v799, v800, v801, v802, v803, v804, v805, v806, v807, v808, v809], callee_variadic=false, fixed_args=260, fp_return=false, fp_arg_mask=0x0 } -> x0 + v812 BinopI { op=ne, lhs=v811, rhs_imm=33930 } -> x0 + terminator Bz { cond=v812, target=b8, fall=b7 } (exit_acc=v812) + block 7 start_pc=0 + v813 Imm(2) -> x0 + terminator Return(v813) (exit_acc=v813) + block 8 start_pc=0 + v814 ImmData(24) -> x7 + v815 Imm(0) -> x0 + v816 Imm(16) -> x0 + v817 BinopI { op=add, lhs=v814, rhs_imm=16 } -> x6 + v818 Imm(32) -> x0 + v819 BinopI { op=add, lhs=v814, rhs_imm=32 } -> x2 + v820 Imm(48) -> x0 + v821 BinopI { op=add, lhs=v814, rhs_imm=48 } -> x1 + v822 Imm(64) -> x0 + v823 BinopI { op=add, lhs=v814, rhs_imm=64 } -> x8 + v824 Imm(80) -> x0 + v825 BinopI { op=add, lhs=v814, rhs_imm=80 } -> x9 + v826 Imm(96) -> x0 + v827 BinopI { op=add, lhs=v814, rhs_imm=96 } -> x0 + v828 Imm(112) -> x3 + v829 BinopI { op=add, lhs=v814, rhs_imm=112 } -> x3 + v830 Imm(128) -> x13 + v831 BinopI { op=add, lhs=v814, rhs_imm=128 } -> x13 + v832 Imm(144) -> x14 + v833 BinopI { op=add, lhs=v814, rhs_imm=144 } -> x14 + v834 Imm(160) -> x15 + v835 BinopI { op=add, lhs=v814, rhs_imm=160 } -> x15 + v836 Imm(176) -> [spill 0] + v837 BinopI { op=add, lhs=v814, rhs_imm=176 } -> [spill 0] + v838 Imm(192) -> [spill 1] + v839 BinopI { op=add, lhs=v814, rhs_imm=192 } -> [spill 1] + v840 Imm(208) -> [spill 2] + v841 BinopI { op=add, lhs=v814, rhs_imm=208 } -> [spill 2] + v842 Imm(224) -> [spill 3] + v843 BinopI { op=add, lhs=v814, rhs_imm=224 } -> [spill 3] + v844 Imm(240) -> [spill 4] + v845 BinopI { op=add, lhs=v814, rhs_imm=240 } -> [spill 4] + v846 Imm(256) -> [spill 5] + v847 BinopI { op=add, lhs=v814, rhs_imm=256 } -> [spill 5] + v848 Imm(272) -> [spill 6] + v849 BinopI { op=add, lhs=v814, rhs_imm=272 } -> [spill 6] + v850 Imm(288) -> [spill 7] + v851 BinopI { op=add, lhs=v814, rhs_imm=288 } -> [spill 7] + v852 Imm(304) -> [spill 8] + v853 BinopI { op=add, lhs=v814, rhs_imm=304 } -> [spill 8] + v854 Imm(320) -> [spill 9] + v855 BinopI { op=add, lhs=v814, rhs_imm=320 } -> [spill 9] + v856 Imm(336) -> [spill 10] + v857 BinopI { op=add, lhs=v814, rhs_imm=336 } -> [spill 10] + v858 Imm(352) -> [spill 11] + v859 BinopI { op=add, lhs=v814, rhs_imm=352 } -> [spill 11] + v860 Imm(368) -> [spill 12] + v861 BinopI { op=add, lhs=v814, rhs_imm=368 } -> [spill 12] + v862 Imm(384) -> [spill 13] + v863 BinopI { op=add, lhs=v814, rhs_imm=384 } -> [spill 13] + v864 Imm(400) -> [spill 14] + v865 BinopI { op=add, lhs=v814, rhs_imm=400 } -> [spill 14] + v866 Imm(416) -> [spill 15] + v867 BinopI { op=add, lhs=v814, rhs_imm=416 } -> [spill 15] + v868 Imm(432) -> [spill 16] + v869 BinopI { op=add, lhs=v814, rhs_imm=432 } -> [spill 16] + v870 Imm(448) -> [spill 17] + v871 BinopI { op=add, lhs=v814, rhs_imm=448 } -> [spill 17] + v872 Imm(464) -> [spill 18] + v873 BinopI { op=add, lhs=v814, rhs_imm=464 } -> [spill 18] + v874 Imm(480) -> [spill 19] + v875 BinopI { op=add, lhs=v814, rhs_imm=480 } -> [spill 19] + v876 Imm(496) -> [spill 20] + v877 BinopI { op=add, lhs=v814, rhs_imm=496 } -> [spill 20] + v878 Imm(512) -> [spill 21] + v879 BinopI { op=add, lhs=v814, rhs_imm=512 } -> [spill 21] + v880 Imm(528) -> [spill 22] + v881 BinopI { op=add, lhs=v814, rhs_imm=528 } -> [spill 22] + v882 Imm(544) -> [spill 23] + v883 BinopI { op=add, lhs=v814, rhs_imm=544 } -> [spill 23] + v884 Imm(560) -> [spill 24] + v885 BinopI { op=add, lhs=v814, rhs_imm=560 } -> [spill 24] + v886 Imm(576) -> [spill 25] + v887 BinopI { op=add, lhs=v814, rhs_imm=576 } -> [spill 25] + v888 Imm(592) -> [spill 26] + v889 BinopI { op=add, lhs=v814, rhs_imm=592 } -> [spill 26] + v890 Imm(608) -> [spill 27] + v891 BinopI { op=add, lhs=v814, rhs_imm=608 } -> [spill 27] + v892 Imm(624) -> [spill 28] + v893 BinopI { op=add, lhs=v814, rhs_imm=624 } -> [spill 28] + v894 Imm(640) -> [spill 29] + v895 BinopI { op=add, lhs=v814, rhs_imm=640 } -> [spill 29] + v896 Imm(656) -> [spill 30] + v897 BinopI { op=add, lhs=v814, rhs_imm=656 } -> [spill 30] + v898 Imm(672) -> [spill 31] + v899 BinopI { op=add, lhs=v814, rhs_imm=672 } -> [spill 31] + v900 Imm(688) -> [spill 32] + v901 BinopI { op=add, lhs=v814, rhs_imm=688 } -> [spill 32] + v902 Imm(704) -> [spill 33] + v903 BinopI { op=add, lhs=v814, rhs_imm=704 } -> [spill 33] + v904 Imm(720) -> [spill 34] + v905 BinopI { op=add, lhs=v814, rhs_imm=720 } -> [spill 34] + v906 Imm(736) -> [spill 35] + v907 BinopI { op=add, lhs=v814, rhs_imm=736 } -> [spill 35] + v908 Imm(752) -> [spill 36] + v909 BinopI { op=add, lhs=v814, rhs_imm=752 } -> [spill 36] + v910 Imm(768) -> [spill 37] + v911 BinopI { op=add, lhs=v814, rhs_imm=768 } -> [spill 37] + v912 Imm(784) -> [spill 38] + v913 BinopI { op=add, lhs=v814, rhs_imm=784 } -> [spill 38] + v914 Imm(800) -> [spill 39] + v915 BinopI { op=add, lhs=v814, rhs_imm=800 } -> [spill 39] + v916 Imm(816) -> [spill 40] + v917 BinopI { op=add, lhs=v814, rhs_imm=816 } -> [spill 40] + v918 Imm(832) -> [spill 41] + v919 BinopI { op=add, lhs=v814, rhs_imm=832 } -> [spill 41] + v920 Imm(848) -> [spill 42] + v921 BinopI { op=add, lhs=v814, rhs_imm=848 } -> [spill 42] + v922 Imm(864) -> [spill 43] + v923 BinopI { op=add, lhs=v814, rhs_imm=864 } -> [spill 43] + v924 Imm(880) -> [spill 44] + v925 BinopI { op=add, lhs=v814, rhs_imm=880 } -> [spill 44] + v926 Imm(896) -> [spill 45] + v927 BinopI { op=add, lhs=v814, rhs_imm=896 } -> [spill 45] + v928 Imm(912) -> [spill 46] + v929 BinopI { op=add, lhs=v814, rhs_imm=912 } -> [spill 46] + v930 Imm(928) -> [spill 47] + v931 BinopI { op=add, lhs=v814, rhs_imm=928 } -> [spill 47] + v932 Imm(944) -> [spill 48] + v933 BinopI { op=add, lhs=v814, rhs_imm=944 } -> [spill 48] + v934 Imm(960) -> [spill 49] + v935 BinopI { op=add, lhs=v814, rhs_imm=960 } -> [spill 49] + v936 Imm(976) -> [spill 50] + v937 BinopI { op=add, lhs=v814, rhs_imm=976 } -> [spill 50] + v938 Imm(992) -> [spill 51] + v939 BinopI { op=add, lhs=v814, rhs_imm=992 } -> [spill 51] + v940 Imm(1008) -> [spill 52] + v941 BinopI { op=add, lhs=v814, rhs_imm=1008 } -> [spill 52] + v942 Imm(1024) -> [spill 53] + v943 BinopI { op=add, lhs=v814, rhs_imm=1024 } -> [spill 53] + v944 Imm(1040) -> [spill 54] + v945 BinopI { op=add, lhs=v814, rhs_imm=1040 } -> [spill 54] + v946 Imm(1056) -> [spill 55] + v947 BinopI { op=add, lhs=v814, rhs_imm=1056 } -> [spill 55] + v948 Imm(1072) -> [spill 56] + v949 BinopI { op=add, lhs=v814, rhs_imm=1072 } -> [spill 56] + v950 Imm(1088) -> [spill 57] + v951 BinopI { op=add, lhs=v814, rhs_imm=1088 } -> [spill 57] + v952 Imm(1104) -> [spill 58] + v953 BinopI { op=add, lhs=v814, rhs_imm=1104 } -> [spill 58] + v954 Imm(1120) -> [spill 59] + v955 BinopI { op=add, lhs=v814, rhs_imm=1120 } -> [spill 59] + v956 Imm(1136) -> [spill 60] + v957 BinopI { op=add, lhs=v814, rhs_imm=1136 } -> [spill 60] + v958 Imm(1152) -> [spill 61] + v959 BinopI { op=add, lhs=v814, rhs_imm=1152 } -> [spill 61] + v960 Imm(1168) -> [spill 62] + v961 BinopI { op=add, lhs=v814, rhs_imm=1168 } -> [spill 62] + v962 Imm(1184) -> [spill 63] + v963 BinopI { op=add, lhs=v814, rhs_imm=1184 } -> [spill 63] + v964 Imm(1200) -> [spill 64] + v965 BinopI { op=add, lhs=v814, rhs_imm=1200 } -> [spill 64] + v966 Imm(1216) -> [spill 65] + v967 BinopI { op=add, lhs=v814, rhs_imm=1216 } -> [spill 65] + v968 Imm(1232) -> [spill 66] + v969 BinopI { op=add, lhs=v814, rhs_imm=1232 } -> [spill 66] + v970 Imm(1248) -> [spill 67] + v971 BinopI { op=add, lhs=v814, rhs_imm=1248 } -> [spill 67] + v972 Imm(1264) -> [spill 68] + v973 BinopI { op=add, lhs=v814, rhs_imm=1264 } -> [spill 68] + v974 Imm(1280) -> [spill 69] + v975 BinopI { op=add, lhs=v814, rhs_imm=1280 } -> [spill 69] + v976 Imm(1296) -> [spill 70] + v977 BinopI { op=add, lhs=v814, rhs_imm=1296 } -> [spill 70] + v978 Imm(1312) -> [spill 71] + v979 BinopI { op=add, lhs=v814, rhs_imm=1312 } -> [spill 71] + v980 Imm(1328) -> [spill 72] + v981 BinopI { op=add, lhs=v814, rhs_imm=1328 } -> [spill 72] + v982 Imm(1344) -> [spill 73] + v983 BinopI { op=add, lhs=v814, rhs_imm=1344 } -> [spill 73] + v984 Imm(1360) -> [spill 74] + v985 BinopI { op=add, lhs=v814, rhs_imm=1360 } -> [spill 74] + v986 Imm(1376) -> [spill 75] + v987 BinopI { op=add, lhs=v814, rhs_imm=1376 } -> [spill 75] + v988 Imm(1392) -> [spill 76] + v989 BinopI { op=add, lhs=v814, rhs_imm=1392 } -> [spill 76] + v990 Imm(1408) -> [spill 77] + v991 BinopI { op=add, lhs=v814, rhs_imm=1408 } -> [spill 77] + v992 Imm(1424) -> [spill 78] + v993 BinopI { op=add, lhs=v814, rhs_imm=1424 } -> [spill 78] + v994 Imm(1440) -> [spill 79] + v995 BinopI { op=add, lhs=v814, rhs_imm=1440 } -> [spill 79] + v996 Imm(1456) -> [spill 80] + v997 BinopI { op=add, lhs=v814, rhs_imm=1456 } -> [spill 80] + v998 Imm(1472) -> [spill 81] + v999 BinopI { op=add, lhs=v814, rhs_imm=1472 } -> [spill 81] + v1000 Imm(1488) -> [spill 82] + v1001 BinopI { op=add, lhs=v814, rhs_imm=1488 } -> [spill 82] + v1002 Imm(1504) -> [spill 83] + v1003 BinopI { op=add, lhs=v814, rhs_imm=1504 } -> [spill 83] + v1004 Imm(1520) -> [spill 84] + v1005 BinopI { op=add, lhs=v814, rhs_imm=1520 } -> [spill 84] + v1006 Imm(1536) -> [spill 85] + v1007 BinopI { op=add, lhs=v814, rhs_imm=1536 } -> [spill 85] + v1008 Imm(1552) -> [spill 86] + v1009 BinopI { op=add, lhs=v814, rhs_imm=1552 } -> [spill 86] + v1010 Imm(1568) -> [spill 87] + v1011 BinopI { op=add, lhs=v814, rhs_imm=1568 } -> [spill 87] + v1012 Imm(1584) -> [spill 88] + v1013 BinopI { op=add, lhs=v814, rhs_imm=1584 } -> [spill 88] + v1014 Imm(1600) -> [spill 89] + v1015 BinopI { op=add, lhs=v814, rhs_imm=1600 } -> [spill 89] + v1016 Imm(1616) -> [spill 90] + v1017 BinopI { op=add, lhs=v814, rhs_imm=1616 } -> [spill 90] + v1018 Imm(1632) -> [spill 91] + v1019 BinopI { op=add, lhs=v814, rhs_imm=1632 } -> [spill 91] + v1020 Imm(1648) -> [spill 92] + v1021 BinopI { op=add, lhs=v814, rhs_imm=1648 } -> [spill 92] + v1022 Imm(1664) -> [spill 93] + v1023 BinopI { op=add, lhs=v814, rhs_imm=1664 } -> [spill 93] + v1024 Imm(1680) -> [spill 94] + v1025 BinopI { op=add, lhs=v814, rhs_imm=1680 } -> [spill 94] + v1026 Imm(1696) -> [spill 95] + v1027 BinopI { op=add, lhs=v814, rhs_imm=1696 } -> [spill 95] + v1028 Imm(1712) -> [spill 96] + v1029 BinopI { op=add, lhs=v814, rhs_imm=1712 } -> [spill 96] + v1030 Imm(1728) -> [spill 97] + v1031 BinopI { op=add, lhs=v814, rhs_imm=1728 } -> [spill 97] + v1032 Imm(1744) -> [spill 98] + v1033 BinopI { op=add, lhs=v814, rhs_imm=1744 } -> [spill 98] + v1034 Imm(1760) -> [spill 99] + v1035 BinopI { op=add, lhs=v814, rhs_imm=1760 } -> [spill 99] + v1036 Imm(1776) -> [spill 100] + v1037 BinopI { op=add, lhs=v814, rhs_imm=1776 } -> [spill 100] + v1038 Imm(1792) -> [spill 101] + v1039 BinopI { op=add, lhs=v814, rhs_imm=1792 } -> [spill 101] + v1040 Imm(1808) -> [spill 102] + v1041 BinopI { op=add, lhs=v814, rhs_imm=1808 } -> [spill 102] + v1042 Imm(1824) -> [spill 103] + v1043 BinopI { op=add, lhs=v814, rhs_imm=1824 } -> [spill 103] + v1044 Imm(1840) -> [spill 104] + v1045 BinopI { op=add, lhs=v814, rhs_imm=1840 } -> [spill 104] + v1046 Imm(1856) -> [spill 105] + v1047 BinopI { op=add, lhs=v814, rhs_imm=1856 } -> [spill 105] + v1048 Imm(1872) -> [spill 106] + v1049 BinopI { op=add, lhs=v814, rhs_imm=1872 } -> [spill 106] + v1050 Imm(1888) -> [spill 107] + v1051 BinopI { op=add, lhs=v814, rhs_imm=1888 } -> [spill 107] + v1052 Imm(1904) -> [spill 108] + v1053 BinopI { op=add, lhs=v814, rhs_imm=1904 } -> [spill 108] + v1054 Imm(1920) -> [spill 109] + v1055 BinopI { op=add, lhs=v814, rhs_imm=1920 } -> [spill 109] + v1056 Imm(1936) -> [spill 110] + v1057 BinopI { op=add, lhs=v814, rhs_imm=1936 } -> [spill 110] + v1058 Imm(1952) -> [spill 111] + v1059 BinopI { op=add, lhs=v814, rhs_imm=1952 } -> [spill 111] + v1060 Imm(1968) -> [spill 112] + v1061 BinopI { op=add, lhs=v814, rhs_imm=1968 } -> [spill 112] + v1062 Imm(1984) -> [spill 113] + v1063 BinopI { op=add, lhs=v814, rhs_imm=1984 } -> [spill 113] + v1064 Imm(2000) -> [spill 114] + v1065 BinopI { op=add, lhs=v814, rhs_imm=2000 } -> [spill 114] + v1066 Imm(2016) -> [spill 115] + v1067 BinopI { op=add, lhs=v814, rhs_imm=2016 } -> [spill 115] + v1068 Imm(2032) -> [spill 116] + v1069 BinopI { op=add, lhs=v814, rhs_imm=2032 } -> [spill 116] + v1070 Imm(2048) -> [spill 117] + v1071 BinopI { op=add, lhs=v814, rhs_imm=2048 } -> [spill 117] + v1072 Imm(2064) -> [spill 118] + v1073 BinopI { op=add, lhs=v814, rhs_imm=2064 } -> [spill 118] + v1074 Imm(2080) -> [spill 119] + v1075 BinopI { op=add, lhs=v814, rhs_imm=2080 } -> [spill 119] + v1076 Imm(2096) -> [spill 120] + v1077 BinopI { op=add, lhs=v814, rhs_imm=2096 } -> [spill 120] + v1078 Imm(2112) -> [spill 121] + v1079 BinopI { op=add, lhs=v814, rhs_imm=2112 } -> [spill 121] + v1080 Imm(2128) -> [spill 122] + v1081 BinopI { op=add, lhs=v814, rhs_imm=2128 } -> [spill 122] + v1082 Imm(2144) -> [spill 123] + v1083 BinopI { op=add, lhs=v814, rhs_imm=2144 } -> [spill 123] + v1084 Imm(2160) -> [spill 124] + v1085 BinopI { op=add, lhs=v814, rhs_imm=2160 } -> [spill 124] + v1086 Imm(2176) -> [spill 125] + v1087 BinopI { op=add, lhs=v814, rhs_imm=2176 } -> [spill 125] + v1088 Imm(2192) -> [spill 126] + v1089 BinopI { op=add, lhs=v814, rhs_imm=2192 } -> [spill 126] + v1090 Imm(2208) -> [spill 127] + v1091 BinopI { op=add, lhs=v814, rhs_imm=2208 } -> [spill 127] + v1092 Imm(2224) -> [spill 128] + v1093 BinopI { op=add, lhs=v814, rhs_imm=2224 } -> [spill 128] + v1094 Imm(2240) -> [spill 129] + v1095 BinopI { op=add, lhs=v814, rhs_imm=2240 } -> [spill 129] + v1096 Imm(2256) -> [spill 130] + v1097 BinopI { op=add, lhs=v814, rhs_imm=2256 } -> [spill 130] + v1098 Imm(2272) -> [spill 131] + v1099 BinopI { op=add, lhs=v814, rhs_imm=2272 } -> [spill 131] + v1100 Imm(2288) -> [spill 132] + v1101 BinopI { op=add, lhs=v814, rhs_imm=2288 } -> [spill 132] + v1102 Imm(2304) -> [spill 133] + v1103 BinopI { op=add, lhs=v814, rhs_imm=2304 } -> [spill 133] + v1104 Imm(2320) -> [spill 134] + v1105 BinopI { op=add, lhs=v814, rhs_imm=2320 } -> [spill 134] + v1106 Imm(2336) -> [spill 135] + v1107 BinopI { op=add, lhs=v814, rhs_imm=2336 } -> [spill 135] + v1108 Imm(2352) -> [spill 136] + v1109 BinopI { op=add, lhs=v814, rhs_imm=2352 } -> [spill 136] + v1110 Imm(2368) -> [spill 137] + v1111 BinopI { op=add, lhs=v814, rhs_imm=2368 } -> [spill 137] + v1112 Imm(2384) -> [spill 138] + v1113 BinopI { op=add, lhs=v814, rhs_imm=2384 } -> [spill 138] + v1114 Imm(2400) -> [spill 139] + v1115 BinopI { op=add, lhs=v814, rhs_imm=2400 } -> [spill 139] + v1116 Imm(2416) -> [spill 140] + v1117 BinopI { op=add, lhs=v814, rhs_imm=2416 } -> [spill 140] + v1118 Imm(2432) -> [spill 141] + v1119 BinopI { op=add, lhs=v814, rhs_imm=2432 } -> [spill 141] + v1120 Imm(2448) -> [spill 142] + v1121 BinopI { op=add, lhs=v814, rhs_imm=2448 } -> [spill 142] + v1122 Imm(2464) -> [spill 143] + v1123 BinopI { op=add, lhs=v814, rhs_imm=2464 } -> [spill 143] + v1124 Imm(2480) -> [spill 144] + v1125 BinopI { op=add, lhs=v814, rhs_imm=2480 } -> [spill 144] + v1126 Imm(2496) -> [spill 145] + v1127 BinopI { op=add, lhs=v814, rhs_imm=2496 } -> [spill 145] + v1128 Imm(2512) -> [spill 146] + v1129 BinopI { op=add, lhs=v814, rhs_imm=2512 } -> [spill 146] + v1130 Imm(2528) -> [spill 147] + v1131 BinopI { op=add, lhs=v814, rhs_imm=2528 } -> [spill 147] + v1132 Imm(2544) -> [spill 148] + v1133 BinopI { op=add, lhs=v814, rhs_imm=2544 } -> [spill 148] + v1134 Imm(2560) -> [spill 149] + v1135 BinopI { op=add, lhs=v814, rhs_imm=2560 } -> [spill 149] + v1136 Imm(2576) -> [spill 150] + v1137 BinopI { op=add, lhs=v814, rhs_imm=2576 } -> [spill 150] + v1138 Imm(2592) -> [spill 151] + v1139 BinopI { op=add, lhs=v814, rhs_imm=2592 } -> [spill 151] + v1140 Imm(2608) -> [spill 152] + v1141 BinopI { op=add, lhs=v814, rhs_imm=2608 } -> [spill 152] + v1142 Imm(2624) -> [spill 153] + v1143 BinopI { op=add, lhs=v814, rhs_imm=2624 } -> [spill 153] + v1144 Imm(2640) -> [spill 154] + v1145 BinopI { op=add, lhs=v814, rhs_imm=2640 } -> [spill 154] + v1146 Imm(2656) -> [spill 155] + v1147 BinopI { op=add, lhs=v814, rhs_imm=2656 } -> [spill 155] + v1148 Imm(2672) -> [spill 156] + v1149 BinopI { op=add, lhs=v814, rhs_imm=2672 } -> [spill 156] + v1150 Imm(2688) -> [spill 157] + v1151 BinopI { op=add, lhs=v814, rhs_imm=2688 } -> [spill 157] + v1152 Imm(2704) -> [spill 158] + v1153 BinopI { op=add, lhs=v814, rhs_imm=2704 } -> [spill 158] + v1154 Imm(2720) -> [spill 159] + v1155 BinopI { op=add, lhs=v814, rhs_imm=2720 } -> [spill 159] + v1156 Imm(2736) -> [spill 160] + v1157 BinopI { op=add, lhs=v814, rhs_imm=2736 } -> [spill 160] + v1158 Imm(2752) -> [spill 161] + v1159 BinopI { op=add, lhs=v814, rhs_imm=2752 } -> [spill 161] + v1160 Imm(2768) -> [spill 162] + v1161 BinopI { op=add, lhs=v814, rhs_imm=2768 } -> [spill 162] + v1162 Imm(2784) -> [spill 163] + v1163 BinopI { op=add, lhs=v814, rhs_imm=2784 } -> [spill 163] + v1164 Imm(2800) -> [spill 164] + v1165 BinopI { op=add, lhs=v814, rhs_imm=2800 } -> [spill 164] + v1166 Imm(2816) -> [spill 165] + v1167 BinopI { op=add, lhs=v814, rhs_imm=2816 } -> [spill 165] + v1168 Imm(2832) -> [spill 166] + v1169 BinopI { op=add, lhs=v814, rhs_imm=2832 } -> [spill 166] + v1170 Imm(2848) -> [spill 167] + v1171 BinopI { op=add, lhs=v814, rhs_imm=2848 } -> [spill 167] + v1172 Imm(2864) -> [spill 168] + v1173 BinopI { op=add, lhs=v814, rhs_imm=2864 } -> [spill 168] + v1174 Imm(2880) -> [spill 169] + v1175 BinopI { op=add, lhs=v814, rhs_imm=2880 } -> [spill 169] + v1176 Imm(2896) -> [spill 170] + v1177 BinopI { op=add, lhs=v814, rhs_imm=2896 } -> [spill 170] + v1178 Imm(2912) -> [spill 171] + v1179 BinopI { op=add, lhs=v814, rhs_imm=2912 } -> [spill 171] + v1180 Imm(2928) -> [spill 172] + v1181 BinopI { op=add, lhs=v814, rhs_imm=2928 } -> [spill 172] + v1182 Imm(2944) -> [spill 173] + v1183 BinopI { op=add, lhs=v814, rhs_imm=2944 } -> [spill 173] + v1184 Imm(2960) -> [spill 174] + v1185 BinopI { op=add, lhs=v814, rhs_imm=2960 } -> [spill 174] + v1186 Imm(2976) -> [spill 175] + v1187 BinopI { op=add, lhs=v814, rhs_imm=2976 } -> [spill 175] + v1188 Imm(2992) -> [spill 176] + v1189 BinopI { op=add, lhs=v814, rhs_imm=2992 } -> [spill 176] + v1190 Imm(3008) -> [spill 177] + v1191 BinopI { op=add, lhs=v814, rhs_imm=3008 } -> [spill 177] + v1192 Imm(3024) -> [spill 178] + v1193 BinopI { op=add, lhs=v814, rhs_imm=3024 } -> [spill 178] + v1194 Imm(3040) -> [spill 179] + v1195 BinopI { op=add, lhs=v814, rhs_imm=3040 } -> [spill 179] + v1196 Imm(3056) -> [spill 180] + v1197 BinopI { op=add, lhs=v814, rhs_imm=3056 } -> [spill 180] + v1198 Imm(3072) -> [spill 181] + v1199 BinopI { op=add, lhs=v814, rhs_imm=3072 } -> [spill 181] + v1200 Imm(3088) -> [spill 182] + v1201 BinopI { op=add, lhs=v814, rhs_imm=3088 } -> [spill 182] + v1202 Imm(3104) -> [spill 183] + v1203 BinopI { op=add, lhs=v814, rhs_imm=3104 } -> [spill 183] + v1204 Imm(3120) -> [spill 184] + v1205 BinopI { op=add, lhs=v814, rhs_imm=3120 } -> [spill 184] + v1206 Imm(3136) -> [spill 185] + v1207 BinopI { op=add, lhs=v814, rhs_imm=3136 } -> [spill 185] + v1208 Imm(3152) -> [spill 186] + v1209 BinopI { op=add, lhs=v814, rhs_imm=3152 } -> [spill 186] + v1210 Imm(3168) -> [spill 187] + v1211 BinopI { op=add, lhs=v814, rhs_imm=3168 } -> [spill 187] + v1212 Imm(3184) -> [spill 188] + v1213 BinopI { op=add, lhs=v814, rhs_imm=3184 } -> [spill 188] + v1214 Imm(3200) -> [spill 189] + v1215 BinopI { op=add, lhs=v814, rhs_imm=3200 } -> [spill 189] + v1216 Imm(3216) -> [spill 190] + v1217 BinopI { op=add, lhs=v814, rhs_imm=3216 } -> [spill 190] + v1218 Imm(3232) -> [spill 191] + v1219 BinopI { op=add, lhs=v814, rhs_imm=3232 } -> [spill 191] + v1220 Imm(3248) -> [spill 192] + v1221 BinopI { op=add, lhs=v814, rhs_imm=3248 } -> [spill 192] + v1222 Imm(3264) -> [spill 193] + v1223 BinopI { op=add, lhs=v814, rhs_imm=3264 } -> [spill 193] + v1224 Imm(3280) -> [spill 194] + v1225 BinopI { op=add, lhs=v814, rhs_imm=3280 } -> [spill 194] + v1226 Imm(3296) -> [spill 195] + v1227 BinopI { op=add, lhs=v814, rhs_imm=3296 } -> [spill 195] + v1228 Imm(3312) -> [spill 196] + v1229 BinopI { op=add, lhs=v814, rhs_imm=3312 } -> [spill 196] + v1230 Imm(3328) -> [spill 197] + v1231 BinopI { op=add, lhs=v814, rhs_imm=3328 } -> [spill 197] + v1232 Imm(3344) -> [spill 198] + v1233 BinopI { op=add, lhs=v814, rhs_imm=3344 } -> [spill 198] + v1234 Imm(3360) -> [spill 199] + v1235 BinopI { op=add, lhs=v814, rhs_imm=3360 } -> [spill 199] + v1236 Imm(3376) -> [spill 200] + v1237 BinopI { op=add, lhs=v814, rhs_imm=3376 } -> [spill 200] + v1238 Imm(3392) -> [spill 201] + v1239 BinopI { op=add, lhs=v814, rhs_imm=3392 } -> [spill 201] + v1240 Imm(3408) -> [spill 202] + v1241 BinopI { op=add, lhs=v814, rhs_imm=3408 } -> [spill 202] + v1242 Imm(3424) -> [spill 203] + v1243 BinopI { op=add, lhs=v814, rhs_imm=3424 } -> [spill 203] + v1244 Imm(3440) -> [spill 204] + v1245 BinopI { op=add, lhs=v814, rhs_imm=3440 } -> [spill 204] + v1246 Imm(3456) -> [spill 205] + v1247 BinopI { op=add, lhs=v814, rhs_imm=3456 } -> [spill 205] + v1248 Imm(3472) -> [spill 206] + v1249 BinopI { op=add, lhs=v814, rhs_imm=3472 } -> [spill 206] + v1250 Imm(3488) -> [spill 207] + v1251 BinopI { op=add, lhs=v814, rhs_imm=3488 } -> [spill 207] + v1252 Imm(3504) -> [spill 208] + v1253 BinopI { op=add, lhs=v814, rhs_imm=3504 } -> [spill 208] + v1254 Imm(3520) -> [spill 209] + v1255 BinopI { op=add, lhs=v814, rhs_imm=3520 } -> [spill 209] + v1256 Imm(3536) -> [spill 210] + v1257 BinopI { op=add, lhs=v814, rhs_imm=3536 } -> [spill 210] + v1258 Imm(3552) -> [spill 211] + v1259 BinopI { op=add, lhs=v814, rhs_imm=3552 } -> [spill 211] + v1260 Imm(3568) -> [spill 212] + v1261 BinopI { op=add, lhs=v814, rhs_imm=3568 } -> [spill 212] + v1262 Imm(3584) -> [spill 213] + v1263 BinopI { op=add, lhs=v814, rhs_imm=3584 } -> [spill 213] + v1264 Imm(3600) -> [spill 214] + v1265 BinopI { op=add, lhs=v814, rhs_imm=3600 } -> [spill 214] + v1266 Imm(3616) -> [spill 215] + v1267 BinopI { op=add, lhs=v814, rhs_imm=3616 } -> [spill 215] + v1268 Imm(3632) -> [spill 216] + v1269 BinopI { op=add, lhs=v814, rhs_imm=3632 } -> [spill 216] + v1270 Imm(3648) -> [spill 217] + v1271 BinopI { op=add, lhs=v814, rhs_imm=3648 } -> [spill 217] + v1272 Imm(3664) -> [spill 218] + v1273 BinopI { op=add, lhs=v814, rhs_imm=3664 } -> [spill 218] + v1274 Imm(3680) -> [spill 219] + v1275 BinopI { op=add, lhs=v814, rhs_imm=3680 } -> [spill 219] + v1276 Imm(3696) -> [spill 220] + v1277 BinopI { op=add, lhs=v814, rhs_imm=3696 } -> [spill 220] + v1278 Imm(3712) -> [spill 221] + v1279 BinopI { op=add, lhs=v814, rhs_imm=3712 } -> [spill 221] + v1280 Imm(3728) -> [spill 222] + v1281 BinopI { op=add, lhs=v814, rhs_imm=3728 } -> [spill 222] + v1282 Imm(3744) -> [spill 223] + v1283 BinopI { op=add, lhs=v814, rhs_imm=3744 } -> [spill 223] + v1284 Imm(3760) -> [spill 224] + v1285 BinopI { op=add, lhs=v814, rhs_imm=3760 } -> [spill 224] + v1286 Imm(3776) -> [spill 225] + v1287 BinopI { op=add, lhs=v814, rhs_imm=3776 } -> [spill 225] + v1288 Imm(3792) -> [spill 226] + v1289 BinopI { op=add, lhs=v814, rhs_imm=3792 } -> [spill 226] + v1290 Imm(3808) -> [spill 227] + v1291 BinopI { op=add, lhs=v814, rhs_imm=3808 } -> [spill 227] + v1292 Imm(3824) -> [spill 228] + v1293 BinopI { op=add, lhs=v814, rhs_imm=3824 } -> [spill 228] + v1294 Imm(3840) -> [spill 229] + v1295 BinopI { op=add, lhs=v814, rhs_imm=3840 } -> [spill 229] + v1296 Imm(3856) -> [spill 230] + v1297 BinopI { op=add, lhs=v814, rhs_imm=3856 } -> [spill 230] + v1298 Imm(3872) -> [spill 231] + v1299 BinopI { op=add, lhs=v814, rhs_imm=3872 } -> [spill 231] + v1300 Imm(3888) -> [spill 232] + v1301 BinopI { op=add, lhs=v814, rhs_imm=3888 } -> [spill 232] + v1302 Imm(3904) -> [spill 233] + v1303 BinopI { op=add, lhs=v814, rhs_imm=3904 } -> [spill 233] + v1304 Imm(3920) -> [spill 234] + v1305 BinopI { op=add, lhs=v814, rhs_imm=3920 } -> [spill 234] + v1306 Imm(3936) -> [spill 235] + v1307 BinopI { op=add, lhs=v814, rhs_imm=3936 } -> [spill 235] + v1308 Imm(3952) -> [spill 236] + v1309 BinopI { op=add, lhs=v814, rhs_imm=3952 } -> [spill 236] + v1310 Imm(3968) -> [spill 237] + v1311 BinopI { op=add, lhs=v814, rhs_imm=3968 } -> [spill 237] + v1312 Imm(3984) -> [spill 238] + v1313 BinopI { op=add, lhs=v814, rhs_imm=3984 } -> [spill 238] + v1314 Imm(4000) -> [spill 239] + v1315 BinopI { op=add, lhs=v814, rhs_imm=4000 } -> [spill 239] + v1316 Imm(4016) -> [spill 240] + v1317 BinopI { op=add, lhs=v814, rhs_imm=4016 } -> [spill 240] + v1318 Imm(4032) -> [spill 241] + v1319 BinopI { op=add, lhs=v814, rhs_imm=4032 } -> [spill 241] + v1320 Imm(4048) -> [spill 242] + v1321 BinopI { op=add, lhs=v814, rhs_imm=4048 } -> [spill 242] + v1322 Imm(4064) -> [spill 243] + v1323 BinopI { op=add, lhs=v814, rhs_imm=4064 } -> [spill 243] + v1324 Imm(4080) -> [spill 244] + v1325 BinopI { op=add, lhs=v814, rhs_imm=4080 } -> [spill 244] + v1326 Imm(4096) -> [spill 245] + v1327 BinopI { op=add, lhs=v814, rhs_imm=4096 } -> [spill 245] + v1328 Imm(4112) -> [spill 246] + v1329 BinopI { op=add, lhs=v814, rhs_imm=4112 } -> [spill 246] + v1330 Imm(4128) -> [spill 247] + v1331 BinopI { op=add, lhs=v814, rhs_imm=4128 } -> [spill 247] + v1332 Imm(4144) -> [spill 248] + v1333 BinopI { op=add, lhs=v814, rhs_imm=4144 } -> [spill 248] + v1334 Imm(4160) -> [spill 249] + v1335 BinopI { op=add, lhs=v814, rhs_imm=4160 } -> [spill 249] + v1336 LoadLocal { off=-2, kind=I64 } -> [spill 250] + v1337 CallIndirect { target=v3, args=[v814, v817, v819, v821, v823, v825, v827, v829, v831, v833, v835, v837, v839, v841, v843, v845, v847, v849, v851, v853, v855, v857, v859, v861, v863, v865, v867, v869, v871, v873, v875, v877, v879, v881, v883, v885, v887, v889, v891, v893, v895, v897, v899, v901, v903, v905, v907, v909, v911, v913, v915, v917, v919, v921, v923, v925, v927, v929, v931, v933, v935, v937, v939, v941, v943, v945, v947, v949, v951, v953, v955, v957, v959, v961, v963, v965, v967, v969, v971, v973, v975, v977, v979, v981, v983, v985, v987, v989, v991, v993, v995, v997, v999, v1001, v1003, v1005, v1007, v1009, v1011, v1013, v1015, v1017, v1019, v1021, v1023, v1025, v1027, v1029, v1031, v1033, v1035, v1037, v1039, v1041, v1043, v1045, v1047, v1049, v1051, v1053, v1055, v1057, v1059, v1061, v1063, v1065, v1067, v1069, v1071, v1073, v1075, v1077, v1079, v1081, v1083, v1085, v1087, v1089, v1091, v1093, v1095, v1097, v1099, v1101, v1103, v1105, v1107, v1109, v1111, v1113, v1115, v1117, v1119, v1121, v1123, v1125, v1127, v1129, v1131, v1133, v1135, v1137, v1139, v1141, v1143, v1145, v1147, v1149, v1151, v1153, v1155, v1157, v1159, v1161, v1163, v1165, v1167, v1169, v1171, v1173, v1175, v1177, v1179, v1181, v1183, v1185, v1187, v1189, v1191, v1193, v1195, v1197, v1199, v1201, v1203, v1205, v1207, v1209, v1211, v1213, v1215, v1217, v1219, v1221, v1223, v1225, v1227, v1229, v1231, v1233, v1235, v1237, v1239, v1241, v1243, v1245, v1247, v1249, v1251, v1253, v1255, v1257, v1259, v1261, v1263, v1265, v1267, v1269, v1271, v1273, v1275, v1277, v1279, v1281, v1283, v1285, v1287, v1289, v1291, v1293, v1295, v1297, v1299, v1301, v1303, v1305, v1307, v1309, v1311, v1313, v1315, v1317, v1319, v1321, v1323, v1325, v1327, v1329, v1331, v1333, v1335], callee_variadic=false, fixed_args=261, fp_return=false, fp_arg_mask=0x0 } -> x0 + v1338 BinopI { op=ne, lhs=v1337, rhs_imm=101790 } -> x0 + terminator Bz { cond=v1338, target=b10, fall=b9 } (exit_acc=v1338) + block 9 start_pc=0 + v1339 Imm(3) -> x0 + terminator Return(v1339) (exit_acc=v1339) + block 10 start_pc=0 + v1340 Imm(0) -> x0 + terminator Return(v1340) (exit_acc=v1340) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/clock_monotonic_advances.ssa b/tests/snapshots/ssa/clock_monotonic_advances.ssa index dec8ae196..0a14025a6 100644 --- a/tests/snapshots/ssa/clock_monotonic_advances.ssa +++ b/tests/snapshots/ssa/clock_monotonic_advances.ssa @@ -69,74 +69,73 @@ fn ent_pc=5 n_params=0 variadic=false locals=11 terminator Return(v40) (exit_acc=v40) block 12 start_pc=0 v41 Imm(0) -> x1 - v42 Imm(0) -> x0 + v42 StoreLocal { off=-5, value=v41, kind=I32, volatile } -> - v43 Imm(0) -> x0 terminator Jmp(b13) (exit_acc=v41) block 13 start_pc=0 - v44 Phi { incoming=[b12:v41, b14:v49], kind=I64 } -> x1 - v45 Phi { incoming=[b12:v41, b14:v54], kind=I64 } -> x0 - v46 Extend { value=v44, kind=I32 } -> x2 - v47 BinopI { op=lt, lhs=v46, rhs_imm=1000000 } -> x2 - terminator Bz { cond=v47, target=b16, fall=b15 } (exit_acc=v47) + v44 Phi { incoming=[b12:v41, b14:v48], kind=I64 } -> x1 + v45 Extend { value=v44, kind=I32 } -> x0 + v46 BinopI { op=lt, lhs=v45, rhs_imm=1000000 } -> x0 + terminator Bz { cond=v46, target=b16, fall=b15 } (exit_acc=v46) block 14 start_pc=0 - v48 Extend { value=v44, kind=I32 } -> x1 - v49 BinopI { op=add, lhs=v48, rhs_imm=1 } -> x1 - v50 Imm(0) -> x2 - terminator Jmp(b13) (exit_acc=v49) + v47 Extend { value=v44, kind=I32 } -> x0 + v48 BinopI { op=add, lhs=v47, rhs_imm=1 } -> x1 + v49 Imm(0) -> x0 + terminator Jmp(b13) (exit_acc=v48) block 15 start_pc=0 - v51 Extend { value=v45, kind=I32 } -> x2 - v52 BinopI { op=add, lhs=v45, rhs_imm=1 } -> x0 - v53 BinopI { op=shl, lhs=v52, rhs_imm=32 } -> x2 - v54 Extend { value=v52, kind=I32 } -> x0 - v55 Imm(0) -> x2 + v50 LoadLocal { off=-5, kind=I32, volatile } -> x0 + v51 BinopI { op=add, lhs=v50, rhs_imm=1 } -> x0 + v52 BinopI { op=shl, lhs=v51, rhs_imm=32 } -> x2 + v53 Extend { value=v51, kind=I32 } -> x2 + v54 StoreLocal { off=-5, value=v51, kind=I32, volatile } -> - terminator Jmp(b14) (exit_acc=v54) block 16 start_pc=0 - v56 Imm(1) -> x7 - v57 LocalAddr(-4) -> x6 - v58 CallExt { binding_idx=2, args=[v56, v57], fp_arg_mask=0x0 } -> x0 - v59 BinopI { op=ne, lhs=v58, rhs_imm=0 } -> x0 - terminator Bz { cond=v59, target=b18, fall=b17 } (exit_acc=v59) + v55 Imm(1) -> x7 + v56 LocalAddr(-4) -> x6 + v57 CallExt { binding_idx=2, args=[v55, v56], fp_arg_mask=0x0 } -> x0 + v58 BinopI { op=ne, lhs=v57, rhs_imm=0 } -> x0 + terminator Bz { cond=v58, target=b18, fall=b17 } (exit_acc=v58) block 17 start_pc=0 - v60 Imm(5) -> x0 - terminator Return(v60) (exit_acc=v60) + v59 Imm(5) -> x0 + terminator Return(v59) (exit_acc=v59) block 18 start_pc=0 - v61 LocalAddr(-4) -> x0 - v62 Load { addr=v61, disp=0, kind=I64 } -> x0 - v63 LocalAddr(-2) -> x1 - v64 Load { addr=v63, disp=0, kind=I64 } -> x1 - v65 Binop { op=lt, lhs=v62, rhs=v64 } -> x0 - terminator Bz { cond=v65, target=b20, fall=b19 } (exit_acc=v65) + v60 LocalAddr(-4) -> x0 + v61 Load { addr=v60, disp=0, kind=I64 } -> x0 + v62 LocalAddr(-2) -> x1 + v63 Load { addr=v62, disp=0, kind=I64 } -> x1 + v64 Binop { op=lt, lhs=v61, rhs=v63 } -> x0 + terminator Bz { cond=v64, target=b20, fall=b19 } (exit_acc=v64) block 19 start_pc=0 - v66 Imm(6) -> x0 - terminator Return(v66) (exit_acc=v66) + v65 Imm(6) -> x0 + terminator Return(v65) (exit_acc=v65) block 20 start_pc=0 - v67 LocalAddr(-4) -> x0 - v68 Load { addr=v67, disp=0, kind=I64 } -> x0 - v69 LocalAddr(-2) -> x1 - v70 Load { addr=v69, disp=0, kind=I64 } -> x1 - v71 Binop { op=eq, lhs=v68, rhs=v70 } -> x1 - v72 Imm(0) -> x0 - terminator Bz { cond=v71, target=b27, fall=b21 } (exit_acc=v71) + v66 LocalAddr(-4) -> x0 + v67 Load { addr=v66, disp=0, kind=I64 } -> x0 + v68 LocalAddr(-2) -> x1 + v69 Load { addr=v68, disp=0, kind=I64 } -> x1 + v70 Binop { op=eq, lhs=v67, rhs=v69 } -> x1 + v71 Imm(0) -> x0 + terminator Bz { cond=v70, target=b27, fall=b21 } (exit_acc=v70) block 21 start_pc=0 - v73 LocalAddr(-4) -> x0 - v74 BinopI { op=add, lhs=v73, rhs_imm=8 } -> x1 - v75 Load { addr=v73, disp=8, kind=I64 } -> x0 - v76 LocalAddr(-2) -> x1 - v77 BinopI { op=add, lhs=v76, rhs_imm=8 } -> x2 - v78 Load { addr=v76, disp=8, kind=I64 } -> x1 - v79 Binop { op=lt, lhs=v75, rhs=v78 } -> x1 - v80 Imm(0) -> x0 - terminator Jmp(b22) (exit_acc=v79) + v72 LocalAddr(-4) -> x0 + v73 BinopI { op=add, lhs=v72, rhs_imm=8 } -> x1 + v74 Load { addr=v72, disp=8, kind=I64 } -> x0 + v75 LocalAddr(-2) -> x1 + v76 BinopI { op=add, lhs=v75, rhs_imm=8 } -> x2 + v77 Load { addr=v75, disp=8, kind=I64 } -> x1 + v78 Binop { op=lt, lhs=v74, rhs=v77 } -> x1 + v79 Imm(0) -> x0 + terminator Jmp(b22) (exit_acc=v78) block 22 start_pc=0 - v81 Phi { incoming=[b27:v71, b21:v79], kind=I64 } -> x1 - v82 LoadLocal { off=-11, kind=I64 } -> x0 - terminator Bz { cond=v81, target=b24, fall=b23 } (exit_acc=v81) + v80 Phi { incoming=[b27:v70, b21:v78], kind=I64 } -> x1 + v81 LoadLocal { off=-11, kind=I64 } -> x0 + terminator Bz { cond=v80, target=b24, fall=b23 } (exit_acc=v80) block 23 start_pc=0 - v83 Imm(7) -> x0 - terminator Return(v83) (exit_acc=v83) + v82 Imm(7) -> x0 + terminator Return(v82) (exit_acc=v82) block 24 start_pc=0 - v84 Imm(0) -> x0 - terminator Return(v84) (exit_acc=v84) + v83 Imm(0) -> x0 + terminator Return(v83) (exit_acc=v83) block 25 start_pc=0 terminator Jmp(b4) block 26 start_pc=0 diff --git a/tests/snapshots/ssa/compound_assign_unsigned_div.ssa b/tests/snapshots/ssa/compound_assign_unsigned_div.ssa new file mode 100644 index 000000000..c57e699fb --- /dev/null +++ b/tests/snapshots/ssa/compound_assign_unsigned_div.ssa @@ -0,0 +1,142 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=6 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(4294967295) -> x0 + v2 Imm(0) -> x1 + v3 LoadLocal { off=-1, kind=U32 } -> x1 + v4 Imm(-2) -> x1 + v5 Imm(4294967294) -> x1 + v6 Binop { op=divu, lhs=v1, rhs=v5 } -> x0 + v7 Imm(0) -> x1 + v8 BinopI { op=and, lhs=v6, rhs_imm=4294967295 } -> x0 + v9 BinopI { op=xor, lhs=v8, rhs_imm=1 } -> x0 + v10 BinopI { op=and, lhs=v9, rhs_imm=4294967295 } -> x0 + v11 BinopI { op=ne, lhs=v10, rhs_imm=0 } -> x0 + terminator Bz { cond=v11, target=b2, fall=b1 } (exit_acc=v11) + block 1 start_pc=0 + v12 Imm(1) -> x0 + terminator Return(v12) (exit_acc=v12) + block 2 start_pc=0 + v13 Imm(4294967295) -> x0 + v14 Imm(0) -> x1 + v15 LoadLocal { off=-2, kind=U32 } -> x1 + v16 Imm(-2) -> x1 + v17 Imm(4294967294) -> x1 + v18 Binop { op=modu, lhs=v13, rhs=v17 } -> x0 + v19 Imm(0) -> x1 + v20 BinopI { op=and, lhs=v18, rhs_imm=4294967295 } -> x0 + v21 BinopI { op=xor, lhs=v20, rhs_imm=1 } -> x0 + v22 BinopI { op=and, lhs=v21, rhs_imm=4294967295 } -> x0 + v23 BinopI { op=ne, lhs=v22, rhs_imm=0 } -> x0 + terminator Bz { cond=v23, target=b4, fall=b3 } (exit_acc=v23) + block 3 start_pc=0 + v24 Imm(2) -> x0 + terminator Return(v24) (exit_acc=v24) + block 4 start_pc=0 + v25 Imm(-2) -> x0 + v26 Imm(0) -> x1 + v27 LoadLocal { off=-3, kind=I32 } -> x1 + v28 Imm(2) -> x1 + v29 BinopI { op=and, lhs=v25, rhs_imm=4294967295 } -> x0 + v30 Binop { op=divu, lhs=v29, rhs=v28 } -> x0 + v31 Imm(0) -> x1 + v32 Extend { value=v30, kind=I32 } -> x0 + v33 BinopI { op=ne, lhs=v32, rhs_imm=2147483647 } -> x0 + terminator Bz { cond=v33, target=b6, fall=b5 } (exit_acc=v33) + block 5 start_pc=0 + v34 Imm(3) -> x0 + terminator Return(v34) (exit_acc=v34) + block 6 start_pc=0 + v35 Imm(-7) -> x0 + v36 Imm(0) -> x1 + v37 LoadLocal { off=-4, kind=I32 } -> x1 + v38 Imm(3) -> x1 + v39 Binop { op=mod, lhs=v35, rhs=v38 } -> x0 + v40 Imm(0) -> x1 + v41 Extend { value=v39, kind=I32 } -> x0 + v42 BinopI { op=ne, lhs=v41, rhs_imm=-1 } -> x0 + terminator Bz { cond=v42, target=b8, fall=b7 } (exit_acc=v42) + block 7 start_pc=0 + v43 Imm(4) -> x0 + terminator Return(v43) (exit_acc=v43) + block 8 start_pc=0 + v44 Imm(-1) -> x0 + v45 Imm(0) -> x1 + v46 LoadLocal { off=-5, kind=I64 } -> x1 + v47 Imm(3) -> x1 + v48 Binop { op=divu, lhs=v44, rhs=v47 } -> x0 + v49 Imm(0) -> x1 + v50 LoadLocal { off=-5, kind=I64 } -> x1 + v51 BinopI { op=ne, lhs=v48, rhs_imm=6148914691236517205 } -> x0 + terminator Bz { cond=v51, target=b10, fall=b9 } (exit_acc=v51) + block 9 start_pc=0 + v52 Imm(5) -> x0 + terminator Return(v52) (exit_acc=v52) + block 10 start_pc=0 + v53 Imm(255) -> x0 + v54 Imm(0) -> x1 + v55 LoadLocal { off=-6, kind=U8 } -> x1 + v56 Imm(-2) -> x1 + v57 Binop { op=div, lhs=v53, rhs=v56 } -> x0 + v58 Imm(0) -> x1 + v59 BinopI { op=and, lhs=v57, rhs_imm=255 } -> x0 + v60 BinopI { op=xor, lhs=v59, rhs_imm=129 } -> x0 + v61 BinopI { op=and, lhs=v60, rhs_imm=4294967295 } -> x0 + v62 BinopI { op=ne, lhs=v61, rhs_imm=0 } -> x0 + terminator Bz { cond=v62, target=b12, fall=b11 } (exit_acc=v62) + block 11 start_pc=0 + v63 Imm(6) -> x0 + terminator Return(v63) (exit_acc=v63) + block 12 start_pc=0 + v64 Imm(0) -> x0 + terminator Return(v64) (exit_acc=v64) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/const_expr_unsigned_fold.ssa b/tests/snapshots/ssa/const_expr_unsigned_fold.ssa new file mode 100644 index 000000000..f21f6019a --- /dev/null +++ b/tests/snapshots/ssa/const_expr_unsigned_fold.ssa @@ -0,0 +1,139 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ImmData(8) -> x0 + v2 Load { addr=v1, disp=0, kind=I64 } -> x0 + v3 BinopI { op=ne, lhs=v2, rhs_imm=6148914691236517205 } -> x0 + terminator Bz { cond=v3, target=b2, fall=b1 } (exit_acc=v3) + block 1 start_pc=0 + v4 Imm(1) -> x0 + terminator Return(v4) (exit_acc=v4) + block 2 start_pc=0 + v5 ImmData(16) -> x0 + v6 Load { addr=v5, disp=0, kind=I64 } -> x0 + v7 BinopI { op=ne, lhs=v6, rhs_imm=1152921504606846975 } -> x0 + terminator Bz { cond=v7, target=b4, fall=b3 } (exit_acc=v7) + block 3 start_pc=0 + v8 Imm(2) -> x0 + terminator Return(v8) (exit_acc=v8) + block 4 start_pc=0 + v9 ImmData(24) -> x0 + v10 Load { addr=v9, disp=0, kind=I64 } -> x0 + v11 BinopI { op=ne, lhs=v10, rhs_imm=1 } -> x0 + terminator Bz { cond=v11, target=b6, fall=b5 } (exit_acc=v11) + block 5 start_pc=0 + v12 Imm(3) -> x0 + terminator Return(v12) (exit_acc=v12) + block 6 start_pc=0 + v13 ImmData(32) -> x0 + v14 Load { addr=v13, disp=0, kind=I32 } -> x0 + v15 BinopI { op=ne, lhs=v14, rhs_imm=1 } -> x0 + terminator Bz { cond=v15, target=b8, fall=b7 } (exit_acc=v15) + block 7 start_pc=0 + v16 Imm(4) -> x0 + terminator Return(v16) (exit_acc=v16) + block 8 start_pc=0 + v17 ImmData(72) -> x0 + v18 Load { addr=v17, disp=0, kind=I32 } -> x0 + v19 BinopI { op=ne, lhs=v18, rhs_imm=0 } -> x0 + terminator Bz { cond=v19, target=b10, fall=b9 } (exit_acc=v19) + block 9 start_pc=0 + v20 Imm(5) -> x0 + terminator Return(v20) (exit_acc=v20) + block 10 start_pc=0 + v21 ImmData(48) -> x0 + v22 Load { addr=v21, disp=0, kind=I64 } -> x0 + v23 Imm(-9223372036854775808) -> x1 + v24 BinopI { op=ne, lhs=v22, rhs_imm=-9223372036854775808 } -> x0 + terminator Bz { cond=v24, target=b12, fall=b11 } (exit_acc=v24) + block 11 start_pc=0 + v25 Imm(6) -> x0 + terminator Return(v25) (exit_acc=v25) + block 12 start_pc=0 + v26 Imm(16) -> x0 + v27 Imm(4) -> x1 + v28 Imm(0) -> x1 + v29 Binop { op=add, lhs=v26, rhs=v28 } -> x0 + v30 BinopI { op=shr, lhs=v29, rhs_imm=2 } -> x0 + v31 BinopI { op=ne, lhs=v30, rhs_imm=4 } -> x0 + terminator Bz { cond=v31, target=b14, fall=b13 } (exit_acc=v31) + block 13 start_pc=0 + v32 Imm(7) -> x0 + terminator Return(v32) (exit_acc=v32) + block 14 start_pc=0 + v33 Imm(12) -> x0 + v34 Imm(4) -> x1 + v35 Imm(0) -> x1 + v36 Binop { op=add, lhs=v33, rhs=v35 } -> x0 + v37 BinopI { op=shr, lhs=v36, rhs_imm=2 } -> x0 + v38 BinopI { op=ne, lhs=v37, rhs_imm=3 } -> x1 + v39 Imm(0) -> x0 + terminator Bnz { cond=v38, target=b19, fall=b15 } (exit_acc=v38) + block 15 start_pc=0 + v40 ImmData(88) -> x0 + v41 Load { addr=v40, disp=0, kind=I32 } -> x0 + v42 BinopI { op=ne, lhs=v41, rhs_imm=0 } -> x1 + v43 Imm(0) -> x0 + terminator Jmp(b16) (exit_acc=v42) + block 16 start_pc=0 + v44 Phi { incoming=[b19:v38, b15:v42], kind=I64 } -> x1 + v45 LoadLocal { off=-1, kind=I64 } -> x0 + terminator Bz { cond=v44, target=b18, fall=b17 } (exit_acc=v44) + block 17 start_pc=0 + v46 Imm(8) -> x0 + terminator Return(v46) (exit_acc=v46) + block 18 start_pc=0 + v47 Imm(0) -> x0 + terminator Return(v47) (exit_acc=v47) + block 19 start_pc=0 + terminator Jmp(b16) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/data_reloc_one_past_end.ssa b/tests/snapshots/ssa/data_reloc_one_past_end.ssa new file mode 100644 index 000000000..d78ef6ed1 --- /dev/null +++ b/tests/snapshots/ssa/data_reloc_one_past_end.ssa @@ -0,0 +1,87 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=2 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(0) -> x2 + v2 Imm(0) -> x0 + v3 ImmData(8) -> x1 + v4 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v3) + block 1 start_pc=0 + v5 Phi { incoming=[b0:v3, b2:v16], kind=I64 } -> x1 + v6 Phi { incoming=[b0:v1, b2:v14], kind=I64 } -> x2 + v7 LoadLocal { off=-2, kind=I64 } -> x0 + v8 ImmData(40) -> x0 + v9 Load { addr=v8, disp=0, kind=I64 } -> x0 + v10 Binop { op=ne, lhs=v5, rhs=v9 } -> x0 + terminator Bz { cond=v10, target=b3, fall=b2 } (exit_acc=v10) + block 2 start_pc=0 + v11 LoadLocal { off=-1, kind=I64 } -> x0 + v12 LoadLocal { off=-2, kind=I64 } -> x0 + v13 Load { addr=v5, disp=0, kind=I64 } -> x0 + v14 Binop { op=add, lhs=v6, rhs=v13 } -> x2 + v15 Imm(0) -> x0 + v16 BinopI { op=add, lhs=v5, rhs_imm=8 } -> x1 + v17 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v16) + block 3 start_pc=0 + v18 LoadLocal { off=-1, kind=I64 } -> x0 + v19 ImmData(56) -> x0 + v20 Imm(24) -> x1 + v21 BinopI { op=add, lhs=v19, rhs_imm=24 } -> x1 + v22 Load { addr=v19, disp=24, kind=I64 } -> x0 + v23 Binop { op=add, lhs=v6, rhs=v22 } -> x0 + v24 Imm(0) -> x1 + v25 LoadLocal { off=-1, kind=I64 } -> x1 + v26 BinopI { op=shl, lhs=v23, rhs_imm=32 } -> x1 + v27 Extend { value=v23, kind=I32 } -> x0 + terminator Return(v27) (exit_acc=v27) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/decl_specifier_any_order.ssa b/tests/snapshots/ssa/decl_specifier_any_order.ssa new file mode 100644 index 000000000..b296295ce --- /dev/null +++ b/tests/snapshots/ssa/decl_specifier_any_order.ssa @@ -0,0 +1,128 @@ +decl_specifier_any_order.c:29: warning: unused variable `llv` +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=6 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(0) -> x0 + terminator Jmp(b2) (exit_acc=v1) + block 1 start_pc=0 + v2 Imm(1) -> x0 + terminator Return(v2) (exit_acc=v2) + block 2 start_pc=0 + v3 Imm(0) -> x0 + terminator Jmp(b4) (exit_acc=v3) + block 3 start_pc=0 + v4 Imm(2) -> x0 + terminator Return(v4) (exit_acc=v4) + block 4 start_pc=0 + v5 Imm(4294967296) -> x0 + v6 Imm(0) -> x1 + v7 LoadLocal { off=-1, kind=I64 } -> x1 + v8 BinopI { op=shr, lhs=v5, rhs_imm=32 } -> x0 + v9 BinopI { op=ne, lhs=v8, rhs_imm=1 } -> x0 + terminator Bz { cond=v9, target=b6, fall=b5 } (exit_acc=v9) + block 5 start_pc=0 + v10 Imm(3) -> x0 + terminator Return(v10) (exit_acc=v10) + block 6 start_pc=0 + v11 Imm(-1) -> x0 + v12 Imm(0) -> x1 + v13 BinopI { op=and, lhs=v11, rhs_imm=4294967295 } -> x0 + v14 BinopI { op=ugt, lhs=v13, rhs_imm=0 } -> x0 + v15 BinopI { op=eq, lhs=v14, rhs_imm=0 } -> x0 + terminator Bz { cond=v15, target=b8, fall=b7 } (exit_acc=v15) + block 7 start_pc=0 + v16 Imm(4) -> x0 + terminator Return(v16) (exit_acc=v16) + block 8 start_pc=0 + v17 Imm(-1) -> x0 + v18 Imm(0) -> x1 + v19 BinopI { op=and, lhs=v17, rhs_imm=255 } -> x0 + v20 BinopI { op=xor, lhs=v19, rhs_imm=255 } -> x0 + v21 BinopI { op=and, lhs=v20, rhs_imm=4294967295 } -> x0 + v22 BinopI { op=ne, lhs=v21, rhs_imm=0 } -> x0 + terminator Bz { cond=v22, target=b10, fall=b9 } (exit_acc=v22) + block 9 start_pc=0 + v23 Imm(5) -> x0 + terminator Return(v23) (exit_acc=v23) + block 10 start_pc=0 + v24 Imm(-1) -> x0 + v25 Imm(0) -> x0 + v26 Imm(0) -> x0 + terminator Jmp(b12) (exit_acc=v26) + block 11 start_pc=0 + v27 Imm(6) -> x0 + terminator Return(v27) (exit_acc=v27) + block 12 start_pc=0 + v28 Imm(16) -> x0 + v29 Imm(68719476736) -> x0 + v30 Imm(0) -> x0 + terminator Jmp(b14) (exit_acc=v30) + block 13 start_pc=0 + v31 Imm(7) -> x0 + terminator Return(v31) (exit_acc=v31) + block 14 start_pc=0 + v32 LocalAddr(-6) -> x0 + v33 BinopI { op=add, lhs=v32, rhs_imm=8 } -> x1 + v34 Imm(-5) -> x1 + v35 Store { addr=v32, disp=8, value=v34, kind=I64 } -> - + v36 LocalAddr(-6) -> x0 + v37 BinopI { op=add, lhs=v36, rhs_imm=8 } -> x1 + v38 Load { addr=v36, disp=8, kind=I64 } -> x0 + v39 BinopI { op=ge, lhs=v38, rhs_imm=0 } -> x0 + terminator Bz { cond=v39, target=b16, fall=b15 } (exit_acc=v39) + block 15 start_pc=0 + v40 Imm(8) -> x0 + terminator Return(v40) (exit_acc=v40) + block 16 start_pc=0 + v41 Imm(0) -> x0 + terminator Return(v41) (exit_acc=v41) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/dlopen_atoi.ssa b/tests/snapshots/ssa/dlopen_atoi.ssa index 46c2dc6c8..b01389618 100644 --- a/tests/snapshots/ssa/dlopen_atoi.ssa +++ b/tests/snapshots/ssa/dlopen_atoi.ssa @@ -6,7 +6,7 @@ fn ent_pc=5 n_params=0 variadic=false locals=5 v0 AllocaInit(0) -> - v1 Imm(0) -> x7 v2 Imm(2) -> x6 - v3 CallExt { binding_idx=222, args=[v1, v2], fp_arg_mask=0x0 } -> x3 + v3 CallExt { binding_idx=221, args=[v1, v2], fp_arg_mask=0x0 } -> x3 v4 Imm(0) -> x0 v5 LoadLocal { off=-1, kind=I64 } -> x0 v6 BinopI { op=eq, lhs=v3, rhs_imm=0 } -> x0 @@ -17,14 +17,14 @@ fn ent_pc=5 n_params=0 variadic=false locals=5 block 2 start_pc=0 v8 LoadLocal { off=-1, kind=I64 } -> x0 v9 ImmData(48) -> x6 - v10 CallExt { binding_idx=223, args=[v3, v9], fp_arg_mask=0x0 } -> x12 + v10 CallExt { binding_idx=222, args=[v3, v9], fp_arg_mask=0x0 } -> x12 v11 Imm(0) -> x0 v12 LoadLocal { off=-2, kind=I64 } -> x0 v13 BinopI { op=eq, lhs=v10, rhs_imm=0 } -> x0 terminator Bz { cond=v13, target=b4, fall=b3 } (exit_acc=v13) block 3 start_pc=0 v14 LoadLocal { off=-1, kind=I64 } -> x0 - v15 CallExt { binding_idx=224, args=[v3], fp_arg_mask=0x0 } -> x0 + v15 CallExt { binding_idx=223, args=[v3], fp_arg_mask=0x0 } -> x0 v16 Imm(2) -> x0 terminator Return(v16) (exit_acc=v16) block 4 start_pc=0 @@ -35,7 +35,7 @@ fn ent_pc=5 n_params=0 variadic=false locals=5 v21 Extend { value=v19, kind=I32 } -> x12 v22 Imm(0) -> x0 v23 LoadLocal { off=-1, kind=I64 } -> x0 - v24 CallExt { binding_idx=224, args=[v3], fp_arg_mask=0x0 } -> x0 + v24 CallExt { binding_idx=223, args=[v3], fp_arg_mask=0x0 } -> x0 v25 LoadLocal { off=-3, kind=I32 } -> x0 terminator Return(v21) (exit_acc=v21) ; --- SSA dump (ok=true) ent_pc=0 --- diff --git a/tests/snapshots/ssa/fcntl_lock_via_cast_fnptr.ssa b/tests/snapshots/ssa/fcntl_lock_via_cast_fnptr.ssa new file mode 100644 index 000000000..da62f8815 --- /dev/null +++ b/tests/snapshots/ssa/fcntl_lock_via_cast_fnptr.ssa @@ -0,0 +1,149 @@ +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=31 + spill_count=0 gpr_used=[3, 12, 13, 14, 15] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-8) -> x3 + v2 Imm(64) -> x12 + v3 ImmData(40) -> x13 + v4 CallExt { binding_idx=107, args=[], fp_arg_mask=0x0 } -> x1 + v5 CallExt { binding_idx=3, args=[v1, v2, v3, v4], fp_arg_mask=0x0 } -> x0 + v6 LocalAddr(-8) -> x7 + v7 Imm(66) -> x6 + v8 Imm(420) -> x2 + v9 CallExt { binding_idx=79, args=[v6, v7, v8], fp_arg_mask=0x0 } -> x3 + v10 Imm(0) -> x0 + v11 Extend { value=v9, kind=I32 } -> x0 + v12 BinopI { op=lt, lhs=v11, rhs_imm=0 } -> x0 + terminator Bz { cond=v12, target=b2, fall=b1 } (exit_acc=v12) + block 1 start_pc=0 + v13 Imm(3) -> x0 + terminator Return(v13) (exit_acc=v13) + block 2 start_pc=0 + v14 LocalAddr(-21) -> x7 + v15 Imm(0) -> x12 + v16 Imm(96) -> x2 + v17 CallExt { binding_idx=208, args=[v14, v15, v16], fp_arg_mask=0x0 } -> x0 + v18 LocalAddr(-21) -> x0 + v19 Imm(1) -> x13 + v20 Store { addr=v18, disp=0, value=v19, kind=I16 } -> - + v21 Imm(281474976710656) -> x0 + v22 LocalAddr(-21) -> x0 + v23 BinopI { op=add, lhs=v22, rhs_imm=2 } -> x1 + v24 Store { addr=v22, disp=2, value=v15, kind=I16 } -> - + v25 Extend { value=v9, kind=I32 } -> x7 + v26 Imm(6) -> x12 + v27 LocalAddr(-21) -> x2 + v28 CallExt { binding_idx=54, args=[v25, v26, v27], fp_arg_mask=0x0 } -> x14 + v29 Imm(0) -> x0 + v30 LocalAddr(-21) -> x0 + v31 Imm(2) -> x1 + v32 Store { addr=v30, disp=0, value=v31, kind=I16 } -> - + v33 Imm(562949953421312) -> x0 + v34 Extend { value=v9, kind=I32 } -> x7 + v35 LocalAddr(-21) -> x2 + v36 CallExt { binding_idx=54, args=[v34, v26, v35], fp_arg_mask=0x0 } -> x15 + v37 Imm(0) -> x0 + v38 LocalAddr(-21) -> x0 + v39 Store { addr=v38, disp=0, value=v19, kind=I16 } -> - + v40 ImmData(32) -> x0 + v41 Load { addr=v40, disp=0, kind=I64 } -> x0 + v42 Extend { value=v9, kind=I32 } -> x7 + v43 LocalAddr(-21) -> x2 + v44 CallIndirect { target=v41, args=[v42, v26, v43], callee_variadic=true, fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x0 + v45 BinopI { op=shl, lhs=v44, rhs_imm=32 } -> x1 + v46 Extend { value=v44, kind=I32 } -> x12 + v47 Imm(0) -> x0 + v48 Extend { value=v9, kind=I32 } -> x7 + v49 CallExt { binding_idx=83, args=[v48], fp_arg_mask=0x0 } -> x0 + v50 LocalAddr(-8) -> x7 + v51 CallExt { binding_idx=97, args=[v50], fp_arg_mask=0x0 } -> x0 + v52 Extend { value=v28, kind=I32 } -> x0 + v53 BinopI { op=ne, lhs=v52, rhs_imm=0 } -> x1 + v54 Imm(0) -> x0 + terminator Bnz { cond=v53, target=b10, fall=b3 } (exit_acc=v53) + block 3 start_pc=0 + v55 Extend { value=v36, kind=I32 } -> x0 + v56 BinopI { op=ne, lhs=v55, rhs_imm=0 } -> x1 + v57 Imm(0) -> x0 + terminator Jmp(b4) (exit_acc=v56) + block 4 start_pc=0 + v58 Phi { incoming=[b10:v53, b3:v56], kind=I64 } -> x1 + v59 LoadLocal { off=-30, kind=I64 } -> x0 + terminator Bz { cond=v58, target=b6, fall=b5 } (exit_acc=v58) + block 5 start_pc=0 + v60 Imm(2) -> x0 + terminator Return(v60) (exit_acc=v60) + block 6 start_pc=0 + v61 LoadLocal { off=-24, kind=I32 } -> x0 + v62 BinopI { op=eq, lhs=v46, rhs_imm=0 } -> x0 + terminator Bz { cond=v62, target=b8, fall=b7 } (exit_acc=v62) + block 7 start_pc=0 + v63 Imm(0) -> x1 + v64 Imm(0) -> x0 + terminator Jmp(b9) (exit_acc=v63) + block 8 start_pc=0 + v65 Imm(1) -> x1 + v66 Imm(0) -> x0 + terminator Jmp(b9) (exit_acc=v65) + block 9 start_pc=0 + v67 Phi { incoming=[b7:v63, b8:v65], kind=I64 } -> x1 + v68 LoadLocal { off=-31, kind=I64 } -> x0 + terminator Return(v67) (exit_acc=v67) + block 10 start_pc=0 + terminator Jmp(b4) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=__c5_sys_fcntl +fn ent_pc=2 n_params=0 variadic=false locals=0 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + terminator TailExt(54) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/float_arith_in_static_init.ssa b/tests/snapshots/ssa/float_arith_in_static_init.ssa index 473ec8a4b..02f921fd9 100644 --- a/tests/snapshots/ssa/float_arith_in_static_init.ssa +++ b/tests/snapshots/ssa/float_arith_in_static_init.ssa @@ -18,7 +18,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=1 v8 ImmData(40) -> x1 v9 Imm(4) -> x1 v10 BinopI { op=add, lhs=v1, rhs_imm=4 } -> x1 - v11 Load { addr=v10, disp=0, kind=F32 } -> d0 [f32] + v11 Load { addr=v1, disp=4, kind=F32 } -> d0 [f32] v12 Imm(4612811918334230528) -> x1 v13 Fneg(v12) -> d1 v14 FpCast { kind=F32ToF64, value=v11 } -> d0 @@ -30,8 +30,8 @@ fn ent_pc=1 n_params=0 variadic=false locals=1 block 4 start_pc=0 v17 ImmData(40) -> x1 v18 Imm(8) -> x1 - v19 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x0 - v20 Load { addr=v19, disp=0, kind=F32 } -> d0 [f32] + v19 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x1 + v20 Load { addr=v1, disp=8, kind=F32 } -> d0 [f32] v21 Imm(4622945017495814144) -> x0 v22 FpCast { kind=F32ToF64, value=v20 } -> d0 v23 Binop { op=fne, lhs=v22, rhs=v21 } -> x0 @@ -65,8 +65,8 @@ fn ent_pc=1 n_params=0 variadic=false locals=1 block 10 start_pc=0 v40 ImmData(56) -> x0 v41 Imm(8) -> x1 - v42 BinopI { op=add, lhs=v40, rhs_imm=8 } -> x0 - v43 Load { addr=v42, disp=0, kind=F64 } -> d0 + v42 BinopI { op=add, lhs=v40, rhs_imm=8 } -> x1 + v43 Load { addr=v40, disp=8, kind=F64 } -> d0 v44 Imm(4604930618986332160) -> x0 v45 Fneg(v44) -> d1 v46 Binop { op=fne, lhs=v43, rhs=v45 } -> x0 diff --git a/tests/snapshots/ssa/float_increment_decrement.ssa b/tests/snapshots/ssa/float_increment_decrement.ssa index 85ad72086..971b50493 100644 --- a/tests/snapshots/ssa/float_increment_decrement.ssa +++ b/tests/snapshots/ssa/float_increment_decrement.ssa @@ -155,11 +155,11 @@ fn ent_pc=0 n_params=0 variadic=false locals=22 v113 FpCast { kind=F64ToF32, value=v112 } -> d0 [f32] v114 Store { addr=v108, disp=0, value=v113, kind=F32 } -> - v115 LocalAddr(-12) -> x0 - v116 BinopI { op=add, lhs=v115, rhs_imm=8 } -> x0 - v117 Load { addr=v116, disp=0, kind=F64 } -> d0 + v116 BinopI { op=add, lhs=v115, rhs_imm=8 } -> x1 + v117 Load { addr=v115, disp=8, kind=F64 } -> d0 v118 Imm(-4616189618054758400) -> x1 v119 Binop { op=fadd, lhs=v117, rhs=v118 } -> d0 - v120 Store { addr=v116, disp=0, value=v119, kind=F64 } -> - + v120 Store { addr=v115, disp=8, value=v119, kind=F64 } -> - v121 LocalAddr(-12) -> x0 v122 Load { addr=v121, disp=0, kind=F32 } -> d0 [f32] v123 Imm(4612811918334230528) -> x0 @@ -169,8 +169,8 @@ fn ent_pc=0 n_params=0 variadic=false locals=22 terminator Bnz { cond=v125, target=b35, fall=b19 } (exit_acc=v125) block 19 start_pc=0 v127 LocalAddr(-12) -> x0 - v128 BinopI { op=add, lhs=v127, rhs_imm=8 } -> x0 - v129 Load { addr=v128, disp=0, kind=F64 } -> d0 + v128 BinopI { op=add, lhs=v127, rhs_imm=8 } -> x1 + v129 Load { addr=v127, disp=8, kind=F64 } -> d0 v130 Imm(4609434218613702656) -> x0 v131 Binop { op=fne, lhs=v129, rhs=v130 } -> x1 v132 Imm(0) -> x0 @@ -204,21 +204,21 @@ fn ent_pc=0 n_params=0 variadic=false locals=22 v150 Mcpy { dst=v148, src=v149, size=24 } -> x0 v151 LocalAddr(-15) -> x0 v152 Imm(8) -> x1 - v153 BinopI { op=add, lhs=v151, rhs_imm=8 } -> x0 - v154 Load { addr=v153, disp=0, kind=F64 } -> d0 + v153 BinopI { op=add, lhs=v151, rhs_imm=8 } -> x1 + v154 Load { addr=v151, disp=8, kind=F64 } -> d0 v155 Imm(4607182418800017408) -> x1 v156 Binop { op=fadd, lhs=v154, rhs=v155 } -> d0 - v157 Store { addr=v153, disp=0, value=v156, kind=F64 } -> - + v157 Store { addr=v151, disp=8, value=v156, kind=F64 } -> - v158 LocalAddr(-15) -> x0 v159 Imm(16) -> x1 - v160 BinopI { op=add, lhs=v158, rhs_imm=16 } -> x0 - v161 Load { addr=v160, disp=0, kind=F64 } -> d0 + v160 BinopI { op=add, lhs=v158, rhs_imm=16 } -> x1 + v161 Load { addr=v158, disp=16, kind=F64 } -> d0 v162 Imm(-4616189618054758400) -> x1 v163 Binop { op=fadd, lhs=v161, rhs=v162 } -> d0 - v164 Store { addr=v160, disp=0, value=v163, kind=F64 } -> - + v164 Store { addr=v158, disp=16, value=v163, kind=F64 } -> - v165 LocalAddr(-15) -> x0 - v166 BinopI { op=add, lhs=v165, rhs_imm=8 } -> x0 - v167 Load { addr=v166, disp=0, kind=F64 } -> d0 + v166 BinopI { op=add, lhs=v165, rhs_imm=8 } -> x1 + v167 Load { addr=v165, disp=8, kind=F64 } -> d0 v168 Imm(4611686018427387904) -> x0 v169 Binop { op=fne, lhs=v167, rhs=v168 } -> x1 v170 Imm(0) -> x0 @@ -226,8 +226,8 @@ fn ent_pc=0 n_params=0 variadic=false locals=22 block 25 start_pc=0 v171 LocalAddr(-15) -> x0 v172 Imm(16) -> x1 - v173 BinopI { op=add, lhs=v171, rhs_imm=16 } -> x0 - v174 Load { addr=v173, disp=0, kind=F64 } -> d0 + v173 BinopI { op=add, lhs=v171, rhs_imm=16 } -> x1 + v174 Load { addr=v171, disp=16, kind=F64 } -> d0 v175 Imm(4607182418800017408) -> x0 v176 Binop { op=fne, lhs=v174, rhs=v175 } -> x1 v177 Imm(0) -> x0 diff --git a/tests/snapshots/ssa/float_is_four_bytes.ssa b/tests/snapshots/ssa/float_is_four_bytes.ssa index fcbb40210..7eb9e802f 100644 --- a/tests/snapshots/ssa/float_is_four_bytes.ssa +++ b/tests/snapshots/ssa/float_is_four_bytes.ssa @@ -152,8 +152,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=13 v89 Phi { incoming=[b36:v74, b13:v87], kind=I64 } -> x3 v90 ImmData(40) -> x0 v91 Imm(4) -> x1 - v92 BinopI { op=add, lhs=v90, rhs_imm=4 } -> x0 - v93 Load { addr=v92, disp=0, kind=F32 } -> d0 [f32] + v92 BinopI { op=add, lhs=v90, rhs_imm=4 } -> x1 + v93 Load { addr=v90, disp=4, kind=F32 } -> d0 [f32] v94 Imm(4612811918334230528) -> x0 v95 FpCast { kind=F32ToF64, value=v93 } -> d0 v96 Binop { op=fne, lhs=v95, rhs=v94 } -> x0 @@ -162,8 +162,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=13 v97 ImmData(232) -> x7 v98 ImmData(40) -> x0 v99 Imm(4) -> x1 - v100 BinopI { op=add, lhs=v98, rhs_imm=4 } -> x0 - v101 Load { addr=v100, disp=0, kind=F32 } -> d0 [f32] + v100 BinopI { op=add, lhs=v98, rhs_imm=4 } -> x1 + v101 Load { addr=v98, disp=4, kind=F32 } -> d0 [f32] v102 FpCast { kind=F32ToF64, value=v101 } -> d0 v103 CallExt { binding_idx=0, args=[v97, v102], fp_arg_mask=0x2 } -> x0 v104 Imm(8) -> x3 @@ -173,8 +173,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=13 v106 Phi { incoming=[b37:v89, b15:v104], kind=I64 } -> x3 v107 ImmData(40) -> x0 v108 Imm(8) -> x1 - v109 BinopI { op=add, lhs=v107, rhs_imm=8 } -> x0 - v110 Load { addr=v109, disp=0, kind=F32 } -> d0 [f32] + v109 BinopI { op=add, lhs=v107, rhs_imm=8 } -> x1 + v110 Load { addr=v107, disp=8, kind=F32 } -> d0 [f32] v111 Imm(4615063718147915776) -> x0 v112 FpCast { kind=F32ToF64, value=v110 } -> d0 v113 Binop { op=fne, lhs=v112, rhs=v111 } -> x0 @@ -183,8 +183,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=13 v114 ImmData(252) -> x7 v115 ImmData(40) -> x0 v116 Imm(8) -> x1 - v117 BinopI { op=add, lhs=v115, rhs_imm=8 } -> x0 - v118 Load { addr=v117, disp=0, kind=F32 } -> d0 [f32] + v117 BinopI { op=add, lhs=v115, rhs_imm=8 } -> x1 + v118 Load { addr=v115, disp=8, kind=F32 } -> d0 [f32] v119 FpCast { kind=F32ToF64, value=v118 } -> d0 v120 CallExt { binding_idx=0, args=[v114, v119], fp_arg_mask=0x2 } -> x0 v121 Imm(9) -> x3 @@ -194,8 +194,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=13 v123 Phi { incoming=[b38:v106, b17:v121], kind=I64 } -> x3 v124 ImmData(40) -> x0 v125 Imm(12) -> x1 - v126 BinopI { op=add, lhs=v124, rhs_imm=12 } -> x0 - v127 Load { addr=v126, disp=0, kind=F32 } -> d0 [f32] + v126 BinopI { op=add, lhs=v124, rhs_imm=12 } -> x1 + v127 Load { addr=v124, disp=12, kind=F32 } -> d0 [f32] v128 Imm(4616752568008179712) -> x0 v129 FpCast { kind=F32ToF64, value=v127 } -> d0 v130 Binop { op=fne, lhs=v129, rhs=v128 } -> x0 @@ -204,8 +204,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=13 v131 ImmData(272) -> x7 v132 ImmData(40) -> x0 v133 Imm(12) -> x1 - v134 BinopI { op=add, lhs=v132, rhs_imm=12 } -> x0 - v135 Load { addr=v134, disp=0, kind=F32 } -> d0 [f32] + v134 BinopI { op=add, lhs=v132, rhs_imm=12 } -> x1 + v135 Load { addr=v132, disp=12, kind=F32 } -> d0 [f32] v136 FpCast { kind=F32ToF64, value=v135 } -> d0 v137 CallExt { binding_idx=0, args=[v131, v136], fp_arg_mask=0x2 } -> x0 v138 Imm(10) -> x3 diff --git a/tests/snapshots/ssa/float_ternary_promote.ssa b/tests/snapshots/ssa/float_ternary_promote.ssa new file mode 100644 index 000000000..4d9fc570f --- /dev/null +++ b/tests/snapshots/ssa/float_ternary_promote.ssa @@ -0,0 +1,197 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=sel +fn ent_pc=0 n_params=3 variadic=false locals=4 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=F32) -> d2 [f32] + v4 Imm(0) -> x0 + v5 ParamRef(2, kind=F32) -> d1 [f32] + v6 Imm(0) -> x0 + v7 LoadLocal { off=2, kind=I32 } -> x0 + terminator Bz { cond=v1, target=b2, fall=b1 } (exit_acc=v1) + block 1 start_pc=0 + v8 LoadLocal { off=-1, kind=F32 } -> d0 [f32] + v9 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v3) + block 2 start_pc=0 + v10 LoadLocal { off=-2, kind=F32 } -> d0 [f32] + v11 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v5) + block 3 start_pc=0 + v12 Phi { incoming=[b1:v3, b2:v5], kind=F32 } -> d2 [f32] + v13 LoadLocal { off=-4, kind=F32 } -> d0 [f32] + v14 Imm(0) -> x0 + v15 LoadLocal { off=-3, kind=F32 } -> d0 [f32] + terminator Return(v12) (exit_acc=v12) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=8 + spill_count=1 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(1) -> x7 + v2 Imm(4609434218613702656) -> x3 + v3 FpCast { kind=F64ToF32, value=v2 } -> d0 [f32] + v4 Imm(4612811918334230528) -> x0 + v5 Fneg(v4) -> d1 + v6 FpCast { kind=F64ToF32, value=v5 } -> d1 [f32] + v7 Call { target_pc=0, args=[v1, v3, v6], fixed_args=3, fp_return=true, fp_arg_mask=0x6 } -> d0 [f32] + v8 FpCast { kind=F32ToF64, value=v7 } -> d0 + v9 Binop { op=fne, lhs=v8, rhs=v2 } -> x0 + terminator Bz { cond=v9, target=b2, fall=b1 } (exit_acc=v9) + block 1 start_pc=0 + v10 Imm(1) -> x0 + terminator Return(v10) (exit_acc=v10) + block 2 start_pc=0 + v11 Imm(0) -> x7 + v12 Imm(4609434218613702656) -> x0 + v13 FpCast { kind=F64ToF32, value=v12 } -> d0 [f32] + v14 Imm(4612811918334230528) -> x0 + v15 Fneg(v14) -> [spill 0] + v16 FpCast { kind=F64ToF32, value=v15 } -> d1 [f32] + v17 Call { target_pc=0, args=[v11, v13, v16], fixed_args=3, fp_return=true, fp_arg_mask=0x6 } -> d0 [f32] + v18 FpCast { kind=F32ToF64, value=v17 } -> d0 + v19 Binop { op=fne, lhs=v18, rhs=v15 } -> x0 + terminator Bz { cond=v19, target=b4, fall=b3 } (exit_acc=v19) + block 3 start_pc=0 + v20 Imm(2) -> x0 + terminator Return(v20) (exit_acc=v20) + block 4 start_pc=0 + v21 Imm(4614500768194494464) -> x0 + v22 FpCast { kind=F64ToF32, value=v21 } -> d2 [f32] + v23 Imm(0) -> x0 + v24 LoadLocal { off=-1, kind=F32 } -> d0 [f32] + v25 Imm(0) -> x0 + v26 FpCast { kind=F32ToF64, value=v22 } -> d0 + v27 Binop { op=fgt, lhs=v26, rhs=v25 } -> x0 + terminator Bz { cond=v27, target=b6, fall=b5 } (exit_acc=v27) + block 5 start_pc=0 + v28 LoadLocal { off=-1, kind=F32 } -> d0 [f32] + v29 Imm(0) -> x0 + terminator Jmp(b7) (exit_acc=v22) + block 6 start_pc=0 + v30 LoadLocal { off=-1, kind=F32 } -> d0 [f32] + v31 Fneg(v22) -> d0 [f32] + v32 Imm(0) -> x0 + terminator Jmp(b7) (exit_acc=v31) + block 7 start_pc=0 + v33 Phi { incoming=[b5:v22, b6:v31], kind=F32 } -> d0 [f32] + v34 LoadLocal { off=-5, kind=F32 } -> d1 [f32] + v35 LoadLocal { off=-1, kind=F32 } -> d1 [f32] + v36 Imm(0) -> x0 + v37 FpCast { kind=F32ToF64, value=v22 } -> d1 + v38 Binop { op=flt, lhs=v37, rhs=v36 } -> x0 + terminator Bz { cond=v38, target=b9, fall=b8 } (exit_acc=v38) + block 8 start_pc=0 + v39 LoadLocal { off=-1, kind=F32 } -> d1 [f32] + v40 Fneg(v22) -> d2 [f32] + v41 Imm(0) -> x0 + terminator Jmp(b10) (exit_acc=v40) + block 9 start_pc=0 + v42 LoadLocal { off=-1, kind=F32 } -> d1 [f32] + v43 Imm(0) -> x0 + terminator Jmp(b10) (exit_acc=v22) + block 10 start_pc=0 + v44 Phi { incoming=[b8:v40, b9:v22], kind=F32 } -> d2 [f32] + v45 LoadLocal { off=-6, kind=F32 } -> d1 [f32] + v46 Binop { op=fadd, lhs=v33, rhs=v44 } -> d0 [f32] + v47 Imm(0) -> x0 + v48 LoadLocal { off=-2, kind=F32 } -> d1 [f32] + v49 Imm(4619004367821864960) -> x0 + v50 FpCast { kind=F32ToF64, value=v46 } -> d0 + v51 Binop { op=fne, lhs=v50, rhs=v49 } -> x0 + terminator Bz { cond=v51, target=b12, fall=b11 } (exit_acc=v51) + block 11 start_pc=0 + v52 Imm(3) -> x0 + terminator Return(v52) (exit_acc=v52) + block 12 start_pc=0 + v53 Imm(2) -> x0 + v54 Imm(0) -> x1 + v55 LoadLocal { off=-3, kind=I32 } -> x1 + v56 BinopI { op=eq, lhs=v53, rhs_imm=0 } -> x1 + terminator Bz { cond=v56, target=b14, fall=b13 } (exit_acc=v56) + block 13 start_pc=0 + v57 Imm(0) -> x0 + v58 StoreLocal { off=-7, value=v57, kind=F64 } -> - + terminator Jmp(b15) (exit_acc=v58) + block 14 start_pc=0 + v59 LoadLocal { off=-3, kind=I32 } -> x1 + v60 BinopI { op=eq, lhs=v53, rhs_imm=1 } -> x0 + terminator Bz { cond=v60, target=b17, fall=b16 } (exit_acc=v60) + block 15 start_pc=0 + v61 LoadLocal { off=-7, kind=F64 } -> d0 + v62 FpCast { kind=F64ToF32, value=v61 } -> d0 [f32] + v63 Imm(0) -> x0 + v64 LoadLocal { off=-4, kind=F32 } -> d1 [f32] + v65 Imm(4626322717216342016) -> x0 + v66 FpCast { kind=F32ToF64, value=v62 } -> d0 + v67 Binop { op=fne, lhs=v66, rhs=v65 } -> x0 + terminator Bz { cond=v67, target=b20, fall=b19 } (exit_acc=v67) + block 16 start_pc=0 + v68 Imm(4621819117588971520) -> x0 + v69 StoreLocal { off=-8, value=v68, kind=F64 } -> - + terminator Jmp(b18) (exit_acc=v69) + block 17 start_pc=0 + v70 Imm(4626322717216342016) -> x0 + v71 StoreLocal { off=-8, value=v70, kind=F64 } -> - + terminator Jmp(b18) (exit_acc=v71) + block 18 start_pc=0 + v72 LoadLocal { off=-8, kind=F64 } -> d0 + v73 StoreLocal { off=-7, value=v72, kind=F64 } -> - + terminator Jmp(b15) (exit_acc=v73) + block 19 start_pc=0 + v74 Imm(4) -> x0 + terminator Return(v74) (exit_acc=v74) + block 20 start_pc=0 + v75 Imm(0) -> x0 + terminator Return(v75) (exit_acc=v75) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/fma_numeric_kernels.ssa b/tests/snapshots/ssa/fma_numeric_kernels.ssa index a75b1d2c0..7ae3d438f 100644 --- a/tests/snapshots/ssa/fma_numeric_kernels.ssa +++ b/tests/snapshots/ssa/fma_numeric_kernels.ssa @@ -184,24 +184,24 @@ fn ent_pc=4 n_params=0 variadic=false locals=31 v4 Store { addr=v1, disp=0, value=v3, kind=F64 } -> - v5 LocalAddr(-5) -> x0 v6 Imm(8) -> x1 - v7 BinopI { op=add, lhs=v5, rhs_imm=8 } -> x0 + v7 BinopI { op=add, lhs=v5, rhs_imm=8 } -> x1 v8 Imm(4611686018427387904) -> x2 - v9 Store { addr=v7, disp=0, value=v8, kind=F64 } -> - + v9 Store { addr=v5, disp=8, value=v8, kind=F64 } -> - v10 LocalAddr(-5) -> x0 v11 Imm(16) -> x1 - v12 BinopI { op=add, lhs=v10, rhs_imm=16 } -> x0 + v12 BinopI { op=add, lhs=v10, rhs_imm=16 } -> x1 v13 Imm(4613937818241073152) -> x1 - v14 Store { addr=v12, disp=0, value=v13, kind=F64 } -> - + v14 Store { addr=v10, disp=16, value=v13, kind=F64 } -> - v15 LocalAddr(-5) -> x0 v16 Imm(24) -> x1 - v17 BinopI { op=add, lhs=v15, rhs_imm=24 } -> x0 + v17 BinopI { op=add, lhs=v15, rhs_imm=24 } -> x1 v18 Imm(4616189618054758400) -> x1 - v19 Store { addr=v17, disp=0, value=v18, kind=F64 } -> - + v19 Store { addr=v15, disp=24, value=v18, kind=F64 } -> - v20 LocalAddr(-5) -> x0 v21 Imm(32) -> x1 - v22 BinopI { op=add, lhs=v20, rhs_imm=32 } -> x0 + v22 BinopI { op=add, lhs=v20, rhs_imm=32 } -> x1 v23 Imm(4617315517961601024) -> x1 - v24 Store { addr=v22, disp=0, value=v23, kind=F64 } -> - + v24 Store { addr=v20, disp=32, value=v23, kind=F64 } -> - v25 LocalAddr(-5) -> x7 v26 Imm(5) -> x6 v27 Call { target_pc=1, args=[v25, v26, v8], fixed_args=3, fp_return=true, fp_arg_mask=0x4 } -> d0 diff --git a/tests/snapshots/ssa/fp_load_folded_disp.ssa b/tests/snapshots/ssa/fp_load_folded_disp.ssa new file mode 100644 index 000000000..6a6ed4450 --- /dev/null +++ b/tests/snapshots/ssa/fp_load_folded_disp.ssa @@ -0,0 +1,186 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=read_f +fn ent_pc=0 n_params=1 variadic=false locals=0 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I64 } -> x0 + v4 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x0 + v5 Load { addr=v1, disp=8, kind=F32 } -> d0 [f32] + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=read_d +fn ent_pc=1 n_params=1 variadic=false locals=0 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I64 } -> x0 + v4 BinopI { op=add, lhs=v1, rhs_imm=16 } -> x0 + v5 Load { addr=v1, disp=16, kind=F64 } -> d0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=read_g2 +fn ent_pc=2 n_params=1 variadic=false locals=0 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I64 } -> x0 + v4 BinopI { op=add, lhs=v1, rhs_imm=24 } -> x0 + v5 Imm(8) -> x0 + v6 BinopI { op=add, lhs=v1, rhs_imm=32 } -> x0 + v7 Load { addr=v1, disp=32, kind=F32 } -> d0 [f32] + terminator Return(v7) (exit_acc=v7) +; --- SSA dump (ok=true) ent_pc=3 --- +; name=bump_d +fn ent_pc=3 n_params=1 variadic=false locals=0 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I64 } -> x0 + v4 BinopI { op=add, lhs=v1, rhs_imm=16 } -> x0 + v5 Load { addr=v1, disp=16, kind=F64 } -> d0 + v6 Imm(4602678819172646912) -> x0 + v7 Binop { op=fadd, lhs=v5, rhs=v6 } -> d0 + v8 Store { addr=v1, disp=16, value=v7, kind=F64 } -> - + v9 Imm(0) -> x0 + terminator Return(v9) (exit_acc=v9) +; --- SSA dump (ok=true) ent_pc=4 --- +; name=main +fn ent_pc=4 n_params=0 variadic=false locals=6 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-5) -> x0 + v2 Imm(-1) -> x1 + v3 Store { addr=v1, disp=0, value=v2, kind=I64 } -> - + v4 LocalAddr(-5) -> x0 + v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x1 + v6 Imm(4608308318706860032) -> x1 + v7 FpCast { kind=F64ToF32, value=v6 } -> d0 [f32] + v8 Store { addr=v4, disp=8, value=v7, kind=F32 } -> - + v9 LocalAddr(-5) -> x0 + v10 BinopI { op=add, lhs=v9, rhs_imm=16 } -> x2 + v11 Imm(4612811918334230528) -> x2 + v12 Store { addr=v9, disp=16, value=v11, kind=F64 } -> - + v13 LocalAddr(-5) -> x0 + v14 BinopI { op=add, lhs=v13, rhs_imm=24 } -> x2 + v15 Imm(0) -> x2 + v16 FpCast { kind=F64ToF32, value=v15 } -> d0 [f32] + v17 Store { addr=v13, disp=24, value=v16, kind=F32 } -> - + v18 LocalAddr(-5) -> x0 + v19 BinopI { op=add, lhs=v18, rhs_imm=24 } -> x2 + v20 Imm(4) -> x2 + v21 BinopI { op=add, lhs=v18, rhs_imm=28 } -> x2 + v22 Store { addr=v18, disp=28, value=v16, kind=F32 } -> - + v23 LocalAddr(-5) -> x0 + v24 BinopI { op=add, lhs=v23, rhs_imm=24 } -> x2 + v25 Imm(8) -> x2 + v26 BinopI { op=add, lhs=v23, rhs_imm=32 } -> x2 + v27 Imm(4617034042984890368) -> x2 + v28 FpCast { kind=F64ToF32, value=v27 } -> d0 [f32] + v29 Store { addr=v23, disp=32, value=v28, kind=F32 } -> - + v30 LocalAddr(-5) -> x0 + v31 Imm(0) -> x2 + v32 BinopI { op=add, lhs=v30, rhs_imm=8 } -> x2 + v33 Load { addr=v30, disp=8, kind=F32 } -> d0 [f32] + v34 FpCast { kind=F32ToF64, value=v33 } -> d0 + v35 Binop { op=fne, lhs=v34, rhs=v6 } -> x0 + terminator Bz { cond=v35, target=b2, fall=b1 } (exit_acc=v35) + block 1 start_pc=0 + v36 Imm(1) -> x0 + terminator Return(v36) (exit_acc=v36) + block 2 start_pc=0 + v37 LocalAddr(-5) -> x0 + v38 Imm(0) -> x1 + v39 BinopI { op=add, lhs=v37, rhs_imm=16 } -> x1 + v40 Load { addr=v37, disp=16, kind=F64 } -> d0 + v41 Imm(4612811918334230528) -> x0 + v42 Binop { op=fne, lhs=v40, rhs=v41 } -> x0 + terminator Bz { cond=v42, target=b4, fall=b3 } (exit_acc=v42) + block 3 start_pc=0 + v43 Imm(2) -> x0 + terminator Return(v43) (exit_acc=v43) + block 4 start_pc=0 + v44 LocalAddr(-5) -> x0 + v45 Imm(0) -> x1 + v46 BinopI { op=add, lhs=v44, rhs_imm=24 } -> x1 + v47 Imm(8) -> x1 + v48 BinopI { op=add, lhs=v44, rhs_imm=32 } -> x1 + v49 Load { addr=v44, disp=32, kind=F32 } -> d0 [f32] + v50 Imm(4617034042984890368) -> x0 + v51 FpCast { kind=F32ToF64, value=v49 } -> d0 + v52 Binop { op=fne, lhs=v51, rhs=v50 } -> x0 + terminator Bz { cond=v52, target=b6, fall=b5 } (exit_acc=v52) + block 5 start_pc=0 + v53 Imm(3) -> x0 + terminator Return(v53) (exit_acc=v53) + block 6 start_pc=0 + v54 LocalAddr(-5) -> x7 + v55 Call { target_pc=3, args=[v54], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + v56 LocalAddr(-5) -> x0 + v57 BinopI { op=add, lhs=v56, rhs_imm=16 } -> x1 + v58 Load { addr=v56, disp=16, kind=F64 } -> d0 + v59 Imm(4613937818241073152) -> x0 + v60 Binop { op=fne, lhs=v58, rhs=v59 } -> x0 + terminator Bz { cond=v60, target=b8, fall=b7 } (exit_acc=v60) + block 7 start_pc=0 + v61 Imm(4) -> x0 + terminator Return(v61) (exit_acc=v61) + block 8 start_pc=0 + v62 Imm(0) -> x0 + terminator Return(v62) (exit_acc=v62) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/fp_param_ternary.ssa b/tests/snapshots/ssa/fp_param_ternary.ssa index 744c939c7..c239b7da6 100644 --- a/tests/snapshots/ssa/fp_param_ternary.ssa +++ b/tests/snapshots/ssa/fp_param_ternary.ssa @@ -6,25 +6,24 @@ fn ent_pc=1 n_params=2 variadic=false locals=2 v0 AllocaInit(0) -> - v1 ParamRef(0, kind=I32) -> x7 v2 Imm(0) -> x0 - v3 ParamRef(1, kind=F32) -> d0 [f32] + v3 ParamRef(1, kind=F32) -> d1 [f32] v4 Imm(0) -> x0 v5 LoadLocal { off=2, kind=I32 } -> x0 v6 BinopI { op=and, lhs=v1, rhs_imm=1 } -> x0 terminator Bz { cond=v6, target=b2, fall=b1 } (exit_acc=v6) block 1 start_pc=0 - v7 LoadLocal { off=-1, kind=F32 } -> d1 [f32] - v8 LocalAddr(-2) -> x0 - v9 Store { addr=v8, disp=0, value=v3, kind=F32 } -> - - terminator Jmp(b3) (exit_acc=v9) + v7 LoadLocal { off=-1, kind=F32 } -> d0 [f32] + v8 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v3) block 2 start_pc=0 - v10 LoadLocal { off=-1, kind=F32 } -> d1 [f32] - v11 Fneg(v3) -> d0 [f32] - v12 LocalAddr(-2) -> x0 - v13 Store { addr=v12, disp=0, value=v11, kind=F32 } -> - - terminator Jmp(b3) (exit_acc=v13) + v9 LoadLocal { off=-1, kind=F32 } -> d0 [f32] + v10 Fneg(v3) -> d1 [f32] + v11 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v10) block 3 start_pc=0 - v14 LoadLocal { off=-2, kind=F32 } -> d0 [f32] - terminator Return(v14) (exit_acc=v14) + v12 Phi { incoming=[b1:v3, b2:v10], kind=F32 } -> d1 [f32] + v13 LoadLocal { off=-2, kind=F32 } -> d0 [f32] + terminator Return(v12) (exit_acc=v12) ; --- SSA dump (ok=true) ent_pc=2 --- ; name=grad_dot fn ent_pc=2 n_params=3 variadic=false locals=6 @@ -33,7 +32,7 @@ fn ent_pc=2 n_params=3 variadic=false locals=6 v0 AllocaInit(0) -> - v1 ParamRef(0, kind=I32) -> x7 v2 Imm(0) -> x0 - v3 ParamRef(1, kind=F32) -> d0 [f32] + v3 ParamRef(1, kind=F32) -> d2 [f32] v4 Imm(0) -> x0 v5 ParamRef(2, kind=F32) -> d1 [f32] v6 Imm(0) -> x0 @@ -41,40 +40,38 @@ fn ent_pc=2 n_params=3 variadic=false locals=6 v8 BinopI { op=and, lhs=v1, rhs_imm=1 } -> x0 terminator Bz { cond=v8, target=b2, fall=b1 } (exit_acc=v8) block 1 start_pc=0 - v9 LoadLocal { off=-1, kind=F32 } -> d2 [f32] - v10 LocalAddr(-5) -> x0 - v11 Store { addr=v10, disp=0, value=v3, kind=F32 } -> - - terminator Jmp(b3) (exit_acc=v11) + v9 LoadLocal { off=-1, kind=F32 } -> d0 [f32] + v10 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v3) block 2 start_pc=0 - v12 LoadLocal { off=-1, kind=F32 } -> d2 [f32] - v13 Fneg(v3) -> d0 [f32] - v14 LocalAddr(-5) -> x0 - v15 Store { addr=v14, disp=0, value=v13, kind=F32 } -> - - terminator Jmp(b3) (exit_acc=v15) + v11 LoadLocal { off=-1, kind=F32 } -> d0 [f32] + v12 Fneg(v3) -> d2 [f32] + v13 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v12) block 3 start_pc=0 - v16 LoadLocal { off=-5, kind=F32 } -> d0 [f32] - v17 Imm(0) -> x0 - v18 LoadLocal { off=2, kind=I32 } -> x0 - v19 BinopI { op=and, lhs=v1, rhs_imm=2 } -> x0 - terminator Bz { cond=v19, target=b5, fall=b4 } (exit_acc=v19) + v14 Phi { incoming=[b1:v3, b2:v12], kind=F32 } -> d2 [f32] + v15 LoadLocal { off=-5, kind=F32 } -> d0 [f32] + v16 Imm(0) -> x0 + v17 LoadLocal { off=2, kind=I32 } -> x0 + v18 BinopI { op=and, lhs=v1, rhs_imm=2 } -> x0 + terminator Bz { cond=v18, target=b5, fall=b4 } (exit_acc=v18) block 4 start_pc=0 - v20 LoadLocal { off=-2, kind=F32 } -> d2 [f32] - v21 LocalAddr(-6) -> x0 - v22 Store { addr=v21, disp=0, value=v5, kind=F32 } -> - - terminator Jmp(b6) (exit_acc=v22) + v19 LoadLocal { off=-2, kind=F32 } -> d0 [f32] + v20 Imm(0) -> x0 + terminator Jmp(b6) (exit_acc=v5) block 5 start_pc=0 - v23 LoadLocal { off=-2, kind=F32 } -> d2 [f32] - v24 Fneg(v5) -> d1 [f32] - v25 LocalAddr(-6) -> x0 - v26 Store { addr=v25, disp=0, value=v24, kind=F32 } -> - - terminator Jmp(b6) (exit_acc=v26) + v21 LoadLocal { off=-2, kind=F32 } -> d0 [f32] + v22 Fneg(v5) -> d1 [f32] + v23 Imm(0) -> x0 + terminator Jmp(b6) (exit_acc=v22) block 6 start_pc=0 - v27 LoadLocal { off=-6, kind=F32 } -> d1 [f32] - v28 Imm(0) -> x0 - v29 LoadLocal { off=-3, kind=F32 } -> d2 [f32] - v30 LoadLocal { off=-4, kind=F32 } -> d2 [f32] - v31 Binop { op=fadd, lhs=v16, rhs=v27 } -> d0 [f32] - terminator Return(v31) (exit_acc=v31) + v24 Phi { incoming=[b4:v5, b5:v22], kind=F32 } -> d1 [f32] + v25 LoadLocal { off=-6, kind=F32 } -> d0 [f32] + v26 Imm(0) -> x0 + v27 LoadLocal { off=-3, kind=F32 } -> d0 [f32] + v28 LoadLocal { off=-4, kind=F32 } -> d0 [f32] + v29 Binop { op=fadd, lhs=v14, rhs=v24 } -> d0 [f32] + terminator Return(v29) (exit_acc=v29) ; --- SSA dump (ok=true) ent_pc=3 --- ; name=main fn ent_pc=3 n_params=0 variadic=false locals=3 diff --git a/tests/snapshots/ssa/hfa_param_interleave.ssa b/tests/snapshots/ssa/hfa_param_interleave.ssa index 77bf6e746..9df4cfbe4 100644 --- a/tests/snapshots/ssa/hfa_param_interleave.ssa +++ b/tests/snapshots/ssa/hfa_param_interleave.ssa @@ -9,29 +9,29 @@ fn ent_pc=0 n_params=6 variadic=false locals=6 v3 LocalAddr(-1) -> x0 v4 Load { addr=v3, disp=0, kind=F32 } -> d1 [f32] v5 LocalAddr(-1) -> x0 - v6 BinopI { op=add, lhs=v5, rhs_imm=4 } -> x0 - v7 Load { addr=v6, disp=0, kind=F32 } -> d2 [f32] + v6 BinopI { op=add, lhs=v5, rhs_imm=4 } -> x1 + v7 Load { addr=v5, disp=4, kind=F32 } -> d2 [f32] v8 Binop { op=fadd, lhs=v4, rhs=v7 } -> d1 [f32] v9 LocalAddr(-2) -> x0 v10 Load { addr=v9, disp=0, kind=F32 } -> d2 [f32] v11 Binop { op=fadd, lhs=v8, rhs=v10 } -> d1 [f32] v12 LocalAddr(-2) -> x0 - v13 BinopI { op=add, lhs=v12, rhs_imm=4 } -> x0 - v14 Load { addr=v13, disp=0, kind=F32 } -> d2 [f32] + v13 BinopI { op=add, lhs=v12, rhs_imm=4 } -> x1 + v14 Load { addr=v12, disp=4, kind=F32 } -> d2 [f32] v15 Binop { op=fadd, lhs=v11, rhs=v14 } -> d1 [f32] v16 LocalAddr(-3) -> x0 v17 Load { addr=v16, disp=0, kind=F32 } -> d2 [f32] v18 Binop { op=fadd, lhs=v15, rhs=v17 } -> d1 [f32] v19 LocalAddr(-3) -> x0 - v20 BinopI { op=add, lhs=v19, rhs_imm=4 } -> x0 - v21 Load { addr=v20, disp=0, kind=F32 } -> d2 [f32] + v20 BinopI { op=add, lhs=v19, rhs_imm=4 } -> x1 + v21 Load { addr=v19, disp=4, kind=F32 } -> d2 [f32] v22 Binop { op=fadd, lhs=v18, rhs=v21 } -> d1 [f32] v23 LocalAddr(-4) -> x0 v24 Load { addr=v23, disp=0, kind=F32 } -> d2 [f32] v25 Binop { op=fadd, lhs=v22, rhs=v24 } -> d1 [f32] v26 LocalAddr(-4) -> x0 - v27 BinopI { op=add, lhs=v26, rhs_imm=4 } -> x0 - v28 Load { addr=v27, disp=0, kind=F32 } -> d2 [f32] + v27 BinopI { op=add, lhs=v26, rhs_imm=4 } -> x1 + v28 Load { addr=v26, disp=4, kind=F32 } -> d2 [f32] v29 Binop { op=fadd, lhs=v25, rhs=v28 } -> d1 [f32] v30 LoadLocal { off=-6, kind=F32 } -> d2 [f32] v31 Binop { op=fadd, lhs=v29, rhs=v1 } -> d0 [f32] diff --git a/tests/snapshots/ssa/hfa_struct_return.ssa b/tests/snapshots/ssa/hfa_struct_return.ssa index d7f7f8a9d..8c8399831 100644 --- a/tests/snapshots/ssa/hfa_struct_return.ssa +++ b/tests/snapshots/ssa/hfa_struct_return.ssa @@ -25,9 +25,9 @@ fn ent_pc=1 n_params=2 variadic=false locals=2 v6 LoadLocal { off=2, kind=F64 } -> d2 v7 Store { addr=v5, disp=0, value=v1, kind=F64 } -> - v8 LocalAddr(-2) -> x0 - v9 BinopI { op=add, lhs=v8, rhs_imm=8 } -> x0 + v9 BinopI { op=add, lhs=v8, rhs_imm=8 } -> x1 v10 LoadLocal { off=3, kind=F64 } -> d0 - v11 Store { addr=v9, disp=0, value=v3, kind=F64 } -> - + v11 Store { addr=v8, disp=8, value=v3, kind=F64 } -> - v12 LocalAddr(-2) -> x0 terminator Return(v12) (exit_acc=v12) ; --- SSA dump (ok=true) ent_pc=2 --- @@ -40,13 +40,13 @@ fn ent_pc=2 n_params=4 variadic=false locals=3 v2 LoadLocal { off=3, kind=F64 } -> d0 v3 Store { addr=v1, disp=0, value=v2, kind=F64 } -> - v4 LocalAddr(-3) -> x0 - v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x0 + v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x1 v6 LoadLocal { off=4, kind=F64 } -> d0 - v7 Store { addr=v5, disp=0, value=v6, kind=F64 } -> - + v7 Store { addr=v4, disp=8, value=v6, kind=F64 } -> - v8 LocalAddr(-3) -> x0 - v9 BinopI { op=add, lhs=v8, rhs_imm=16 } -> x0 + v9 BinopI { op=add, lhs=v8, rhs_imm=16 } -> x1 v10 LoadLocal { off=5, kind=F64 } -> d0 - v11 Store { addr=v9, disp=0, value=v10, kind=F64 } -> - + v11 Store { addr=v8, disp=16, value=v10, kind=F64 } -> - v12 LoadLocal { off=2, kind=I64 } -> x0 v13 LocalAddr(-3) -> x1 v14 Mcpy { dst=v12, src=v13, size=24 } -> x1 @@ -61,17 +61,17 @@ fn ent_pc=3 n_params=5 variadic=false locals=4 v2 LoadLocal { off=3, kind=F64 } -> d0 v3 Store { addr=v1, disp=0, value=v2, kind=F64 } -> - v4 LocalAddr(-4) -> x0 - v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x0 + v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x1 v6 LoadLocal { off=4, kind=F64 } -> d0 - v7 Store { addr=v5, disp=0, value=v6, kind=F64 } -> - + v7 Store { addr=v4, disp=8, value=v6, kind=F64 } -> - v8 LocalAddr(-4) -> x0 - v9 BinopI { op=add, lhs=v8, rhs_imm=16 } -> x0 + v9 BinopI { op=add, lhs=v8, rhs_imm=16 } -> x1 v10 LoadLocal { off=5, kind=F64 } -> d0 - v11 Store { addr=v9, disp=0, value=v10, kind=F64 } -> - + v11 Store { addr=v8, disp=16, value=v10, kind=F64 } -> - v12 LocalAddr(-4) -> x0 - v13 BinopI { op=add, lhs=v12, rhs_imm=24 } -> x0 + v13 BinopI { op=add, lhs=v12, rhs_imm=24 } -> x1 v14 LoadLocal { off=6, kind=F64 } -> d0 - v15 Store { addr=v13, disp=0, value=v14, kind=F64 } -> - + v15 Store { addr=v12, disp=24, value=v14, kind=F64 } -> - v16 LoadLocal { off=2, kind=I64 } -> x0 v17 LocalAddr(-4) -> x1 v18 Mcpy { dst=v16, src=v17, size=32 } -> x1 @@ -90,9 +90,9 @@ fn ent_pc=4 n_params=2 variadic=false locals=3 v6 LoadLocal { off=-1, kind=F32 } -> d2 [f32] v7 Store { addr=v5, disp=0, value=v1, kind=F32 } -> - v8 LocalAddr(-3) -> x0 - v9 BinopI { op=add, lhs=v8, rhs_imm=4 } -> x0 + v9 BinopI { op=add, lhs=v8, rhs_imm=4 } -> x1 v10 LoadLocal { off=-2, kind=F32 } -> d0 [f32] - v11 Store { addr=v9, disp=0, value=v3, kind=F32 } -> - + v11 Store { addr=v8, disp=4, value=v3, kind=F32 } -> - v12 LocalAddr(-3) -> x0 terminator Return(v12) (exit_acc=v12) ; --- SSA dump (ok=true) ent_pc=5 --- @@ -104,8 +104,8 @@ fn ent_pc=5 n_params=1 variadic=false locals=2 v1 LocalAddr(-2) -> x0 v2 Load { addr=v1, disp=0, kind=F64 } -> d0 v3 LocalAddr(-2) -> x0 - v4 BinopI { op=add, lhs=v3, rhs_imm=8 } -> x0 - v5 Load { addr=v4, disp=0, kind=F64 } -> d1 + v4 BinopI { op=add, lhs=v3, rhs_imm=8 } -> x1 + v5 Load { addr=v3, disp=8, kind=F64 } -> d1 v6 Binop { op=fadd, lhs=v2, rhs=v5 } -> d0 terminator Return(v6) (exit_acc=v6) ; --- SSA dump (ok=true) ent_pc=6 --- @@ -117,16 +117,16 @@ fn ent_pc=6 n_params=1 variadic=false locals=4 v1 LocalAddr(-4) -> x0 v2 Load { addr=v1, disp=0, kind=F64 } -> d0 v3 LocalAddr(-4) -> x0 - v4 BinopI { op=add, lhs=v3, rhs_imm=8 } -> x0 - v5 Load { addr=v4, disp=0, kind=F64 } -> d1 + v4 BinopI { op=add, lhs=v3, rhs_imm=8 } -> x1 + v5 Load { addr=v3, disp=8, kind=F64 } -> d1 v6 Binop { op=fadd, lhs=v2, rhs=v5 } -> d0 v7 LocalAddr(-4) -> x0 - v8 BinopI { op=add, lhs=v7, rhs_imm=16 } -> x0 - v9 Load { addr=v8, disp=0, kind=F64 } -> d1 + v8 BinopI { op=add, lhs=v7, rhs_imm=16 } -> x1 + v9 Load { addr=v7, disp=16, kind=F64 } -> d1 v10 Binop { op=fadd, lhs=v6, rhs=v9 } -> d0 v11 LocalAddr(-4) -> x0 - v12 BinopI { op=add, lhs=v11, rhs_imm=24 } -> x0 - v13 Load { addr=v12, disp=0, kind=F64 } -> d1 + v12 BinopI { op=add, lhs=v11, rhs_imm=24 } -> x1 + v13 Load { addr=v11, disp=24, kind=F64 } -> d1 v14 Binop { op=fadd, lhs=v10, rhs=v13 } -> d0 terminator Return(v14) (exit_acc=v14) ; --- SSA dump (ok=true) ent_pc=7 --- @@ -138,16 +138,16 @@ fn ent_pc=7 n_params=1 variadic=false locals=2 v1 LocalAddr(-2) -> x0 v2 Load { addr=v1, disp=0, kind=F32 } -> d0 [f32] v3 LocalAddr(-2) -> x0 - v4 BinopI { op=add, lhs=v3, rhs_imm=4 } -> x0 - v5 Load { addr=v4, disp=0, kind=F32 } -> d1 [f32] + v4 BinopI { op=add, lhs=v3, rhs_imm=4 } -> x1 + v5 Load { addr=v3, disp=4, kind=F32 } -> d1 [f32] v6 Binop { op=fadd, lhs=v2, rhs=v5 } -> d0 [f32] v7 LocalAddr(-2) -> x0 - v8 BinopI { op=add, lhs=v7, rhs_imm=8 } -> x0 - v9 Load { addr=v8, disp=0, kind=F32 } -> d1 [f32] + v8 BinopI { op=add, lhs=v7, rhs_imm=8 } -> x1 + v9 Load { addr=v7, disp=8, kind=F32 } -> d1 [f32] v10 Binop { op=fadd, lhs=v6, rhs=v9 } -> d0 [f32] v11 LocalAddr(-2) -> x0 - v12 BinopI { op=add, lhs=v11, rhs_imm=12 } -> x0 - v13 Load { addr=v12, disp=0, kind=F32 } -> d1 [f32] + v12 BinopI { op=add, lhs=v11, rhs_imm=12 } -> x1 + v13 Load { addr=v11, disp=12, kind=F32 } -> d1 [f32] v14 Binop { op=fadd, lhs=v10, rhs=v13 } -> d0 [f32] terminator Return(v14) (exit_acc=v14) ; --- SSA dump (ok=true) ent_pc=8 --- @@ -182,8 +182,8 @@ fn ent_pc=8 n_params=0 variadic=false locals=45 terminator Bnz { cond=v18, target=b31, fall=b3 } (exit_acc=v18) block 3 start_pc=0 v20 LocalAddr(-4) -> x0 - v21 BinopI { op=add, lhs=v20, rhs_imm=8 } -> x0 - v22 Load { addr=v21, disp=0, kind=F64 } -> d0 + v21 BinopI { op=add, lhs=v20, rhs_imm=8 } -> x1 + v22 Load { addr=v20, disp=8, kind=F64 } -> d0 v23 Imm(4602678819172646912) -> x0 v24 Binop { op=fne, lhs=v22, rhs=v23 } -> x3 v25 Imm(0) -> x0 @@ -214,8 +214,8 @@ fn ent_pc=8 n_params=0 variadic=false locals=45 terminator Bnz { cond=v41, target=b32, fall=b7 } (exit_acc=v41) block 7 start_pc=0 v44 LocalAddr(-9) -> x0 - v45 BinopI { op=add, lhs=v44, rhs_imm=8 } -> x0 - v46 Load { addr=v45, disp=0, kind=F64 } -> d0 + v45 BinopI { op=add, lhs=v44, rhs_imm=8 } -> x1 + v46 Load { addr=v44, disp=8, kind=F64 } -> d0 v47 Imm(4611686018427387904) -> x0 v48 Binop { op=fne, lhs=v46, rhs=v47 } -> x0 v49 BinopI { op=ne, lhs=v48, rhs_imm=0 } -> x3 @@ -228,8 +228,8 @@ fn ent_pc=8 n_params=0 variadic=false locals=45 terminator Bnz { cond=v51, target=b33, fall=b9 } (exit_acc=v51) block 9 start_pc=0 v54 LocalAddr(-9) -> x0 - v55 BinopI { op=add, lhs=v54, rhs_imm=16 } -> x0 - v56 Load { addr=v55, disp=0, kind=F64 } -> d0 + v55 BinopI { op=add, lhs=v54, rhs_imm=16 } -> x1 + v56 Load { addr=v54, disp=16, kind=F64 } -> d0 v57 Imm(4613937818241073152) -> x0 v58 Binop { op=fne, lhs=v56, rhs=v57 } -> x3 v59 Imm(0) -> x0 @@ -261,8 +261,8 @@ fn ent_pc=8 n_params=0 variadic=false locals=45 terminator Bnz { cond=v76, target=b34, fall=b13 } (exit_acc=v76) block 13 start_pc=0 v79 LocalAddr(-16) -> x0 - v80 BinopI { op=add, lhs=v79, rhs_imm=8 } -> x0 - v81 Load { addr=v80, disp=0, kind=F64 } -> d0 + v80 BinopI { op=add, lhs=v79, rhs_imm=8 } -> x1 + v81 Load { addr=v79, disp=8, kind=F64 } -> d0 v82 Imm(4626322717216342016) -> x0 v83 Binop { op=fne, lhs=v81, rhs=v82 } -> x0 v84 BinopI { op=ne, lhs=v83, rhs_imm=0 } -> x3 @@ -276,8 +276,8 @@ fn ent_pc=8 n_params=0 variadic=false locals=45 terminator Bnz { cond=v86, target=b35, fall=b15 } (exit_acc=v86) block 15 start_pc=0 v90 LocalAddr(-16) -> x0 - v91 BinopI { op=add, lhs=v90, rhs_imm=16 } -> x0 - v92 Load { addr=v91, disp=0, kind=F64 } -> d0 + v91 BinopI { op=add, lhs=v90, rhs_imm=16 } -> x1 + v92 Load { addr=v90, disp=16, kind=F64 } -> d0 v93 Imm(4629137466983448576) -> x0 v94 Binop { op=fne, lhs=v92, rhs=v93 } -> x0 v95 BinopI { op=ne, lhs=v94, rhs_imm=0 } -> x12 @@ -290,8 +290,8 @@ fn ent_pc=8 n_params=0 variadic=false locals=45 terminator Bnz { cond=v97, target=b36, fall=b17 } (exit_acc=v97) block 17 start_pc=0 v100 LocalAddr(-16) -> x0 - v101 BinopI { op=add, lhs=v100, rhs_imm=24 } -> x0 - v102 Load { addr=v101, disp=0, kind=F64 } -> d0 + v101 BinopI { op=add, lhs=v100, rhs_imm=24 } -> x1 + v102 Load { addr=v100, disp=24, kind=F64 } -> d0 v103 Imm(4630826316843712512) -> x0 v104 Binop { op=fne, lhs=v102, rhs=v103 } -> x12 v105 Imm(0) -> x0 @@ -320,8 +320,8 @@ fn ent_pc=8 n_params=0 variadic=false locals=45 terminator Bnz { cond=v120, target=b37, fall=b21 } (exit_acc=v120) block 21 start_pc=0 v122 LocalAddr(-21) -> x0 - v123 BinopI { op=add, lhs=v122, rhs_imm=4 } -> x0 - v124 Load { addr=v123, disp=0, kind=F32 } -> d0 [f32] + v123 BinopI { op=add, lhs=v122, rhs_imm=4 } -> x1 + v124 Load { addr=v122, disp=4, kind=F32 } -> d0 [f32] v125 Imm(4612811918334230528) -> x0 v126 FpCast { kind=F32ToF64, value=v124 } -> d0 v127 Binop { op=fne, lhs=v126, rhs=v125 } -> x3 diff --git a/tests/snapshots/ssa/indirect_call_target_scratch_exhausted.ssa b/tests/snapshots/ssa/indirect_call_target_scratch_exhausted.ssa new file mode 100644 index 000000000..33163816c --- /dev/null +++ b/tests/snapshots/ssa/indirect_call_target_scratch_exhausted.ssa @@ -0,0 +1,322 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=sum17 +fn ent_pc=0 n_params=17 variadic=false locals=0 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 ParamRef(2, kind=I64) -> x2 + v6 Imm(0) -> x0 + v7 ParamRef(3, kind=I64) -> x1 + v8 Imm(0) -> x0 + v9 ParamRef(4, kind=I64) -> x8 + v10 Imm(0) -> x0 + v11 ParamRef(5, kind=I64) -> x9 + v12 Imm(0) -> x0 + v13 LoadLocal { off=2, kind=I64 } -> x0 + v14 LoadLocal { off=3, kind=I64 } -> x0 + v15 Binop { op=add, lhs=v1, rhs=v3 } -> x0 + v16 LoadLocal { off=4, kind=I64 } -> x6 + v17 Binop { op=add, lhs=v15, rhs=v5 } -> x0 + v18 LoadLocal { off=5, kind=I64 } -> x2 + v19 Binop { op=add, lhs=v17, rhs=v7 } -> x0 + v20 LoadLocal { off=6, kind=I64 } -> x1 + v21 Binop { op=add, lhs=v19, rhs=v9 } -> x0 + v22 LoadLocal { off=7, kind=I64 } -> x1 + v23 Binop { op=add, lhs=v21, rhs=v11 } -> x0 + v24 LoadLocal { off=8, kind=I64 } -> x1 + v25 Binop { op=add, lhs=v23, rhs=v24 } -> x0 + v26 LoadLocal { off=9, kind=I64 } -> x1 + v27 Binop { op=add, lhs=v25, rhs=v26 } -> x0 + v28 LoadLocal { off=10, kind=I64 } -> x1 + v29 Binop { op=add, lhs=v27, rhs=v28 } -> x0 + v30 LoadLocal { off=11, kind=I64 } -> x1 + v31 Binop { op=add, lhs=v29, rhs=v30 } -> x0 + v32 LoadLocal { off=12, kind=I64 } -> x1 + v33 Binop { op=add, lhs=v31, rhs=v32 } -> x0 + v34 LoadLocal { off=13, kind=I64 } -> x1 + v35 Binop { op=add, lhs=v33, rhs=v34 } -> x0 + v36 LoadLocal { off=14, kind=I64 } -> x1 + v37 Binop { op=add, lhs=v35, rhs=v36 } -> x0 + v38 LoadLocal { off=15, kind=I64 } -> x1 + v39 Binop { op=add, lhs=v37, rhs=v38 } -> x0 + v40 LoadLocal { off=16, kind=I64 } -> x1 + v41 Binop { op=add, lhs=v39, rhs=v40 } -> x0 + v42 LoadLocal { off=17, kind=I64 } -> x1 + v43 Binop { op=add, lhs=v41, rhs=v42 } -> x0 + v44 LoadLocal { off=18, kind=I64 } -> x1 + v45 Binop { op=add, lhs=v43, rhs=v44 } -> x0 + terminator Return(v45) (exit_acc=v45) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=sum16p +fn ent_pc=1 n_params=16 variadic=false locals=32 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-2) -> x0 + v2 Load { addr=v1, disp=0, kind=I64 } -> x0 + v3 LocalAddr(-2) -> x1 + v4 BinopI { op=add, lhs=v3, rhs_imm=8 } -> x2 + v5 Load { addr=v3, disp=8, kind=I64 } -> x1 + v6 Binop { op=add, lhs=v2, rhs=v5 } -> x0 + v7 LocalAddr(-4) -> x1 + v8 Load { addr=v7, disp=0, kind=I64 } -> x1 + v9 Binop { op=add, lhs=v6, rhs=v8 } -> x0 + v10 LocalAddr(-4) -> x1 + v11 BinopI { op=add, lhs=v10, rhs_imm=8 } -> x2 + v12 Load { addr=v10, disp=8, kind=I64 } -> x1 + v13 Binop { op=add, lhs=v9, rhs=v12 } -> x0 + v14 LocalAddr(-6) -> x1 + v15 Load { addr=v14, disp=0, kind=I64 } -> x1 + v16 Binop { op=add, lhs=v13, rhs=v15 } -> x0 + v17 LocalAddr(-6) -> x1 + v18 BinopI { op=add, lhs=v17, rhs_imm=8 } -> x2 + v19 Load { addr=v17, disp=8, kind=I64 } -> x1 + v20 Binop { op=add, lhs=v16, rhs=v19 } -> x0 + v21 LocalAddr(-8) -> x1 + v22 Load { addr=v21, disp=0, kind=I64 } -> x1 + v23 Binop { op=add, lhs=v20, rhs=v22 } -> x0 + v24 LocalAddr(-8) -> x1 + v25 BinopI { op=add, lhs=v24, rhs_imm=8 } -> x2 + v26 Load { addr=v24, disp=8, kind=I64 } -> x1 + v27 Binop { op=add, lhs=v23, rhs=v26 } -> x0 + v28 LocalAddr(-10) -> x1 + v29 Load { addr=v28, disp=0, kind=I64 } -> x1 + v30 Binop { op=add, lhs=v27, rhs=v29 } -> x0 + v31 LocalAddr(-10) -> x1 + v32 BinopI { op=add, lhs=v31, rhs_imm=8 } -> x2 + v33 Load { addr=v31, disp=8, kind=I64 } -> x1 + v34 Binop { op=add, lhs=v30, rhs=v33 } -> x0 + v35 LocalAddr(-12) -> x1 + v36 Load { addr=v35, disp=0, kind=I64 } -> x1 + v37 Binop { op=add, lhs=v34, rhs=v36 } -> x0 + v38 LocalAddr(-12) -> x1 + v39 BinopI { op=add, lhs=v38, rhs_imm=8 } -> x2 + v40 Load { addr=v38, disp=8, kind=I64 } -> x1 + v41 Binop { op=add, lhs=v37, rhs=v40 } -> x0 + v42 LocalAddr(-14) -> x1 + v43 Load { addr=v42, disp=0, kind=I64 } -> x1 + v44 Binop { op=add, lhs=v41, rhs=v43 } -> x0 + v45 LocalAddr(-14) -> x1 + v46 BinopI { op=add, lhs=v45, rhs_imm=8 } -> x2 + v47 Load { addr=v45, disp=8, kind=I64 } -> x1 + v48 Binop { op=add, lhs=v44, rhs=v47 } -> x0 + v49 LocalAddr(-16) -> x1 + v50 Load { addr=v49, disp=0, kind=I64 } -> x1 + v51 Binop { op=add, lhs=v48, rhs=v50 } -> x0 + v52 LocalAddr(-16) -> x1 + v53 BinopI { op=add, lhs=v52, rhs_imm=8 } -> x2 + v54 Load { addr=v52, disp=8, kind=I64 } -> x1 + v55 Binop { op=add, lhs=v51, rhs=v54 } -> x0 + v56 LocalAddr(-18) -> x1 + v57 Load { addr=v56, disp=0, kind=I64 } -> x1 + v58 Binop { op=add, lhs=v55, rhs=v57 } -> x0 + v59 LocalAddr(-18) -> x1 + v60 BinopI { op=add, lhs=v59, rhs_imm=8 } -> x2 + v61 Load { addr=v59, disp=8, kind=I64 } -> x1 + v62 Binop { op=add, lhs=v58, rhs=v61 } -> x0 + v63 LocalAddr(-20) -> x1 + v64 Load { addr=v63, disp=0, kind=I64 } -> x1 + v65 Binop { op=add, lhs=v62, rhs=v64 } -> x0 + v66 LocalAddr(-20) -> x1 + v67 BinopI { op=add, lhs=v66, rhs_imm=8 } -> x2 + v68 Load { addr=v66, disp=8, kind=I64 } -> x1 + v69 Binop { op=add, lhs=v65, rhs=v68 } -> x0 + v70 LocalAddr(-22) -> x1 + v71 Load { addr=v70, disp=0, kind=I64 } -> x1 + v72 Binop { op=add, lhs=v69, rhs=v71 } -> x0 + v73 LocalAddr(-22) -> x1 + v74 BinopI { op=add, lhs=v73, rhs_imm=8 } -> x2 + v75 Load { addr=v73, disp=8, kind=I64 } -> x1 + v76 Binop { op=add, lhs=v72, rhs=v75 } -> x0 + v77 LocalAddr(-24) -> x1 + v78 Load { addr=v77, disp=0, kind=I64 } -> x1 + v79 Binop { op=add, lhs=v76, rhs=v78 } -> x0 + v80 LocalAddr(-24) -> x1 + v81 BinopI { op=add, lhs=v80, rhs_imm=8 } -> x2 + v82 Load { addr=v80, disp=8, kind=I64 } -> x1 + v83 Binop { op=add, lhs=v79, rhs=v82 } -> x0 + v84 LocalAddr(-26) -> x1 + v85 Load { addr=v84, disp=0, kind=I64 } -> x1 + v86 Binop { op=add, lhs=v83, rhs=v85 } -> x0 + v87 LocalAddr(-26) -> x1 + v88 BinopI { op=add, lhs=v87, rhs_imm=8 } -> x2 + v89 Load { addr=v87, disp=8, kind=I64 } -> x1 + v90 Binop { op=add, lhs=v86, rhs=v89 } -> x0 + v91 LocalAddr(-28) -> x1 + v92 Load { addr=v91, disp=0, kind=I64 } -> x1 + v93 Binop { op=add, lhs=v90, rhs=v92 } -> x0 + v94 LocalAddr(-28) -> x1 + v95 BinopI { op=add, lhs=v94, rhs_imm=8 } -> x2 + v96 Load { addr=v94, disp=8, kind=I64 } -> x1 + v97 Binop { op=add, lhs=v93, rhs=v96 } -> x0 + v98 LocalAddr(-30) -> x1 + v99 Load { addr=v98, disp=0, kind=I64 } -> x1 + v100 Binop { op=add, lhs=v97, rhs=v99 } -> x0 + v101 LocalAddr(-30) -> x1 + v102 BinopI { op=add, lhs=v101, rhs_imm=8 } -> x2 + v103 Load { addr=v101, disp=8, kind=I64 } -> x1 + v104 Binop { op=add, lhs=v100, rhs=v103 } -> x0 + v105 LocalAddr(-32) -> x1 + v106 Load { addr=v105, disp=0, kind=I64 } -> x1 + v107 Binop { op=add, lhs=v104, rhs=v106 } -> x0 + v108 LocalAddr(-32) -> x1 + v109 BinopI { op=add, lhs=v108, rhs_imm=8 } -> x2 + v110 Load { addr=v108, disp=8, kind=I64 } -> x1 + v111 Binop { op=add, lhs=v107, rhs=v110 } -> x0 + terminator Return(v111) (exit_acc=v111) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=main +fn ent_pc=2 n_params=0 variadic=false locals=20 + spill_count=8 gpr_used=[3, 12, 13, 14, 15] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ImmCode(ent_pc=0) -> x0 + v2 Imm(0) -> x1 + v3 ImmCode(ent_pc=1) -> x3 + v4 Imm(0) -> x1 + v5 Imm(0) -> x2 + v6 Imm(0) -> x1 + terminator Jmp(b1) (exit_acc=v5) + block 1 start_pc=0 + v7 Phi { incoming=[b0:v5, b2:v11], kind=I64 } -> x2 + v8 LoadLocal { off=-3, kind=I64 } -> x1 + v9 BinopI { op=lt, lhs=v7, rhs_imm=16 } -> x1 + terminator Bz { cond=v9, target=b4, fall=b3 } (exit_acc=v9) + block 2 start_pc=0 + v10 LoadLocal { off=-3, kind=I64 } -> x1 + v11 BinopI { op=add, lhs=v7, rhs_imm=1 } -> x2 + v12 Imm(0) -> x1 + terminator Jmp(b1) (exit_acc=v11) + block 3 start_pc=0 + v13 ImmData(24) -> x1 + v14 LoadLocal { off=-3, kind=I64 } -> x6 + v15 BinopI { op=shl, lhs=v7, rhs_imm=4 } -> x6 + v16 Binop { op=add, lhs=v13, rhs=v15 } -> x6 + v17 Store { addr=v16, disp=0, value=v7, kind=I64 } -> - + v18 LoadLocal { off=-3, kind=I64 } -> x6 + v19 BinopI { op=shl, lhs=v7, rhs_imm=4 } -> x6 + v20 Binop { op=add, lhs=v13, rhs=v19 } -> x1 + v21 BinopI { op=add, lhs=v20, rhs_imm=8 } -> x6 + v22 Imm(2) -> x6 + v23 BinopI { op=shl, lhs=v7, rhs_imm=1 } -> x6 + v24 Store { addr=v20, disp=8, value=v23, kind=I64 } -> - + terminator Jmp(b2) (exit_acc=v24) + block 4 start_pc=0 + v25 Imm(1) -> x7 + v26 Imm(2) -> x6 + v27 Imm(3) -> x2 + v28 Imm(4) -> x1 + v29 Imm(5) -> x8 + v30 Imm(6) -> x9 + v31 Imm(7) -> x12 + v32 Imm(8) -> x13 + v33 Imm(9) -> x14 + v34 Imm(10) -> x15 + v35 Imm(11) -> [spill 0] + v36 Imm(12) -> [spill 1] + v37 Imm(13) -> [spill 2] + v38 Imm(14) -> [spill 3] + v39 Imm(15) -> [spill 4] + v40 Imm(16) -> [spill 5] + v41 Imm(17) -> [spill 6] + v42 LoadLocal { off=-1, kind=I64 } -> [spill 7] + v43 CallIndirect { target=v1, args=[v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41], callee_variadic=false, fixed_args=17, fp_return=false, fp_arg_mask=0x0 } -> x0 + v44 BinopI { op=ne, lhs=v43, rhs_imm=153 } -> x0 + terminator Bz { cond=v44, target=b6, fall=b5 } (exit_acc=v44) + block 5 start_pc=0 + v45 Imm(1) -> x0 + terminator Return(v45) (exit_acc=v45) + block 6 start_pc=0 + v46 ImmData(24) -> x7 + v47 Imm(0) -> x0 + v48 Imm(16) -> x0 + v49 BinopI { op=add, lhs=v46, rhs_imm=16 } -> x6 + v50 Imm(32) -> x0 + v51 BinopI { op=add, lhs=v46, rhs_imm=32 } -> x2 + v52 Imm(48) -> x0 + v53 BinopI { op=add, lhs=v46, rhs_imm=48 } -> x1 + v54 Imm(64) -> x0 + v55 BinopI { op=add, lhs=v46, rhs_imm=64 } -> x8 + v56 Imm(80) -> x0 + v57 BinopI { op=add, lhs=v46, rhs_imm=80 } -> x9 + v58 Imm(96) -> x0 + v59 BinopI { op=add, lhs=v46, rhs_imm=96 } -> x0 + v60 Imm(112) -> x12 + v61 BinopI { op=add, lhs=v46, rhs_imm=112 } -> x12 + v62 Imm(128) -> x13 + v63 BinopI { op=add, lhs=v46, rhs_imm=128 } -> x13 + v64 Imm(144) -> x14 + v65 BinopI { op=add, lhs=v46, rhs_imm=144 } -> x14 + v66 Imm(160) -> x15 + v67 BinopI { op=add, lhs=v46, rhs_imm=160 } -> x15 + v68 Imm(176) -> [spill 0] + v69 BinopI { op=add, lhs=v46, rhs_imm=176 } -> [spill 0] + v70 Imm(192) -> [spill 1] + v71 BinopI { op=add, lhs=v46, rhs_imm=192 } -> [spill 1] + v72 Imm(208) -> [spill 2] + v73 BinopI { op=add, lhs=v46, rhs_imm=208 } -> [spill 2] + v74 Imm(224) -> [spill 3] + v75 BinopI { op=add, lhs=v46, rhs_imm=224 } -> [spill 3] + v76 Imm(240) -> [spill 4] + v77 BinopI { op=add, lhs=v46, rhs_imm=240 } -> [spill 4] + v78 LoadLocal { off=-2, kind=I64 } -> [spill 5] + v79 CallIndirect { target=v3, args=[v46, v49, v51, v53, v55, v57, v59, v61, v63, v65, v67, v69, v71, v73, v75, v77], callee_variadic=false, fixed_args=16, fp_return=false, fp_arg_mask=0x0 } -> x0 + v80 BinopI { op=ne, lhs=v79, rhs_imm=360 } -> x0 + terminator Bz { cond=v80, target=b8, fall=b7 } (exit_acc=v80) + block 7 start_pc=0 + v81 Imm(2) -> x0 + terminator Return(v81) (exit_acc=v81) + block 8 start_pc=0 + v82 Imm(0) -> x0 + terminator Return(v82) (exit_acc=v82) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/init_float_to_int.ssa b/tests/snapshots/ssa/init_float_to_int.ssa index 1b8c29617..3adc41c1a 100644 --- a/tests/snapshots/ssa/init_float_to_int.ssa +++ b/tests/snapshots/ssa/init_float_to_int.ssa @@ -84,8 +84,8 @@ fn ent_pc=0 n_params=0 variadic=false locals=4 block 13 start_pc=0 v53 ImmData(48) -> x0 v54 Imm(8) -> x1 - v55 BinopI { op=add, lhs=v53, rhs_imm=8 } -> x0 - v56 Load { addr=v55, disp=0, kind=F64 } -> d0 + v55 BinopI { op=add, lhs=v53, rhs_imm=8 } -> x1 + v56 Load { addr=v53, disp=8, kind=F64 } -> d0 v57 Imm(4611686018427387904) -> x0 v58 Binop { op=fne, lhs=v56, rhs=v57 } -> x1 v59 Imm(0) -> x0 diff --git a/tests/snapshots/ssa/init_scalar_conversion.ssa b/tests/snapshots/ssa/init_scalar_conversion.ssa index 30a7a63aa..ddf079a52 100644 --- a/tests/snapshots/ssa/init_scalar_conversion.ssa +++ b/tests/snapshots/ssa/init_scalar_conversion.ssa @@ -12,8 +12,8 @@ fn ent_pc=0 n_params=1 variadic=false locals=7 terminator Bz { cond=v4, target=b7, fall=b1 } (exit_acc=v4) block 1 start_pc=0 v6 LocalAddr(-4) -> x0 - v7 BinopI { op=add, lhs=v6, rhs_imm=8 } -> x0 - v8 Load { addr=v7, disp=0, kind=F64 } -> d0 + v7 BinopI { op=add, lhs=v6, rhs_imm=8 } -> x1 + v8 Load { addr=v6, disp=8, kind=F64 } -> d0 v9 Imm(0) -> x0 v10 Binop { op=feq, lhs=v8, rhs=v9 } -> x0 v11 BinopI { op=ne, lhs=v10, rhs_imm=0 } -> x2 @@ -27,8 +27,8 @@ fn ent_pc=0 n_params=1 variadic=false locals=7 terminator Bz { cond=v13, target=b8, fall=b3 } (exit_acc=v13) block 3 start_pc=0 v17 LocalAddr(-4) -> x0 - v18 BinopI { op=add, lhs=v17, rhs_imm=16 } -> x0 - v19 Load { addr=v18, disp=0, kind=F64 } -> d0 + v18 BinopI { op=add, lhs=v17, rhs_imm=16 } -> x1 + v19 Load { addr=v17, disp=16, kind=F64 } -> d0 v20 Imm(4650599933957636096) -> x0 v21 Binop { op=feq, lhs=v19, rhs=v20 } -> x0 v22 BinopI { op=ne, lhs=v21, rhs_imm=0 } -> x1 @@ -43,8 +43,8 @@ fn ent_pc=0 n_params=1 variadic=false locals=7 block 5 start_pc=0 v28 LocalAddr(-4) -> x0 v29 BinopI { op=add, lhs=v28, rhs_imm=16 } -> x1 - v30 BinopI { op=add, lhs=v28, rhs_imm=24 } -> x0 - v31 Load { addr=v30, disp=0, kind=F64 } -> d0 + v30 BinopI { op=add, lhs=v28, rhs_imm=24 } -> x1 + v31 Load { addr=v28, disp=24, kind=F64 } -> d0 v32 Imm(4647961106050973696) -> x0 v33 Binop { op=feq, lhs=v31, rhs=v32 } -> x0 v34 BinopI { op=ne, lhs=v33, rhs_imm=0 } -> x2 @@ -80,8 +80,8 @@ fn ent_pc=1 n_params=0 variadic=false locals=24 v12 LoadLocal { off=-2, kind=I32 } -> x0 v13 FpCast { kind=IntToFp, value=v3 } -> d0 v14 LocalAddr(-4) -> x0 - v15 BinopI { op=add, lhs=v14, rhs_imm=8 } -> x0 - v16 Store { addr=v15, disp=0, value=v13, kind=F64 } -> - + v15 BinopI { op=add, lhs=v14, rhs_imm=8 } -> x1 + v16 Store { addr=v14, disp=8, value=v13, kind=F64 } -> - v17 LocalAddr(-4) -> x0 v18 Load { addr=v17, disp=0, kind=F64 } -> d0 v19 Imm(4650599933957636096) -> x0 @@ -90,8 +90,8 @@ fn ent_pc=1 n_params=0 variadic=false locals=24 terminator Bnz { cond=v20, target=b25, fall=b1 } (exit_acc=v20) block 1 start_pc=0 v22 LocalAddr(-4) -> x0 - v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x0 - v24 Load { addr=v23, disp=0, kind=F64 } -> d0 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x1 + v24 Load { addr=v22, disp=8, kind=F64 } -> d0 v25 Imm(4647961106050973696) -> x0 v26 Binop { op=fne, lhs=v24, rhs=v25 } -> x13 v27 Imm(0) -> x0 @@ -112,21 +112,21 @@ fn ent_pc=1 n_params=0 variadic=false locals=24 v36 LocalAddr(-8) -> x0 v37 Store { addr=v36, disp=0, value=v35, kind=F64 } -> - v38 LocalAddr(-8) -> x0 - v39 BinopI { op=add, lhs=v38, rhs_imm=8 } -> x0 - v40 Store { addr=v39, disp=0, value=v35, kind=F64 } -> - + v39 BinopI { op=add, lhs=v38, rhs_imm=8 } -> x1 + v40 Store { addr=v38, disp=8, value=v35, kind=F64 } -> - v41 LoadLocal { off=-1, kind=I32 } -> x0 v42 FpCast { kind=IntToFp, value=v1 } -> d0 v43 LocalAddr(-8) -> x0 - v44 BinopI { op=add, lhs=v43, rhs_imm=16 } -> x0 - v45 Store { addr=v44, disp=0, value=v42, kind=F64 } -> - + v44 BinopI { op=add, lhs=v43, rhs_imm=16 } -> x1 + v45 Store { addr=v43, disp=16, value=v42, kind=F64 } -> - v46 LoadLocal { off=-2, kind=I32 } -> x0 v47 FpCast { kind=IntToFp, value=v3 } -> d0 v48 LocalAddr(-8) -> x0 - v49 BinopI { op=add, lhs=v48, rhs_imm=24 } -> x0 - v50 Store { addr=v49, disp=0, value=v47, kind=F64 } -> - + v49 BinopI { op=add, lhs=v48, rhs_imm=24 } -> x1 + v50 Store { addr=v48, disp=24, value=v47, kind=F64 } -> - v51 LocalAddr(-8) -> x0 - v52 BinopI { op=add, lhs=v51, rhs_imm=16 } -> x0 - v53 Load { addr=v52, disp=0, kind=F64 } -> d0 + v52 BinopI { op=add, lhs=v51, rhs_imm=16 } -> x1 + v53 Load { addr=v51, disp=16, kind=F64 } -> d0 v54 Imm(4650599933957636096) -> x0 v55 Binop { op=fne, lhs=v53, rhs=v54 } -> x13 v56 Imm(0) -> x0 @@ -134,8 +134,8 @@ fn ent_pc=1 n_params=0 variadic=false locals=24 block 5 start_pc=0 v57 LocalAddr(-8) -> x0 v58 BinopI { op=add, lhs=v57, rhs_imm=16 } -> x1 - v59 BinopI { op=add, lhs=v57, rhs_imm=24 } -> x0 - v60 Load { addr=v59, disp=0, kind=F64 } -> d0 + v59 BinopI { op=add, lhs=v57, rhs_imm=24 } -> x1 + v60 Load { addr=v57, disp=24, kind=F64 } -> d0 v61 Imm(4647961106050973696) -> x0 v62 Binop { op=fne, lhs=v60, rhs=v61 } -> x13 v63 Imm(0) -> x0 @@ -158,8 +158,8 @@ fn ent_pc=1 n_params=0 variadic=false locals=24 v74 LoadLocal { off=-2, kind=I32 } -> x0 v75 FpCast { kind=IntToFp, value=v3 } -> d0 v76 LocalAddr(-10) -> x0 - v77 BinopI { op=add, lhs=v76, rhs_imm=8 } -> x0 - v78 Store { addr=v77, disp=0, value=v75, kind=F64 } -> - + v77 BinopI { op=add, lhs=v76, rhs_imm=8 } -> x1 + v78 Store { addr=v76, disp=8, value=v75, kind=F64 } -> - v79 LocalAddr(-10) -> x0 v80 Imm(0) -> x1 v81 Load { addr=v79, disp=0, kind=F64 } -> d0 @@ -170,8 +170,8 @@ fn ent_pc=1 n_params=0 variadic=false locals=24 block 9 start_pc=0 v85 LocalAddr(-10) -> x0 v86 Imm(8) -> x1 - v87 BinopI { op=add, lhs=v85, rhs_imm=8 } -> x0 - v88 Load { addr=v87, disp=0, kind=F64 } -> d0 + v87 BinopI { op=add, lhs=v85, rhs_imm=8 } -> x1 + v88 Load { addr=v85, disp=8, kind=F64 } -> d0 v89 Imm(4647961106050973696) -> x0 v90 Binop { op=fne, lhs=v88, rhs=v89 } -> x13 v91 Imm(0) -> x0 @@ -268,18 +268,18 @@ fn ent_pc=1 n_params=0 variadic=false locals=24 v156 LocalAddr(-19) -> x0 v157 Store { addr=v156, disp=0, value=v155, kind=F64 } -> - v158 LocalAddr(-19) -> x0 - v159 BinopI { op=add, lhs=v158, rhs_imm=8 } -> x0 - v160 Store { addr=v159, disp=0, value=v155, kind=F64 } -> - + v159 BinopI { op=add, lhs=v158, rhs_imm=8 } -> x1 + v160 Store { addr=v158, disp=8, value=v155, kind=F64 } -> - v161 LoadLocal { off=-1, kind=I32 } -> x0 v162 FpCast { kind=IntToFp, value=v1 } -> d0 v163 LocalAddr(-19) -> x0 - v164 BinopI { op=add, lhs=v163, rhs_imm=16 } -> x0 - v165 Store { addr=v164, disp=0, value=v162, kind=F64 } -> - + v164 BinopI { op=add, lhs=v163, rhs_imm=16 } -> x1 + v165 Store { addr=v163, disp=16, value=v162, kind=F64 } -> - v166 LoadLocal { off=-2, kind=I32 } -> x0 v167 FpCast { kind=IntToFp, value=v3 } -> d0 v168 LocalAddr(-19) -> x0 - v169 BinopI { op=add, lhs=v168, rhs_imm=24 } -> x0 - v170 Store { addr=v169, disp=0, value=v167, kind=F64 } -> - + v169 BinopI { op=add, lhs=v168, rhs_imm=24 } -> x1 + v170 Store { addr=v168, disp=24, value=v167, kind=F64 } -> - v171 LocalAddr(-19) -> x7 v172 Call { target_pc=0, args=[v171], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 v173 BinopI { op=eq, lhs=v172, rhs_imm=0 } -> x0 diff --git a/tests/snapshots/ssa/inline_multi_block_result_forward.ssa b/tests/snapshots/ssa/inline_multi_block_result_forward.ssa new file mode 100644 index 000000000..7556898d7 --- /dev/null +++ b/tests/snapshots/ssa/inline_multi_block_result_forward.ssa @@ -0,0 +1,128 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=helper_one +fn ent_pc=0 n_params=1 variadic=false locals=0 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 Binop { op=add, lhs=v1, rhs=v1 } -> x0 + v5 BinopI { op=shl, lhs=v4, rhs_imm=32 } -> x1 + v6 Extend { value=v4, kind=I32 } -> x0 + terminator Return(v6) (exit_acc=v6) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=helper_two +fn ent_pc=1 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v1) + block 1 start_pc=0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 BinopI { op=shl, lhs=v1, rhs_imm=1 } -> x0 + v5 BinopI { op=shl, lhs=v4, rhs_imm=32 } -> x1 + v6 Extend { value=v4, kind=I32 } -> x0 + v7 Imm(0) -> x1 + v8 LoadLocal { off=-1, kind=I32 } -> x1 + terminator Return(v6) (exit_acc=v6) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=test +fn ent_pc=2 n_params=1 variadic=false locals=3 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + terminator Jmp(b4) + block 1 start_pc=0 + v16 Imm(0) -> x0 + v17 LoadLocal { off=2, kind=I32 } -> x0 + v18 Extend { value=v1, kind=I32 } -> x0 + v19 Imm(0) -> x0 + v20 Binop { op=add, lhs=v1, rhs=v1 } -> x2 + v21 BinopI { op=shl, lhs=v20, rhs_imm=32 } -> x0 + v22 Extend { value=v20, kind=I32 } -> x6 + v23 Imm(0) -> x0 + v24 LoadLocal { off=2, kind=I32 } -> x0 + v25 BinopI { op=gt, lhs=v1, rhs_imm=3 } -> x0 + terminator Bz { cond=v25, target=b3, fall=b2 } (exit_acc=v25) + block 2 start_pc=0 + v4 Extend { value=v14, kind=I32 } -> x0 + terminator Return(v4) (exit_acc=v4) + block 3 start_pc=0 + v5 Extend { value=v14, kind=I32 } -> x0 + v6 Extend { value=v22, kind=I32 } -> x0 + v7 Binop { op=add, lhs=v14, rhs=v20 } -> x0 + v8 BinopI { op=shl, lhs=v7, rhs_imm=32 } -> x1 + v9 Extend { value=v7, kind=I32 } -> x0 + terminator Return(v9) (exit_acc=v9) + block 4 start_pc=0 + v10 Extend { value=v1, kind=I32 } -> x0 + v11 Imm(0) -> x1 + terminator Jmp(b5) (exit_acc=v10) + block 5 start_pc=0 + v12 BinopI { op=shl, lhs=v10, rhs_imm=1 } -> x0 + v13 BinopI { op=shl, lhs=v12, rhs_imm=32 } -> x1 + v14 Extend { value=v12, kind=I32 } -> x1 + v15 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v14) +; --- SSA dump (ok=true) ent_pc=3 --- +; name=main +fn ent_pc=3 n_params=0 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(5) -> x7 + v2 Call { target_pc=2, args=[v1], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v2) (exit_acc=v2) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/int_literal_boundary_types.ssa b/tests/snapshots/ssa/int_literal_boundary_types.ssa new file mode 100644 index 000000000..1a5c96b40 --- /dev/null +++ b/tests/snapshots/ssa/int_literal_boundary_types.ssa @@ -0,0 +1,146 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=4 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(-2147483649) -> x0 + v2 Imm(0) -> x1 + v3 LoadLocal { off=-1, kind=I64 } -> x1 + v4 BinopI { op=ne, lhs=v1, rhs_imm=-2147483649 } -> x0 + terminator Bz { cond=v4, target=b2, fall=b1 } (exit_acc=v4) + block 1 start_pc=0 + v5 Imm(1) -> x0 + terminator Return(v5) (exit_acc=v5) + block 2 start_pc=0 + v6 Imm(0) -> x1 + v7 Imm(0) -> x0 + terminator Jmp(b4) (exit_acc=v6) + block 3 start_pc=0 + v8 Imm(0) -> x1 + v9 Imm(0) -> x0 + terminator Jmp(b4) (exit_acc=v8) + block 4 start_pc=0 + v10 Phi { incoming=[b2:v6, b3:v8], kind=I64 } -> x1 + v11 LoadLocal { off=-2, kind=I64 } -> x0 + terminator Bz { cond=v10, target=b6, fall=b5 } (exit_acc=v10) + block 5 start_pc=0 + v12 Imm(2) -> x0 + terminator Return(v12) (exit_acc=v12) + block 6 start_pc=0 + v13 Imm(-1) -> x0 + v14 Imm(2147483648) -> x0 + v15 Imm(4294967295) -> x1 + v16 Binop { op=ult, lhs=v15, rhs=v14 } -> x0 + terminator Bz { cond=v16, target=b8, fall=b7 } (exit_acc=v16) + block 7 start_pc=0 + v17 Imm(3) -> x0 + terminator Return(v17) (exit_acc=v17) + block 8 start_pc=0 + v18 Imm(0) -> x0 + terminator Jmp(b10) (exit_acc=v18) + block 9 start_pc=0 + v19 Imm(4) -> x0 + terminator Return(v19) (exit_acc=v19) + block 10 start_pc=0 + v20 Imm(1) -> x0 + v21 Imm(0) -> x0 + terminator Jmp(b12) (exit_acc=v21) + block 11 start_pc=0 + v22 Imm(5) -> x0 + terminator Return(v22) (exit_acc=v22) + block 12 start_pc=0 + v23 Imm(-9223372036854775808) -> x0 + v24 Imm(2) -> x0 + v25 Imm(4611686018427387904) -> x0 + v26 Imm(0) -> x0 + terminator Jmp(b14) (exit_acc=v26) + block 13 start_pc=0 + v27 Imm(6) -> x0 + terminator Return(v27) (exit_acc=v27) + block 14 start_pc=0 + v28 Imm(0) -> x0 + v29 Imm(1) -> x2 + v30 Imm(0) -> x1 + terminator Jmp(b15) (exit_acc=v28) + block 15 start_pc=0 + v31 Imm(0) -> x2 + v32 Imm(0) -> x0 + terminator Jmp(b16) (exit_acc=v31) + block 16 start_pc=0 + v33 Phi { incoming=[b14:v29, b15:v31], kind=I64 } -> x2 + v34 LoadLocal { off=-4, kind=I64 } -> x0 + v35 Imm(0) -> x0 + terminator Bnz { cond=v33, target=b23, fall=b17 } (exit_acc=v33) + block 17 start_pc=0 + v36 Imm(0) -> x2 + v37 Imm(0) -> x0 + terminator Jmp(b18) (exit_acc=v36) + block 18 start_pc=0 + v38 Phi { incoming=[b23:v33, b17:v36], kind=I64 } -> x2 + v39 LoadLocal { off=-3, kind=I64 } -> x0 + terminator Bz { cond=v38, target=b20, fall=b19 } (exit_acc=v38) + block 19 start_pc=0 + v40 Imm(7) -> x0 + terminator Return(v40) (exit_acc=v40) + block 20 start_pc=0 + v41 Imm(-1) -> x0 + v42 Imm(8) -> x0 + v43 Imm(4294967295) -> x1 + v44 Binop { op=ult, lhs=v43, rhs=v42 } -> x0 + terminator Bz { cond=v44, target=b22, fall=b21 } (exit_acc=v44) + block 21 start_pc=0 + v45 Imm(8) -> x0 + terminator Return(v45) (exit_acc=v45) + block 22 start_pc=0 + v46 Imm(0) -> x0 + terminator Return(v46) (exit_acc=v46) + block 23 start_pc=0 + terminator Jmp(b18) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/ioctl_fionread_pipe.ssa b/tests/snapshots/ssa/ioctl_fionread_pipe.ssa new file mode 100644 index 000000000..98940c89a --- /dev/null +++ b/tests/snapshots/ssa/ioctl_fionread_pipe.ssa @@ -0,0 +1,105 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=5 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(0) -> x0 + v2 StoreLocal { off=-2, value=v1, kind=I32 } -> - + v3 LocalAddr(-1) -> x7 + v4 CallExt { binding_idx=64, args=[v3], fp_arg_mask=0x0 } -> x0 + v5 BinopI { op=ne, lhs=v4, rhs_imm=0 } -> x0 + terminator Bz { cond=v5, target=b2, fall=b1 } (exit_acc=v5) + block 1 start_pc=0 + v6 Imm(1) -> x0 + terminator Return(v6) (exit_acc=v6) + block 2 start_pc=0 + v7 LocalAddr(-1) -> x0 + v8 Imm(4) -> x1 + v9 BinopI { op=add, lhs=v7, rhs_imm=4 } -> x1 + v10 Load { addr=v7, disp=4, kind=I32 } -> x7 + v11 ImmData(48) -> x6 + v12 Imm(5) -> x2 + v13 CallExt { binding_idx=28, args=[v10, v11, v12], fp_arg_mask=0x0 } -> x0 + v14 BinopI { op=ne, lhs=v13, rhs_imm=5 } -> x0 + terminator Bz { cond=v14, target=b4, fall=b3 } (exit_acc=v14) + block 3 start_pc=0 + v15 Imm(2) -> x0 + terminator Return(v15) (exit_acc=v15) + block 4 start_pc=0 + v16 LocalAddr(-1) -> x0 + v17 Imm(0) -> x1 + v18 Load { addr=v16, disp=0, kind=I32 } -> x7 + v19 Imm(21531) -> x6 + v20 LocalAddr(-2) -> x2 + v21 CallExt { binding_idx=0, args=[v18, v19, v20], fp_arg_mask=0x0 } -> x0 + v22 BinopI { op=ne, lhs=v21, rhs_imm=0 } -> x0 + terminator Bz { cond=v22, target=b6, fall=b5 } (exit_acc=v22) + block 5 start_pc=0 + v23 Imm(3) -> x0 + terminator Return(v23) (exit_acc=v23) + block 6 start_pc=0 + v24 LoadLocal { off=-2, kind=I32 } -> x0 + v25 BinopI { op=ne, lhs=v24, rhs_imm=5 } -> x0 + terminator Bz { cond=v25, target=b8, fall=b7 } (exit_acc=v25) + block 7 start_pc=0 + v26 Imm(4) -> x0 + terminator Return(v26) (exit_acc=v26) + block 8 start_pc=0 + v27 LocalAddr(-1) -> x0 + v28 Imm(0) -> x3 + v29 Load { addr=v27, disp=0, kind=I32 } -> x7 + v30 CallExt { binding_idx=25, args=[v29], fp_arg_mask=0x0 } -> x0 + v31 LocalAddr(-1) -> x0 + v32 Imm(4) -> x1 + v33 BinopI { op=add, lhs=v31, rhs_imm=4 } -> x1 + v34 Load { addr=v31, disp=4, kind=I32 } -> x7 + v35 CallExt { binding_idx=25, args=[v34], fp_arg_mask=0x0 } -> x0 + terminator Return(v28) (exit_acc=v28) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/libc_fp_classify.ssa b/tests/snapshots/ssa/libc_fp_classify.ssa index 9552795d2..72af75b50 100644 --- a/tests/snapshots/ssa/libc_fp_classify.ssa +++ b/tests/snapshots/ssa/libc_fp_classify.ssa @@ -74,7 +74,9 @@ fn ent_pc=4 n_params=1 variadic=false locals=1 v6 LocalAddr(-1) -> x0 v7 Load { addr=v6, disp=0, kind=I64 } -> x0 v8 BinopI { op=shru, lhs=v7, rhs_imm=63 } -> x0 - terminator Return(v8) (exit_acc=v8) + v9 BinopI { op=shl, lhs=v8, rhs_imm=32 } -> x1 + v10 Extend { value=v8, kind=I32 } -> x0 + terminator Return(v10) (exit_acc=v10) ; --- SSA dump (ok=true) ent_pc=5 --- ; name=copysign fn ent_pc=5 n_params=2 variadic=false locals=2 diff --git a/tests/snapshots/ssa/libc_pread64_pwrite64.ssa b/tests/snapshots/ssa/libc_pread64_pwrite64.ssa index 197925fdb..d08734651 100644 --- a/tests/snapshots/ssa/libc_pread64_pwrite64.ssa +++ b/tests/snapshots/ssa/libc_pread64_pwrite64.ssa @@ -7,7 +7,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=19 v1 LocalAddr(-8) -> x3 v2 ImmData(304) -> x12 v3 CallExt { binding_idx=48, args=[], fp_arg_mask=0x0 } -> x2 - v4 CallExt { binding_idx=186, args=[v1, v2, v3], fp_arg_mask=0x0 } -> x0 + v4 CallExt { binding_idx=185, args=[v1, v2, v3], fp_arg_mask=0x0 } -> x0 v5 LocalAddr(-8) -> x7 v6 Imm(66) -> x0 v7 Imm(578) -> x6 @@ -24,7 +24,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=19 v14 LocalAddr(-11) -> x7 v15 ImmData(320) -> x6 v16 Imm(16) -> x12 - v17 CallExt { binding_idx=157, args=[v14, v15, v16], fp_arg_mask=0x0 } -> x0 + v17 CallExt { binding_idx=156, args=[v14, v15, v16], fp_arg_mask=0x0 } -> x0 v18 Extend { value=v9, kind=I32 } -> x7 v19 LocalAddr(-11) -> x6 v20 Imm(0) -> x1 @@ -40,7 +40,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=19 v26 LocalAddr(-13) -> x7 v27 Imm(0) -> x12 v28 Imm(16) -> x13 - v29 CallExt { binding_idx=155, args=[v26, v27, v28], fp_arg_mask=0x0 } -> x0 + v29 CallExt { binding_idx=154, args=[v26, v27, v28], fp_arg_mask=0x0 } -> x0 v30 Extend { value=v9, kind=I32 } -> x7 v31 LocalAddr(-13) -> x6 v32 CallExt { binding_idx=23, args=[v30, v31, v28, v27], fp_arg_mask=0x0 } -> x0 @@ -55,7 +55,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=19 v37 LocalAddr(-11) -> x7 v38 LocalAddr(-13) -> x6 v39 Imm(16) -> x2 - v40 CallExt { binding_idx=156, args=[v37, v38, v39], fp_arg_mask=0x0 } -> x0 + v40 CallExt { binding_idx=155, args=[v37, v38, v39], fp_arg_mask=0x0 } -> x0 v41 BinopI { op=ne, lhs=v40, rhs_imm=0 } -> x0 terminator Bz { cond=v41, target=b8, fall=b7 } (exit_acc=v41) block 7 start_pc=0 @@ -92,7 +92,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=19 v66 LocalAddr(-13) -> x7 v67 Imm(0) -> x6 v68 Imm(16) -> x13 - v69 CallExt { binding_idx=155, args=[v66, v67, v68], fp_arg_mask=0x0 } -> x0 + v69 CallExt { binding_idx=154, args=[v66, v67, v68], fp_arg_mask=0x0 } -> x0 v70 Extend { value=v9, kind=I32 } -> x7 v71 LocalAddr(-13) -> x6 v72 Imm(8) -> x2 @@ -109,7 +109,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=19 v79 LocalAddr(-11) -> x7 v80 LocalAddr(-13) -> x6 v81 Imm(8) -> x2 - v82 CallExt { binding_idx=156, args=[v79, v80, v81], fp_arg_mask=0x0 } -> x0 + v82 CallExt { binding_idx=155, args=[v79, v80, v81], fp_arg_mask=0x0 } -> x0 v83 BinopI { op=ne, lhs=v82, rhs_imm=0 } -> x0 terminator Bz { cond=v83, target=b14, fall=b13 } (exit_acc=v83) block 13 start_pc=0 diff --git a/tests/snapshots/ssa/libc_struct_buf_size.ssa b/tests/snapshots/ssa/libc_struct_buf_size.ssa index 802a1d3b8..12bb2c90c 100644 --- a/tests/snapshots/ssa/libc_struct_buf_size.ssa +++ b/tests/snapshots/ssa/libc_struct_buf_size.ssa @@ -14,7 +14,7 @@ fn ent_pc=6 n_params=0 variadic=false locals=21 block 1 start_pc=0 v7 ImmData(81) -> x7 v8 Extend { value=v3, kind=I32 } -> x6 - v9 CallExt { binding_idx=193, args=[v7, v8], fp_arg_mask=0x0 } -> x0 + v9 CallExt { binding_idx=192, args=[v7, v8], fp_arg_mask=0x0 } -> x0 v10 Imm(1) -> x0 terminator Return(v10) (exit_acc=v10) block 2 start_pc=0 diff --git a/tests/snapshots/ssa/local_array_partial_init_zero.ssa b/tests/snapshots/ssa/local_array_partial_init_zero.ssa index 47c475d17..a6e53dca7 100644 --- a/tests/snapshots/ssa/local_array_partial_init_zero.ssa +++ b/tests/snapshots/ssa/local_array_partial_init_zero.ssa @@ -37,8 +37,8 @@ fn ent_pc=0 n_params=1 variadic=false locals=22 v23 Load { addr=v20, disp=156, kind=U32 } -> x2 v24 Binop { op=add, lhs=v19, rhs=v23 } -> x0 v25 BinopI { op=and, lhs=v24, rhs_imm=4294967295 } -> x0 - v26 Imm(0) -> x2 - v27 BinopI { op=and, lhs=v25, rhs_imm=4294967295 } -> x0 + v26 StoreLocal { off=-22, value=v25, kind=I32, volatile } -> - + v27 LoadLocal { off=-22, kind=U32, volatile } -> x0 v28 BinopI { op=and, lhs=v27, rhs_imm=255 } -> x0 terminator Return(v18) (exit_acc=v18) ; --- SSA dump (ok=true) ent_pc=1 --- diff --git a/tests/snapshots/ssa/math_classify.ssa b/tests/snapshots/ssa/math_classify.ssa index c04ff43ec..b139a45c1 100644 --- a/tests/snapshots/ssa/math_classify.ssa +++ b/tests/snapshots/ssa/math_classify.ssa @@ -110,7 +110,9 @@ fn ent_pc=4 n_params=1 variadic=false locals=1 v6 LocalAddr(-1) -> x0 v7 Load { addr=v6, disp=0, kind=I64 } -> x0 v8 BinopI { op=shru, lhs=v7, rhs_imm=63 } -> x0 - terminator Return(v8) (exit_acc=v8) + v9 BinopI { op=shl, lhs=v8, rhs_imm=32 } -> x1 + v10 Extend { value=v8, kind=I32 } -> x0 + terminator Return(v10) (exit_acc=v10) ; --- SSA dump (ok=true) ent_pc=13 --- ; name=main fn ent_pc=13 n_params=0 variadic=false locals=5 diff --git a/tests/snapshots/ssa/mixed_sse_int_aggregate_args.ssa b/tests/snapshots/ssa/mixed_sse_int_aggregate_args.ssa new file mode 100644 index 000000000..14b3bc870 --- /dev/null +++ b/tests/snapshots/ssa/mixed_sse_int_aggregate_args.ssa @@ -0,0 +1,201 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=take3 +fn ent_pc=0 n_params=5 variadic=false locals=9 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(1, kind=I64) -> x6 + v2 Imm(0) -> x0 + v3 ParamRef(3, kind=F64) -> d0 + v4 Imm(0) -> x0 + v5 LocalAddr(-2) -> x0 + v6 Load { addr=v5, disp=0, kind=F64 } -> d1 + v7 Imm(4612811918334230528) -> x0 + v8 Binop { op=fne, lhs=v6, rhs=v7 } -> x1 + v9 Imm(0) -> x0 + terminator Bnz { cond=v8, target=b17, fall=b1 } (exit_acc=v8) + block 1 start_pc=0 + v10 LocalAddr(-2) -> x0 + v11 BinopI { op=add, lhs=v10, rhs_imm=8 } -> x1 + v12 Load { addr=v10, disp=8, kind=I64 } -> x0 + v13 BinopI { op=ne, lhs=v12, rhs_imm=7 } -> x1 + v14 Imm(0) -> x0 + terminator Jmp(b2) (exit_acc=v13) + block 2 start_pc=0 + v15 Phi { incoming=[b17:v8, b1:v13], kind=I64 } -> x1 + v16 LoadLocal { off=-7, kind=I64 } -> x0 + terminator Bz { cond=v15, target=b4, fall=b3 } (exit_acc=v15) + block 3 start_pc=0 + v17 Imm(1) -> x0 + terminator Return(v17) (exit_acc=v17) + block 4 start_pc=0 + v18 LoadLocal { off=3, kind=I64 } -> x0 + v19 BinopI { op=ne, lhs=v1, rhs_imm=4 } -> x0 + terminator Bz { cond=v19, target=b6, fall=b5 } (exit_acc=v19) + block 5 start_pc=0 + v20 Imm(2) -> x0 + terminator Return(v20) (exit_acc=v20) + block 6 start_pc=0 + v21 LocalAddr(-4) -> x0 + v22 Load { addr=v21, disp=0, kind=I64 } -> x0 + v23 BinopI { op=ne, lhs=v22, rhs_imm=11 } -> x1 + v24 Imm(0) -> x0 + terminator Bnz { cond=v23, target=b18, fall=b7 } (exit_acc=v23) + block 7 start_pc=0 + v25 LocalAddr(-4) -> x0 + v26 BinopI { op=add, lhs=v25, rhs_imm=8 } -> x1 + v27 Load { addr=v25, disp=8, kind=F64 } -> d1 + v28 Imm(4602678819172646912) -> x0 + v29 Binop { op=fne, lhs=v27, rhs=v28 } -> x1 + v30 Imm(0) -> x0 + terminator Jmp(b8) (exit_acc=v29) + block 8 start_pc=0 + v31 Phi { incoming=[b18:v23, b7:v29], kind=I64 } -> x1 + v32 LoadLocal { off=-8, kind=I64 } -> x0 + terminator Bz { cond=v31, target=b10, fall=b9 } (exit_acc=v31) + block 9 start_pc=0 + v33 Imm(3) -> x0 + terminator Return(v33) (exit_acc=v33) + block 10 start_pc=0 + v34 LoadLocal { off=5, kind=F64 } -> d1 + v35 Imm(4608308318706860032) -> x0 + v36 Binop { op=fne, lhs=v3, rhs=v35 } -> x0 + terminator Bz { cond=v36, target=b12, fall=b11 } (exit_acc=v36) + block 11 start_pc=0 + v37 Imm(4) -> x0 + terminator Return(v37) (exit_acc=v37) + block 12 start_pc=0 + v38 LocalAddr(-6) -> x0 + v39 Load { addr=v38, disp=0, kind=F64 } -> d0 + v40 Imm(4615063718147915776) -> x0 + v41 Binop { op=fne, lhs=v39, rhs=v40 } -> x1 + v42 Imm(0) -> x0 + terminator Bnz { cond=v41, target=b19, fall=b13 } (exit_acc=v41) + block 13 start_pc=0 + v43 LocalAddr(-6) -> x0 + v44 BinopI { op=add, lhs=v43, rhs_imm=8 } -> x1 + v45 Load { addr=v43, disp=8, kind=F64 } -> d0 + v46 Imm(4616752568008179712) -> x0 + v47 Binop { op=fne, lhs=v45, rhs=v46 } -> x1 + v48 Imm(0) -> x0 + terminator Jmp(b14) (exit_acc=v47) + block 14 start_pc=0 + v49 Phi { incoming=[b19:v41, b13:v47], kind=I64 } -> x1 + v50 LoadLocal { off=-9, kind=I64 } -> x0 + terminator Bz { cond=v49, target=b16, fall=b15 } (exit_acc=v49) + block 15 start_pc=0 + v51 Imm(5) -> x0 + terminator Return(v51) (exit_acc=v51) + block 16 start_pc=0 + v52 Imm(0) -> x0 + terminator Return(v52) (exit_acc=v52) + block 17 start_pc=0 + terminator Jmp(b2) + block 18 start_pc=0 + terminator Jmp(b8) + block 19 start_pc=0 + terminator Jmp(b14) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=docall +fn ent_pc=1 n_params=5 variadic=false locals=5 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 ParamRef(2, kind=I64) -> x2 + v6 Imm(0) -> x0 + v7 ParamRef(3, kind=I64) -> x1 + v8 Imm(0) -> x0 + v9 ParamRef(4, kind=F64) -> d0 + v10 Imm(0) -> x0 + v11 LoadLocal { off=3, kind=I64 } -> x0 + v12 LoadLocal { off=2, kind=I64 } -> x0 + v13 LoadLocal { off=4, kind=I64 } -> x0 + v14 LoadLocal { off=6, kind=F64 } -> d1 + v15 LoadLocal { off=5, kind=I64 } -> x0 + v16 Call { target_pc=0, args=[v3, v1, v5, v9, v7], fixed_args=5, fp_return=false, fp_arg_mask=0x8 } -> x0 + terminator Return(v16) (exit_acc=v16) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=main +fn ent_pc=2 n_params=0 variadic=false locals=11 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-2) -> x0 + v2 Imm(4612811918334230528) -> x1 + v3 Store { addr=v1, disp=0, value=v2, kind=F64 } -> - + v4 LocalAddr(-2) -> x0 + v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x1 + v6 Imm(7) -> x1 + v7 Store { addr=v4, disp=8, value=v6, kind=I64 } -> - + v8 LocalAddr(-4) -> x0 + v9 Imm(11) -> x1 + v10 Store { addr=v8, disp=0, value=v9, kind=I64 } -> - + v11 LocalAddr(-4) -> x0 + v12 BinopI { op=add, lhs=v11, rhs_imm=8 } -> x1 + v13 Imm(4602678819172646912) -> x1 + v14 Store { addr=v11, disp=8, value=v13, kind=F64 } -> - + v15 LocalAddr(-6) -> x0 + v16 Imm(4615063718147915776) -> x1 + v17 Store { addr=v15, disp=0, value=v16, kind=F64 } -> - + v18 LocalAddr(-6) -> x0 + v19 BinopI { op=add, lhs=v18, rhs_imm=8 } -> x1 + v20 Imm(4616752568008179712) -> x1 + v21 Store { addr=v18, disp=8, value=v20, kind=F64 } -> - + v22 Imm(4) -> x7 + v23 LocalAddr(-2) -> x6 + v24 LocalAddr(-4) -> x2 + v25 LocalAddr(-6) -> x1 + v26 Imm(4608308318706860032) -> x8 + v27 Call { target_pc=1, args=[v22, v23, v24, v25, v26], fixed_args=5, fp_return=false, fp_arg_mask=0x10 } -> x0 + terminator Return(v27) (exit_acc=v27) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/mixed_struct_gpr_abi.ssa b/tests/snapshots/ssa/mixed_struct_gpr_abi.ssa index 5867a73e9..8008bfb61 100644 --- a/tests/snapshots/ssa/mixed_struct_gpr_abi.ssa +++ b/tests/snapshots/ssa/mixed_struct_gpr_abi.ssa @@ -10,8 +10,8 @@ fn ent_pc=0 n_params=2 variadic=false locals=2 v4 Load { addr=v3, disp=0, kind=I64 } -> x0 v5 FpCast { kind=IntToFp, value=v4 } -> d0 v6 LocalAddr(-2) -> x0 - v7 BinopI { op=add, lhs=v6, rhs_imm=8 } -> x0 - v8 Load { addr=v7, disp=0, kind=F64 } -> d1 + v7 BinopI { op=add, lhs=v6, rhs_imm=8 } -> x1 + v8 Load { addr=v6, disp=8, kind=F64 } -> d1 v9 Imm(4611686018427387904) -> x0 v10 Binop { op=fmul, lhs=v8, rhs=v9 } -> d2 v11 Fma { a=v8, b=v9, c=v5, neg_product=false, neg_addend=false } -> d0 @@ -62,8 +62,8 @@ fn ent_pc=1 n_params=7 variadic=false locals=2 v35 Load { addr=v34, disp=0, kind=I64 } -> x1 v36 Binop { op=add, lhs=v33, rhs=v35 } -> x0 v37 LocalAddr(-2) -> x1 - v38 BinopI { op=add, lhs=v37, rhs_imm=8 } -> x1 - v39 Load { addr=v38, disp=0, kind=F64 } -> d0 + v38 BinopI { op=add, lhs=v37, rhs_imm=8 } -> x2 + v39 Load { addr=v37, disp=8, kind=F64 } -> d0 v40 FpCast { kind=FpToInt, value=v39 } -> x1 v41 Binop { op=add, lhs=v36, rhs=v40 } -> x0 terminator Return(v41) (exit_acc=v41) diff --git a/tests/snapshots/ssa/negative_float_in_array_init.ssa b/tests/snapshots/ssa/negative_float_in_array_init.ssa index 63adac9c8..f5670eb3a 100644 --- a/tests/snapshots/ssa/negative_float_in_array_init.ssa +++ b/tests/snapshots/ssa/negative_float_in_array_init.ssa @@ -17,7 +17,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 v7 ImmData(40) -> x1 v8 Imm(8) -> x1 v9 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x1 - v10 Load { addr=v9, disp=0, kind=F64 } -> d0 + v10 Load { addr=v1, disp=8, kind=F64 } -> d0 v11 Imm(4612811918334230528) -> x1 v12 Fneg(v11) -> d1 v13 Binop { op=fne, lhs=v10, rhs=v12 } -> x1 @@ -29,7 +29,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 v15 ImmData(40) -> x1 v16 Imm(16) -> x1 v17 BinopI { op=add, lhs=v1, rhs_imm=16 } -> x1 - v18 Load { addr=v17, disp=0, kind=F64 } -> d0 + v18 Load { addr=v1, disp=16, kind=F64 } -> d0 v19 Imm(4764320886503243776) -> x1 v20 Fneg(v19) -> d1 v21 Binop { op=fne, lhs=v18, rhs=v20 } -> x1 @@ -43,11 +43,11 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 v25 Load { addr=v1, disp=0, kind=F64 } -> d0 v26 Imm(8) -> x1 v27 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x1 - v28 Load { addr=v27, disp=0, kind=F64 } -> d1 + v28 Load { addr=v1, disp=8, kind=F64 } -> d1 v29 Binop { op=fadd, lhs=v25, rhs=v28 } -> d0 v30 Imm(16) -> x1 - v31 BinopI { op=add, lhs=v1, rhs_imm=16 } -> x0 - v32 Load { addr=v31, disp=0, kind=F64 } -> d1 + v31 BinopI { op=add, lhs=v1, rhs_imm=16 } -> x1 + v32 Load { addr=v1, disp=16, kind=F64 } -> d1 v33 Binop { op=fadd, lhs=v29, rhs=v32 } -> d0 v34 Imm(0) -> x0 v35 LoadLocal { off=-1, kind=F64 } -> d1 diff --git a/tests/snapshots/ssa/nested_designator_string_member.ssa b/tests/snapshots/ssa/nested_designator_string_member.ssa new file mode 100644 index 000000000..b9ea18718 --- /dev/null +++ b/tests/snapshots/ssa/nested_designator_string_member.ssa @@ -0,0 +1,279 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=str_eq +fn ent_pc=0 n_params=2 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v3) + block 1 start_pc=0 + v5 Phi { incoming=[b0:v1, b2:v11], kind=I64 } -> x7 + v6 Phi { incoming=[b0:v3, b2:v14], kind=I64 } -> x6 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Load { addr=v5, disp=0, kind=I8 } -> x1 + v9 Imm(0) -> x0 + terminator Bz { cond=v8, target=b6, fall=b4 } (exit_acc=v8) + block 2 start_pc=0 + v10 LoadLocal { off=2, kind=I64 } -> x0 + v11 BinopI { op=add, lhs=v5, rhs_imm=1 } -> x7 + v12 Imm(0) -> x0 + v13 LoadLocal { off=3, kind=I64 } -> x0 + v14 BinopI { op=add, lhs=v6, rhs_imm=1 } -> x6 + v15 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v14) + block 3 start_pc=0 + v16 LoadLocal { off=2, kind=I64 } -> x0 + v17 Load { addr=v5, disp=0, kind=I8 } -> x0 + v18 LoadLocal { off=3, kind=I64 } -> x1 + v19 Load { addr=v6, disp=0, kind=I8 } -> x1 + v20 Binop { op=eq, lhs=v17, rhs=v19 } -> x0 + terminator Return(v20) (exit_acc=v20) + block 4 start_pc=0 + v21 LoadLocal { off=2, kind=I64 } -> x0 + v22 Load { addr=v5, disp=0, kind=I8 } -> x0 + v23 LoadLocal { off=3, kind=I64 } -> x1 + v24 Load { addr=v6, disp=0, kind=I8 } -> x1 + v25 Binop { op=eq, lhs=v22, rhs=v24 } -> x1 + v26 Imm(0) -> x0 + terminator Jmp(b5) (exit_acc=v25) + block 5 start_pc=0 + v27 Phi { incoming=[b6:v8, b4:v25], kind=I64 } -> x1 + v28 LoadLocal { off=-1, kind=I64 } -> x0 + terminator Bz { cond=v27, target=b3, fall=b2 } (exit_acc=v27) + block 6 start_pc=0 + terminator Jmp(b5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=2 variadic=false locals=8 + spill_count=0 gpr_used=[3, 12, 13] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x3 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 ImmData(8) -> x12 + v8 BinopI { op=add, lhs=v7, rhs_imm=4 } -> x7 + v9 ImmData(28) -> x6 + v10 Call { target_pc=0, args=[v8, v9], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x0 + v11 BinopI { op=eq, lhs=v10, rhs_imm=0 } -> x0 + terminator Bz { cond=v11, target=b2, fall=b1 } (exit_acc=v11) + block 1 start_pc=0 + v12 Imm(1) -> x0 + terminator Return(v12) (exit_acc=v12) + block 2 start_pc=0 + v13 ImmData(8) -> x0 + v14 BinopI { op=add, lhs=v7, rhs_imm=4 } -> x0 + v15 Imm(3) -> x0 + v16 BinopI { op=add, lhs=v7, rhs_imm=7 } -> x0 + v17 Load { addr=v7, disp=7, kind=I8 } -> x0 + v18 BinopI { op=ne, lhs=v17, rhs_imm=0 } -> x13 + v19 Imm(0) -> x0 + terminator Bnz { cond=v18, target=b21, fall=b3 } (exit_acc=v18) + block 3 start_pc=0 + v20 ImmData(8) -> x0 + v21 BinopI { op=add, lhs=v7, rhs_imm=4 } -> x0 + v22 Imm(7) -> x0 + v23 BinopI { op=add, lhs=v7, rhs_imm=11 } -> x0 + v24 Load { addr=v7, disp=11, kind=I8 } -> x0 + v25 BinopI { op=ne, lhs=v24, rhs_imm=0 } -> x13 + v26 Imm(0) -> x0 + terminator Jmp(b4) (exit_acc=v25) + block 4 start_pc=0 + v27 Phi { incoming=[b21:v18, b3:v25], kind=I64 } -> x13 + v28 LoadLocal { off=-5, kind=I64 } -> x0 + terminator Bz { cond=v27, target=b6, fall=b5 } (exit_acc=v27) + block 5 start_pc=0 + v29 Imm(2) -> x0 + terminator Return(v29) (exit_acc=v29) + block 6 start_pc=0 + v30 ImmData(8) -> x0 + v31 BinopI { op=add, lhs=v7, rhs_imm=12 } -> x0 + v32 Load { addr=v7, disp=12, kind=I32 } -> x0 + v33 BinopI { op=ne, lhs=v32, rhs_imm=7 } -> x13 + v34 Imm(0) -> x0 + terminator Bnz { cond=v33, target=b22, fall=b7 } (exit_acc=v33) + block 7 start_pc=0 + v35 ImmData(8) -> x0 + v36 Load { addr=v7, disp=0, kind=I32 } -> x0 + v37 BinopI { op=ne, lhs=v36, rhs_imm=5 } -> x13 + v38 Imm(0) -> x0 + terminator Jmp(b8) (exit_acc=v37) + block 8 start_pc=0 + v39 Phi { incoming=[b22:v33, b7:v37], kind=I64 } -> x13 + v40 LoadLocal { off=-6, kind=I64 } -> x0 + terminator Bz { cond=v39, target=b10, fall=b9 } (exit_acc=v39) + block 9 start_pc=0 + v41 Imm(3) -> x0 + terminator Return(v41) (exit_acc=v41) + block 10 start_pc=0 + v42 LocalAddr(-2) -> x0 + v43 ImmData(36) -> x1 + v44 Mcpy { dst=v42, src=v43, size=16 } -> x0 + v45 Imm(119) -> x0 + v46 LocalAddr(-2) -> x1 + v47 BinopI { op=add, lhs=v46, rhs_imm=4 } -> x2 + v48 Store { addr=v46, disp=4, value=v45, kind=I8 } -> - + v49 Imm(120) -> x0 + v50 LocalAddr(-2) -> x1 + v51 BinopI { op=add, lhs=v50, rhs_imm=5 } -> x2 + v52 Store { addr=v50, disp=5, value=v49, kind=I8 } -> - + v53 Imm(121) -> x0 + v54 LocalAddr(-2) -> x1 + v55 BinopI { op=add, lhs=v54, rhs_imm=6 } -> x2 + v56 Store { addr=v54, disp=6, value=v53, kind=I8 } -> - + v57 Imm(122) -> x0 + v58 LocalAddr(-2) -> x1 + v59 BinopI { op=add, lhs=v58, rhs_imm=7 } -> x2 + v60 Store { addr=v58, disp=7, value=v57, kind=I8 } -> - + v61 Imm(0) -> x0 + v62 LocalAddr(-2) -> x1 + v63 BinopI { op=add, lhs=v62, rhs_imm=8 } -> x2 + v64 Store { addr=v62, disp=8, value=v61, kind=I8 } -> - + v65 LocalAddr(-2) -> x1 + v66 BinopI { op=add, lhs=v65, rhs_imm=9 } -> x2 + v67 Store { addr=v65, disp=9, value=v61, kind=I8 } -> - + v68 LocalAddr(-2) -> x1 + v69 BinopI { op=add, lhs=v68, rhs_imm=10 } -> x2 + v70 Store { addr=v68, disp=10, value=v61, kind=I8 } -> - + v71 LocalAddr(-2) -> x1 + v72 BinopI { op=add, lhs=v71, rhs_imm=11 } -> x2 + v73 Store { addr=v71, disp=11, value=v61, kind=I8 } -> - + v74 LoadLocal { off=2, kind=I32 } -> x0 + v75 BinopI { op=add, lhs=v1, rhs_imm=6 } -> x0 + v76 BinopI { op=shl, lhs=v75, rhs_imm=32 } -> x1 + v77 Extend { value=v75, kind=I32 } -> x1 + v78 LocalAddr(-2) -> x1 + v79 BinopI { op=add, lhs=v78, rhs_imm=12 } -> x2 + v80 Store { addr=v78, disp=12, value=v75, kind=I32 } -> - + v81 LoadLocal { off=2, kind=I32 } -> x0 + v82 BinopI { op=add, lhs=v1, rhs_imm=4 } -> x0 + v83 BinopI { op=shl, lhs=v82, rhs_imm=32 } -> x1 + v84 Extend { value=v82, kind=I32 } -> x1 + v85 LocalAddr(-2) -> x1 + v86 Store { addr=v85, disp=0, value=v82, kind=I32 } -> - + v87 LocalAddr(-2) -> x0 + v88 BinopI { op=add, lhs=v87, rhs_imm=4 } -> x7 + v89 ImmData(57) -> x6 + v90 Call { target_pc=0, args=[v88, v89], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x0 + v91 BinopI { op=eq, lhs=v90, rhs_imm=0 } -> x0 + terminator Bz { cond=v91, target=b12, fall=b11 } (exit_acc=v91) + block 11 start_pc=0 + v92 Imm(4) -> x0 + terminator Return(v92) (exit_acc=v92) + block 12 start_pc=0 + v93 LocalAddr(-2) -> x0 + v94 BinopI { op=add, lhs=v93, rhs_imm=4 } -> x1 + v95 Imm(4) -> x1 + v96 BinopI { op=add, lhs=v93, rhs_imm=8 } -> x1 + v97 Load { addr=v93, disp=8, kind=I8 } -> x0 + v98 BinopI { op=ne, lhs=v97, rhs_imm=0 } -> x1 + v99 Imm(0) -> x0 + terminator Bnz { cond=v98, target=b23, fall=b13 } (exit_acc=v98) + block 13 start_pc=0 + v100 LocalAddr(-2) -> x0 + v101 BinopI { op=add, lhs=v100, rhs_imm=4 } -> x1 + v102 Imm(7) -> x1 + v103 BinopI { op=add, lhs=v100, rhs_imm=11 } -> x1 + v104 Load { addr=v100, disp=11, kind=I8 } -> x0 + v105 BinopI { op=ne, lhs=v104, rhs_imm=0 } -> x1 + v106 Imm(0) -> x0 + terminator Jmp(b14) (exit_acc=v105) + block 14 start_pc=0 + v107 Phi { incoming=[b23:v98, b13:v105], kind=I64 } -> x1 + v108 LoadLocal { off=-7, kind=I64 } -> x0 + terminator Bz { cond=v107, target=b16, fall=b15 } (exit_acc=v107) + block 15 start_pc=0 + v109 Imm(5) -> x0 + terminator Return(v109) (exit_acc=v109) + block 16 start_pc=0 + v110 LocalAddr(-2) -> x0 + v111 BinopI { op=add, lhs=v110, rhs_imm=12 } -> x1 + v112 Load { addr=v110, disp=12, kind=I32 } -> x0 + v113 LoadLocal { off=2, kind=I32 } -> x1 + v114 BinopI { op=add, lhs=v1, rhs_imm=6 } -> x1 + v115 BinopI { op=shl, lhs=v114, rhs_imm=32 } -> x2 + v116 Extend { value=v114, kind=I32 } -> x1 + v117 Binop { op=ne, lhs=v112, rhs=v116 } -> x1 + v118 Imm(0) -> x0 + terminator Bnz { cond=v117, target=b24, fall=b17 } (exit_acc=v117) + block 17 start_pc=0 + v119 LocalAddr(-2) -> x0 + v120 Load { addr=v119, disp=0, kind=I32 } -> x0 + v121 LoadLocal { off=2, kind=I32 } -> x1 + v122 BinopI { op=add, lhs=v1, rhs_imm=4 } -> x1 + v123 BinopI { op=shl, lhs=v122, rhs_imm=32 } -> x2 + v124 Extend { value=v122, kind=I32 } -> x1 + v125 Binop { op=ne, lhs=v120, rhs=v124 } -> x1 + v126 Imm(0) -> x0 + terminator Jmp(b18) (exit_acc=v125) + block 18 start_pc=0 + v127 Phi { incoming=[b24:v117, b17:v125], kind=I64 } -> x1 + v128 LoadLocal { off=-8, kind=I64 } -> x0 + terminator Bz { cond=v127, target=b20, fall=b19 } (exit_acc=v127) + block 19 start_pc=0 + v129 Imm(6) -> x0 + terminator Return(v129) (exit_acc=v129) + block 20 start_pc=0 + v130 Imm(0) -> x0 + terminator Return(v130) (exit_acc=v130) + block 21 start_pc=0 + terminator Jmp(b4) + block 22 start_pc=0 + terminator Jmp(b8) + block 23 start_pc=0 + terminator Jmp(b14) + block 24 start_pc=0 + terminator Jmp(b18) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/out_pointer_return_float_args.ssa b/tests/snapshots/ssa/out_pointer_return_float_args.ssa index d18973dd7..4ddff7ed4 100644 --- a/tests/snapshots/ssa/out_pointer_return_float_args.ssa +++ b/tests/snapshots/ssa/out_pointer_return_float_args.ssa @@ -16,17 +16,17 @@ fn ent_pc=0 n_params=4 variadic=false locals=6 v10 LoadLocal { off=-1, kind=F32 } -> d4 [f32] v11 Store { addr=v9, disp=0, value=v1, kind=F32 } -> - v12 LocalAddr(-6) -> x0 - v13 BinopI { op=add, lhs=v12, rhs_imm=4 } -> x0 + v13 BinopI { op=add, lhs=v12, rhs_imm=4 } -> x1 v14 LoadLocal { off=-2, kind=F32 } -> d0 [f32] - v15 Store { addr=v13, disp=0, value=v3, kind=F32 } -> - + v15 Store { addr=v12, disp=4, value=v3, kind=F32 } -> - v16 LocalAddr(-6) -> x0 - v17 BinopI { op=add, lhs=v16, rhs_imm=8 } -> x0 + v17 BinopI { op=add, lhs=v16, rhs_imm=8 } -> x1 v18 LoadLocal { off=-3, kind=F32 } -> d0 [f32] - v19 Store { addr=v17, disp=0, value=v5, kind=F32 } -> - + v19 Store { addr=v16, disp=8, value=v5, kind=F32 } -> - v20 LocalAddr(-6) -> x0 - v21 BinopI { op=add, lhs=v20, rhs_imm=12 } -> x0 + v21 BinopI { op=add, lhs=v20, rhs_imm=12 } -> x1 v22 LoadLocal { off=-4, kind=F32 } -> d0 [f32] - v23 Store { addr=v21, disp=0, value=v7, kind=F32 } -> - + v23 Store { addr=v20, disp=12, value=v7, kind=F32 } -> - v24 LocalAddr(-6) -> x0 terminator Return(v24) (exit_acc=v24) ; --- SSA dump (ok=true) ent_pc=1 --- @@ -49,21 +49,21 @@ fn ent_pc=1 n_params=6 variadic=false locals=8 v12 LoadLocal { off=-1, kind=F32 } -> d0 [f32] v13 Store { addr=v11, disp=0, value=v12, kind=F32 } -> - v14 LocalAddr(-8) -> x0 - v15 BinopI { op=add, lhs=v14, rhs_imm=4 } -> x0 + v15 BinopI { op=add, lhs=v14, rhs_imm=4 } -> x1 v16 LoadLocal { off=-2, kind=F32 } -> d0 [f32] - v17 Store { addr=v15, disp=0, value=v16, kind=F32 } -> - + v17 Store { addr=v14, disp=4, value=v16, kind=F32 } -> - v18 LocalAddr(-8) -> x0 - v19 BinopI { op=add, lhs=v18, rhs_imm=8 } -> x0 + v19 BinopI { op=add, lhs=v18, rhs_imm=8 } -> x1 v20 LoadLocal { off=-3, kind=F32 } -> d0 [f32] - v21 Store { addr=v19, disp=0, value=v20, kind=F32 } -> - + v21 Store { addr=v18, disp=8, value=v20, kind=F32 } -> - v22 LocalAddr(-8) -> x0 - v23 BinopI { op=add, lhs=v22, rhs_imm=12 } -> x0 + v23 BinopI { op=add, lhs=v22, rhs_imm=12 } -> x1 v24 LoadLocal { off=-4, kind=F32 } -> d0 [f32] - v25 Store { addr=v23, disp=0, value=v24, kind=F32 } -> - + v25 Store { addr=v22, disp=12, value=v24, kind=F32 } -> - v26 LocalAddr(-8) -> x0 - v27 BinopI { op=add, lhs=v26, rhs_imm=16 } -> x0 + v27 BinopI { op=add, lhs=v26, rhs_imm=16 } -> x1 v28 LoadLocal { off=-5, kind=F32 } -> d0 [f32] - v29 Store { addr=v27, disp=0, value=v28, kind=F32 } -> - + v29 Store { addr=v26, disp=16, value=v28, kind=F32 } -> - v30 LoadLocal { off=2, kind=I64 } -> x0 v31 LocalAddr(-8) -> x1 v32 Mcpy { dst=v30, src=v31, size=20 } -> x1 @@ -78,13 +78,13 @@ fn ent_pc=2 n_params=4 variadic=false locals=3 v2 LoadLocal { off=3, kind=F64 } -> d0 v3 Store { addr=v1, disp=0, value=v2, kind=F64 } -> - v4 LocalAddr(-3) -> x0 - v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x0 + v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x1 v6 LoadLocal { off=4, kind=F64 } -> d0 - v7 Store { addr=v5, disp=0, value=v6, kind=F64 } -> - + v7 Store { addr=v4, disp=8, value=v6, kind=F64 } -> - v8 LocalAddr(-3) -> x0 - v9 BinopI { op=add, lhs=v8, rhs_imm=16 } -> x0 + v9 BinopI { op=add, lhs=v8, rhs_imm=16 } -> x1 v10 LoadLocal { off=5, kind=F64 } -> d0 - v11 Store { addr=v9, disp=0, value=v10, kind=F64 } -> - + v11 Store { addr=v8, disp=16, value=v10, kind=F64 } -> - v12 LoadLocal { off=2, kind=I64 } -> x0 v13 LocalAddr(-3) -> x1 v14 Mcpy { dst=v12, src=v13, size=24 } -> x1 @@ -116,8 +116,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=43 terminator Bnz { cond=v16, target=b25, fall=b1 } (exit_acc=v16) block 1 start_pc=0 v19 LocalAddr(-2) -> x0 - v20 BinopI { op=add, lhs=v19, rhs_imm=4 } -> x0 - v21 Load { addr=v20, disp=0, kind=F32 } -> d0 [f32] + v20 BinopI { op=add, lhs=v19, rhs_imm=4 } -> x1 + v21 Load { addr=v19, disp=4, kind=F32 } -> d0 [f32] v22 Imm(4611686018427387904) -> x0 v23 FpCast { kind=F32ToF64, value=v21 } -> d0 v24 Binop { op=fne, lhs=v23, rhs=v22 } -> x0 @@ -132,8 +132,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=43 terminator Bnz { cond=v27, target=b26, fall=b3 } (exit_acc=v27) block 3 start_pc=0 v31 LocalAddr(-2) -> x0 - v32 BinopI { op=add, lhs=v31, rhs_imm=8 } -> x0 - v33 Load { addr=v32, disp=0, kind=F32 } -> d0 [f32] + v32 BinopI { op=add, lhs=v31, rhs_imm=8 } -> x1 + v33 Load { addr=v31, disp=8, kind=F32 } -> d0 [f32] v34 Imm(4613937818241073152) -> x0 v35 FpCast { kind=F32ToF64, value=v33 } -> d0 v36 Binop { op=fne, lhs=v35, rhs=v34 } -> x0 @@ -147,8 +147,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=43 terminator Bnz { cond=v39, target=b27, fall=b5 } (exit_acc=v39) block 5 start_pc=0 v42 LocalAddr(-2) -> x0 - v43 BinopI { op=add, lhs=v42, rhs_imm=12 } -> x0 - v44 Load { addr=v43, disp=0, kind=F32 } -> d0 [f32] + v43 BinopI { op=add, lhs=v42, rhs_imm=12 } -> x1 + v44 Load { addr=v42, disp=12, kind=F32 } -> d0 [f32] v45 Imm(4616189618054758400) -> x0 v46 FpCast { kind=F32ToF64, value=v44 } -> d0 v47 Binop { op=fne, lhs=v46, rhs=v45 } -> x12 @@ -203,8 +203,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=43 terminator Bnz { cond=v87, target=b28, fall=b9 } (exit_acc=v87) block 9 start_pc=0 v90 LocalAddr(-7) -> x0 - v91 BinopI { op=add, lhs=v90, rhs_imm=4 } -> x0 - v92 Load { addr=v91, disp=0, kind=F32 } -> d0 [f32] + v91 BinopI { op=add, lhs=v90, rhs_imm=4 } -> x1 + v92 Load { addr=v90, disp=4, kind=F32 } -> d0 [f32] v93 Imm(4612811918334230528) -> x0 v94 FpCast { kind=F32ToF64, value=v92 } -> d0 v95 Binop { op=fne, lhs=v94, rhs=v93 } -> x0 @@ -219,8 +219,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=43 terminator Bnz { cond=v98, target=b29, fall=b11 } (exit_acc=v98) block 11 start_pc=0 v102 LocalAddr(-7) -> x0 - v103 BinopI { op=add, lhs=v102, rhs_imm=8 } -> x0 - v104 Load { addr=v103, disp=0, kind=F32 } -> d0 [f32] + v103 BinopI { op=add, lhs=v102, rhs_imm=8 } -> x1 + v104 Load { addr=v102, disp=8, kind=F32 } -> d0 [f32] v105 Imm(4615063718147915776) -> x0 v106 FpCast { kind=F32ToF64, value=v104 } -> d0 v107 Binop { op=fne, lhs=v106, rhs=v105 } -> x0 @@ -235,8 +235,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=43 terminator Bnz { cond=v110, target=b30, fall=b13 } (exit_acc=v110) block 13 start_pc=0 v114 LocalAddr(-7) -> x0 - v115 BinopI { op=add, lhs=v114, rhs_imm=12 } -> x0 - v116 Load { addr=v115, disp=0, kind=F32 } -> d0 [f32] + v115 BinopI { op=add, lhs=v114, rhs_imm=12 } -> x1 + v116 Load { addr=v114, disp=12, kind=F32 } -> d0 [f32] v117 Imm(4616752568008179712) -> x0 v118 FpCast { kind=F32ToF64, value=v116 } -> d0 v119 Binop { op=fne, lhs=v118, rhs=v117 } -> x0 @@ -250,8 +250,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=43 terminator Bnz { cond=v122, target=b31, fall=b15 } (exit_acc=v122) block 15 start_pc=0 v125 LocalAddr(-7) -> x0 - v126 BinopI { op=add, lhs=v125, rhs_imm=16 } -> x0 - v127 Load { addr=v126, disp=0, kind=F32 } -> d0 [f32] + v126 BinopI { op=add, lhs=v125, rhs_imm=16 } -> x1 + v127 Load { addr=v125, disp=16, kind=F32 } -> d0 [f32] v128 Imm(4617878467915022336) -> x0 v129 FpCast { kind=F32ToF64, value=v127 } -> d0 v130 Binop { op=fne, lhs=v129, rhs=v128 } -> x3 @@ -283,8 +283,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=43 terminator Bnz { cond=v147, target=b32, fall=b19 } (exit_acc=v147) block 19 start_pc=0 v150 LocalAddr(-13) -> x0 - v151 BinopI { op=add, lhs=v150, rhs_imm=8 } -> x0 - v152 Load { addr=v151, disp=0, kind=F64 } -> d0 + v151 BinopI { op=add, lhs=v150, rhs_imm=8 } -> x1 + v152 Load { addr=v150, disp=8, kind=F64 } -> d0 v153 Imm(4626322717216342016) -> x0 v154 Binop { op=fne, lhs=v152, rhs=v153 } -> x0 v155 BinopI { op=ne, lhs=v154, rhs_imm=0 } -> x2 @@ -297,8 +297,8 @@ fn ent_pc=3 n_params=0 variadic=false locals=43 terminator Bnz { cond=v157, target=b33, fall=b21 } (exit_acc=v157) block 21 start_pc=0 v160 LocalAddr(-13) -> x0 - v161 BinopI { op=add, lhs=v160, rhs_imm=16 } -> x0 - v162 Load { addr=v161, disp=0, kind=F64 } -> d0 + v161 BinopI { op=add, lhs=v160, rhs_imm=16 } -> x1 + v162 Load { addr=v160, disp=16, kind=F64 } -> d0 v163 Imm(4629137466983448576) -> x0 v164 Binop { op=fne, lhs=v162, rhs=v163 } -> x2 v165 Imm(0) -> x0 diff --git a/tests/snapshots/ssa/packed_bitfield_repack.ssa b/tests/snapshots/ssa/packed_bitfield_repack.ssa new file mode 100644 index 000000000..b85f525bd --- /dev/null +++ b/tests/snapshots/ssa/packed_bitfield_repack.ssa @@ -0,0 +1,335 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=14 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(0) -> x1 + v2 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v1) + block 1 start_pc=0 + v3 Imm(0) -> x1 + v4 Imm(1) -> x0 + v5 Imm(0) -> x0 + terminator Jmp(b2) (exit_acc=v3) + block 2 start_pc=0 + v6 Phi { incoming=[b0:v1, b1:v3], kind=I64 } -> x1 + v7 LoadLocal { off=-5, kind=I64 } -> x0 + terminator Bz { cond=v6, target=b4, fall=b3 } (exit_acc=v6) + block 3 start_pc=0 + v8 Imm(1) -> x0 + terminator Return(v8) (exit_acc=v8) + block 4 start_pc=0 + v9 Imm(0) -> x1 + v10 Imm(0) -> x0 + terminator Jmp(b5) (exit_acc=v9) + block 5 start_pc=0 + v11 Imm(0) -> x1 + v12 Imm(4) -> x0 + v13 Imm(0) -> x0 + terminator Jmp(b6) (exit_acc=v11) + block 6 start_pc=0 + v14 Phi { incoming=[b4:v9, b5:v11], kind=I64 } -> x1 + v15 LoadLocal { off=-6, kind=I64 } -> x0 + terminator Bz { cond=v14, target=b8, fall=b7 } (exit_acc=v14) + block 7 start_pc=0 + v16 Imm(2) -> x0 + terminator Return(v16) (exit_acc=v16) + block 8 start_pc=0 + v17 Imm(0) -> x1 + v18 Imm(0) -> x0 + terminator Jmp(b9) (exit_acc=v17) + block 9 start_pc=0 + v19 Imm(0) -> x1 + v20 Imm(2) -> x0 + v21 Imm(0) -> x0 + terminator Jmp(b10) (exit_acc=v19) + block 10 start_pc=0 + v22 Phi { incoming=[b8:v17, b9:v19], kind=I64 } -> x1 + v23 LoadLocal { off=-7, kind=I64 } -> x0 + terminator Bz { cond=v22, target=b12, fall=b11 } (exit_acc=v22) + block 11 start_pc=0 + v24 Imm(3) -> x0 + terminator Return(v24) (exit_acc=v24) + block 12 start_pc=0 + v25 Imm(0) -> x0 + terminator Jmp(b14) (exit_acc=v25) + block 13 start_pc=0 + v26 Imm(4) -> x0 + terminator Return(v26) (exit_acc=v26) + block 14 start_pc=0 + v27 LocalAddr(-1) -> x0 + v28 Imm(85) -> x1 + v29 Load { addr=v27, disp=0, kind=U8 } -> x2 + v30 BinopI { op=and, lhs=v29, rhs_imm=-256 } -> x2 + v31 Binop { op=or, lhs=v30, rhs=v28 } -> x1 + v32 Store { addr=v27, disp=0, value=v31, kind=I8 } -> - + v33 Imm(6124895493223874560) -> x0 + v34 LocalAddr(-1) -> x0 + v35 BinopI { op=add, lhs=v34, rhs_imm=1 } -> x1 + v36 Imm(7) -> x1 + v37 Store { addr=v34, disp=1, value=v36, kind=I8 } -> - + v38 Imm(504403158265495552) -> x0 + v39 LocalAddr(-1) -> x0 + v40 Load { addr=v39, disp=0, kind=U8 } -> x0 + v41 BinopI { op=shl, lhs=v40, rhs_imm=56 } -> x1 + v42 Extend { value=v40, kind=I8 } -> x0 + v43 BinopI { op=ne, lhs=v42, rhs_imm=85 } -> x1 + v44 Imm(0) -> x0 + terminator Bnz { cond=v43, target=b39, fall=b15 } (exit_acc=v43) + block 15 start_pc=0 + v45 LocalAddr(-1) -> x0 + v46 BinopI { op=add, lhs=v45, rhs_imm=1 } -> x1 + v47 Load { addr=v45, disp=1, kind=I8 } -> x0 + v48 BinopI { op=ne, lhs=v47, rhs_imm=7 } -> x1 + v49 Imm(0) -> x0 + terminator Jmp(b16) (exit_acc=v48) + block 16 start_pc=0 + v50 Phi { incoming=[b39:v43, b15:v48], kind=I64 } -> x1 + v51 LoadLocal { off=-8, kind=I64 } -> x0 + terminator Bz { cond=v50, target=b18, fall=b17 } (exit_acc=v50) + block 17 start_pc=0 + v52 Imm(5) -> x0 + terminator Return(v52) (exit_acc=v52) + block 18 start_pc=0 + v53 LocalAddr(-2) -> x0 + v54 Imm(65000) -> x1 + v55 Load { addr=v53, disp=0, kind=U32 } -> x2 + v56 BinopI { op=and, lhs=v55, rhs_imm=-131072 } -> x2 + v57 Binop { op=or, lhs=v56, rhs=v54 } -> x1 + v58 Store { addr=v53, disp=0, value=v57, kind=I32 } -> - + v59 Imm(9147936743096320000) -> x0 + v60 LocalAddr(-2) -> x0 + v61 BinopI { op=add, lhs=v60, rhs_imm=2 } -> x1 + v62 Imm(500) -> x1 + v63 Load { addr=v60, disp=2, kind=U16 } -> x1 + v64 BinopI { op=and, lhs=v63, rhs_imm=-2047 } -> x1 + v65 Imm(1000) -> x2 + v66 Binop { op=or, lhs=v64, rhs=v65 } -> x1 + v67 Store { addr=v60, disp=2, value=v66, kind=I16 } -> - + v68 Imm(9007199254740992000) -> x0 + v69 LocalAddr(-2) -> x0 + v70 BinopI { op=add, lhs=v69, rhs_imm=4 } -> x1 + v71 Imm(9) -> x1 + v72 Store { addr=v69, disp=4, value=v71, kind=I8 } -> - + v73 Imm(648518346341351424) -> x0 + v74 LocalAddr(-2) -> x0 + v75 Load { addr=v74, disp=0, kind=U32 } -> x0 + v76 BinopI { op=and, lhs=v75, rhs_imm=131071 } -> x0 + v77 BinopI { op=shl, lhs=v76, rhs_imm=47 } -> x0 + v78 BinopI { op=shr, lhs=v77, rhs_imm=47 } -> x0 + v79 BinopI { op=ne, lhs=v78, rhs_imm=65000 } -> x0 + v80 Imm(1) -> x2 + v81 Imm(0) -> x1 + terminator Bnz { cond=v79, target=b40, fall=b19 } (exit_acc=v79) + block 19 start_pc=0 + v82 LocalAddr(-2) -> x0 + v83 BinopI { op=add, lhs=v82, rhs_imm=2 } -> x1 + v84 Load { addr=v82, disp=2, kind=U16 } -> x0 + v85 BinopI { op=shr, lhs=v84, rhs_imm=1 } -> x0 + v86 BinopI { op=and, lhs=v85, rhs_imm=1023 } -> x0 + v87 BinopI { op=shl, lhs=v86, rhs_imm=54 } -> x0 + v88 BinopI { op=shr, lhs=v87, rhs_imm=54 } -> x0 + v89 BinopI { op=ne, lhs=v88, rhs_imm=500 } -> x0 + v90 BinopI { op=ne, lhs=v89, rhs_imm=0 } -> x2 + v91 Imm(0) -> x0 + terminator Jmp(b20) (exit_acc=v90) + block 20 start_pc=0 + v92 Phi { incoming=[b40:v80, b19:v90], kind=I64 } -> x2 + v93 LoadLocal { off=-10, kind=I64 } -> x0 + v94 Imm(0) -> x0 + terminator Bnz { cond=v92, target=b41, fall=b21 } (exit_acc=v92) + block 21 start_pc=0 + v95 LocalAddr(-2) -> x0 + v96 BinopI { op=add, lhs=v95, rhs_imm=4 } -> x1 + v97 Load { addr=v95, disp=4, kind=I8 } -> x0 + v98 BinopI { op=ne, lhs=v97, rhs_imm=9 } -> x2 + v99 Imm(0) -> x0 + terminator Jmp(b22) (exit_acc=v98) + block 22 start_pc=0 + v100 Phi { incoming=[b41:v92, b21:v98], kind=I64 } -> x2 + v101 LoadLocal { off=-9, kind=I64 } -> x0 + terminator Bz { cond=v100, target=b24, fall=b23 } (exit_acc=v100) + block 23 start_pc=0 + v102 Imm(6) -> x0 + terminator Return(v102) (exit_acc=v102) + block 24 start_pc=0 + v103 LocalAddr(-3) -> x0 + v104 Imm(3) -> x1 + v105 Load { addr=v103, disp=0, kind=U8 } -> x2 + v106 BinopI { op=and, lhs=v105, rhs_imm=-8 } -> x2 + v107 Binop { op=or, lhs=v106, rhs=v104 } -> x1 + v108 Store { addr=v103, disp=0, value=v107, kind=I8 } -> - + v109 Imm(6917529027641081856) -> x0 + v110 LocalAddr(-3) -> x0 + v111 Imm(60) -> x1 + v112 Load { addr=v110, disp=0, kind=U16 } -> x1 + v113 BinopI { op=and, lhs=v112, rhs_imm=-1017 } -> x1 + v114 Imm(480) -> x2 + v115 Binop { op=or, lhs=v113, rhs=v114 } -> x1 + v116 Store { addr=v110, disp=0, value=v115, kind=I16 } -> - + v117 Imm(8646911284551352320) -> x0 + v118 LocalAddr(-3) -> x0 + v119 BinopI { op=add, lhs=v118, rhs_imm=2 } -> x1 + v120 Imm(4) -> x1 + v121 Store { addr=v118, disp=2, value=v120, kind=I8 } -> - + v122 Imm(288230376151711744) -> x0 + v123 LocalAddr(-3) -> x0 + v124 Load { addr=v123, disp=0, kind=U8 } -> x0 + v125 BinopI { op=and, lhs=v124, rhs_imm=7 } -> x0 + v126 BinopI { op=shl, lhs=v125, rhs_imm=61 } -> x0 + v127 BinopI { op=shr, lhs=v126, rhs_imm=61 } -> x0 + v128 BinopI { op=ne, lhs=v127, rhs_imm=3 } -> x0 + v129 Imm(1) -> x2 + v130 Imm(0) -> x1 + terminator Bnz { cond=v128, target=b42, fall=b25 } (exit_acc=v128) + block 25 start_pc=0 + v131 LocalAddr(-3) -> x0 + v132 Load { addr=v131, disp=0, kind=U16 } -> x0 + v133 BinopI { op=shr, lhs=v132, rhs_imm=3 } -> x0 + v134 BinopI { op=and, lhs=v133, rhs_imm=127 } -> x0 + v135 BinopI { op=shl, lhs=v134, rhs_imm=57 } -> x0 + v136 BinopI { op=shr, lhs=v135, rhs_imm=57 } -> x0 + v137 BinopI { op=ne, lhs=v136, rhs_imm=60 } -> x0 + v138 BinopI { op=ne, lhs=v137, rhs_imm=0 } -> x2 + v139 Imm(0) -> x0 + terminator Jmp(b26) (exit_acc=v138) + block 26 start_pc=0 + v140 Phi { incoming=[b42:v129, b25:v138], kind=I64 } -> x2 + v141 LoadLocal { off=-12, kind=I64 } -> x0 + v142 Imm(0) -> x0 + terminator Bnz { cond=v140, target=b43, fall=b27 } (exit_acc=v140) + block 27 start_pc=0 + v143 LocalAddr(-3) -> x0 + v144 BinopI { op=add, lhs=v143, rhs_imm=2 } -> x1 + v145 Load { addr=v143, disp=2, kind=I8 } -> x0 + v146 BinopI { op=ne, lhs=v145, rhs_imm=4 } -> x2 + v147 Imm(0) -> x0 + terminator Jmp(b28) (exit_acc=v146) + block 28 start_pc=0 + v148 Phi { incoming=[b43:v140, b27:v146], kind=I64 } -> x2 + v149 LoadLocal { off=-11, kind=I64 } -> x0 + terminator Bz { cond=v148, target=b30, fall=b29 } (exit_acc=v148) + block 29 start_pc=0 + v150 Imm(7) -> x0 + terminator Return(v150) (exit_acc=v150) + block 30 start_pc=0 + v151 LocalAddr(-4) -> x0 + v152 Imm(11) -> x1 + v153 Store { addr=v151, disp=0, value=v152, kind=I8 } -> - + v154 Imm(792633534417207296) -> x0 + v155 LocalAddr(-4) -> x0 + v156 BinopI { op=add, lhs=v155, rhs_imm=1 } -> x0 + v157 Imm(30000) -> x1 + v158 Load { addr=v156, disp=0, kind=U16 } -> x2 + v159 BinopI { op=and, lhs=v158, rhs_imm=-65536 } -> x2 + v160 Binop { op=or, lhs=v159, rhs=v157 } -> x1 + v161 Store { addr=v156, disp=0, value=v160, kind=I16 } -> - + v162 Imm(8444249301319680000) -> x0 + v163 LocalAddr(-4) -> x0 + v164 Load { addr=v163, disp=0, kind=I8 } -> x0 + v165 BinopI { op=ne, lhs=v164, rhs_imm=11 } -> x1 + v166 Imm(0) -> x0 + terminator Bnz { cond=v165, target=b44, fall=b31 } (exit_acc=v165) + block 31 start_pc=0 + v167 LocalAddr(-4) -> x0 + v168 BinopI { op=add, lhs=v167, rhs_imm=1 } -> x0 + v169 Load { addr=v168, disp=0, kind=U16 } -> x0 + v170 BinopI { op=shl, lhs=v169, rhs_imm=48 } -> x1 + v171 Extend { value=v169, kind=I16 } -> x0 + v172 BinopI { op=ne, lhs=v171, rhs_imm=30000 } -> x1 + v173 Imm(0) -> x0 + terminator Jmp(b32) (exit_acc=v172) + block 32 start_pc=0 + v174 Phi { incoming=[b44:v165, b31:v172], kind=I64 } -> x1 + v175 LoadLocal { off=-13, kind=I64 } -> x0 + terminator Bz { cond=v174, target=b34, fall=b33 } (exit_acc=v174) + block 33 start_pc=0 + v176 Imm(8) -> x0 + terminator Return(v176) (exit_acc=v176) + block 34 start_pc=0 + v177 ImmData(8) -> x0 + v178 Load { addr=v177, disp=0, kind=U8 } -> x0 + v179 BinopI { op=shl, lhs=v178, rhs_imm=56 } -> x1 + v180 Extend { value=v178, kind=I8 } -> x0 + v181 BinopI { op=ne, lhs=v180, rhs_imm=85 } -> x1 + v182 Imm(0) -> x0 + terminator Bnz { cond=v181, target=b45, fall=b35 } (exit_acc=v181) + block 35 start_pc=0 + v183 ImmData(8) -> x0 + v184 BinopI { op=add, lhs=v183, rhs_imm=1 } -> x1 + v185 Load { addr=v183, disp=1, kind=I8 } -> x0 + v186 BinopI { op=ne, lhs=v185, rhs_imm=7 } -> x1 + v187 Imm(0) -> x0 + terminator Jmp(b36) (exit_acc=v186) + block 36 start_pc=0 + v188 Phi { incoming=[b45:v181, b35:v186], kind=I64 } -> x1 + v189 LoadLocal { off=-14, kind=I64 } -> x0 + terminator Bz { cond=v188, target=b38, fall=b37 } (exit_acc=v188) + block 37 start_pc=0 + v190 Imm(9) -> x0 + terminator Return(v190) (exit_acc=v190) + block 38 start_pc=0 + v191 Imm(0) -> x0 + terminator Return(v191) (exit_acc=v191) + block 39 start_pc=0 + terminator Jmp(b16) + block 40 start_pc=0 + terminator Jmp(b20) + block 41 start_pc=0 + terminator Jmp(b22) + block 42 start_pc=0 + terminator Jmp(b26) + block 43 start_pc=0 + terminator Jmp(b28) + block 44 start_pc=0 + terminator Jmp(b32) + block 45 start_pc=0 + terminator Jmp(b36) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/posix_os_headers.ssa b/tests/snapshots/ssa/posix_os_headers.ssa index b60fa06cf..ec531840c 100644 --- a/tests/snapshots/ssa/posix_os_headers.ssa +++ b/tests/snapshots/ssa/posix_os_headers.ssa @@ -84,10 +84,10 @@ fn ent_pc=0 n_params=0 variadic=false locals=17 v54 Load { addr=v51, disp=4, kind=I32 } -> x7 v55 CallExt { binding_idx=27, args=[v54], fp_arg_mask=0x0 } -> x0 v56 LocalAddr(-13) -> x6 - v57 CallExt { binding_idx=153, args=[v48, v56], fp_arg_mask=0x0 } -> x0 + v57 CallExt { binding_idx=152, args=[v48, v56], fp_arg_mask=0x0 } -> x0 v58 Imm(21523) -> x6 v59 LocalAddr(-14) -> x2 - v60 CallExt { binding_idx=164, args=[v48, v58, v59], fp_arg_mask=0x0 } -> x0 + v60 CallExt { binding_idx=163, args=[v48, v58, v59], fp_arg_mask=0x0 } -> x0 terminator Return(v48) (exit_acc=v48) ; --- SSA dump (ok=true) ent_pc=0 --- ; name=__c5_exit diff --git a/tests/snapshots/ssa/pthread_create.ssa b/tests/snapshots/ssa/pthread_create.ssa index fc5b555aa..d3a26f18e 100644 --- a/tests/snapshots/ssa/pthread_create.ssa +++ b/tests/snapshots/ssa/pthread_create.ssa @@ -19,15 +19,15 @@ fn ent_pc=1 n_params=0 variadic=false locals=9 v0 AllocaInit(0) -> - v1 Imm(0) -> x3 v2 Imm(2) -> x6 - v3 CallExt { binding_idx=179, args=[v1, v2], fp_arg_mask=0x0 } -> x12 + v3 CallExt { binding_idx=178, args=[v1, v2], fp_arg_mask=0x0 } -> x12 v4 Imm(0) -> x0 v5 LoadLocal { off=-1, kind=I64 } -> x0 v6 ImmData(48) -> x6 - v7 CallExt { binding_idx=180, args=[v3, v6], fp_arg_mask=0x0 } -> x13 + v7 CallExt { binding_idx=179, args=[v3, v6], fp_arg_mask=0x0 } -> x13 v8 Imm(0) -> x0 v9 LoadLocal { off=-1, kind=I64 } -> x0 v10 ImmData(63) -> x6 - v11 CallExt { binding_idx=180, args=[v3, v10], fp_arg_mask=0x0 } -> x12 + v11 CallExt { binding_idx=179, args=[v3, v10], fp_arg_mask=0x0 } -> x12 v12 Imm(0) -> x0 v13 LocalAddr(-4) -> x7 v14 ImmCode(ent_pc=0) -> x2 diff --git a/tests/snapshots/ssa/rotate_variable_count.ssa b/tests/snapshots/ssa/rotate_variable_count.ssa index de5901e7c..65a320067 100644 --- a/tests/snapshots/ssa/rotate_variable_count.ssa +++ b/tests/snapshots/ssa/rotate_variable_count.ssa @@ -76,7 +76,7 @@ fn ent_pc=1 n_params=2 variadic=false locals=3 ; --- SSA dump (ok=true) ent_pc=2 --- ; name=main fn ent_pc=2 n_params=0 variadic=false locals=11 - spill_count=0 gpr_used=[3, 12, 13] fp_used=[] + spill_count=0 gpr_used=[3, 12] fp_used=[] block 0 start_pc=0 v0 AllocaInit(0) -> - v1 LocalAddr(-6) -> x0 @@ -102,53 +102,53 @@ fn ent_pc=2 n_params=0 variadic=false locals=11 v17 Imm(0) -> x0 terminator Jmp(b1) (exit_acc=v16) block 3 start_pc=0 - v18 Imm(1) -> x12 - v19 Imm(0) -> x0 - terminator Jmp(b5) (exit_acc=v18) + v18 Imm(1) -> x0 + v19 StoreLocal { off=-8, value=v18, kind=I32, volatile } -> - + terminator Jmp(b5) (exit_acc=v19) block 4 start_pc=0 v20 Imm(81985529216486895) -> x7 - v21 Imm(0) -> x0 - v22 LoadLocal { off=-9, kind=I64 } -> x0 - v23 BinopI { op=shru, lhs=v20, rhs_imm=7 } -> x0 - v24 BinopI { op=shl, lhs=v20, rhs_imm=57 } -> x0 - v25 BinopI { op=ror, lhs=v20, rhs_imm=7 } -> x3 - v26 Imm(7) -> x6 - v27 Call { target_pc=1, args=[v20, v26], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x0 - v28 Binop { op=ne, lhs=v25, rhs=v27 } -> x0 - terminator Bz { cond=v28, target=b12, fall=b11 } (exit_acc=v28) + v21 StoreLocal { off=-9, value=v20, kind=I64, volatile } -> - + v22 LoadLocal { off=-9, kind=I64, volatile } -> x0 + v23 BinopI { op=shru, lhs=v22, rhs_imm=7 } -> x0 + v24 LoadLocal { off=-9, kind=I64, volatile } -> x1 + v25 BinopI { op=shl, lhs=v24, rhs_imm=57 } -> x1 + v26 Binop { op=or, lhs=v23, rhs=v25 } -> x3 + v27 Imm(7) -> x6 + v28 Call { target_pc=1, args=[v20, v27], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x0 + v29 Binop { op=ne, lhs=v26, rhs=v28 } -> x0 + terminator Bz { cond=v29, target=b12, fall=b11 } (exit_acc=v29) block 5 start_pc=0 - v29 Phi { incoming=[b3:v18, b6:v33], kind=I64 } -> x12 - v30 Extend { value=v29, kind=I32 } -> x0 + v30 LoadLocal { off=-8, kind=I32, volatile } -> x0 v31 BinopI { op=lt, lhs=v30, rhs_imm=64 } -> x0 terminator Bz { cond=v31, target=b8, fall=b7 } (exit_acc=v31) block 6 start_pc=0 - v32 Extend { value=v29, kind=I32 } -> x0 - v33 BinopI { op=add, lhs=v32, rhs_imm=1 } -> x12 - v34 Imm(0) -> x0 - terminator Jmp(b5) (exit_acc=v33) + v32 LoadLocal { off=-8, kind=I32, volatile } -> x0 + v33 BinopI { op=add, lhs=v32, rhs_imm=1 } -> x0 + v34 StoreLocal { off=-8, value=v33, kind=I32, volatile } -> - + terminator Jmp(b5) (exit_acc=v34) block 7 start_pc=0 v35 LocalAddr(-6) -> x0 v36 BinopI { op=and, lhs=v6, rhs_imm=4294967295 } -> x1 v37 BinopI { op=shl, lhs=v36, rhs_imm=3 } -> x2 v38 Binop { op=add, lhs=v35, rhs=v37 } -> x2 v39 LoadIndexed { base=v35, index=v36, scale=8, kind=I64 } -> x0 - v40 Extend { value=v29, kind=I32 } -> x1 + v40 LoadLocal { off=-8, kind=I32, volatile } -> x1 v41 Imm(0) -> x2 - v42 Extend { value=v40, kind=I32 } -> x1 + v42 Extend { value=v40, kind=I32 } -> x2 v43 Imm(0) -> x2 - v44 Binop { op=shru, lhs=v39, rhs=v42 } -> x2 + v44 Binop { op=shru, lhs=v39, rhs=v40 } -> x2 v45 Imm(64) -> x2 - v46 Binop { op=sub, lhs=v45, rhs=v42 } -> x2 + v46 Binop { op=sub, lhs=v45, rhs=v40 } -> x2 v47 BinopI { op=shl, lhs=v46, rhs_imm=32 } -> x6 v48 Extend { value=v46, kind=I32 } -> x2 v49 Binop { op=shl, lhs=v39, rhs=v48 } -> x2 - v50 Binop { op=ror, lhs=v39, rhs=v42 } -> x13 + v50 Binop { op=ror, lhs=v39, rhs=v40 } -> x12 v51 LocalAddr(-6) -> x0 v52 BinopI { op=and, lhs=v6, rhs_imm=4294967295 } -> x1 v53 BinopI { op=shl, lhs=v52, rhs_imm=3 } -> x2 v54 Binop { op=add, lhs=v51, rhs=v53 } -> x2 v55 LoadIndexed { base=v51, index=v52, scale=8, kind=I64 } -> x7 - v56 Extend { value=v29, kind=I32 } -> x6 + v56 LoadLocal { off=-8, kind=I32, volatile } -> x6 v57 Call { target_pc=1, args=[v55, v56], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x0 v58 Binop { op=ne, lhs=v50, rhs=v57 } -> x0 terminator Bz { cond=v58, target=b10, fall=b9 } (exit_acc=v58) diff --git a/tests/snapshots/ssa/setenv_overwrite.ssa b/tests/snapshots/ssa/setenv_overwrite.ssa new file mode 100644 index 000000000..1553f500d --- /dev/null +++ b/tests/snapshots/ssa/setenv_overwrite.ssa @@ -0,0 +1,86 @@ +; --- SSA dump (ok=true) ent_pc=5 --- +; name=main +fn ent_pc=5 n_params=0 variadic=false locals=3 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ImmData(8) -> x7 + v2 ImmData(25) -> x6 + v3 Imm(1) -> x2 + v4 CallExt { binding_idx=18, args=[v1, v2, v3], fp_arg_mask=0x0 } -> x0 + v5 ImmData(31) -> x7 + v6 ImmData(48) -> x6 + v7 Imm(0) -> x2 + v8 CallExt { binding_idx=18, args=[v5, v6, v7], fp_arg_mask=0x0 } -> x0 + v9 ImmData(55) -> x7 + v10 CallExt { binding_idx=17, args=[v9], fp_arg_mask=0x0 } -> x0 + v11 Load { addr=v10, disp=0, kind=I8 } -> x0 + v12 BinopI { op=ne, lhs=v11, rhs_imm=102 } -> x0 + terminator Bz { cond=v12, target=b2, fall=b1 } (exit_acc=v12) + block 1 start_pc=0 + v13 Imm(1) -> x0 + terminator Return(v13) (exit_acc=v13) + block 2 start_pc=0 + v14 ImmData(72) -> x7 + v15 ImmData(89) -> x6 + v16 Imm(1) -> x2 + v17 CallExt { binding_idx=18, args=[v14, v15, v16], fp_arg_mask=0x0 } -> x0 + v18 ImmData(95) -> x7 + v19 CallExt { binding_idx=17, args=[v18], fp_arg_mask=0x0 } -> x0 + v20 Imm(0) -> x1 + v21 Load { addr=v19, disp=0, kind=I8 } -> x0 + v22 BinopI { op=ne, lhs=v21, rhs_imm=116 } -> x0 + terminator Bz { cond=v22, target=b4, fall=b3 } (exit_acc=v22) + block 3 start_pc=0 + v23 Imm(2) -> x0 + terminator Return(v23) (exit_acc=v23) + block 4 start_pc=0 + v24 Imm(0) -> x0 + terminator Return(v24) (exit_acc=v24) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/setjmp_longjmp.ssa b/tests/snapshots/ssa/setjmp_longjmp.ssa index ba1129278..c50f93c1f 100644 --- a/tests/snapshots/ssa/setjmp_longjmp.ssa +++ b/tests/snapshots/ssa/setjmp_longjmp.ssa @@ -20,7 +20,7 @@ fn ent_pc=0 n_params=2 variadic=false locals=2 ; --- SSA dump (ok=true) ent_pc=1 --- ; name=main fn ent_pc=1 n_params=0 variadic=false locals=69 - spill_count=0 gpr_used=[3, 12] fp_used=[] + spill_count=0 gpr_used=[3] fp_used=[] block 0 start_pc=0 v0 AllocaInit(0) -> - v1 Imm(0) -> x0 @@ -29,20 +29,20 @@ fn ent_pc=1 n_params=0 variadic=false locals=69 v2 Imm(11) -> x0 terminator Return(v2) (exit_acc=v2) block 2 start_pc=0 - v3 Imm(0) -> x3 - v4 Imm(0) -> x0 + v3 Imm(0) -> x0 + v4 StoreLocal { off=-66, value=v3, kind=I32, volatile } -> - v5 LocalAddr(-65) -> x7 - v6 CallExt { binding_idx=0, args=[v5], fp_arg_mask=0x0 } -> x12 + v6 CallExt { binding_idx=0, args=[v5], fp_arg_mask=0x0 } -> x3 v7 Imm(0) -> x0 v8 Extend { value=v6, kind=I32 } -> x0 v9 BinopI { op=eq, lhs=v8, rhs_imm=0 } -> x0 terminator Bz { cond=v9, target=b4, fall=b3 } (exit_acc=v9) block 3 start_pc=0 - v10 LoadLocal { off=-66, kind=I32 } -> x0 - v11 BinopI { op=add, lhs=v3, rhs_imm=1 } -> x0 + v10 LoadLocal { off=-66, kind=I32, volatile } -> x0 + v11 BinopI { op=add, lhs=v10, rhs_imm=1 } -> x0 v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 - v13 Extend { value=v11, kind=I32 } -> x0 - v14 Imm(0) -> x0 + v13 Extend { value=v11, kind=I32 } -> x1 + v14 StoreLocal { off=-66, value=v11, kind=I32, volatile } -> - v15 LocalAddr(-65) -> x7 v16 Imm(7) -> x6 v17 Call { target_pc=0, args=[v15, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x0 @@ -56,8 +56,8 @@ fn ent_pc=1 n_params=0 variadic=false locals=69 v21 Imm(13) -> x0 terminator Return(v21) (exit_acc=v21) block 6 start_pc=0 - v22 LoadLocal { off=-66, kind=I32 } -> x0 - v23 BinopI { op=ne, lhs=v3, rhs_imm=1 } -> x0 + v22 LoadLocal { off=-66, kind=I32, volatile } -> x0 + v23 BinopI { op=ne, lhs=v22, rhs_imm=1 } -> x0 terminator Bz { cond=v23, target=b8, fall=b7 } (exit_acc=v23) block 7 start_pc=0 v24 Imm(14) -> x0 diff --git a/tests/snapshots/ssa/setjmp_longjmp_roundtrip.ssa b/tests/snapshots/ssa/setjmp_longjmp_roundtrip.ssa index 220b7f09b..4fdd962e0 100644 --- a/tests/snapshots/ssa/setjmp_longjmp_roundtrip.ssa +++ b/tests/snapshots/ssa/setjmp_longjmp_roundtrip.ssa @@ -9,11 +9,11 @@ fn ent_pc=0 n_params=2 variadic=false locals=2 v3 ParamRef(1, kind=I32) -> x3 v4 Imm(0) -> x0 v5 ImmData(536) -> x0 - v6 Load { addr=v5, disp=0, kind=I32 } -> x1 + v6 Load { addr=v5, disp=0, kind=I32, volatile } -> x1 v7 BinopI { op=add, lhs=v6, rhs_imm=1 } -> x1 v8 BinopI { op=shl, lhs=v7, rhs_imm=32 } -> x2 v9 Extend { value=v7, kind=I32 } -> x2 - v10 Store { addr=v5, disp=0, value=v7, kind=I32 } -> - + v10 Store { addr=v5, disp=0, value=v7, kind=I32, volatile } -> - v11 LoadLocal { off=2, kind=I32 } -> x0 v12 BinopI { op=gt, lhs=v1, rhs_imm=0 } -> x0 terminator Bz { cond=v12, target=b3, fall=b1 } (exit_acc=v12) @@ -41,7 +41,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 v0 AllocaInit(0) -> - v1 ImmData(552) -> x3 v2 Imm(1) -> x0 - v3 Store { addr=v1, disp=0, value=v2, kind=I32 } -> - + v3 Store { addr=v1, disp=0, value=v2, kind=I32, volatile } -> - v4 ImmData(24) -> x12 v5 CallExt { binding_idx=0, args=[v4], fp_arg_mask=0x0 } -> x0 v6 BinopI { op=eq, lhs=v5, rhs_imm=0 } -> x0 @@ -49,7 +49,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 block 1 start_pc=0 v7 ImmData(536) -> x0 v8 Imm(0) -> x1 - v9 Store { addr=v7, disp=0, value=v8, kind=I32 } -> - + v9 Store { addr=v7, disp=0, value=v8, kind=I32, volatile } -> - v10 Imm(5) -> x7 v11 Imm(42) -> x6 v12 Call { target_pc=0, args=[v10, v11], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x0 @@ -57,7 +57,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 terminator Return(v13) (exit_acc=v13) block 2 start_pc=0 v14 ImmData(536) -> x0 - v15 Load { addr=v14, disp=0, kind=I32 } -> x0 + v15 Load { addr=v14, disp=0, kind=I32, volatile } -> x0 v16 BinopI { op=ne, lhs=v15, rhs_imm=6 } -> x0 terminator Bz { cond=v16, target=b4, fall=b3 } (exit_acc=v16) block 3 start_pc=0 @@ -66,7 +66,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 block 4 start_pc=0 v18 ImmData(552) -> x0 v19 Imm(2) -> x0 - v20 Store { addr=v1, disp=0, value=v19, kind=I32 } -> - + v20 Store { addr=v1, disp=0, value=v19, kind=I32, volatile } -> - v21 ImmData(24) -> x0 v22 CallExt { binding_idx=0, args=[v4], fp_arg_mask=0x0 } -> x0 v23 BinopI { op=eq, lhs=v22, rhs_imm=0 } -> x0 @@ -80,23 +80,23 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 block 6 start_pc=0 v28 ImmData(544) -> x0 v29 Imm(0) -> x1 - v30 Store { addr=v28, disp=0, value=v29, kind=I32 } -> - + v30 Store { addr=v28, disp=0, value=v29, kind=I32, volatile } -> - v31 ImmData(24) -> x0 v32 CallExt { binding_idx=0, args=[v4], fp_arg_mask=0x0 } -> x0 v33 BinopI { op=ne, lhs=v32, rhs_imm=0 } -> x0 terminator Bz { cond=v33, target=b9, fall=b7 } (exit_acc=v33) block 7 start_pc=0 v34 ImmData(544) -> x0 - v35 Load { addr=v34, disp=0, kind=I32 } -> x0 + v35 Load { addr=v34, disp=0, kind=I32, volatile } -> x0 v36 BinopI { op=ne, lhs=v35, rhs_imm=1 } -> x0 terminator Bz { cond=v36, target=b11, fall=b10 } (exit_acc=v36) block 8 start_pc=0 v45 ImmData(552) -> x0 v46 Imm(3) -> x0 - v47 Store { addr=v1, disp=0, value=v46, kind=I32 } -> - + v47 Store { addr=v1, disp=0, value=v46, kind=I32, volatile } -> - v48 ImmData(544) -> x0 v49 Imm(0) -> x1 - v50 Store { addr=v48, disp=0, value=v49, kind=I32 } -> - + v50 Store { addr=v48, disp=0, value=v49, kind=I32, volatile } -> - v51 ImmData(24) -> x0 v52 CallExt { binding_idx=0, args=[v4], fp_arg_mask=0x0 } -> x0 v53 BinopI { op=ne, lhs=v52, rhs_imm=0 } -> x0 @@ -104,7 +104,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 block 9 start_pc=0 v38 ImmData(544) -> x0 v39 Imm(1) -> x1 - v40 Store { addr=v38, disp=0, value=v39, kind=I32 } -> - + v40 Store { addr=v38, disp=0, value=v39, kind=I32, volatile } -> - v41 ImmData(24) -> x0 v42 Imm(0) -> x6 v43 CallExt { binding_idx=1, args=[v4, v42], fp_arg_mask=0x0 } -> x0 @@ -117,7 +117,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 terminator Jmp(b8) block 12 start_pc=0 v54 ImmData(544) -> x0 - v55 Load { addr=v54, disp=0, kind=I32 } -> x0 + v55 Load { addr=v54, disp=0, kind=I32, volatile } -> x0 v56 BinopI { op=ne, lhs=v55, rhs_imm=7 } -> x0 terminator Bz { cond=v56, target=b16, fall=b15 } (exit_acc=v56) block 13 start_pc=0 @@ -126,7 +126,7 @@ fn ent_pc=1 n_params=0 variadic=false locals=2 block 14 start_pc=0 v58 ImmData(544) -> x0 v59 Imm(7) -> x6 - v60 Store { addr=v58, disp=0, value=v59, kind=I32 } -> - + v60 Store { addr=v58, disp=0, value=v59, kind=I32, volatile } -> - v61 ImmData(24) -> x0 v62 CallExt { binding_idx=1, args=[v4, v59], fp_arg_mask=0x0 } -> x0 v63 Imm(31) -> x0 diff --git a/tests/snapshots/ssa/setjmp_value_live_across.ssa b/tests/snapshots/ssa/setjmp_value_live_across.ssa new file mode 100644 index 000000000..9b18b1ed5 --- /dev/null +++ b/tests/snapshots/ssa/setjmp_value_live_across.ssa @@ -0,0 +1,110 @@ +; --- SSA dump (ok=true) ent_pc=5 --- +; name=h +fn ent_pc=5 n_params=0 variadic=false locals=2 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ImmData(24) -> x7 + v2 Imm(1) -> x6 + v3 CallExt { binding_idx=1, args=[v1, v2], fp_arg_mask=0x0 } -> x0 + v4 Imm(0) -> x0 + terminator Return(v4) (exit_acc=v4) +; --- SSA dump (ok=true) ent_pc=6 --- +; name=test +fn ent_pc=6 n_params=2 variadic=false locals=2 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I32) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=2, kind=I32 } -> x0 + v6 BinopI { op=mul, lhs=v1, rhs_imm=7 } -> x0 + v7 BinopI { op=shl, lhs=v6, rhs_imm=32 } -> x1 + v8 Extend { value=v6, kind=I32 } -> x1 + v9 LoadLocal { off=3, kind=I32 } -> x1 + v10 Binop { op=add, lhs=v6, rhs=v3 } -> x0 + v11 BinopI { op=shl, lhs=v10, rhs_imm=32 } -> x1 + v12 Extend { value=v10, kind=I32 } -> x3 + v13 Imm(0) -> x0 + v14 ImmData(24) -> x7 + v15 CallExt { binding_idx=0, args=[v14], fp_arg_mask=0x0 } -> x0 + terminator Bz { cond=v15, target=b2, fall=b1 } (exit_acc=v15) + block 1 start_pc=0 + v16 LoadLocal { off=-1, kind=I32 } -> x0 + terminator Return(v12) (exit_acc=v12) + block 2 start_pc=0 + v17 Call { target_pc=5, args=[], fixed_args=0, fp_return=false, fp_arg_mask=0x0 } -> x0 + v18 Imm(0) -> x0 + terminator Return(v18) (exit_acc=v18) +; --- SSA dump (ok=true) ent_pc=7 --- +; name=main +fn ent_pc=7 n_params=0 variadic=false locals=3 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(5) -> x7 + v2 Imm(7) -> x6 + v3 Call { target_pc=6, args=[v1, v2], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x0 + v4 BinopI { op=eq, lhs=v3, rhs_imm=42 } -> x0 + terminator Bz { cond=v4, target=b2, fall=b1 } (exit_acc=v4) + block 1 start_pc=0 + v5 Imm(0) -> x1 + v6 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v5) + block 2 start_pc=0 + v7 Imm(1) -> x1 + v8 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v7) + block 3 start_pc=0 + v9 Phi { incoming=[b1:v5, b2:v7], kind=I64 } -> x1 + v10 LoadLocal { off=-3, kind=I64 } -> x0 + terminator Return(v9) (exit_acc=v9) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/shift_result_promoted_type.ssa b/tests/snapshots/ssa/shift_result_promoted_type.ssa new file mode 100644 index 000000000..1b42b4b32 --- /dev/null +++ b/tests/snapshots/ssa/shift_result_promoted_type.ssa @@ -0,0 +1,109 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=6 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(-8589934592) -> x0 + v2 Imm(0) -> x1 + v3 LoadLocal { off=-1, kind=I64 } -> x1 + v4 BinopI { op=shr, lhs=v1, rhs_imm=1 } -> x0 + v5 Imm(0) -> x1 + v6 LoadLocal { off=-2, kind=I64 } -> x1 + v7 BinopI { op=ne, lhs=v4, rhs_imm=-4294967296 } -> x0 + terminator Bz { cond=v7, target=b2, fall=b1 } (exit_acc=v7) + block 1 start_pc=0 + v8 Imm(1) -> x0 + terminator Return(v8) (exit_acc=v8) + block 2 start_pc=0 + v9 Imm(-9223372036854775808) -> x0 + v10 Imm(0) -> x1 + v11 LoadLocal { off=-3, kind=I64 } -> x1 + v12 BinopI { op=shru, lhs=v9, rhs_imm=63 } -> x0 + v13 BinopI { op=ne, lhs=v12, rhs_imm=1 } -> x0 + terminator Bz { cond=v13, target=b4, fall=b3 } (exit_acc=v13) + block 3 start_pc=0 + v14 Imm(2) -> x0 + terminator Return(v14) (exit_acc=v14) + block 4 start_pc=0 + v15 Imm(2147483648) -> x0 + v16 Imm(0) -> x1 + v17 LoadLocal { off=-4, kind=U32 } -> x1 + v18 BinopI { op=shru, lhs=v15, rhs_imm=31 } -> x0 + v19 BinopI { op=xor, lhs=v18, rhs_imm=1 } -> x0 + v20 BinopI { op=and, lhs=v19, rhs_imm=4294967295 } -> x0 + v21 BinopI { op=ne, lhs=v20, rhs_imm=0 } -> x0 + terminator Bz { cond=v21, target=b6, fall=b5 } (exit_acc=v21) + block 5 start_pc=0 + v22 Imm(3) -> x0 + terminator Return(v22) (exit_acc=v22) + block 6 start_pc=0 + v23 Imm(-16) -> x0 + v24 Imm(0) -> x1 + v25 LoadLocal { off=-5, kind=I32 } -> x1 + v26 BinopI { op=shr, lhs=v23, rhs_imm=2 } -> x0 + v27 BinopI { op=ne, lhs=v26, rhs_imm=-4 } -> x0 + terminator Bz { cond=v27, target=b8, fall=b7 } (exit_acc=v27) + block 7 start_pc=0 + v28 Imm(4) -> x0 + terminator Return(v28) (exit_acc=v28) + block 8 start_pc=0 + v29 Imm(128) -> x0 + v30 Imm(0) -> x1 + v31 LoadLocal { off=-6, kind=U8 } -> x1 + v32 BinopI { op=shru, lhs=v29, rhs_imm=3 } -> x0 + v33 BinopI { op=ne, lhs=v32, rhs_imm=16 } -> x0 + terminator Bz { cond=v33, target=b10, fall=b9 } (exit_acc=v33) + block 9 start_pc=0 + v34 Imm(5) -> x0 + terminator Return(v34) (exit_acc=v34) + block 10 start_pc=0 + v35 Imm(0) -> x0 + terminator Return(v35) (exit_acc=v35) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/shm_open_mode_arg.ssa b/tests/snapshots/ssa/shm_open_mode_arg.ssa new file mode 100644 index 000000000..ca78edbf4 --- /dev/null +++ b/tests/snapshots/ssa/shm_open_mode_arg.ssa @@ -0,0 +1,107 @@ +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=31 + spill_count=0 gpr_used=[3, 12, 13] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(0) -> x13 + v2 Imm(0) -> x0 + v3 LocalAddr(-8) -> x3 + v4 ImmData(76) -> x12 + v5 CallExt { binding_idx=64, args=[], fp_arg_mask=0x0 } -> x2 + v6 CallExt { binding_idx=167, args=[v3, v4, v5], fp_arg_mask=0x0 } -> x0 + v7 LocalAddr(-8) -> x7 + v8 CallExt { binding_idx=7, args=[v7], fp_arg_mask=0x0 } -> x0 + v9 LocalAddr(-8) -> x7 + v10 Imm(192) -> x0 + v11 Imm(194) -> x6 + v12 Imm(384) -> x2 + v13 CallExt { binding_idx=6, args=[v9, v11, v12], fp_arg_mask=0x0 } -> x3 + v14 Imm(0) -> x0 + v15 Extend { value=v13, kind=I32 } -> x0 + v16 BinopI { op=lt, lhs=v15, rhs_imm=0 } -> x0 + terminator Bz { cond=v16, target=b2, fall=b1 } (exit_acc=v16) + block 1 start_pc=0 + v17 Imm(1) -> x0 + terminator Return(v17) (exit_acc=v17) + block 2 start_pc=0 + v18 Extend { value=v13, kind=I32 } -> x7 + v19 LocalAddr(-26) -> x6 + v20 CallExt { binding_idx=53, args=[v18, v19], fp_arg_mask=0x0 } -> x0 + v21 BinopI { op=ne, lhs=v20, rhs_imm=0 } -> x0 + terminator Bz { cond=v21, target=b5, fall=b3 } (exit_acc=v21) + block 3 start_pc=0 + v22 Imm(2) -> x13 + v23 Imm(0) -> x0 + terminator Jmp(b4) (exit_acc=v22) + block 4 start_pc=0 + v24 Phi { incoming=[b3:v22, b7:v37], kind=I64 } -> x13 + v25 Extend { value=v13, kind=I32 } -> x7 + v26 CallExt { binding_idx=40, args=[v25], fp_arg_mask=0x0 } -> x0 + v27 LocalAddr(-8) -> x7 + v28 CallExt { binding_idx=7, args=[v27], fp_arg_mask=0x0 } -> x0 + v29 Extend { value=v24, kind=I32 } -> x0 + terminator Return(v29) (exit_acc=v29) + block 5 start_pc=0 + v30 LocalAddr(-26) -> x0 + v31 BinopI { op=add, lhs=v30, rhs_imm=24 } -> x1 + v32 Load { addr=v30, disp=24, kind=I32 } -> x0 + v33 BinopI { op=and, lhs=v32, rhs_imm=511 } -> x0 + v34 BinopI { op=ne, lhs=v33, rhs_imm=384 } -> x0 + terminator Bz { cond=v34, target=b8, fall=b6 } (exit_acc=v34) + block 6 start_pc=0 + v35 Imm(3) -> x13 + v36 Imm(0) -> x0 + terminator Jmp(b7) (exit_acc=v35) + block 7 start_pc=0 + v37 Phi { incoming=[b8:v1, b6:v35], kind=I64 } -> x13 + terminator Jmp(b4) + block 8 start_pc=0 + terminator Jmp(b7) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/slot_coalesce_alloca.ssa b/tests/snapshots/ssa/slot_coalesce_alloca.ssa index 55529add7..580e272cf 100644 --- a/tests/snapshots/ssa/slot_coalesce_alloca.ssa +++ b/tests/snapshots/ssa/slot_coalesce_alloca.ssa @@ -7,7 +7,7 @@ fn ent_pc=0 n_params=1 variadic=false locals=27 v0 AllocaInit(0) -> - v1 ParamRef(0, kind=I32) -> x7 v2 Imm(0) -> x0 - v3 Imm(0) -> x9 + v3 Imm(0) -> x8 v4 Imm(0) -> x0 v5 Imm(0) -> x0 terminator Jmp(b1) (exit_acc=v3) @@ -25,13 +25,13 @@ fn ent_pc=0 n_params=1 variadic=false locals=27 v12 LocalAddr(-24) -> x1 v13 Extend { value=v6, kind=I32 } -> x2 v14 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x6 - v15 Binop { op=add, lhs=v12, rhs=v14 } -> x6 - v16 BinopI { op=add, lhs=v13, rhs_imm=1 } -> x6 - v17 BinopI { op=shl, lhs=v16, rhs_imm=32 } -> x8 - v18 Extend { value=v16, kind=I32 } -> x6 - v19 LoadLocal { off=2, kind=I32 } -> x8 - v20 Binop { op=mul, lhs=v18, rhs=v1 } -> x6 - v21 StoreIndexed { base=v12, index=v13, scale=8, value=v20, kind=I64 } -> - + v15 Binop { op=add, lhs=v12, rhs=v14 } -> x1 + v16 BinopI { op=add, lhs=v13, rhs_imm=1 } -> x2 + v17 BinopI { op=shl, lhs=v16, rhs_imm=32 } -> x6 + v18 Extend { value=v16, kind=I32 } -> x2 + v19 LoadLocal { off=2, kind=I32 } -> x6 + v20 Binop { op=mul, lhs=v18, rhs=v1 } -> x2 + v21 Store { addr=v15, disp=0, value=v20, kind=I64, volatile } -> - terminator Jmp(b2) (exit_acc=v21) block 4 start_pc=0 v22 Imm(0) -> x1 @@ -39,7 +39,7 @@ fn ent_pc=0 n_params=1 variadic=false locals=27 terminator Jmp(b5) (exit_acc=v22) block 5 start_pc=0 v24 Phi { incoming=[b4:v22, b6:v29], kind=I64 } -> x1 - v25 Phi { incoming=[b4:v3, b6:v37], kind=I64 } -> x9 + v25 Phi { incoming=[b4:v3, b6:v37], kind=I64 } -> x8 v26 Extend { value=v24, kind=I32 } -> x0 v27 BinopI { op=lt, lhs=v26, rhs_imm=24 } -> x0 terminator Bz { cond=v27, target=b8, fall=b7 } (exit_acc=v27) @@ -52,10 +52,10 @@ fn ent_pc=0 n_params=1 variadic=false locals=27 v31 LoadLocal { off=-25, kind=I64 } -> x0 v32 LocalAddr(-24) -> x0 v33 Extend { value=v24, kind=I32 } -> x2 - v34 BinopI { op=shl, lhs=v33, rhs_imm=3 } -> x6 - v35 Binop { op=add, lhs=v32, rhs=v34 } -> x6 - v36 LoadIndexed { base=v32, index=v33, scale=8, kind=I64 } -> x0 - v37 Binop { op=add, lhs=v25, rhs=v36 } -> x9 + v34 BinopI { op=shl, lhs=v33, rhs_imm=3 } -> x2 + v35 Binop { op=add, lhs=v32, rhs=v34 } -> x0 + v36 Load { addr=v35, disp=0, kind=I64, volatile } -> x0 + v37 Binop { op=add, lhs=v25, rhs=v36 } -> x8 v38 Imm(0) -> x0 terminator Jmp(b6) (exit_acc=v37) block 8 start_pc=0 diff --git a/tests/snapshots/ssa/snprintf_truncation_c99.ssa b/tests/snapshots/ssa/snprintf_truncation_c99.ssa new file mode 100644 index 000000000..38300acc4 --- /dev/null +++ b/tests/snapshots/ssa/snprintf_truncation_c99.ssa @@ -0,0 +1,157 @@ +; --- SSA dump (ok=true) ent_pc=1 --- +; name=wrap +fn ent_pc=1 n_params=3 variadic=true locals=8 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-3) -> x0 + v2 LocalAddr(4) -> x1 + v3 Intrinsic { kind=4, args=[v1, v2] } -> x0 + v4 LoadLocal { off=2, kind=I64 } -> x7 + v5 LoadLocal { off=3, kind=I32 } -> x6 + v6 LoadLocal { off=4, kind=I64 } -> x2 + v7 LocalAddr(-3) -> x1 + v8 CallExt { binding_idx=7, args=[v4, v5, v6, v7], fp_arg_mask=0x0 } -> x0 + v9 Imm(0) -> x1 + v10 LocalAddr(-3) -> x1 + v11 Intrinsic { kind=6, args=[v10] } -> x1 + v12 Extend { value=v8, kind=I32 } -> x0 + terminator Return(v12) (exit_acc=v12) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=main +fn ent_pc=2 n_params=0 variadic=false locals=6 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-1) -> x7 + v2 Imm(65) -> x6 + v3 Imm(8) -> x2 + v4 CallExt { binding_idx=54, args=[v1, v2, v3], fp_arg_mask=0x0 } -> x0 + v5 LocalAddr(-1) -> x7 + v6 Imm(4) -> x6 + v7 ImmData(36) -> x2 + v8 Imm(123456) -> x1 + v9 CallExt { binding_idx=3, args=[v5, v6, v7, v8], fp_arg_mask=0x0 } -> x0 + v10 BinopI { op=ne, lhs=v9, rhs_imm=6 } -> x0 + terminator Bz { cond=v10, target=b2, fall=b1 } (exit_acc=v10) + block 1 start_pc=0 + v11 Imm(1) -> x0 + terminator Return(v11) (exit_acc=v11) + block 2 start_pc=0 + v12 LocalAddr(-1) -> x7 + v13 ImmData(39) -> x6 + v14 CallExt { binding_idx=62, args=[v12, v13], fp_arg_mask=0x0 } -> x0 + v15 BinopI { op=ne, lhs=v14, rhs_imm=0 } -> x0 + terminator Bz { cond=v15, target=b4, fall=b3 } (exit_acc=v15) + block 3 start_pc=0 + v16 Imm(2) -> x0 + terminator Return(v16) (exit_acc=v16) + block 4 start_pc=0 + v17 Imm(0) -> x7 + v18 ImmData(43) -> x2 + v19 ImmData(46) -> x1 + v20 CallExt { binding_idx=3, args=[v17, v17, v18, v19], fp_arg_mask=0x0 } -> x0 + v21 BinopI { op=ne, lhs=v20, rhs_imm=5 } -> x0 + terminator Bz { cond=v21, target=b6, fall=b5 } (exit_acc=v21) + block 5 start_pc=0 + v22 Imm(3) -> x0 + terminator Return(v22) (exit_acc=v22) + block 6 start_pc=0 + v23 LocalAddr(-1) -> x7 + v24 Imm(65) -> x6 + v25 Imm(8) -> x2 + v26 CallExt { binding_idx=54, args=[v23, v24, v25], fp_arg_mask=0x0 } -> x0 + v27 LocalAddr(-1) -> x7 + v28 Imm(4) -> x6 + v29 ImmData(52) -> x2 + v30 Imm(987654) -> x1 + v31 Call { target_pc=1, args=[v27, v28, v29, v30], fixed_args=3, fp_return=false, fp_arg_mask=0x0 } -> x0 + v32 BinopI { op=ne, lhs=v31, rhs_imm=6 } -> x0 + terminator Bz { cond=v32, target=b8, fall=b7 } (exit_acc=v32) + block 7 start_pc=0 + v33 Imm(4) -> x0 + terminator Return(v33) (exit_acc=v33) + block 8 start_pc=0 + v34 LocalAddr(-1) -> x7 + v35 ImmData(55) -> x6 + v36 CallExt { binding_idx=62, args=[v34, v35], fp_arg_mask=0x0 } -> x0 + v37 BinopI { op=ne, lhs=v36, rhs_imm=0 } -> x0 + terminator Bz { cond=v37, target=b10, fall=b9 } (exit_acc=v37) + block 9 start_pc=0 + v38 Imm(5) -> x0 + terminator Return(v38) (exit_acc=v38) + block 10 start_pc=0 + v39 LocalAddr(-1) -> x7 + v40 Imm(8) -> x6 + v41 ImmData(59) -> x2 + v42 Imm(42) -> x1 + v43 CallExt { binding_idx=3, args=[v39, v40, v41, v42], fp_arg_mask=0x0 } -> x0 + v44 BinopI { op=ne, lhs=v43, rhs_imm=2 } -> x1 + v45 Imm(0) -> x0 + terminator Bnz { cond=v44, target=b15, fall=b11 } (exit_acc=v44) + block 11 start_pc=0 + v46 LocalAddr(-1) -> x7 + v47 ImmData(62) -> x6 + v48 CallExt { binding_idx=62, args=[v46, v47], fp_arg_mask=0x0 } -> x0 + v49 BinopI { op=ne, lhs=v48, rhs_imm=0 } -> x1 + v50 Imm(0) -> x0 + terminator Jmp(b12) (exit_acc=v49) + block 12 start_pc=0 + v51 Phi { incoming=[b15:v44, b11:v49], kind=I64 } -> x1 + v52 LoadLocal { off=-6, kind=I64 } -> x0 + terminator Bz { cond=v51, target=b14, fall=b13 } (exit_acc=v51) + block 13 start_pc=0 + v53 Imm(6) -> x0 + terminator Return(v53) (exit_acc=v53) + block 14 start_pc=0 + v54 Imm(0) -> x0 + terminator Return(v54) (exit_acc=v54) + block 15 start_pc=0 + terminator Jmp(b12) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/sqlite_min.ssa b/tests/snapshots/ssa/sqlite_min.ssa index 01acd8999..b7d423dac 100644 --- a/tests/snapshots/ssa/sqlite_min.ssa +++ b/tests/snapshots/ssa/sqlite_min.ssa @@ -90,15 +90,11 @@ fn ent_pc=5 n_params=0 variadic=false locals=28 terminator Return(v66) (exit_acc=v66) ; --- SSA dump (ok=true) ent_pc=6 --- ; name=__c5_sys_open -fn ent_pc=6 n_params=3 variadic=false locals=0 +fn ent_pc=6 n_params=0 variadic=false locals=0 spill_count=0 gpr_used=[] fp_used=[] block 0 start_pc=0 v0 AllocaInit(0) -> - - v1 LoadLocal { off=2, kind=I64 } -> x7 - v2 LoadLocal { off=3, kind=I64 } -> x6 - v3 LoadLocal { off=4, kind=I64 } -> x2 - v4 CallExt { binding_idx=61, args=[v1, v2, v3], fp_arg_mask=0x0 } -> x0 - terminator Return(v4) (exit_acc=v4) + terminator TailExt(61) ; --- SSA dump (ok=true) ent_pc=7 --- ; name=__c5_sys_close fn ent_pc=7 n_params=1 variadic=false locals=0 @@ -120,15 +116,11 @@ fn ent_pc=8 n_params=2 variadic=false locals=0 terminator Return(v3) (exit_acc=v3) ; --- SSA dump (ok=true) ent_pc=9 --- ; name=__c5_sys_fcntl -fn ent_pc=9 n_params=3 variadic=false locals=0 +fn ent_pc=9 n_params=0 variadic=false locals=0 spill_count=0 gpr_used=[] fp_used=[] block 0 start_pc=0 v0 AllocaInit(0) -> - - v1 LoadLocal { off=2, kind=I64 } -> x7 - v2 LoadLocal { off=3, kind=I64 } -> x6 - v3 LoadLocal { off=4, kind=I64 } -> x2 - v4 CallExt { binding_idx=75, args=[v1, v2, v3], fp_arg_mask=0x0 } -> x0 - terminator Return(v4) (exit_acc=v4) + terminator TailExt(75) ; --- SSA dump (ok=true) ent_pc=10 --- ; name=__c5_sys_stat fn ent_pc=10 n_params=2 variadic=false locals=0 diff --git a/tests/snapshots/ssa/static_neg_infinity_init.ssa b/tests/snapshots/ssa/static_neg_infinity_init.ssa index 38b0540eb..ce2d4a0a9 100644 --- a/tests/snapshots/ssa/static_neg_infinity_init.ssa +++ b/tests/snapshots/ssa/static_neg_infinity_init.ssa @@ -42,8 +42,8 @@ fn ent_pc=14 n_params=0 variadic=false locals=1 terminator Return(v5) (exit_acc=v5) block 2 start_pc=0 v6 ImmData(16) -> x0 - v7 BinopI { op=add, lhs=v6, rhs_imm=8 } -> x0 - v8 Load { addr=v7, disp=0, kind=F64 } -> d0 + v7 BinopI { op=add, lhs=v6, rhs_imm=8 } -> x1 + v8 Load { addr=v6, disp=8, kind=F64 } -> d0 v9 Call { target_pc=13, args=[v8], fixed_args=1, fp_return=false, fp_arg_mask=0x1 } -> x0 v10 BinopI { op=eq, lhs=v9, rhs_imm=0 } -> x0 terminator Bz { cond=v10, target=b4, fall=b3 } (exit_acc=v10) diff --git a/tests/snapshots/ssa/strength_reduce_pow2_divmod.ssa b/tests/snapshots/ssa/strength_reduce_pow2_divmod.ssa index a43e31bfa..10a1f0bfa 100644 --- a/tests/snapshots/ssa/strength_reduce_pow2_divmod.ssa +++ b/tests/snapshots/ssa/strength_reduce_pow2_divmod.ssa @@ -5,29 +5,29 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 block 0 start_pc=0 v0 AllocaInit(0) -> - v1 Imm(-7) -> x0 - v2 Imm(0) -> x1 - v3 LoadLocal { off=-1, kind=I32 } -> x1 + v2 StoreLocal { off=-1, value=v1, kind=I32, volatile } -> - + v3 LoadLocal { off=-1, kind=I32, volatile } -> x0 v4 Imm(2) -> x1 - v5 BinopI { op=shr, lhs=v1, rhs_imm=63 } -> x1 + v5 BinopI { op=shr, lhs=v3, rhs_imm=63 } -> x1 v6 BinopI { op=shru, lhs=v5, rhs_imm=63 } -> x1 - v7 Binop { op=add, lhs=v1, rhs=v6 } -> x1 - v8 BinopI { op=shr, lhs=v7, rhs_imm=1 } -> x1 - v9 BinopI { op=ne, lhs=v8, rhs_imm=-3 } -> x2 - v10 Imm(0) -> x1 + v7 Binop { op=add, lhs=v3, rhs=v6 } -> x0 + v8 BinopI { op=shr, lhs=v7, rhs_imm=1 } -> x0 + v9 BinopI { op=ne, lhs=v8, rhs_imm=-3 } -> x1 + v10 Imm(0) -> x0 terminator Bnz { cond=v9, target=b45, fall=b1 } (exit_acc=v9) block 1 start_pc=0 - v11 LoadLocal { off=-1, kind=I32 } -> x1 + v11 LoadLocal { off=-1, kind=I32, volatile } -> x0 v12 Imm(2) -> x1 - v13 BinopI { op=shr, lhs=v1, rhs_imm=63 } -> x1 + v13 BinopI { op=shr, lhs=v11, rhs_imm=63 } -> x1 v14 BinopI { op=shru, lhs=v13, rhs_imm=63 } -> x1 - v15 Binop { op=add, lhs=v1, rhs=v14 } -> x0 + v15 Binop { op=add, lhs=v11, rhs=v14 } -> x0 v16 BinopI { op=and, lhs=v15, rhs_imm=1 } -> x0 v17 Binop { op=sub, lhs=v16, rhs=v14 } -> x0 - v18 BinopI { op=ne, lhs=v17, rhs_imm=-1 } -> x2 + v18 BinopI { op=ne, lhs=v17, rhs_imm=-1 } -> x1 v19 Imm(0) -> x0 terminator Jmp(b2) (exit_acc=v18) block 2 start_pc=0 - v20 Phi { incoming=[b45:v9, b1:v18], kind=I64 } -> x2 + v20 Phi { incoming=[b45:v9, b1:v18], kind=I64 } -> x1 v21 LoadLocal { off=-9, kind=I64 } -> x0 terminator Bz { cond=v20, target=b4, fall=b3 } (exit_acc=v20) block 3 start_pc=0 @@ -35,29 +35,29 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 terminator Return(v22) (exit_acc=v22) block 4 start_pc=0 v23 Imm(-16) -> x0 - v24 Imm(0) -> x1 - v25 LoadLocal { off=-1, kind=I32 } -> x1 + v24 StoreLocal { off=-1, value=v23, kind=I32, volatile } -> - + v25 LoadLocal { off=-1, kind=I32, volatile } -> x0 v26 Imm(16) -> x1 - v27 BinopI { op=shr, lhs=v23, rhs_imm=63 } -> x1 + v27 BinopI { op=shr, lhs=v25, rhs_imm=63 } -> x1 v28 BinopI { op=shru, lhs=v27, rhs_imm=60 } -> x1 - v29 Binop { op=add, lhs=v23, rhs=v28 } -> x1 - v30 BinopI { op=shr, lhs=v29, rhs_imm=4 } -> x1 - v31 BinopI { op=ne, lhs=v30, rhs_imm=-1 } -> x2 - v32 Imm(0) -> x1 + v29 Binop { op=add, lhs=v25, rhs=v28 } -> x0 + v30 BinopI { op=shr, lhs=v29, rhs_imm=4 } -> x0 + v31 BinopI { op=ne, lhs=v30, rhs_imm=-1 } -> x1 + v32 Imm(0) -> x0 terminator Bnz { cond=v31, target=b46, fall=b5 } (exit_acc=v31) block 5 start_pc=0 - v33 LoadLocal { off=-1, kind=I32 } -> x1 + v33 LoadLocal { off=-1, kind=I32, volatile } -> x0 v34 Imm(16) -> x1 - v35 BinopI { op=shr, lhs=v23, rhs_imm=63 } -> x1 + v35 BinopI { op=shr, lhs=v33, rhs_imm=63 } -> x1 v36 BinopI { op=shru, lhs=v35, rhs_imm=60 } -> x1 - v37 Binop { op=add, lhs=v23, rhs=v36 } -> x0 + v37 Binop { op=add, lhs=v33, rhs=v36 } -> x0 v38 BinopI { op=and, lhs=v37, rhs_imm=15 } -> x0 v39 Binop { op=sub, lhs=v38, rhs=v36 } -> x0 - v40 BinopI { op=ne, lhs=v39, rhs_imm=0 } -> x2 + v40 BinopI { op=ne, lhs=v39, rhs_imm=0 } -> x1 v41 Imm(0) -> x0 terminator Jmp(b6) (exit_acc=v40) block 6 start_pc=0 - v42 Phi { incoming=[b46:v31, b5:v40], kind=I64 } -> x2 + v42 Phi { incoming=[b46:v31, b5:v40], kind=I64 } -> x1 v43 LoadLocal { off=-10, kind=I64 } -> x0 terminator Bz { cond=v42, target=b8, fall=b7 } (exit_acc=v42) block 7 start_pc=0 @@ -65,29 +65,29 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 terminator Return(v44) (exit_acc=v44) block 8 start_pc=0 v45 Imm(-17) -> x0 - v46 Imm(0) -> x1 - v47 LoadLocal { off=-1, kind=I32 } -> x1 + v46 StoreLocal { off=-1, value=v45, kind=I32, volatile } -> - + v47 LoadLocal { off=-1, kind=I32, volatile } -> x0 v48 Imm(16) -> x1 - v49 BinopI { op=shr, lhs=v45, rhs_imm=63 } -> x1 + v49 BinopI { op=shr, lhs=v47, rhs_imm=63 } -> x1 v50 BinopI { op=shru, lhs=v49, rhs_imm=60 } -> x1 - v51 Binop { op=add, lhs=v45, rhs=v50 } -> x1 - v52 BinopI { op=shr, lhs=v51, rhs_imm=4 } -> x1 - v53 BinopI { op=ne, lhs=v52, rhs_imm=-1 } -> x2 - v54 Imm(0) -> x1 + v51 Binop { op=add, lhs=v47, rhs=v50 } -> x0 + v52 BinopI { op=shr, lhs=v51, rhs_imm=4 } -> x0 + v53 BinopI { op=ne, lhs=v52, rhs_imm=-1 } -> x1 + v54 Imm(0) -> x0 terminator Bnz { cond=v53, target=b47, fall=b9 } (exit_acc=v53) block 9 start_pc=0 - v55 LoadLocal { off=-1, kind=I32 } -> x1 + v55 LoadLocal { off=-1, kind=I32, volatile } -> x0 v56 Imm(16) -> x1 - v57 BinopI { op=shr, lhs=v45, rhs_imm=63 } -> x1 + v57 BinopI { op=shr, lhs=v55, rhs_imm=63 } -> x1 v58 BinopI { op=shru, lhs=v57, rhs_imm=60 } -> x1 - v59 Binop { op=add, lhs=v45, rhs=v58 } -> x0 + v59 Binop { op=add, lhs=v55, rhs=v58 } -> x0 v60 BinopI { op=and, lhs=v59, rhs_imm=15 } -> x0 v61 Binop { op=sub, lhs=v60, rhs=v58 } -> x0 - v62 BinopI { op=ne, lhs=v61, rhs_imm=-1 } -> x2 + v62 BinopI { op=ne, lhs=v61, rhs_imm=-1 } -> x1 v63 Imm(0) -> x0 terminator Jmp(b10) (exit_acc=v62) block 10 start_pc=0 - v64 Phi { incoming=[b47:v53, b9:v62], kind=I64 } -> x2 + v64 Phi { incoming=[b47:v53, b9:v62], kind=I64 } -> x1 v65 LoadLocal { off=-11, kind=I64 } -> x0 terminator Bz { cond=v64, target=b12, fall=b11 } (exit_acc=v64) block 11 start_pc=0 @@ -95,29 +95,29 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 terminator Return(v66) (exit_acc=v66) block 12 start_pc=0 v67 Imm(100) -> x0 - v68 Imm(0) -> x1 - v69 LoadLocal { off=-1, kind=I32 } -> x1 + v68 StoreLocal { off=-1, value=v67, kind=I32, volatile } -> - + v69 LoadLocal { off=-1, kind=I32, volatile } -> x0 v70 Imm(8) -> x1 - v71 BinopI { op=shr, lhs=v67, rhs_imm=63 } -> x1 + v71 BinopI { op=shr, lhs=v69, rhs_imm=63 } -> x1 v72 BinopI { op=shru, lhs=v71, rhs_imm=61 } -> x1 - v73 Binop { op=add, lhs=v67, rhs=v72 } -> x1 - v74 BinopI { op=shr, lhs=v73, rhs_imm=3 } -> x1 - v75 BinopI { op=ne, lhs=v74, rhs_imm=12 } -> x2 - v76 Imm(0) -> x1 + v73 Binop { op=add, lhs=v69, rhs=v72 } -> x0 + v74 BinopI { op=shr, lhs=v73, rhs_imm=3 } -> x0 + v75 BinopI { op=ne, lhs=v74, rhs_imm=12 } -> x1 + v76 Imm(0) -> x0 terminator Bnz { cond=v75, target=b48, fall=b13 } (exit_acc=v75) block 13 start_pc=0 - v77 LoadLocal { off=-1, kind=I32 } -> x1 + v77 LoadLocal { off=-1, kind=I32, volatile } -> x0 v78 Imm(8) -> x1 - v79 BinopI { op=shr, lhs=v67, rhs_imm=63 } -> x1 + v79 BinopI { op=shr, lhs=v77, rhs_imm=63 } -> x1 v80 BinopI { op=shru, lhs=v79, rhs_imm=61 } -> x1 - v81 Binop { op=add, lhs=v67, rhs=v80 } -> x0 + v81 Binop { op=add, lhs=v77, rhs=v80 } -> x0 v82 BinopI { op=and, lhs=v81, rhs_imm=7 } -> x0 v83 Binop { op=sub, lhs=v82, rhs=v80 } -> x0 - v84 BinopI { op=ne, lhs=v83, rhs_imm=4 } -> x2 + v84 BinopI { op=ne, lhs=v83, rhs_imm=4 } -> x1 v85 Imm(0) -> x0 terminator Jmp(b14) (exit_acc=v84) block 14 start_pc=0 - v86 Phi { incoming=[b48:v75, b13:v84], kind=I64 } -> x2 + v86 Phi { incoming=[b48:v75, b13:v84], kind=I64 } -> x1 v87 LoadLocal { off=-12, kind=I64 } -> x0 terminator Bz { cond=v86, target=b16, fall=b15 } (exit_acc=v86) block 15 start_pc=0 @@ -126,29 +126,29 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 block 16 start_pc=0 v89 Imm(-2147483648) -> x0 v90 Imm(-9223372036854775808) -> x1 - v91 Imm(0) -> x1 - v92 LoadLocal { off=-1, kind=I32 } -> x1 + v91 StoreLocal { off=-1, value=v89, kind=I32, volatile } -> - + v92 LoadLocal { off=-1, kind=I32, volatile } -> x0 v93 Imm(2) -> x1 - v94 BinopI { op=shr, lhs=v89, rhs_imm=63 } -> x1 + v94 BinopI { op=shr, lhs=v92, rhs_imm=63 } -> x1 v95 BinopI { op=shru, lhs=v94, rhs_imm=63 } -> x1 - v96 Binop { op=add, lhs=v89, rhs=v95 } -> x1 - v97 BinopI { op=shr, lhs=v96, rhs_imm=1 } -> x1 - v98 BinopI { op=ne, lhs=v97, rhs_imm=-1073741824 } -> x2 - v99 Imm(0) -> x1 + v96 Binop { op=add, lhs=v92, rhs=v95 } -> x0 + v97 BinopI { op=shr, lhs=v96, rhs_imm=1 } -> x0 + v98 BinopI { op=ne, lhs=v97, rhs_imm=-1073741824 } -> x1 + v99 Imm(0) -> x0 terminator Bnz { cond=v98, target=b49, fall=b17 } (exit_acc=v98) block 17 start_pc=0 - v100 LoadLocal { off=-1, kind=I32 } -> x1 + v100 LoadLocal { off=-1, kind=I32, volatile } -> x0 v101 Imm(2) -> x1 - v102 BinopI { op=shr, lhs=v89, rhs_imm=63 } -> x1 + v102 BinopI { op=shr, lhs=v100, rhs_imm=63 } -> x1 v103 BinopI { op=shru, lhs=v102, rhs_imm=63 } -> x1 - v104 Binop { op=add, lhs=v89, rhs=v103 } -> x0 + v104 Binop { op=add, lhs=v100, rhs=v103 } -> x0 v105 BinopI { op=and, lhs=v104, rhs_imm=1 } -> x0 v106 Binop { op=sub, lhs=v105, rhs=v103 } -> x0 - v107 BinopI { op=ne, lhs=v106, rhs_imm=0 } -> x2 + v107 BinopI { op=ne, lhs=v106, rhs_imm=0 } -> x1 v108 Imm(0) -> x0 terminator Jmp(b18) (exit_acc=v107) block 18 start_pc=0 - v109 Phi { incoming=[b49:v98, b17:v107], kind=I64 } -> x2 + v109 Phi { incoming=[b49:v98, b17:v107], kind=I64 } -> x1 v110 LoadLocal { off=-13, kind=I64 } -> x0 terminator Bz { cond=v109, target=b20, fall=b19 } (exit_acc=v109) block 19 start_pc=0 @@ -156,22 +156,22 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 terminator Return(v111) (exit_acc=v111) block 20 start_pc=0 v112 Imm(4294967295) -> x0 - v113 Imm(0) -> x1 - v114 LoadLocal { off=-2, kind=U32 } -> x1 + v113 StoreLocal { off=-2, value=v112, kind=I32, volatile } -> - + v114 LoadLocal { off=-2, kind=U32, volatile } -> x0 v115 Imm(2) -> x1 - v116 BinopI { op=shru, lhs=v112, rhs_imm=1 } -> x1 - v117 BinopI { op=ne, lhs=v116, rhs_imm=2147483647 } -> x2 - v118 Imm(0) -> x1 + v116 BinopI { op=shru, lhs=v114, rhs_imm=1 } -> x0 + v117 BinopI { op=ne, lhs=v116, rhs_imm=2147483647 } -> x1 + v118 Imm(0) -> x0 terminator Bnz { cond=v117, target=b50, fall=b21 } (exit_acc=v117) block 21 start_pc=0 - v119 LoadLocal { off=-2, kind=U32 } -> x1 + v119 LoadLocal { off=-2, kind=U32, volatile } -> x0 v120 Imm(2) -> x1 - v121 BinopI { op=and, lhs=v112, rhs_imm=1 } -> x0 - v122 BinopI { op=ne, lhs=v121, rhs_imm=1 } -> x2 + v121 BinopI { op=and, lhs=v119, rhs_imm=1 } -> x0 + v122 BinopI { op=ne, lhs=v121, rhs_imm=1 } -> x1 v123 Imm(0) -> x0 terminator Jmp(b22) (exit_acc=v122) block 22 start_pc=0 - v124 Phi { incoming=[b50:v117, b21:v122], kind=I64 } -> x2 + v124 Phi { incoming=[b50:v117, b21:v122], kind=I64 } -> x1 v125 LoadLocal { off=-14, kind=I64 } -> x0 terminator Bz { cond=v124, target=b24, fall=b23 } (exit_acc=v124) block 23 start_pc=0 @@ -179,22 +179,22 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 terminator Return(v126) (exit_acc=v126) block 24 start_pc=0 v127 Imm(2147483648) -> x0 - v128 Imm(0) -> x1 - v129 LoadLocal { off=-2, kind=U32 } -> x1 + v128 StoreLocal { off=-2, value=v127, kind=I32, volatile } -> - + v129 LoadLocal { off=-2, kind=U32, volatile } -> x0 v130 Imm(16) -> x1 - v131 BinopI { op=shru, lhs=v127, rhs_imm=4 } -> x1 - v132 BinopI { op=ne, lhs=v131, rhs_imm=134217728 } -> x2 - v133 Imm(0) -> x1 + v131 BinopI { op=shru, lhs=v129, rhs_imm=4 } -> x0 + v132 BinopI { op=ne, lhs=v131, rhs_imm=134217728 } -> x1 + v133 Imm(0) -> x0 terminator Bnz { cond=v132, target=b51, fall=b25 } (exit_acc=v132) block 25 start_pc=0 - v134 LoadLocal { off=-2, kind=U32 } -> x1 + v134 LoadLocal { off=-2, kind=U32, volatile } -> x0 v135 Imm(16) -> x1 - v136 BinopI { op=and, lhs=v127, rhs_imm=15 } -> x0 - v137 BinopI { op=ne, lhs=v136, rhs_imm=0 } -> x2 + v136 BinopI { op=and, lhs=v134, rhs_imm=15 } -> x0 + v137 BinopI { op=ne, lhs=v136, rhs_imm=0 } -> x1 v138 Imm(0) -> x0 terminator Jmp(b26) (exit_acc=v137) block 26 start_pc=0 - v139 Phi { incoming=[b51:v132, b25:v137], kind=I64 } -> x2 + v139 Phi { incoming=[b51:v132, b25:v137], kind=I64 } -> x1 v140 LoadLocal { off=-15, kind=I64 } -> x0 terminator Bz { cond=v139, target=b28, fall=b27 } (exit_acc=v139) block 27 start_pc=0 @@ -202,26 +202,26 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 terminator Return(v141) (exit_acc=v141) block 28 start_pc=0 v142 Imm(-1234567) -> x0 - v143 Imm(0) -> x1 - v144 LoadLocal { off=-7, kind=I64 } -> x1 - v145 Imm(1024) -> x1 - v146 BinopI { op=shr, lhs=v142, rhs_imm=63 } -> x1 - v147 BinopI { op=shru, lhs=v146, rhs_imm=54 } -> x1 - v148 Binop { op=add, lhs=v142, rhs=v147 } -> x1 + v143 StoreLocal { off=-7, value=v142, kind=I64, volatile } -> - + v144 LoadLocal { off=-7, kind=I64, volatile } -> x1 + v145 Imm(1024) -> x2 + v146 BinopI { op=shr, lhs=v144, rhs_imm=63 } -> x2 + v147 BinopI { op=shru, lhs=v146, rhs_imm=54 } -> x2 + v148 Binop { op=add, lhs=v144, rhs=v147 } -> x1 v149 BinopI { op=shr, lhs=v148, rhs_imm=10 } -> x1 v150 Imm(-1) -> x2 v151 Imm(1023) -> x2 - v152 Binop { op=add, lhs=v142, rhs=v151 } -> x2 - v153 BinopI { op=shr, lhs=v152, rhs_imm=10 } -> x2 - v154 Binop { op=ne, lhs=v149, rhs=v153 } -> x2 - v155 Imm(0) -> x1 + v152 Binop { op=add, lhs=v142, rhs=v151 } -> x0 + v153 BinopI { op=shr, lhs=v152, rhs_imm=10 } -> x0 + v154 Binop { op=ne, lhs=v149, rhs=v153 } -> x1 + v155 Imm(0) -> x0 terminator Bnz { cond=v154, target=b52, fall=b29 } (exit_acc=v154) block 29 start_pc=0 - v156 LoadLocal { off=-7, kind=I64 } -> x1 + v156 LoadLocal { off=-7, kind=I64, volatile } -> x0 v157 Imm(1024) -> x1 - v158 BinopI { op=shr, lhs=v142, rhs_imm=63 } -> x1 + v158 BinopI { op=shr, lhs=v156, rhs_imm=63 } -> x1 v159 BinopI { op=shru, lhs=v158, rhs_imm=54 } -> x1 - v160 Binop { op=add, lhs=v142, rhs=v159 } -> x0 + v160 Binop { op=add, lhs=v156, rhs=v159 } -> x0 v161 BinopI { op=and, lhs=v160, rhs_imm=1023 } -> x0 v162 Binop { op=sub, lhs=v161, rhs=v159 } -> x0 v163 Imm(-1234567) -> x1 @@ -230,11 +230,11 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 v166 Binop { op=add, lhs=v163, rhs=v165 } -> x1 v167 BinopI { op=and, lhs=v166, rhs_imm=1023 } -> x1 v168 Binop { op=sub, lhs=v167, rhs=v165 } -> x1 - v169 Binop { op=ne, lhs=v162, rhs=v168 } -> x2 + v169 Binop { op=ne, lhs=v162, rhs=v168 } -> x1 v170 Imm(0) -> x0 terminator Jmp(b30) (exit_acc=v169) block 30 start_pc=0 - v171 Phi { incoming=[b52:v154, b29:v169], kind=I64 } -> x2 + v171 Phi { incoming=[b52:v154, b29:v169], kind=I64 } -> x1 v172 LoadLocal { off=-16, kind=I64 } -> x0 terminator Bz { cond=v171, target=b32, fall=b31 } (exit_acc=v171) block 31 start_pc=0 @@ -242,29 +242,29 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 terminator Return(v173) (exit_acc=v173) block 32 start_pc=0 v174 Imm(-9223372036854775808) -> x0 - v175 Imm(0) -> x1 - v176 LoadLocal { off=-7, kind=I64 } -> x1 + v175 StoreLocal { off=-7, value=v174, kind=I64, volatile } -> - + v176 LoadLocal { off=-7, kind=I64, volatile } -> x0 v177 Imm(2) -> x1 - v178 BinopI { op=shr, lhs=v174, rhs_imm=63 } -> x1 + v178 BinopI { op=shr, lhs=v176, rhs_imm=63 } -> x1 v179 BinopI { op=shru, lhs=v178, rhs_imm=63 } -> x1 - v180 Binop { op=add, lhs=v174, rhs=v179 } -> x1 - v181 BinopI { op=shr, lhs=v180, rhs_imm=1 } -> x1 - v182 BinopI { op=ne, lhs=v181, rhs_imm=-4611686018427387904 } -> x2 - v183 Imm(0) -> x1 + v180 Binop { op=add, lhs=v176, rhs=v179 } -> x0 + v181 BinopI { op=shr, lhs=v180, rhs_imm=1 } -> x0 + v182 BinopI { op=ne, lhs=v181, rhs_imm=-4611686018427387904 } -> x1 + v183 Imm(0) -> x0 terminator Bnz { cond=v182, target=b53, fall=b33 } (exit_acc=v182) block 33 start_pc=0 - v184 LoadLocal { off=-7, kind=I64 } -> x1 + v184 LoadLocal { off=-7, kind=I64, volatile } -> x0 v185 Imm(2) -> x1 - v186 BinopI { op=shr, lhs=v174, rhs_imm=63 } -> x1 + v186 BinopI { op=shr, lhs=v184, rhs_imm=63 } -> x1 v187 BinopI { op=shru, lhs=v186, rhs_imm=63 } -> x1 - v188 Binop { op=add, lhs=v174, rhs=v187 } -> x0 + v188 Binop { op=add, lhs=v184, rhs=v187 } -> x0 v189 BinopI { op=and, lhs=v188, rhs_imm=1 } -> x0 v190 Binop { op=sub, lhs=v189, rhs=v187 } -> x0 - v191 BinopI { op=ne, lhs=v190, rhs_imm=0 } -> x2 + v191 BinopI { op=ne, lhs=v190, rhs_imm=0 } -> x1 v192 Imm(0) -> x0 terminator Jmp(b34) (exit_acc=v191) block 34 start_pc=0 - v193 Phi { incoming=[b53:v182, b33:v191], kind=I64 } -> x2 + v193 Phi { incoming=[b53:v182, b33:v191], kind=I64 } -> x1 v194 LoadLocal { off=-17, kind=I64 } -> x0 terminator Bz { cond=v193, target=b36, fall=b35 } (exit_acc=v193) block 35 start_pc=0 @@ -272,22 +272,22 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 terminator Return(v195) (exit_acc=v195) block 36 start_pc=0 v196 Imm(-1) -> x0 - v197 Imm(0) -> x1 - v198 LoadLocal { off=-8, kind=I64 } -> x1 + v197 StoreLocal { off=-8, value=v196, kind=I64, volatile } -> - + v198 LoadLocal { off=-8, kind=I64, volatile } -> x0 v199 Imm(2) -> x1 - v200 BinopI { op=shru, lhs=v196, rhs_imm=1 } -> x1 - v201 BinopI { op=ne, lhs=v200, rhs_imm=9223372036854775807 } -> x2 - v202 Imm(0) -> x1 + v200 BinopI { op=shru, lhs=v198, rhs_imm=1 } -> x0 + v201 BinopI { op=ne, lhs=v200, rhs_imm=9223372036854775807 } -> x1 + v202 Imm(0) -> x0 terminator Bnz { cond=v201, target=b54, fall=b37 } (exit_acc=v201) block 37 start_pc=0 - v203 LoadLocal { off=-8, kind=I64 } -> x1 + v203 LoadLocal { off=-8, kind=I64, volatile } -> x0 v204 Imm(256) -> x1 - v205 BinopI { op=and, lhs=v196, rhs_imm=255 } -> x0 - v206 BinopI { op=ne, lhs=v205, rhs_imm=255 } -> x2 + v205 BinopI { op=and, lhs=v203, rhs_imm=255 } -> x0 + v206 BinopI { op=ne, lhs=v205, rhs_imm=255 } -> x1 v207 Imm(0) -> x0 terminator Jmp(b38) (exit_acc=v206) block 38 start_pc=0 - v208 Phi { incoming=[b54:v201, b37:v206], kind=I64 } -> x2 + v208 Phi { incoming=[b54:v201, b37:v206], kind=I64 } -> x1 v209 LoadLocal { off=-18, kind=I64 } -> x0 terminator Bz { cond=v208, target=b40, fall=b39 } (exit_acc=v208) block 39 start_pc=0 @@ -295,14 +295,14 @@ fn ent_pc=0 n_params=0 variadic=false locals=19 terminator Return(v210) (exit_acc=v210) block 40 start_pc=0 v211 Imm(-5) -> x0 - v212 Imm(0) -> x1 - v213 LoadLocal { off=-1, kind=I32 } -> x1 + v212 StoreLocal { off=-1, value=v211, kind=I32, volatile } -> - + v213 LoadLocal { off=-1, kind=I32, volatile } -> x0 v214 Imm(1) -> x1 - v215 BinopI { op=ne, lhs=v211, rhs_imm=-5 } -> x1 + v215 BinopI { op=ne, lhs=v213, rhs_imm=-5 } -> x1 v216 Imm(0) -> x0 terminator Bnz { cond=v215, target=b55, fall=b41 } (exit_acc=v215) block 41 start_pc=0 - v217 LoadLocal { off=-1, kind=I32 } -> x0 + v217 LoadLocal { off=-1, kind=I32, volatile } -> x0 v218 Imm(1) -> x0 v219 Imm(0) -> x1 v220 Imm(0) -> x0 diff --git a/tests/snapshots/ssa/strtof_parses_float.ssa b/tests/snapshots/ssa/strtof_parses_float.ssa new file mode 100644 index 000000000..94bd2359a --- /dev/null +++ b/tests/snapshots/ssa/strtof_parses_float.ssa @@ -0,0 +1,86 @@ +; --- SSA dump (ok=true) ent_pc=5 --- +; name=main +fn ent_pc=5 n_params=0 variadic=false locals=4 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ImmData(8) -> x7 + v2 LocalAddr(-1) -> x6 + v3 CallExt { binding_idx=11, args=[v1, v2], fp_arg_mask=0x0, fp_return=true } -> d0 + v4 Imm(0) -> x0 + v5 LoadLocal { off=-2, kind=F64 } -> d1 + v6 Imm(4615063718147915776) -> x0 + v7 Binop { op=fne, lhs=v3, rhs=v6 } -> x0 + terminator Bz { cond=v7, target=b2, fall=b1 } (exit_acc=v7) + block 1 start_pc=0 + v8 Imm(1) -> x0 + terminator Return(v8) (exit_acc=v8) + block 2 start_pc=0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Load { addr=v9, disp=0, kind=I8 } -> x0 + v11 BinopI { op=ne, lhs=v10, rhs_imm=120 } -> x0 + terminator Bz { cond=v11, target=b4, fall=b3 } (exit_acc=v11) + block 3 start_pc=0 + v12 Imm(2) -> x0 + terminator Return(v12) (exit_acc=v12) + block 4 start_pc=0 + v13 ImmData(15) -> x7 + v14 Imm(0) -> x6 + v15 CallExt { binding_idx=11, args=[v13, v14], fp_arg_mask=0x0, fp_return=true } -> d0 + v16 Imm(4598175219545276416) -> x0 + v17 Fneg(v16) -> d1 + v18 Binop { op=fne, lhs=v15, rhs=v17 } -> x0 + terminator Bz { cond=v18, target=b6, fall=b5 } (exit_acc=v18) + block 5 start_pc=0 + v19 Imm(3) -> x0 + terminator Return(v19) (exit_acc=v19) + block 6 start_pc=0 + v20 Imm(0) -> x0 + terminator Return(v20) (exit_acc=v20) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/struct_arg_indirect_subscript.ssa b/tests/snapshots/ssa/struct_arg_indirect_subscript.ssa index 04af1e852..bb5e9c2a3 100644 --- a/tests/snapshots/ssa/struct_arg_indirect_subscript.ssa +++ b/tests/snapshots/ssa/struct_arg_indirect_subscript.ssa @@ -62,8 +62,8 @@ fn ent_pc=1 n_params=2 variadic=false locals=2 v5 Imm(4616189618054758400) -> x0 v6 Binop { op=fmul, lhs=v4, rhs=v5 } -> d1 v7 LocalAddr(-2) -> x1 - v8 BinopI { op=add, lhs=v7, rhs_imm=8 } -> x1 - v9 Load { addr=v8, disp=0, kind=F64 } -> d1 + v8 BinopI { op=add, lhs=v7, rhs_imm=8 } -> x2 + v9 Load { addr=v7, disp=8, kind=F64 } -> d1 v10 Imm(4611686018427387904) -> x1 v11 Binop { op=fmul, lhs=v9, rhs=v10 } -> d1 v12 Fma { a=v4, b=v5, c=v11, neg_product=false, neg_addend=false } -> d0 diff --git a/tests/snapshots/ssa/switch_case_label_promoted.ssa b/tests/snapshots/ssa/switch_case_label_promoted.ssa new file mode 100644 index 000000000..e59f06333 --- /dev/null +++ b/tests/snapshots/ssa/switch_case_label_promoted.ssa @@ -0,0 +1,140 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=4 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(-2147483648) -> x0 + v2 Imm(-9223372036854775808) -> x1 + v3 Imm(0) -> x1 + v4 Imm(0) -> x1 + v5 Imm(0) -> x1 + v6 LoadLocal { off=-1, kind=I32 } -> x1 + v7 BinopI { op=eq, lhs=v1, rhs_imm=-2147483648 } -> x0 + terminator Bnz { cond=v7, target=b2, fall=b3 } (exit_acc=v7) + block 1 start_pc=0 + v8 Phi { incoming=[b2:v11, b3:v13], kind=I64 } -> x0 + v9 Extend { value=v8, kind=I32 } -> x0 + v10 BinopI { op=ne, lhs=v9, rhs_imm=1 } -> x0 + terminator Bz { cond=v10, target=b6, fall=b5 } (exit_acc=v10) + block 2 start_pc=0 + v11 Imm(1) -> x0 + v12 Imm(0) -> x1 + terminator Jmp(b1) (exit_acc=v11) + block 3 start_pc=0 + v13 Imm(2) -> x0 + v14 Imm(0) -> x1 + terminator Jmp(b1) (exit_acc=v13) + block 4 start_pc=0 + terminator Jmp(b2) + block 5 start_pc=0 + v15 Imm(1) -> x0 + terminator Return(v15) (exit_acc=v15) + block 6 start_pc=0 + v16 Imm(4294967294) -> x0 + v17 Imm(0) -> x1 + v18 LoadLocal { off=-3, kind=U32 } -> x1 + v19 BinopI { op=eq, lhs=v16, rhs_imm=4294967294 } -> x0 + terminator Bnz { cond=v19, target=b8, fall=b9 } (exit_acc=v19) + block 7 start_pc=0 + v20 Phi { incoming=[b8:v23, b9:v25], kind=I64 } -> x0 + v21 Extend { value=v20, kind=I32 } -> x0 + v22 BinopI { op=ne, lhs=v21, rhs_imm=3 } -> x0 + terminator Bz { cond=v22, target=b12, fall=b11 } (exit_acc=v22) + block 8 start_pc=0 + v23 Imm(3) -> x0 + v24 Imm(0) -> x1 + terminator Jmp(b7) (exit_acc=v23) + block 9 start_pc=0 + v25 Imm(4) -> x0 + v26 Imm(0) -> x1 + terminator Jmp(b7) (exit_acc=v25) + block 10 start_pc=0 + terminator Jmp(b8) + block 11 start_pc=0 + v27 Imm(2) -> x0 + terminator Return(v27) (exit_acc=v27) + block 12 start_pc=0 + v28 Imm(-4294967296) -> x0 + v29 Imm(0) -> x1 + v30 LoadLocal { off=-4, kind=I64 } -> x1 + v31 BinopI { op=lt, lhs=v28, rhs_imm=2147483648 } -> x1 + terminator Bnz { cond=v31, target=b17, fall=b18 } (exit_acc=v31) + block 13 start_pc=0 + v32 Phi { incoming=[b16:v39, b14:v35, b15:v37], kind=I64 } -> x0 + v33 Extend { value=v32, kind=I32 } -> x0 + v34 BinopI { op=ne, lhs=v33, rhs_imm=5 } -> x0 + terminator Bz { cond=v34, target=b21, fall=b20 } (exit_acc=v34) + block 14 start_pc=0 + v35 Imm(5) -> x0 + v36 Imm(0) -> x1 + terminator Jmp(b13) (exit_acc=v35) + block 15 start_pc=0 + v37 Imm(6) -> x0 + v38 Imm(0) -> x1 + terminator Jmp(b13) (exit_acc=v37) + block 16 start_pc=0 + v39 Imm(7) -> x0 + v40 Imm(0) -> x1 + terminator Jmp(b13) (exit_acc=v39) + block 17 start_pc=0 + v41 BinopI { op=eq, lhs=v28, rhs_imm=-4294967296 } -> x0 + terminator Bnz { cond=v41, target=b14, fall=b16 } (exit_acc=v41) + block 18 start_pc=0 + v42 BinopI { op=eq, lhs=v28, rhs_imm=2147483648 } -> x0 + terminator Bnz { cond=v42, target=b15, fall=b16 } (exit_acc=v42) + block 19 start_pc=0 + terminator Jmp(b14) + block 20 start_pc=0 + v43 Imm(3) -> x0 + terminator Return(v43) (exit_acc=v43) + block 21 start_pc=0 + v44 Imm(0) -> x0 + terminator Return(v44) (exit_acc=v44) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/sxtw_fold_source_liveness.ssa b/tests/snapshots/ssa/sxtw_fold_source_liveness.ssa new file mode 100644 index 000000000..cd0fb70af --- /dev/null +++ b/tests/snapshots/ssa/sxtw_fold_source_liveness.ssa @@ -0,0 +1,92 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=f +fn ent_pc=0 n_params=2 variadic=false locals=3 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=2, kind=I64 } -> x0 + v6 BinopI { op=shl, lhs=v1, rhs_imm=32 } -> x0 + v7 Imm(0) -> x1 + v8 LoadLocal { off=3, kind=I64 } -> x1 + v9 Binop { op=add, lhs=v1, rhs=v3 } -> x1 + v10 Imm(0) -> x2 + v11 LoadLocal { off=-1, kind=I64 } -> x2 + v12 BinopI { op=shr, lhs=v6, rhs_imm=32 } -> x0 + v13 Imm(0) -> x2 + v14 LoadLocal { off=-3, kind=I64 } -> x2 + v15 LoadLocal { off=-2, kind=I64 } -> x2 + v16 Binop { op=add, lhs=v12, rhs=v9 } -> x0 + v17 Binop { op=add, lhs=v16, rhs=v3 } -> x0 + terminator Return(v17) (exit_acc=v17) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=2 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(2) -> x0 + v2 Imm(7) -> x1 + v3 Imm(0) -> x2 + v4 Imm(0) -> x2 + v5 BinopI { op=shl, lhs=v1, rhs_imm=32 } -> x2 + v6 Imm(0) -> x6 + v7 Binop { op=add, lhs=v1, rhs=v2 } -> x0 + v8 Imm(0) -> x6 + v9 BinopI { op=shr, lhs=v5, rhs_imm=32 } -> x2 + v10 Imm(0) -> x6 + v11 Binop { op=add, lhs=v9, rhs=v7 } -> x0 + v12 Binop { op=add, lhs=v11, rhs=v2 } -> x0 + v13 BinopI { op=shl, lhs=v12, rhs_imm=32 } -> x1 + v14 Extend { value=v12, kind=I32 } -> x0 + terminator Return(v14) (exit_acc=v14) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/sys_addr_in_static_init.ssa b/tests/snapshots/ssa/sys_addr_in_static_init.ssa index 6915b04f8..90b7ec4a3 100644 --- a/tests/snapshots/ssa/sys_addr_in_static_init.ssa +++ b/tests/snapshots/ssa/sys_addr_in_static_init.ssa @@ -67,15 +67,11 @@ fn ent_pc=6 n_params=0 variadic=false locals=16 terminator Return(v48) (exit_acc=v48) ; --- SSA dump (ok=true) ent_pc=7 --- ; name=__c5_sys_open -fn ent_pc=7 n_params=3 variadic=false locals=0 +fn ent_pc=7 n_params=0 variadic=false locals=0 spill_count=0 gpr_used=[] fp_used=[] block 0 start_pc=0 v0 AllocaInit(0) -> - - v1 LoadLocal { off=2, kind=I64 } -> x7 - v2 LoadLocal { off=3, kind=I64 } -> x6 - v3 LoadLocal { off=4, kind=I64 } -> x2 - v4 CallExt { binding_idx=61, args=[v1, v2, v3], fp_arg_mask=0x0 } -> x0 - terminator Return(v4) (exit_acc=v4) + terminator TailExt(61) ; --- SSA dump (ok=true) ent_pc=8 --- ; name=__c5_sys_read fn ent_pc=8 n_params=3 variadic=false locals=0 diff --git a/tests/snapshots/ssa/sysconf_pagesize.ssa b/tests/snapshots/ssa/sysconf_pagesize.ssa index ded40d79e..d92b71989 100644 --- a/tests/snapshots/ssa/sysconf_pagesize.ssa +++ b/tests/snapshots/ssa/sysconf_pagesize.ssa @@ -5,7 +5,7 @@ fn ent_pc=0 n_params=0 variadic=false locals=5 block 0 start_pc=0 v0 AllocaInit(0) -> - v1 Imm(30) -> x7 - v2 CallExt { binding_idx=135, args=[v1], fp_arg_mask=0x0 } -> x0 + v2 CallExt { binding_idx=134, args=[v1], fp_arg_mask=0x0 } -> x0 v3 Imm(0) -> x1 v4 LoadLocal { off=-1, kind=I64 } -> x1 v5 BinopI { op=le, lhs=v2, rhs_imm=0 } -> x1 @@ -41,7 +41,7 @@ fn ent_pc=0 n_params=0 variadic=false locals=5 terminator Return(v20) (exit_acc=v20) block 8 start_pc=0 v21 Imm(60) -> x7 - v22 CallExt { binding_idx=135, args=[v21], fp_arg_mask=0x0 } -> x0 + v22 CallExt { binding_idx=134, args=[v21], fp_arg_mask=0x0 } -> x0 v23 Imm(0) -> x1 v24 LoadLocal { off=-2, kind=I64 } -> x1 v25 BinopI { op=lt, lhs=v22, rhs_imm=16 } -> x0 @@ -51,7 +51,7 @@ fn ent_pc=0 n_params=0 variadic=false locals=5 terminator Return(v26) (exit_acc=v26) block 10 start_pc=0 v27 Imm(4) -> x7 - v28 CallExt { binding_idx=135, args=[v27], fp_arg_mask=0x0 } -> x0 + v28 CallExt { binding_idx=134, args=[v27], fp_arg_mask=0x0 } -> x0 v29 BinopI { op=le, lhs=v28, rhs_imm=0 } -> x0 terminator Bz { cond=v29, target=b12, fall=b11 } (exit_acc=v29) block 11 start_pc=0 @@ -59,7 +59,7 @@ fn ent_pc=0 n_params=0 variadic=false locals=5 terminator Return(v30) (exit_acc=v30) block 12 start_pc=0 v31 Imm(84) -> x7 - v32 CallExt { binding_idx=135, args=[v31], fp_arg_mask=0x0 } -> x0 + v32 CallExt { binding_idx=134, args=[v31], fp_arg_mask=0x0 } -> x0 v33 BinopI { op=le, lhs=v32, rhs_imm=0 } -> x0 terminator Bz { cond=v33, target=b14, fall=b13 } (exit_acc=v33) block 13 start_pc=0 @@ -67,7 +67,7 @@ fn ent_pc=0 n_params=0 variadic=false locals=5 terminator Return(v34) (exit_acc=v34) block 14 start_pc=0 v35 Imm(2) -> x7 - v36 CallExt { binding_idx=135, args=[v35], fp_arg_mask=0x0 } -> x0 + v36 CallExt { binding_idx=134, args=[v35], fp_arg_mask=0x0 } -> x0 v37 BinopI { op=le, lhs=v36, rhs_imm=0 } -> x0 terminator Bz { cond=v37, target=b16, fall=b15 } (exit_acc=v37) block 15 start_pc=0 @@ -76,7 +76,7 @@ fn ent_pc=0 n_params=0 variadic=false locals=5 block 16 start_pc=0 v39 ImmData(48) -> x7 v40 Imm(3) -> x6 - v41 CallExt { binding_idx=134, args=[v39, v40], fp_arg_mask=0x0 } -> x0 + v41 CallExt { binding_idx=133, args=[v39, v40], fp_arg_mask=0x0 } -> x0 v42 BinopI { op=le, lhs=v41, rhs_imm=0 } -> x0 terminator Bz { cond=v42, target=b18, fall=b17 } (exit_acc=v42) block 17 start_pc=0 diff --git a/tests/snapshots/ssa/ternary_arith_common_type.ssa b/tests/snapshots/ssa/ternary_arith_common_type.ssa new file mode 100644 index 000000000..0314ec40b --- /dev/null +++ b/tests/snapshots/ssa/ternary_arith_common_type.ssa @@ -0,0 +1,148 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=9 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(0) -> x0 + v2 Imm(0) -> x1 + v3 LoadLocal { off=-1, kind=U32 } -> x1 + v4 BinopI { op=eq, lhs=v1, rhs_imm=0 } -> x1 + terminator Bz { cond=v4, target=b2, fall=b1 } (exit_acc=v4) + block 1 start_pc=0 + v5 Imm(1) -> x2 + v6 Imm(0) -> x1 + terminator Jmp(b3) (exit_acc=v5) + block 2 start_pc=0 + v7 Imm(-1) -> x1 + v8 Imm(4294967295) -> x2 + v9 Imm(0) -> x1 + terminator Jmp(b3) (exit_acc=v8) + block 3 start_pc=0 + v10 Phi { incoming=[b1:v5, b2:v8], kind=I64 } -> x2 + v11 LoadLocal { off=-6, kind=I64 } -> x1 + v12 Imm(0) -> x1 + v13 LoadLocal { off=-2, kind=I64 } -> x1 + v14 BinopI { op=ne, lhs=v10, rhs_imm=1 } -> x1 + terminator Bz { cond=v14, target=b5, fall=b4 } (exit_acc=v14) + block 4 start_pc=0 + v15 Imm(1) -> x0 + terminator Return(v15) (exit_acc=v15) + block 5 start_pc=0 + v16 LoadLocal { off=-1, kind=U32 } -> x1 + v17 BinopI { op=ne, lhs=v1, rhs_imm=0 } -> x1 + terminator Bz { cond=v17, target=b7, fall=b6 } (exit_acc=v17) + block 6 start_pc=0 + v18 Imm(1) -> x2 + v19 Imm(0) -> x1 + terminator Jmp(b8) (exit_acc=v18) + block 7 start_pc=0 + v20 Imm(-1) -> x1 + v21 Imm(4294967295) -> x2 + v22 Imm(0) -> x1 + terminator Jmp(b8) (exit_acc=v21) + block 8 start_pc=0 + v23 Phi { incoming=[b6:v18, b7:v21], kind=I64 } -> x2 + v24 LoadLocal { off=-7, kind=I64 } -> x1 + v25 Imm(0) -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 BinopI { op=ne, lhs=v23, rhs_imm=4294967295 } -> x1 + terminator Bz { cond=v27, target=b10, fall=b9 } (exit_acc=v27) + block 9 start_pc=0 + v28 Imm(2) -> x0 + terminator Return(v28) (exit_acc=v28) + block 10 start_pc=0 + v29 LoadLocal { off=-1, kind=U32 } -> x1 + v30 BinopI { op=eq, lhs=v1, rhs_imm=0 } -> x1 + terminator Bz { cond=v30, target=b12, fall=b11 } (exit_acc=v30) + block 11 start_pc=0 + v31 Imm(-1) -> x1 + v32 Imm(4294967295) -> x2 + v33 Imm(0) -> x1 + terminator Jmp(b13) (exit_acc=v32) + block 12 start_pc=0 + v34 Imm(1) -> x2 + v35 Imm(0) -> x1 + terminator Jmp(b13) (exit_acc=v34) + block 13 start_pc=0 + v36 Phi { incoming=[b11:v32, b12:v34], kind=I64 } -> x2 + v37 LoadLocal { off=-8, kind=I64 } -> x1 + v38 Imm(0) -> x1 + v39 LoadLocal { off=-4, kind=I64 } -> x1 + v40 BinopI { op=ne, lhs=v36, rhs_imm=4294967295 } -> x1 + terminator Bz { cond=v40, target=b15, fall=b14 } (exit_acc=v40) + block 14 start_pc=0 + v41 Imm(3) -> x0 + terminator Return(v41) (exit_acc=v41) + block 15 start_pc=0 + v42 LoadLocal { off=-1, kind=U32 } -> x1 + v43 BinopI { op=eq, lhs=v1, rhs_imm=0 } -> x0 + terminator Bz { cond=v43, target=b17, fall=b16 } (exit_acc=v43) + block 16 start_pc=0 + v44 Imm(-1) -> x1 + v45 Imm(0) -> x0 + terminator Jmp(b18) (exit_acc=v44) + block 17 start_pc=0 + v46 Imm(0) -> x1 + v47 Imm(0) -> x0 + terminator Jmp(b18) (exit_acc=v46) + block 18 start_pc=0 + v48 Phi { incoming=[b16:v44, b17:v46], kind=I64 } -> x1 + v49 LoadLocal { off=-9, kind=I64 } -> x0 + v50 Imm(0) -> x0 + v51 LoadLocal { off=-5, kind=I64 } -> x0 + v52 BinopI { op=ne, lhs=v48, rhs_imm=-1 } -> x0 + terminator Bz { cond=v52, target=b20, fall=b19 } (exit_acc=v52) + block 19 start_pc=0 + v53 Imm(4) -> x0 + terminator Return(v53) (exit_acc=v53) + block 20 start_pc=0 + v54 Imm(0) -> x0 + terminator Return(v54) (exit_acc=v54) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/thread_local_per_thread.ssa b/tests/snapshots/ssa/thread_local_per_thread.ssa index 7cd828504..3ed0563a3 100644 --- a/tests/snapshots/ssa/thread_local_per_thread.ssa +++ b/tests/snapshots/ssa/thread_local_per_thread.ssa @@ -42,15 +42,15 @@ fn ent_pc=6 n_params=0 variadic=false locals=9 v3 Store { addr=v1, disp=0, value=v2, kind=I32 } -> - v4 Imm(0) -> x12 v5 Imm(2) -> x6 - v6 CallExt { binding_idx=222, args=[v4, v5], fp_arg_mask=0x0 } -> x13 + v6 CallExt { binding_idx=221, args=[v4, v5], fp_arg_mask=0x0 } -> x13 v7 Imm(0) -> x0 v8 LoadLocal { off=-1, kind=I64 } -> x0 v9 ImmData(48) -> x6 - v10 CallExt { binding_idx=223, args=[v6, v9], fp_arg_mask=0x0 } -> x14 + v10 CallExt { binding_idx=222, args=[v6, v9], fp_arg_mask=0x0 } -> x14 v11 Imm(0) -> x0 v12 LoadLocal { off=-1, kind=I64 } -> x0 v13 ImmData(63) -> x6 - v14 CallExt { binding_idx=223, args=[v6, v13], fp_arg_mask=0x0 } -> x13 + v14 CallExt { binding_idx=222, args=[v6, v13], fp_arg_mask=0x0 } -> x13 v15 Imm(0) -> x0 v16 LocalAddr(-4) -> x7 v17 ImmCode(ent_pc=5) -> x2 diff --git a/tests/snapshots/ssa/two_d_float_array_partial_init.ssa b/tests/snapshots/ssa/two_d_float_array_partial_init.ssa index a74340323..0f3ca366b 100644 --- a/tests/snapshots/ssa/two_d_float_array_partial_init.ssa +++ b/tests/snapshots/ssa/two_d_float_array_partial_init.ssa @@ -159,11 +159,11 @@ fn ent_pc=1 n_params=0 variadic=false locals=8 v66 Load { addr=v64, disp=0, kind=F32 } -> d1 [f32] v67 Imm(4) -> x6 v68 BinopI { op=add, lhs=v64, rhs_imm=4 } -> x6 - v69 Load { addr=v68, disp=0, kind=F32 } -> d2 [f32] + v69 Load { addr=v64, disp=4, kind=F32 } -> d2 [f32] v70 Binop { op=fadd, lhs=v66, rhs=v69 } -> d1 [f32] v71 Imm(8) -> x6 - v72 BinopI { op=add, lhs=v64, rhs_imm=8 } -> x2 - v73 Load { addr=v72, disp=0, kind=F32 } -> d2 [f32] + v72 BinopI { op=add, lhs=v64, rhs_imm=8 } -> x6 + v73 Load { addr=v64, disp=8, kind=F32 } -> d2 [f32] v74 Binop { op=fadd, lhs=v70, rhs=v73 } -> d1 [f32] v75 Binop { op=fadd, lhs=v60, rhs=v74 } -> d0 [f32] v76 Store { addr=v59, disp=0, value=v75, kind=F32 } -> - diff --git a/tests/snapshots/ssa/two_d_stride_no_leak_across_exprs.ssa b/tests/snapshots/ssa/two_d_stride_no_leak_across_exprs.ssa index 58c2487c1..cee3c4bbe 100644 --- a/tests/snapshots/ssa/two_d_stride_no_leak_across_exprs.ssa +++ b/tests/snapshots/ssa/two_d_stride_no_leak_across_exprs.ssa @@ -66,8 +66,8 @@ fn ent_pc=2 n_params=0 variadic=false locals=163 block 6 start_pc=0 v37 LocalAddr(-161) -> x0 v38 Imm(32) -> x1 - v39 BinopI { op=add, lhs=v37, rhs_imm=32 } -> x0 - v40 Load { addr=v39, disp=0, kind=F32 } -> d0 [f32] + v39 BinopI { op=add, lhs=v37, rhs_imm=32 } -> x1 + v40 Load { addr=v37, disp=32, kind=F32 } -> d0 [f32] v41 Imm(4611686018427387904) -> x0 v42 FpCast { kind=F32ToF64, value=v40 } -> d0 v43 Binop { op=fne, lhs=v42, rhs=v41 } -> x0 diff --git a/tests/snapshots/ssa/unary_plus_init_and_param_shadow.ssa b/tests/snapshots/ssa/unary_plus_init_and_param_shadow.ssa index a0ad44dfe..2e5cba929 100644 --- a/tests/snapshots/ssa/unary_plus_init_and_param_shadow.ssa +++ b/tests/snapshots/ssa/unary_plus_init_and_param_shadow.ssa @@ -63,7 +63,7 @@ fn ent_pc=2 n_params=0 variadic=false locals=5 v9 ImmData(8) -> x0 v10 Imm(8) -> x0 v11 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x0 - v12 Load { addr=v11, disp=0, kind=F64 } -> d0 + v12 Load { addr=v1, disp=8, kind=F64 } -> d0 v13 Imm(4604480259023595110) -> x7 v14 Call { target_pc=0, args=[v12, v13], fixed_args=2, fp_return=false, fp_arg_mask=0x3 } -> x0 v15 BinopI { op=eq, lhs=v14, rhs_imm=0 } -> x0 @@ -75,7 +75,7 @@ fn ent_pc=2 n_params=0 variadic=false locals=5 v17 ImmData(8) -> x0 v18 Imm(16) -> x0 v19 BinopI { op=add, lhs=v1, rhs_imm=16 } -> x0 - v20 Load { addr=v19, disp=0, kind=F64 } -> d0 + v20 Load { addr=v1, disp=16, kind=F64 } -> d0 v21 Imm(4607182418800017408) -> x7 v22 Call { target_pc=0, args=[v20, v21], fixed_args=2, fp_return=false, fp_arg_mask=0x3 } -> x0 v23 BinopI { op=eq, lhs=v22, rhs_imm=0 } -> x0 @@ -87,7 +87,7 @@ fn ent_pc=2 n_params=0 variadic=false locals=5 v25 ImmData(8) -> x0 v26 Imm(24) -> x0 v27 BinopI { op=add, lhs=v1, rhs_imm=24 } -> x0 - v28 Load { addr=v27, disp=0, kind=F64 } -> d0 + v28 Load { addr=v1, disp=24, kind=F64 } -> d0 v29 Imm(4611686018427387904) -> x0 v30 Fneg(v29) -> d1 v31 Call { target_pc=0, args=[v28, v30], fixed_args=2, fp_return=false, fp_arg_mask=0x3 } -> x0 diff --git a/tests/snapshots/ssa/union_member_unbraced_init.ssa b/tests/snapshots/ssa/union_member_unbraced_init.ssa new file mode 100644 index 000000000..c22c61c12 --- /dev/null +++ b/tests/snapshots/ssa/union_member_unbraced_init.ssa @@ -0,0 +1,269 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=15 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ImmData(8) -> x0 + v2 Load { addr=v1, disp=0, kind=F64 } -> d0 + v3 Imm(4613937818241073152) -> x1 + v4 Binop { op=fne, lhs=v2, rhs=v3 } -> x2 + v5 Imm(0) -> x1 + terminator Bnz { cond=v4, target=b37, fall=b1 } (exit_acc=v4) + block 1 start_pc=0 + v6 ImmData(8) -> x1 + v7 BinopI { op=add, lhs=v1, rhs_imm=16 } -> x1 + v8 Load { addr=v1, disp=16, kind=I32 } -> x1 + v9 BinopI { op=ne, lhs=v8, rhs_imm=42 } -> x2 + v10 Imm(0) -> x1 + terminator Jmp(b2) (exit_acc=v9) + block 2 start_pc=0 + v11 Phi { incoming=[b37:v4, b1:v9], kind=I64 } -> x2 + v12 LoadLocal { off=-8, kind=I64 } -> x1 + terminator Bz { cond=v11, target=b4, fall=b3 } (exit_acc=v11) + block 3 start_pc=0 + v13 Imm(1) -> x0 + terminator Return(v13) (exit_acc=v13) + block 4 start_pc=0 + v14 Imm(8) -> x2 + v15 Imm(0) -> x1 + terminator Jmp(b5) (exit_acc=v14) + block 5 start_pc=0 + v16 Phi { incoming=[b4:v14, b6:v20], kind=I64 } -> x2 + v17 Extend { value=v16, kind=I32 } -> x1 + v18 BinopI { op=lt, lhs=v17, rhs_imm=16 } -> x1 + terminator Bz { cond=v18, target=b8, fall=b7 } (exit_acc=v18) + block 6 start_pc=0 + v19 Extend { value=v16, kind=I32 } -> x1 + v20 BinopI { op=add, lhs=v19, rhs_imm=1 } -> x2 + v21 Imm(0) -> x1 + terminator Jmp(b5) (exit_acc=v20) + block 7 start_pc=0 + v22 ImmData(8) -> x1 + v23 Extend { value=v16, kind=I32 } -> x1 + v24 Binop { op=add, lhs=v1, rhs=v23 } -> x1 + v25 Load { addr=v24, disp=0, kind=I8 } -> x1 + v26 BinopI { op=ne, lhs=v25, rhs_imm=0 } -> x1 + terminator Bz { cond=v26, target=b10, fall=b9 } (exit_acc=v26) + block 8 start_pc=0 + v27 ImmData(32) -> x0 + v28 Load { addr=v27, disp=0, kind=F64 } -> d0 + v29 Imm(4617315517961601024) -> x0 + v30 Binop { op=fne, lhs=v28, rhs=v29 } -> x1 + v31 Imm(0) -> x0 + terminator Bnz { cond=v30, target=b38, fall=b11 } (exit_acc=v30) + block 9 start_pc=0 + v32 Imm(2) -> x0 + terminator Return(v32) (exit_acc=v32) + block 10 start_pc=0 + terminator Jmp(b6) + block 11 start_pc=0 + v33 ImmData(32) -> x0 + v34 BinopI { op=add, lhs=v33, rhs_imm=8 } -> x1 + v35 Load { addr=v33, disp=8, kind=I32 } -> x0 + v36 BinopI { op=ne, lhs=v35, rhs_imm=43 } -> x1 + v37 Imm(0) -> x0 + terminator Jmp(b12) (exit_acc=v36) + block 12 start_pc=0 + v38 Phi { incoming=[b38:v30, b11:v36], kind=I64 } -> x1 + v39 LoadLocal { off=-9, kind=I64 } -> x0 + terminator Bz { cond=v38, target=b14, fall=b13 } (exit_acc=v38) + block 13 start_pc=0 + v40 Imm(3) -> x0 + terminator Return(v40) (exit_acc=v40) + block 14 start_pc=0 + v41 ImmData(48) -> x0 + v42 Load { addr=v41, disp=0, kind=I32 } -> x0 + v43 BinopI { op=ne, lhs=v42, rhs_imm=1 } -> x0 + v44 Imm(1) -> x2 + v45 Imm(0) -> x1 + terminator Bnz { cond=v43, target=b39, fall=b15 } (exit_acc=v43) + block 15 start_pc=0 + v46 ImmData(48) -> x0 + v47 BinopI { op=add, lhs=v46, rhs_imm=4 } -> x1 + v48 Load { addr=v46, disp=4, kind=I32 } -> x0 + v49 BinopI { op=ne, lhs=v48, rhs_imm=2 } -> x0 + v50 BinopI { op=ne, lhs=v49, rhs_imm=0 } -> x2 + v51 Imm(0) -> x0 + terminator Jmp(b16) (exit_acc=v50) + block 16 start_pc=0 + v52 Phi { incoming=[b39:v44, b15:v50], kind=I64 } -> x2 + v53 LoadLocal { off=-11, kind=I64 } -> x0 + v54 Imm(0) -> x0 + terminator Bnz { cond=v52, target=b40, fall=b17 } (exit_acc=v52) + block 17 start_pc=0 + v55 ImmData(48) -> x0 + v56 BinopI { op=add, lhs=v55, rhs_imm=8 } -> x1 + v57 Load { addr=v55, disp=8, kind=I32 } -> x0 + v58 BinopI { op=ne, lhs=v57, rhs_imm=9 } -> x2 + v59 Imm(0) -> x0 + terminator Jmp(b18) (exit_acc=v58) + block 18 start_pc=0 + v60 Phi { incoming=[b40:v52, b17:v58], kind=I64 } -> x2 + v61 LoadLocal { off=-10, kind=I64 } -> x0 + terminator Bz { cond=v60, target=b20, fall=b19 } (exit_acc=v60) + block 19 start_pc=0 + v62 Imm(4) -> x0 + terminator Return(v62) (exit_acc=v62) + block 20 start_pc=0 + v63 ImmData(64) -> x0 + v64 Imm(0) -> x1 + v65 Load { addr=v63, disp=0, kind=F64 } -> d0 + v66 Imm(4613937818241073152) -> x0 + v67 Binop { op=fne, lhs=v65, rhs=v66 } -> x1 + v68 Imm(0) -> x0 + terminator Bnz { cond=v67, target=b41, fall=b21 } (exit_acc=v67) + block 21 start_pc=0 + v69 ImmData(64) -> x0 + v70 Imm(0) -> x1 + v71 BinopI { op=add, lhs=v69, rhs_imm=16 } -> x1 + v72 Load { addr=v69, disp=16, kind=I32 } -> x0 + v73 BinopI { op=ne, lhs=v72, rhs_imm=42 } -> x1 + v74 Imm(0) -> x0 + terminator Jmp(b22) (exit_acc=v73) + block 22 start_pc=0 + v75 Phi { incoming=[b41:v67, b21:v73], kind=I64 } -> x1 + v76 LoadLocal { off=-12, kind=I64 } -> x0 + terminator Bz { cond=v75, target=b24, fall=b23 } (exit_acc=v75) + block 23 start_pc=0 + v77 Imm(5) -> x0 + terminator Return(v77) (exit_acc=v77) + block 24 start_pc=0 + v78 ImmData(64) -> x0 + v79 Imm(24) -> x1 + v80 BinopI { op=add, lhs=v78, rhs_imm=24 } -> x1 + v81 Load { addr=v78, disp=24, kind=F64 } -> d0 + v82 Imm(4616189618054758400) -> x0 + v83 Binop { op=fne, lhs=v81, rhs=v82 } -> x1 + v84 Imm(0) -> x0 + terminator Bnz { cond=v83, target=b42, fall=b25 } (exit_acc=v83) + block 25 start_pc=0 + v85 ImmData(64) -> x0 + v86 Imm(24) -> x1 + v87 BinopI { op=add, lhs=v85, rhs_imm=24 } -> x1 + v88 BinopI { op=add, lhs=v85, rhs_imm=40 } -> x1 + v89 Load { addr=v85, disp=40, kind=I32 } -> x0 + v90 BinopI { op=ne, lhs=v89, rhs_imm=43 } -> x1 + v91 Imm(0) -> x0 + terminator Jmp(b26) (exit_acc=v90) + block 26 start_pc=0 + v92 Phi { incoming=[b42:v83, b25:v90], kind=I64 } -> x1 + v93 LoadLocal { off=-13, kind=I64 } -> x0 + terminator Bz { cond=v92, target=b28, fall=b27 } (exit_acc=v92) + block 27 start_pc=0 + v94 Imm(6) -> x0 + terminator Return(v94) (exit_acc=v94) + block 28 start_pc=0 + v95 LocalAddr(-4) -> x0 + v96 ImmData(112) -> x1 + v97 Mcpy { dst=v95, src=v96, size=24 } -> x0 + v98 LocalAddr(-4) -> x0 + v99 Load { addr=v98, disp=0, kind=F64 } -> d0 + v100 Imm(4613937818241073152) -> x0 + v101 Binop { op=fne, lhs=v99, rhs=v100 } -> x1 + v102 Imm(0) -> x0 + terminator Bnz { cond=v101, target=b43, fall=b29 } (exit_acc=v101) + block 29 start_pc=0 + v103 LocalAddr(-4) -> x0 + v104 BinopI { op=add, lhs=v103, rhs_imm=16 } -> x1 + v105 Load { addr=v103, disp=16, kind=I32 } -> x0 + v106 BinopI { op=ne, lhs=v105, rhs_imm=42 } -> x1 + v107 Imm(0) -> x0 + terminator Jmp(b30) (exit_acc=v106) + block 30 start_pc=0 + v108 Phi { incoming=[b43:v101, b29:v106], kind=I64 } -> x1 + v109 LoadLocal { off=-14, kind=I64 } -> x0 + terminator Bz { cond=v108, target=b32, fall=b31 } (exit_acc=v108) + block 31 start_pc=0 + v110 Imm(7) -> x0 + terminator Return(v110) (exit_acc=v110) + block 32 start_pc=0 + v111 LocalAddr(-7) -> x0 + v112 ImmData(136) -> x1 + v113 Mcpy { dst=v111, src=v112, size=24 } -> x0 + v114 LocalAddr(-7) -> x0 + v115 Load { addr=v114, disp=0, kind=F64 } -> d0 + v116 Imm(4618441417868443648) -> x0 + v117 Binop { op=fne, lhs=v115, rhs=v116 } -> x1 + v118 Imm(0) -> x0 + terminator Bnz { cond=v117, target=b44, fall=b33 } (exit_acc=v117) + block 33 start_pc=0 + v119 LocalAddr(-7) -> x0 + v120 BinopI { op=add, lhs=v119, rhs_imm=16 } -> x1 + v121 Load { addr=v119, disp=16, kind=I32 } -> x0 + v122 BinopI { op=ne, lhs=v121, rhs_imm=44 } -> x1 + v123 Imm(0) -> x0 + terminator Jmp(b34) (exit_acc=v122) + block 34 start_pc=0 + v124 Phi { incoming=[b44:v117, b33:v122], kind=I64 } -> x1 + v125 LoadLocal { off=-15, kind=I64 } -> x0 + terminator Bz { cond=v124, target=b36, fall=b35 } (exit_acc=v124) + block 35 start_pc=0 + v126 Imm(8) -> x0 + terminator Return(v126) (exit_acc=v126) + block 36 start_pc=0 + v127 Imm(0) -> x0 + terminator Return(v127) (exit_acc=v127) + block 37 start_pc=0 + terminator Jmp(b2) + block 38 start_pc=0 + terminator Jmp(b12) + block 39 start_pc=0 + terminator Jmp(b16) + block 40 start_pc=0 + terminator Jmp(b18) + block 41 start_pc=0 + terminator Jmp(b22) + block 42 start_pc=0 + terminator Jmp(b26) + block 43 start_pc=0 + terminator Jmp(b30) + block 44 start_pc=0 + terminator Jmp(b34) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/va_arg_composite_straddle.ssa b/tests/snapshots/ssa/va_arg_composite_straddle.ssa new file mode 100644 index 000000000..117f77129 --- /dev/null +++ b/tests/snapshots/ssa/va_arg_composite_straddle.ssa @@ -0,0 +1,146 @@ +; --- SSA dump (ok=true) ent_pc=1 --- +; name=take +fn ent_pc=1 n_params=1 variadic=true locals=8 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-3) -> x0 + v2 LocalAddr(2) -> x1 + v3 Intrinsic { kind=4, args=[v1, v2] } -> x0 + v4 Imm(0) -> x1 + v5 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v4) + block 1 start_pc=0 + v6 Phi { incoming=[b0:v4, b2:v10], kind=I64 } -> x1 + v7 Extend { value=v6, kind=I32 } -> x0 + v8 BinopI { op=lt, lhs=v7, rhs_imm=6 } -> x0 + terminator Bz { cond=v8, target=b4, fall=b3 } (exit_acc=v8) + block 2 start_pc=0 + v9 Extend { value=v6, kind=I32 } -> x0 + v10 BinopI { op=add, lhs=v9, rhs_imm=1 } -> x1 + v11 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v10) + block 3 start_pc=0 + v12 LocalAddr(-3) -> x0 + v13 Imm(8) -> x2 + v14 Intrinsic { kind=5, args=[v12, v13] } -> x0 + v15 Load { addr=v14, disp=0, kind=I64 } -> x0 + v16 BinopI { op=and, lhs=v15, rhs_imm=255 } -> x0 + terminator Jmp(b2) (exit_acc=v16) + block 4 start_pc=0 + v17 LocalAddr(-3) -> x0 + v18 Imm(16) -> x1 + v19 Intrinsic { kind=5, args=[v17, v18] } -> x0 + v20 LocalAddr(-6) -> x1 + v21 Mcpy { dst=v20, src=v19, size=16 } -> x0 + v22 LocalAddr(-3) -> x0 + v23 Imm(8) -> x1 + v24 Intrinsic { kind=5, args=[v22, v23] } -> x0 + v25 Load { addr=v24, disp=0, kind=I64 } -> x0 + v26 Imm(0) -> x1 + v27 LocalAddr(-3) -> x1 + v28 Intrinsic { kind=6, args=[v27] } -> x1 + v29 LocalAddr(-6) -> x1 + v30 Load { addr=v29, disp=0, kind=I64 } -> x1 + v31 BinopI { op=ne, lhs=v30, rhs_imm=111 } -> x2 + v32 Imm(0) -> x1 + terminator Bnz { cond=v31, target=b11, fall=b5 } (exit_acc=v31) + block 5 start_pc=0 + v33 LocalAddr(-6) -> x1 + v34 BinopI { op=add, lhs=v33, rhs_imm=8 } -> x2 + v35 Load { addr=v33, disp=8, kind=I64 } -> x1 + v36 BinopI { op=ne, lhs=v35, rhs_imm=222 } -> x2 + v37 Imm(0) -> x1 + terminator Jmp(b6) (exit_acc=v36) + block 6 start_pc=0 + v38 Phi { incoming=[b11:v31, b5:v36], kind=I64 } -> x2 + v39 LoadLocal { off=-8, kind=I64 } -> x1 + terminator Bz { cond=v38, target=b8, fall=b7 } (exit_acc=v38) + block 7 start_pc=0 + v40 Imm(1) -> x0 + terminator Return(v40) (exit_acc=v40) + block 8 start_pc=0 + v41 LoadLocal { off=-7, kind=I64 } -> x1 + v42 BinopI { op=ne, lhs=v25, rhs_imm=777 } -> x0 + terminator Bz { cond=v42, target=b10, fall=b9 } (exit_acc=v42) + block 9 start_pc=0 + v43 Imm(2) -> x0 + terminator Return(v43) (exit_acc=v43) + block 10 start_pc=0 + v44 Imm(0) -> x0 + terminator Return(v44) (exit_acc=v44) + block 11 start_pc=0 + terminator Jmp(b6) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=main +fn ent_pc=2 n_params=0 variadic=false locals=11 + spill_count=0 gpr_used=[3, 12] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-2) -> x0 + v2 Imm(111) -> x1 + v3 Store { addr=v1, disp=0, value=v2, kind=I64 } -> - + v4 LocalAddr(-2) -> x0 + v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x1 + v6 Imm(222) -> x1 + v7 Store { addr=v4, disp=8, value=v6, kind=I64 } -> - + v8 Imm(1) -> x7 + v9 Imm(2) -> x6 + v10 Imm(3) -> x2 + v11 Imm(4) -> x1 + v12 Imm(5) -> x8 + v13 Imm(6) -> x9 + v14 Imm(7) -> x0 + v15 LocalAddr(-2) -> x3 + v16 Imm(777) -> x12 + v17 Call { target_pc=1, args=[v8, v9, v10, v11, v12, v13, v14, v15, v16], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + v18 BinopI { op=shl, lhs=v17, rhs_imm=32 } -> x1 + v19 Extend { value=v17, kind=I32 } -> x0 + terminator Return(v19) (exit_acc=v19) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/va_copy_under_pressure.ssa b/tests/snapshots/ssa/va_copy_under_pressure.ssa new file mode 100644 index 000000000..0e05542da --- /dev/null +++ b/tests/snapshots/ssa/va_copy_under_pressure.ssa @@ -0,0 +1,189 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=f +fn ent_pc=0 n_params=1 variadic=true locals=22 + spill_count=5 gpr_used=[3, 12, 13, 14, 15] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LoadLocal { off=2, kind=I64 } -> x0 + v2 BinopI { op=mul, lhs=v1, rhs_imm=3 } -> x1 + v3 Imm(0) -> x2 + v4 BinopI { op=add, lhs=v1, rhs_imm=11 } -> x2 + v5 Imm(0) -> x6 + v6 BinopI { op=mul, lhs=v1, rhs_imm=7 } -> x6 + v7 Imm(0) -> x7 + v8 BinopI { op=sub, lhs=v1, rhs_imm=2 } -> x7 + v9 Imm(0) -> x8 + v10 BinopI { op=mul, lhs=v1, rhs_imm=13 } -> x8 + v11 Imm(0) -> x9 + v12 BinopI { op=add, lhs=v1, rhs_imm=29 } -> x9 + v13 Imm(0) -> x3 + v14 BinopI { op=shl, lhs=v1, rhs_imm=2 } -> x3 + v15 Imm(0) -> x12 + v16 BinopI { op=add, lhs=v1, rhs_imm=41 } -> x12 + v17 Imm(0) -> x13 + v18 BinopI { op=mul, lhs=v1, rhs_imm=9 } -> x13 + v19 Imm(0) -> x14 + v20 BinopI { op=add, lhs=v1, rhs_imm=53 } -> x14 + v21 Imm(0) -> x15 + v22 BinopI { op=mul, lhs=v1, rhs_imm=5 } -> x15 + v23 Imm(0) -> [spill 0] + v24 BinopI { op=add, lhs=v1, rhs_imm=61 } -> [spill 0] + v25 Imm(0) -> [spill 1] + v26 BinopI { op=mul, lhs=v1, rhs_imm=15 } -> [spill 1] + v27 Imm(0) -> [spill 2] + v28 BinopI { op=add, lhs=v1, rhs_imm=3 } -> x0 + v29 Imm(0) -> [spill 2] + v30 LocalAddr(-3) -> [spill 2] + v31 LocalAddr(2) -> [spill 3] + v32 Intrinsic { kind=4, args=[v30, v31] } -> [spill 2] + v33 LocalAddr(-6) -> [spill 2] + v34 LocalAddr(-3) -> [spill 3] + v35 Intrinsic { kind=7, args=[v33, v34] } -> [spill 2] + v36 LocalAddr(-6) -> [spill 2] + v37 Imm(8) -> [spill 3] + v38 Intrinsic { kind=5, args=[v36, v37] } -> [spill 2] + v39 Load { addr=v38, disp=0, kind=I64 } -> [spill 2] + v40 Imm(0) -> [spill 3] + v41 LocalAddr(-6) -> [spill 3] + v42 Intrinsic { kind=5, args=[v41, v37] } -> [spill 3] + v43 Load { addr=v42, disp=0, kind=I64 } -> [spill 3] + v44 Imm(0) -> [spill 4] + v45 LocalAddr(-6) -> [spill 4] + v46 Intrinsic { kind=6, args=[v45] } -> [spill 4] + v47 LocalAddr(-3) -> [spill 4] + v48 Intrinsic { kind=6, args=[v47] } -> [spill 4] + v49 LoadLocal { off=-7, kind=I64 } -> [spill 4] + v50 LoadLocal { off=-8, kind=I64 } -> [spill 4] + v51 Binop { op=add, lhs=v2, rhs=v4 } -> x1 + v52 LoadLocal { off=-9, kind=I64 } -> x2 + v53 Binop { op=add, lhs=v51, rhs=v6 } -> x1 + v54 LoadLocal { off=-10, kind=I64 } -> x2 + v55 Binop { op=add, lhs=v53, rhs=v8 } -> x1 + v56 LoadLocal { off=-11, kind=I64 } -> x2 + v57 Binop { op=add, lhs=v55, rhs=v10 } -> x1 + v58 LoadLocal { off=-12, kind=I64 } -> x2 + v59 Binop { op=add, lhs=v57, rhs=v12 } -> x1 + v60 LoadLocal { off=-13, kind=I64 } -> x2 + v61 Binop { op=add, lhs=v59, rhs=v14 } -> x1 + v62 LoadLocal { off=-14, kind=I64 } -> x2 + v63 Binop { op=add, lhs=v61, rhs=v16 } -> x1 + v64 LoadLocal { off=-15, kind=I64 } -> x2 + v65 Binop { op=add, lhs=v63, rhs=v18 } -> x1 + v66 LoadLocal { off=-16, kind=I64 } -> x2 + v67 Binop { op=add, lhs=v65, rhs=v20 } -> x1 + v68 LoadLocal { off=-17, kind=I64 } -> x2 + v69 Binop { op=add, lhs=v67, rhs=v22 } -> x1 + v70 LoadLocal { off=-18, kind=I64 } -> x2 + v71 Binop { op=add, lhs=v69, rhs=v24 } -> x1 + v72 LoadLocal { off=-19, kind=I64 } -> x2 + v73 Binop { op=add, lhs=v71, rhs=v26 } -> x1 + v74 LoadLocal { off=-20, kind=I64 } -> x2 + v75 Binop { op=add, lhs=v73, rhs=v28 } -> x0 + v76 LoadLocal { off=-21, kind=I64 } -> x1 + v77 Binop { op=add, lhs=v75, rhs=v39 } -> x0 + v78 LoadLocal { off=-22, kind=I64 } -> x1 + v79 Binop { op=add, lhs=v77, rhs=v43 } -> x0 + terminator Return(v79) (exit_acc=v79) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=5 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(2) -> x7 + v2 Imm(10) -> x6 + v3 Imm(20) -> x2 + v4 Call { target_pc=0, args=[v1, v2, v3], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x1 + v6 Imm(19) -> x1 + v7 Imm(81604378624) -> x1 + v8 Imm(33) -> x1 + v9 Imm(141733920768) -> x1 + v10 Imm(59) -> x1 + v11 Imm(253403070464) -> x1 + v12 Imm(90) -> x1 + v13 Imm(386547056640) -> x1 + v14 Imm(98) -> x1 + v15 Imm(420906795008) -> x1 + v16 Imm(141) -> x1 + v17 Imm(605590388736) -> x1 + v18 Imm(159) -> x1 + v19 Imm(682899800064) -> x1 + v20 Imm(214) -> x1 + v21 Imm(919123001344) -> x1 + v22 Imm(224) -> x1 + v23 Imm(962072674304) -> x1 + v24 Imm(287) -> x1 + v25 Imm(1232655613952) -> x1 + v26 Imm(317) -> x1 + v27 Imm(1361504632832) -> x1 + v28 Imm(322) -> x1 + v29 Imm(1382979469312) -> x1 + v30 Imm(332) -> x1 + v31 Imm(1425929142272) -> x1 + v32 Imm(352) -> x1 + v33 Imm(1511828488192) -> x2 + v34 Imm(0) -> x2 + v35 LoadLocal { off=-1, kind=I64 } -> x2 + v36 LoadLocal { off=-2, kind=I64 } -> x2 + v37 Binop { op=eq, lhs=v4, rhs=v32 } -> x0 + terminator Bz { cond=v37, target=b2, fall=b1 } (exit_acc=v37) + block 1 start_pc=0 + v38 Imm(0) -> x1 + v39 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v38) + block 2 start_pc=0 + v40 Imm(1) -> x1 + v41 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v40) + block 3 start_pc=0 + v42 Phi { incoming=[b1:v38, b2:v40], kind=I64 } -> x1 + v43 LoadLocal { off=-5, kind=I64 } -> x0 + terminator Return(v42) (exit_acc=v42) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/variable_shift_rcx_loop.ssa b/tests/snapshots/ssa/variable_shift_rcx_loop.ssa new file mode 100644 index 000000000..3907cb045 --- /dev/null +++ b/tests/snapshots/ssa/variable_shift_rcx_loop.ssa @@ -0,0 +1,114 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=g +fn ent_pc=0 n_params=4 variadic=false locals=2 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 ParamRef(2, kind=I64) -> x2 + v6 Imm(0) -> x0 + v7 ParamRef(3, kind=I64) -> x0 + v8 Imm(0) -> x1 + v9 Imm(0) -> x8 + v10 Imm(0) -> x1 + v11 Imm(0) -> x1 + terminator Jmp(b1) (exit_acc=v9) + block 1 start_pc=0 + v12 Phi { incoming=[b0:v9, b2:v21], kind=I64 } -> x8 + v13 Phi { incoming=[b0:v9, b2:v25], kind=I64 } -> x1 + v14 LoadLocal { off=-1, kind=I64 } -> x9 + v15 LoadLocal { off=2, kind=I64 } -> x9 + v16 Binop { op=lt, lhs=v13, rhs=v1 } -> x1 + terminator Bz { cond=v16, target=b4, fall=b3 } (exit_acc=v16) + block 2 start_pc=0 + v17 LoadLocal { off=-2, kind=I64 } -> x9 + v18 LoadLocal { off=3, kind=I64 } -> x9 + v19 LoadLocal { off=4, kind=I64 } -> x9 + v20 Binop { op=shl, lhs=v3, rhs=v5 } -> x9 + v21 Binop { op=add, lhs=v12, rhs=v20 } -> x8 + v22 Imm(0) -> x9 + terminator Jmp(b1) (exit_acc=v21) + block 3 start_pc=0 + v23 LoadLocal { off=-2, kind=I64 } -> x1 + v24 LoadLocal { off=5, kind=I64 } -> x1 + v25 Binop { op=add, lhs=v12, rhs=v7 } -> x1 + v26 Imm(0) -> x9 + terminator Jmp(b2) (exit_acc=v25) + block 4 start_pc=0 + v27 LoadLocal { off=5, kind=I64 } -> x1 + terminator Return(v7) (exit_acc=v7) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=5 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(100) -> x7 + v2 Imm(2) -> x6 + v3 Imm(3) -> x2 + v4 Imm(1) -> x1 + v5 Call { target_pc=0, args=[v1, v2, v3, v4], fixed_args=4, fp_return=false, fp_arg_mask=0x0 } -> x0 + v6 BinopI { op=eq, lhs=v5, rhs_imm=1 } -> x0 + terminator Bz { cond=v6, target=b2, fall=b1 } (exit_acc=v6) + block 1 start_pc=0 + v7 Imm(0) -> x1 + v8 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v7) + block 2 start_pc=0 + v9 Imm(1) -> x1 + v10 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v9) + block 3 start_pc=0 + v11 Phi { incoming=[b1:v7, b2:v9], kind=I64 } -> x1 + v12 LoadLocal { off=-5, kind=I64 } -> x0 + terminator Return(v11) (exit_acc=v11) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/variadic_agg_return_classes.ssa b/tests/snapshots/ssa/variadic_agg_return_classes.ssa new file mode 100644 index 000000000..28c1088ec --- /dev/null +++ b/tests/snapshots/ssa/variadic_agg_return_classes.ssa @@ -0,0 +1,148 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=mkp +fn ent_pc=0 n_params=1 variadic=true locals=2 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-2) -> x0 + v2 Imm(4609434218613702656) -> x1 + v3 LoadLocal { off=2, kind=I32 } -> x2 + v4 FpCast { kind=IntToFp, value=v3 } -> d0 + v5 Binop { op=fmul, lhs=v2, rhs=v4 } -> d0 + v6 Store { addr=v1, disp=0, value=v5, kind=F64 } -> - + v7 LocalAddr(-2) -> x0 + v8 BinopI { op=add, lhs=v7, rhs_imm=8 } -> x1 + v9 Imm(4612248968380809216) -> x1 + v10 Store { addr=v7, disp=8, value=v9, kind=F64 } -> - + v11 LocalAddr(-2) -> x0 + terminator Return(v11) (exit_acc=v11) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=mkm +fn ent_pc=1 n_params=1 variadic=true locals=2 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-2) -> x0 + v2 Imm(4602678819172646912) -> x1 + v3 Store { addr=v1, disp=0, value=v2, kind=F64 } -> - + v4 LocalAddr(-2) -> x0 + v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x1 + v6 LoadLocal { off=2, kind=I32 } -> x1 + v7 BinopI { op=add, lhs=v6, rhs_imm=41 } -> x1 + v8 BinopI { op=shl, lhs=v7, rhs_imm=32 } -> x2 + v9 Extend { value=v7, kind=I32 } -> x1 + v10 Store { addr=v4, disp=8, value=v9, kind=I64 } -> - + v11 LocalAddr(-2) -> x0 + terminator Return(v11) (exit_acc=v11) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=main +fn ent_pc=2 n_params=0 variadic=false locals=15 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(2) -> x7 + v2 Call { target_pc=0, args=[v1], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + v3 LocalAddr(-11) -> x0 + v4 LocalAddr(-2) -> x1 + v5 Mcpy { dst=v4, src=v3, size=16 } -> x0 + v6 LocalAddr(-2) -> x0 + v7 Load { addr=v6, disp=0, kind=F64 } -> d0 + v8 Imm(4613937818241073152) -> x0 + v9 Binop { op=fne, lhs=v7, rhs=v8 } -> x3 + v10 Imm(0) -> x0 + terminator Bnz { cond=v9, target=b9, fall=b1 } (exit_acc=v9) + block 1 start_pc=0 + v11 LocalAddr(-2) -> x0 + v12 BinopI { op=add, lhs=v11, rhs_imm=8 } -> x1 + v13 Load { addr=v11, disp=8, kind=F64 } -> d0 + v14 Imm(4612248968380809216) -> x0 + v15 Binop { op=fne, lhs=v13, rhs=v14 } -> x3 + v16 Imm(0) -> x0 + terminator Jmp(b2) (exit_acc=v15) + block 2 start_pc=0 + v17 Phi { incoming=[b9:v9, b1:v15], kind=I64 } -> x3 + v18 LoadLocal { off=-12, kind=I64 } -> x0 + terminator Bz { cond=v17, target=b4, fall=b3 } (exit_acc=v17) + block 3 start_pc=0 + v19 Imm(1) -> x0 + terminator Return(v19) (exit_acc=v19) + block 4 start_pc=0 + v20 Imm(1) -> x7 + v21 Call { target_pc=1, args=[v20], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + v22 LocalAddr(-14) -> x0 + v23 LocalAddr(-6) -> x1 + v24 Mcpy { dst=v23, src=v22, size=16 } -> x0 + v25 LocalAddr(-6) -> x0 + v26 Load { addr=v25, disp=0, kind=F64 } -> d0 + v27 Imm(4602678819172646912) -> x0 + v28 Binop { op=fne, lhs=v26, rhs=v27 } -> x1 + v29 Imm(0) -> x0 + terminator Bnz { cond=v28, target=b10, fall=b5 } (exit_acc=v28) + block 5 start_pc=0 + v30 LocalAddr(-6) -> x0 + v31 BinopI { op=add, lhs=v30, rhs_imm=8 } -> x1 + v32 Load { addr=v30, disp=8, kind=I64 } -> x0 + v33 BinopI { op=ne, lhs=v32, rhs_imm=42 } -> x1 + v34 Imm(0) -> x0 + terminator Jmp(b6) (exit_acc=v33) + block 6 start_pc=0 + v35 Phi { incoming=[b10:v28, b5:v33], kind=I64 } -> x1 + v36 LoadLocal { off=-15, kind=I64 } -> x0 + terminator Bz { cond=v35, target=b8, fall=b7 } (exit_acc=v35) + block 7 start_pc=0 + v37 Imm(2) -> x0 + terminator Return(v37) (exit_acc=v37) + block 8 start_pc=0 + v38 Imm(0) -> x0 + terminator Return(v38) (exit_acc=v38) + block 9 start_pc=0 + terminator Jmp(b2) + block 10 start_pc=0 + terminator Jmp(b6) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/variadic_cast_fnptr_dispatch.ssa b/tests/snapshots/ssa/variadic_cast_fnptr_dispatch.ssa new file mode 100644 index 000000000..ab41c3498 --- /dev/null +++ b/tests/snapshots/ssa/variadic_cast_fnptr_dispatch.ssa @@ -0,0 +1,93 @@ +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=14 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-4) -> x0 + v2 Imm(0) -> x1 + v3 Store { addr=v1, disp=0, value=v2, kind=I8 } -> - + v4 ImmData(40) -> x0 + v5 Load { addr=v4, disp=0, kind=I64 } -> x0 + v6 LocalAddr(-4) -> x7 + v7 Imm(32) -> x6 + v8 ImmData(48) -> x2 + v9 Imm(4) -> x1 + v10 ImmData(57) -> x8 + v11 Imm(9) -> x9 + v12 CallIndirect { target=v5, args=[v6, v7, v8, v9, v10, v11], callee_variadic=true, fixed_args=3, fp_return=false, fp_arg_mask=0x0 } -> x0 + v13 BinopI { op=shl, lhs=v12, rhs_imm=32 } -> x1 + v14 Extend { value=v12, kind=I32 } -> x0 + v15 Imm(0) -> x1 + v16 LoadLocal { off=-5, kind=I32 } -> x1 + v17 BinopI { op=ne, lhs=v14, rhs_imm=7 } -> x0 + terminator Bz { cond=v17, target=b2, fall=b1 } (exit_acc=v17) + block 1 start_pc=0 + v18 Imm(1) -> x0 + terminator Return(v18) (exit_acc=v18) + block 2 start_pc=0 + v19 LocalAddr(-4) -> x7 + v20 ImmData(61) -> x6 + v21 CallExt { binding_idx=62, args=[v19, v20], fp_arg_mask=0x0 } -> x0 + v22 BinopI { op=ne, lhs=v21, rhs_imm=0 } -> x0 + terminator Bz { cond=v22, target=b4, fall=b3 } (exit_acc=v22) + block 3 start_pc=0 + v23 Imm(2) -> x0 + terminator Return(v23) (exit_acc=v23) + block 4 start_pc=0 + v24 Imm(0) -> x0 + terminator Return(v24) (exit_acc=v24) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=__c5_sys_snprintf +fn ent_pc=2 n_params=0 variadic=false locals=0 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + terminator TailExt(3) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/variadic_hfa_struct_arg.ssa b/tests/snapshots/ssa/variadic_hfa_struct_arg.ssa new file mode 100644 index 000000000..af2581bf9 --- /dev/null +++ b/tests/snapshots/ssa/variadic_hfa_struct_arg.ssa @@ -0,0 +1,101 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=sum +fn ent_pc=0 n_params=1 variadic=true locals=5 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-3) -> x0 + v2 LocalAddr(2) -> x1 + v3 Intrinsic { kind=4, args=[v1, v2] } -> x0 + v4 LocalAddr(-3) -> x0 + v5 Imm(16) -> x1 + v6 Intrinsic { kind=5, args=[v4, v5] } -> x0 + v7 LocalAddr(-5) -> x1 + v8 Mcpy { dst=v7, src=v6, size=16 } -> x0 + v9 LocalAddr(-3) -> x0 + v10 Intrinsic { kind=6, args=[v9] } -> x0 + v11 LocalAddr(-5) -> x0 + v12 Load { addr=v11, disp=0, kind=F64 } -> d0 + v13 LocalAddr(-5) -> x0 + v14 BinopI { op=add, lhs=v13, rhs_imm=8 } -> x1 + v15 Load { addr=v13, disp=8, kind=F64 } -> d1 + v16 Binop { op=fadd, lhs=v12, rhs=v15 } -> d0 + terminator Return(v16) (exit_acc=v16) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=5 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-2) -> x0 + v2 Imm(4609434218613702656) -> x1 + v3 Store { addr=v1, disp=0, value=v2, kind=F64 } -> - + v4 LocalAddr(-2) -> x0 + v5 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x1 + v6 Imm(4612248968380809216) -> x1 + v7 Store { addr=v4, disp=8, value=v6, kind=F64 } -> - + v8 Imm(1) -> x7 + v9 LocalAddr(-2) -> x6 + v10 Call { target_pc=0, args=[v8, v9], fixed_args=1, fp_return=true, fp_arg_mask=0x0 } -> d0 + v11 Imm(4615626668101337088) -> x0 + v12 Binop { op=feq, lhs=v10, rhs=v11 } -> x0 + terminator Bz { cond=v12, target=b2, fall=b1 } (exit_acc=v12) + block 1 start_pc=0 + v13 Imm(0) -> x1 + v14 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v13) + block 2 start_pc=0 + v15 Imm(1) -> x1 + v16 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v15) + block 3 start_pc=0 + v17 Phi { incoming=[b1:v13, b2:v15], kind=I64 } -> x1 + v18 LoadLocal { off=-5, kind=I64 } -> x0 + terminator Return(v17) (exit_acc=v17) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/variadic_libc_fnptr_static_init.ssa b/tests/snapshots/ssa/variadic_libc_fnptr_static_init.ssa new file mode 100644 index 000000000..7ce591b93 --- /dev/null +++ b/tests/snapshots/ssa/variadic_libc_fnptr_static_init.ssa @@ -0,0 +1,87 @@ +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=17 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-8) -> x0 + v2 Imm(0) -> x1 + v3 Store { addr=v1, disp=0, value=v2, kind=I8 } -> - + v4 ImmData(40) -> x0 + v5 Imm(8) -> x1 + v6 BinopI { op=add, lhs=v4, rhs_imm=8 } -> x1 + v7 Load { addr=v4, disp=8, kind=I64 } -> x0 + v8 LocalAddr(-8) -> x7 + v9 Imm(64) -> x6 + v10 ImmData(56) -> x2 + v11 Imm(42) -> x1 + v12 ImmData(65) -> x8 + v13 Imm(99) -> x9 + v14 CallIndirect { target=v7, args=[v8, v9, v10, v11, v12, v13], callee_variadic=true, fixed_args=3, fp_return=false, fp_arg_mask=0x0 } -> x0 + v15 BinopI { op=shl, lhs=v14, rhs_imm=32 } -> x1 + v16 Extend { value=v14, kind=I32 } -> x0 + v17 LocalAddr(-8) -> x7 + v18 ImmData(69) -> x6 + v19 CallExt { binding_idx=62, args=[v17, v18], fp_arg_mask=0x0 } -> x0 + v20 BinopI { op=ne, lhs=v19, rhs_imm=0 } -> x0 + terminator Bz { cond=v20, target=b2, fall=b1 } (exit_acc=v20) + block 1 start_pc=0 + v21 Imm(1) -> x0 + terminator Return(v21) (exit_acc=v21) + block 2 start_pc=0 + v22 Imm(0) -> x0 + terminator Return(v22) (exit_acc=v22) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=__c5_sys_snprintf +fn ent_pc=2 n_params=0 variadic=false locals=0 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + terminator TailExt(3) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/vla_basic_sum.ssa b/tests/snapshots/ssa/vla_basic_sum.ssa new file mode 100644 index 000000000..7834cfc38 --- /dev/null +++ b/tests/snapshots/ssa/vla_basic_sum.ssa @@ -0,0 +1,136 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=compute +fn ent_pc=0 n_params=1 variadic=false locals=1030 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(6) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 StoreLocal { off=2, value=v1, kind=I32 } -> - + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 BinopI { op=shl, lhs=v3, rhs_imm=2 } -> x0 + v5 StoreLocal { off=-2, value=v4, kind=I64 } -> - + v6 Intrinsic { kind=1, args=[v4] } -> x0 + v7 StoreLocal { off=-1, value=v6, kind=I64 } -> - + v8 Imm(0) -> x0 + v9 StoreLocal { off=-3, value=v8, kind=I32 } -> - + terminator Jmp(b1) (exit_acc=v9) + block 1 start_pc=0 + v10 LoadLocal { off=-3, kind=I32 } -> x0 + v11 LoadLocal { off=2, kind=I32 } -> x1 + v12 Binop { op=lt, lhs=v10, rhs=v11 } -> x0 + terminator Bz { cond=v12, target=b4, fall=b3 } (exit_acc=v12) + block 2 start_pc=0 + v13 LoadLocal { off=-3, kind=I32 } -> x0 + v14 BinopI { op=add, lhs=v13, rhs_imm=1 } -> x0 + v15 StoreLocal { off=-3, value=v14, kind=I32 } -> - + terminator Jmp(b1) (exit_acc=v15) + block 3 start_pc=0 + v16 LoadLocal { off=-1, kind=I64 } -> x0 + v17 LoadLocal { off=-3, kind=I32 } -> x1 + v18 BinopI { op=shl, lhs=v17, rhs_imm=2 } -> x2 + v19 Binop { op=add, lhs=v16, rhs=v18 } -> x2 + v20 BinopI { op=shl, lhs=v17, rhs_imm=1 } -> x2 + v21 BinopI { op=shl, lhs=v20, rhs_imm=32 } -> x6 + v22 Extend { value=v20, kind=I32 } -> x6 + v23 StoreIndexed { base=v16, index=v17, scale=4, value=v20, kind=I32 } -> - + terminator Jmp(b2) (exit_acc=v23) + block 4 start_pc=0 + v24 Imm(0) -> x0 + v25 StoreLocal { off=-4, value=v24, kind=I32 } -> - + v26 StoreLocal { off=-5, value=v24, kind=I32 } -> - + terminator Jmp(b5) (exit_acc=v26) + block 5 start_pc=0 + v27 LoadLocal { off=-5, kind=I32 } -> x0 + v28 LoadLocal { off=2, kind=I32 } -> x1 + v29 Binop { op=lt, lhs=v27, rhs=v28 } -> x0 + terminator Bz { cond=v29, target=b8, fall=b7 } (exit_acc=v29) + block 6 start_pc=0 + v30 LoadLocal { off=-5, kind=I32 } -> x0 + v31 BinopI { op=add, lhs=v30, rhs_imm=1 } -> x0 + v32 StoreLocal { off=-5, value=v31, kind=I32 } -> - + terminator Jmp(b5) (exit_acc=v32) + block 7 start_pc=0 + v33 LoadLocal { off=-4, kind=I32 } -> x0 + v34 LoadLocal { off=-1, kind=I64 } -> x1 + v35 LoadLocal { off=-5, kind=I32 } -> x2 + v36 BinopI { op=shl, lhs=v35, rhs_imm=2 } -> x6 + v37 Binop { op=add, lhs=v34, rhs=v36 } -> x6 + v38 LoadIndexed { base=v34, index=v35, scale=4, kind=I32 } -> x1 + v39 Binop { op=add, lhs=v33, rhs=v38 } -> x0 + v40 StoreLocal { off=-4, value=v39, kind=I32 } -> - + v41 LoadLocal { off=-4, kind=I32 } -> x0 + terminator Jmp(b6) (exit_acc=v41) + block 8 start_pc=0 + v42 LoadLocal { off=-4, kind=I32 } -> x0 + terminator Return(v42) (exit_acc=v42) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(5) -> x7 + v2 Call { target_pc=0, args=[v1], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + v3 BinopI { op=ne, lhs=v2, rhs_imm=20 } -> x0 + terminator Bz { cond=v3, target=b2, fall=b1 } (exit_acc=v3) + block 1 start_pc=0 + v4 Imm(1) -> x0 + terminator Return(v4) (exit_acc=v4) + block 2 start_pc=0 + v5 Imm(1) -> x7 + v6 Call { target_pc=0, args=[v5], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + v7 BinopI { op=ne, lhs=v6, rhs_imm=0 } -> x0 + terminator Bz { cond=v7, target=b4, fall=b3 } (exit_acc=v7) + block 3 start_pc=0 + v8 Imm(2) -> x0 + terminator Return(v8) (exit_acc=v8) + block 4 start_pc=0 + v9 Imm(0) -> x0 + terminator Return(v9) (exit_acc=v9) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/vla_param_decay.ssa b/tests/snapshots/ssa/vla_param_decay.ssa new file mode 100644 index 000000000..5575add63 --- /dev/null +++ b/tests/snapshots/ssa/vla_param_decay.ssa @@ -0,0 +1,125 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=dot +fn ent_pc=0 n_params=3 variadic=false locals=2 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 ParamRef(2, kind=I64) -> x2 + v6 Imm(0) -> x0 + v7 Imm(0) -> x1 + v8 Imm(0) -> x0 + v9 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v7) + block 1 start_pc=0 + v10 Phi { incoming=[b0:v7, b2:v16], kind=I64 } -> x1 + v11 Phi { incoming=[b0:v7, b2:v30], kind=I64 } -> x0 + v12 Extend { value=v10, kind=I32 } -> x8 + v13 LoadLocal { off=2, kind=I32 } -> x9 + v14 Binop { op=lt, lhs=v12, rhs=v1 } -> x8 + terminator Bz { cond=v14, target=b4, fall=b3 } (exit_acc=v14) + block 2 start_pc=0 + v15 Extend { value=v10, kind=I32 } -> x1 + v16 BinopI { op=add, lhs=v15, rhs_imm=1 } -> x1 + v17 Imm(0) -> x8 + terminator Jmp(b1) (exit_acc=v16) + block 3 start_pc=0 + v18 Extend { value=v11, kind=I32 } -> x8 + v19 LoadLocal { off=3, kind=I64 } -> x8 + v20 Extend { value=v10, kind=I32 } -> x8 + v21 BinopI { op=shl, lhs=v20, rhs_imm=2 } -> x8 + v22 Binop { op=add, lhs=v3, rhs=v21 } -> x9 + v23 Load { addr=v22, disp=0, kind=I32 } -> x9 + v24 LoadLocal { off=4, kind=I64 } -> x3 + v25 Binop { op=add, lhs=v5, rhs=v21 } -> x8 + v26 Load { addr=v25, disp=0, kind=I32 } -> x8 + v27 Binop { op=mul, lhs=v23, rhs=v26 } -> x8 + v28 BinopI { op=shl, lhs=v27, rhs_imm=32 } -> x9 + v29 Extend { value=v27, kind=I32 } -> x9 + v30 Binop { op=add, lhs=v11, rhs=v27 } -> x0 + v31 Imm(0) -> x8 + v32 Extend { value=v30, kind=I32 } -> x8 + terminator Jmp(b2) (exit_acc=v32) + block 4 start_pc=0 + v33 Extend { value=v11, kind=I32 } -> x0 + terminator Return(v33) (exit_acc=v33) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=8 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-2) -> x0 + v2 ImmData(8) -> x1 + v3 Mcpy { dst=v1, src=v2, size=16 } -> x0 + v4 LocalAddr(-4) -> x0 + v5 ImmData(24) -> x1 + v6 Mcpy { dst=v4, src=v5, size=16 } -> x0 + v7 Imm(4) -> x7 + v8 LocalAddr(-2) -> x6 + v9 LocalAddr(-4) -> x2 + v10 Call { target_pc=0, args=[v7, v8, v9], fixed_args=3, fp_return=false, fp_arg_mask=0x0 } -> x0 + v11 BinopI { op=eq, lhs=v10, rhs_imm=70 } -> x0 + terminator Bz { cond=v11, target=b2, fall=b1 } (exit_acc=v11) + block 1 start_pc=0 + v12 Imm(0) -> x1 + v13 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v12) + block 2 start_pc=0 + v14 Imm(1) -> x1 + v15 Imm(0) -> x0 + terminator Jmp(b3) (exit_acc=v14) + block 3 start_pc=0 + v16 Phi { incoming=[b1:v12, b2:v14], kind=I64 } -> x1 + v17 LoadLocal { off=-8, kind=I64 } -> x0 + terminator Return(v16) (exit_acc=v16) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/vla_runtime_sizeof.ssa b/tests/snapshots/ssa/vla_runtime_sizeof.ssa new file mode 100644 index 000000000..ac11cb193 --- /dev/null +++ b/tests/snapshots/ssa/vla_runtime_sizeof.ssa @@ -0,0 +1,94 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=1029 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(5) -> - + v1 Imm(7) -> x0 + v2 StoreLocal { off=-1, value=v1, kind=I32 } -> - + v3 LoadLocal { off=-1, kind=I32 } -> x0 + v4 BinopI { op=shl, lhs=v3, rhs_imm=3 } -> x0 + v5 StoreLocal { off=-3, value=v4, kind=I64 } -> - + v6 Intrinsic { kind=1, args=[v4] } -> x0 + v7 StoreLocal { off=-2, value=v6, kind=I64 } -> - + v8 LoadLocal { off=-3, kind=I64 } -> x0 + v9 StoreLocal { off=-4, value=v8, kind=I64 } -> - + v10 LoadLocal { off=-4, kind=I64 } -> x0 + v11 LoadLocal { off=-1, kind=I32 } -> x1 + v12 BinopI { op=shl, lhs=v11, rhs_imm=3 } -> x1 + v13 Binop { op=ne, lhs=v10, rhs=v12 } -> x0 + terminator Bz { cond=v13, target=b2, fall=b1 } (exit_acc=v13) + block 1 start_pc=0 + v14 Imm(1) -> x0 + terminator Return(v14) (exit_acc=v14) + block 2 start_pc=0 + v15 LoadLocal { off=-4, kind=I64 } -> x0 + v16 Imm(8) -> x1 + v17 BinopI { op=shru, lhs=v15, rhs_imm=3 } -> x0 + v18 LoadLocal { off=-1, kind=I32 } -> x1 + v19 Binop { op=ne, lhs=v17, rhs=v18 } -> x0 + terminator Bz { cond=v19, target=b4, fall=b3 } (exit_acc=v19) + block 3 start_pc=0 + v20 Imm(2) -> x0 + terminator Return(v20) (exit_acc=v20) + block 4 start_pc=0 + v21 Imm(100) -> x0 + v22 StoreLocal { off=-1, value=v21, kind=I32 } -> - + v23 LoadLocal { off=-3, kind=I64 } -> x0 + v24 Imm(56) -> x1 + v25 Imm(240518168576) -> x1 + v26 BinopI { op=ne, lhs=v23, rhs_imm=56 } -> x0 + terminator Bz { cond=v26, target=b6, fall=b5 } (exit_acc=v26) + block 5 start_pc=0 + v27 Imm(3) -> x0 + terminator Return(v27) (exit_acc=v27) + block 6 start_pc=0 + v28 Imm(0) -> x0 + terminator Return(v28) (exit_acc=v28) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/vla_scope_reclaim_loop.ssa b/tests/snapshots/ssa/vla_scope_reclaim_loop.ssa new file mode 100644 index 000000000..f240d8c33 --- /dev/null +++ b/tests/snapshots/ssa/vla_scope_reclaim_loop.ssa @@ -0,0 +1,146 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=1035 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(10) -> - + v1 Imm(0) -> x0 + v2 StoreLocal { off=-1, value=v1, kind=I64 } -> - + v3 StoreLocal { off=-2, value=v1, kind=I32 } -> - + terminator Jmp(b1) (exit_acc=v3) + block 1 start_pc=0 + v4 LoadLocal { off=-2, kind=I32 } -> x0 + v5 BinopI { op=lt, lhs=v4, rhs_imm=100000 } -> x0 + terminator Bz { cond=v5, target=b4, fall=b3 } (exit_acc=v5) + block 2 start_pc=0 + v6 LoadLocal { off=-2, kind=I32 } -> x0 + v7 BinopI { op=add, lhs=v6, rhs_imm=1 } -> x0 + v8 StoreLocal { off=-2, value=v7, kind=I32 } -> - + terminator Jmp(b1) (exit_acc=v8) + block 3 start_pc=0 + v9 Intrinsic { kind=46, args=[] } -> x0 + v10 StoreLocal { off=-7, value=v9, kind=I64 } -> - + v11 Imm(64) -> x0 + v12 StoreLocal { off=-3, value=v11, kind=I32 } -> - + v13 LoadLocal { off=-3, kind=I32 } -> x0 + v14 BinopI { op=shl, lhs=v13, rhs_imm=2 } -> x0 + v15 StoreLocal { off=-5, value=v14, kind=I64 } -> - + v16 Intrinsic { kind=1, args=[v14] } -> x0 + v17 StoreLocal { off=-4, value=v16, kind=I64 } -> - + v18 Imm(0) -> x0 + v19 StoreLocal { off=-6, value=v18, kind=I32 } -> - + terminator Jmp(b5) (exit_acc=v19) + block 4 start_pc=0 + v42 Imm(0) -> x0 + v43 StoreLocal { off=-8, value=v42, kind=I64 } -> - + v44 StoreLocal { off=-9, value=v42, kind=I32 } -> - + terminator Jmp(b9) (exit_acc=v44) + block 5 start_pc=0 + v20 LoadLocal { off=-6, kind=I32 } -> x0 + v21 LoadLocal { off=-3, kind=I32 } -> x1 + v22 Binop { op=lt, lhs=v20, rhs=v21 } -> x0 + terminator Bz { cond=v22, target=b8, fall=b7 } (exit_acc=v22) + block 6 start_pc=0 + v23 LoadLocal { off=-6, kind=I32 } -> x0 + v24 BinopI { op=add, lhs=v23, rhs_imm=1 } -> x0 + v25 StoreLocal { off=-6, value=v24, kind=I32 } -> - + terminator Jmp(b5) (exit_acc=v25) + block 7 start_pc=0 + v26 LoadLocal { off=-4, kind=I64 } -> x0 + v27 LoadLocal { off=-6, kind=I32 } -> x1 + v28 BinopI { op=shl, lhs=v27, rhs_imm=2 } -> x2 + v29 Binop { op=add, lhs=v26, rhs=v28 } -> x2 + v30 StoreIndexed { base=v26, index=v27, scale=4, value=v27, kind=I32 } -> - + terminator Jmp(b6) (exit_acc=v30) + block 8 start_pc=0 + v31 LoadLocal { off=-1, kind=I64 } -> x0 + v32 LoadLocal { off=-4, kind=I64 } -> x1 + v33 LoadLocal { off=-2, kind=I32 } -> x2 + v34 BinopI { op=and, lhs=v33, rhs_imm=63 } -> x2 + v35 BinopI { op=shl, lhs=v34, rhs_imm=2 } -> x6 + v36 Binop { op=add, lhs=v32, rhs=v35 } -> x6 + v37 LoadIndexed { base=v32, index=v34, scale=4, kind=I32 } -> x1 + v38 Binop { op=add, lhs=v31, rhs=v37 } -> x0 + v39 StoreLocal { off=-1, value=v38, kind=I64 } -> - + v40 LoadLocal { off=-7, kind=I64 } -> x0 + v41 Intrinsic { kind=47, args=[v40] } -> x0 + terminator Jmp(b2) (exit_acc=v41) + block 9 start_pc=0 + v45 LoadLocal { off=-9, kind=I32 } -> x0 + v46 BinopI { op=lt, lhs=v45, rhs_imm=100000 } -> x0 + terminator Bz { cond=v46, target=b12, fall=b11 } (exit_acc=v46) + block 10 start_pc=0 + v47 LoadLocal { off=-9, kind=I32 } -> x0 + v48 BinopI { op=add, lhs=v47, rhs_imm=1 } -> x0 + v49 StoreLocal { off=-9, value=v48, kind=I32 } -> - + terminator Jmp(b9) (exit_acc=v49) + block 11 start_pc=0 + v50 LoadLocal { off=-8, kind=I64 } -> x0 + v51 LoadLocal { off=-9, kind=I32 } -> x1 + v52 BinopI { op=and, lhs=v51, rhs_imm=63 } -> x1 + v53 Binop { op=add, lhs=v50, rhs=v52 } -> x0 + v54 StoreLocal { off=-8, value=v53, kind=I64 } -> - + terminator Jmp(b10) (exit_acc=v54) + block 12 start_pc=0 + v55 LoadLocal { off=-1, kind=I64 } -> x0 + v56 LoadLocal { off=-8, kind=I64 } -> x1 + v57 Binop { op=eq, lhs=v55, rhs=v56 } -> x0 + terminator Bz { cond=v57, target=b14, fall=b13 } (exit_acc=v57) + block 13 start_pc=0 + v58 Imm(0) -> x0 + v59 StoreLocal { off=-1035, value=v58, kind=I64 } -> - + terminator Jmp(b15) (exit_acc=v59) + block 14 start_pc=0 + v60 Imm(1) -> x0 + v61 StoreLocal { off=-1035, value=v60, kind=I64 } -> - + terminator Jmp(b15) (exit_acc=v61) + block 15 start_pc=0 + v62 LoadLocal { off=-1035, kind=I64 } -> x0 + terminator Return(v62) (exit_acc=v62) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/vla_size_from_arg.ssa b/tests/snapshots/ssa/vla_size_from_arg.ssa new file mode 100644 index 000000000..c250f9f93 --- /dev/null +++ b/tests/snapshots/ssa/vla_size_from_arg.ssa @@ -0,0 +1,135 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=fill_and_sum +fn ent_pc=0 n_params=1 variadic=false locals=1030 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(6) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 StoreLocal { off=2, value=v1, kind=I32 } -> - + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 StoreLocal { off=-2, value=v3, kind=I64 } -> - + v5 Intrinsic { kind=1, args=[v3] } -> x0 + v6 StoreLocal { off=-1, value=v5, kind=I64 } -> - + v7 Imm(0) -> x0 + v8 StoreLocal { off=-3, value=v7, kind=I32 } -> - + terminator Jmp(b1) (exit_acc=v8) + block 1 start_pc=0 + v9 LoadLocal { off=-3, kind=I32 } -> x0 + v10 LoadLocal { off=2, kind=I32 } -> x1 + v11 Binop { op=lt, lhs=v9, rhs=v10 } -> x0 + terminator Bz { cond=v11, target=b4, fall=b3 } (exit_acc=v11) + block 2 start_pc=0 + v12 LoadLocal { off=-3, kind=I32 } -> x0 + v13 BinopI { op=add, lhs=v12, rhs_imm=1 } -> x0 + v14 StoreLocal { off=-3, value=v13, kind=I32 } -> - + terminator Jmp(b1) (exit_acc=v14) + block 3 start_pc=0 + v15 LoadLocal { off=-1, kind=I64 } -> x0 + v16 LoadLocal { off=-3, kind=I32 } -> x1 + v17 Binop { op=add, lhs=v15, rhs=v16 } -> x0 + v18 BinopI { op=add, lhs=v16, rhs_imm=1 } -> x1 + v19 BinopI { op=shl, lhs=v18, rhs_imm=32 } -> x2 + v20 Extend { value=v18, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v18, rhs_imm=56 } -> x1 + v22 Extend { value=v20, kind=I8 } -> x1 + v23 Store { addr=v17, disp=0, value=v20, kind=I8 } -> - + terminator Jmp(b2) (exit_acc=v23) + block 4 start_pc=0 + v24 Imm(0) -> x0 + v25 StoreLocal { off=-4, value=v24, kind=I32 } -> - + v26 StoreLocal { off=-5, value=v24, kind=I32 } -> - + terminator Jmp(b5) (exit_acc=v26) + block 5 start_pc=0 + v27 LoadLocal { off=-5, kind=I32 } -> x0 + v28 LoadLocal { off=2, kind=I32 } -> x1 + v29 Binop { op=lt, lhs=v27, rhs=v28 } -> x0 + terminator Bz { cond=v29, target=b8, fall=b7 } (exit_acc=v29) + block 6 start_pc=0 + v30 LoadLocal { off=-5, kind=I32 } -> x0 + v31 BinopI { op=add, lhs=v30, rhs_imm=1 } -> x0 + v32 StoreLocal { off=-5, value=v31, kind=I32 } -> - + terminator Jmp(b5) (exit_acc=v32) + block 7 start_pc=0 + v33 LoadLocal { off=-4, kind=I32 } -> x0 + v34 LoadLocal { off=-1, kind=I64 } -> x1 + v35 LoadLocal { off=-5, kind=I32 } -> x2 + v36 Binop { op=add, lhs=v34, rhs=v35 } -> x1 + v37 Load { addr=v36, disp=0, kind=I8 } -> x1 + v38 Binop { op=add, lhs=v33, rhs=v37 } -> x0 + v39 StoreLocal { off=-4, value=v38, kind=I32 } -> - + v40 LoadLocal { off=-4, kind=I32 } -> x0 + terminator Jmp(b6) (exit_acc=v40) + block 8 start_pc=0 + v41 LoadLocal { off=-4, kind=I32 } -> x0 + terminator Return(v41) (exit_acc=v41) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=main +fn ent_pc=1 n_params=0 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(10) -> x7 + v2 Call { target_pc=0, args=[v1], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + v3 BinopI { op=ne, lhs=v2, rhs_imm=55 } -> x0 + terminator Bz { cond=v3, target=b2, fall=b1 } (exit_acc=v3) + block 1 start_pc=0 + v4 Imm(1) -> x0 + terminator Return(v4) (exit_acc=v4) + block 2 start_pc=0 + v5 Imm(4) -> x7 + v6 Call { target_pc=0, args=[v5], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + v7 BinopI { op=ne, lhs=v6, rhs_imm=10 } -> x0 + terminator Bz { cond=v7, target=b4, fall=b3 } (exit_acc=v7) + block 3 start_pc=0 + v8 Imm(2) -> x0 + terminator Return(v8) (exit_acc=v8) + block 4 start_pc=0 + v9 Imm(0) -> x0 + terminator Return(v9) (exit_acc=v9) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/volatile_param_classes.ssa b/tests/snapshots/ssa/volatile_param_classes.ssa new file mode 100644 index 000000000..837baf316 --- /dev/null +++ b/tests/snapshots/ssa/volatile_param_classes.ssa @@ -0,0 +1,153 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=step +fn ent_pc=0 n_params=2 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 StoreLocal { off=2, value=v1, kind=I64 } -> - + v3 ParamRef(1, kind=F64) -> d0 + v4 StoreLocal { off=3, value=v3, kind=F64 } -> - + v5 LoadLocal { off=2, kind=I64, volatile } -> x0 + v6 Load { addr=v5, disp=0, kind=F64, volatile } -> d0 + v7 StoreLocal { off=-1, value=v6, kind=F64, volatile } -> - + v8 LoadLocal { off=2, kind=I64, volatile } -> x0 + v9 LoadLocal { off=-1, kind=F64, volatile } -> d0 + v10 LoadLocal { off=3, kind=F64, volatile } -> d1 + v11 Binop { op=fadd, lhs=v9, rhs=v10 } -> d0 + v12 Store { addr=v8, disp=0, value=v11, kind=F64 } -> - + v13 Imm(0) -> x0 + terminator Return(v13) (exit_acc=v13) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=half +fn ent_pc=1 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=F32) -> d0 [f32] + v2 StoreLocal { off=-1, value=v1, kind=F32 } -> - + v3 LoadLocal { off=-1, kind=F32, volatile } -> d0 [f32] + v4 FpCast { kind=F32ToF64, value=v3 } -> d0 + v5 Imm(4602678819172646912) -> x0 + v6 Binop { op=fmul, lhs=v4, rhs=v5 } -> d0 + terminator Return(v6) (exit_acc=v6) +; --- SSA dump (ok=true) ent_pc=2 --- +; name=bump +fn ent_pc=2 n_params=2 variadic=false locals=2 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=F64) -> d0 + v4 Imm(0) -> x0 + v5 LoadLocal { off=2, kind=I64 } -> x0 + v6 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x0 + v7 Load { addr=v1, disp=8, kind=I64 } -> x0 + v8 BinopI { op=add, lhs=v7, rhs_imm=1 } -> x0 + v9 Store { addr=v1, disp=8, value=v8, kind=I64 } -> - + v10 LoadLocal { off=2, kind=I64 } -> x0 + v11 LoadLocal { off=3, kind=F64 } -> d1 + v12 Call { target_pc=0, args=[v1, v3], fixed_args=2, fp_return=false, fp_arg_mask=0x2 } -> x0 + v13 Imm(0) -> x0 + terminator Return(v13) (exit_acc=v13) +; --- SSA dump (ok=true) ent_pc=3 --- +; name=main +fn ent_pc=3 n_params=0 variadic=false locals=5 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 LocalAddr(-2) -> x0 + v2 ImmData(8) -> x1 + v3 Mcpy { dst=v1, src=v2, size=16 } -> x0 + v4 LocalAddr(-2) -> x7 + v5 Imm(4609434218613702656) -> x6 + v6 Call { target_pc=2, args=[v4, v5], fixed_args=2, fp_return=false, fp_arg_mask=0x2 } -> x0 + v7 LocalAddr(-2) -> x7 + v8 Imm(4612811918334230528) -> x6 + v9 Call { target_pc=2, args=[v7, v8], fixed_args=2, fp_return=false, fp_arg_mask=0x2 } -> x0 + v10 LocalAddr(-2) -> x7 + v11 Imm(4615063718147915776) -> x6 + v12 Call { target_pc=2, args=[v10, v11], fixed_args=2, fp_return=false, fp_arg_mask=0x2 } -> x0 + v13 LocalAddr(-2) -> x0 + v14 Load { addr=v13, disp=0, kind=F64 } -> d0 + v15 Imm(4620130267728707584) -> x0 + v16 Binop { op=fne, lhs=v14, rhs=v15 } -> x3 + v17 Imm(0) -> x0 + terminator Bnz { cond=v16, target=b7, fall=b1 } (exit_acc=v16) + block 1 start_pc=0 + v18 LocalAddr(-2) -> x0 + v19 BinopI { op=add, lhs=v18, rhs_imm=8 } -> x1 + v20 Load { addr=v18, disp=8, kind=I64 } -> x0 + v21 BinopI { op=ne, lhs=v20, rhs_imm=3 } -> x3 + v22 Imm(0) -> x0 + terminator Jmp(b2) (exit_acc=v21) + block 2 start_pc=0 + v23 Phi { incoming=[b7:v16, b1:v21], kind=I64 } -> x3 + v24 LoadLocal { off=-5, kind=I64 } -> x0 + terminator Bz { cond=v23, target=b4, fall=b3 } (exit_acc=v23) + block 3 start_pc=0 + v25 Imm(1) -> x0 + terminator Return(v25) (exit_acc=v25) + block 4 start_pc=0 + v26 Imm(4617315517961601024) -> x0 + v27 FpCast { kind=F64ToF32, value=v26 } -> d0 [f32] + v28 Call { target_pc=1, args=[v27], fixed_args=1, fp_return=true, fp_arg_mask=0x1 } -> d0 + v29 Imm(4612811918334230528) -> x0 + v30 Binop { op=fne, lhs=v28, rhs=v29 } -> x0 + terminator Bz { cond=v30, target=b6, fall=b5 } (exit_acc=v30) + block 5 start_pc=0 + v31 Imm(2) -> x0 + terminator Return(v31) (exit_acc=v31) + block 6 start_pc=0 + v32 Imm(0) -> x0 + terminator Return(v32) (exit_acc=v32) + block 7 start_pc=0 + terminator Jmp(b2) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/volatile_ptr_alias_loop.ssa b/tests/snapshots/ssa/volatile_ptr_alias_loop.ssa new file mode 100644 index 000000000..ced7a2a8b --- /dev/null +++ b/tests/snapshots/ssa/volatile_ptr_alias_loop.ssa @@ -0,0 +1,98 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=4 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(0) -> x1 + v2 StoreLocal { off=-1, value=v1, kind=I32, volatile } -> - + v3 LocalAddr(-1) -> x0 + v4 StoreLocal { off=-2, value=v3, kind=I64, volatile } -> - + v5 Imm(0) -> x0 + terminator Jmp(b1) (exit_acc=v1) + block 1 start_pc=0 + v6 Phi { incoming=[b0:v1, b5:v16], kind=I64 } -> x1 + v7 LoadLocal { off=-1, kind=I32, volatile } -> x0 + v8 BinopI { op=lt, lhs=v7, rhs_imm=3 } -> x0 + terminator Bz { cond=v8, target=b3, fall=b2 } (exit_acc=v8) + block 2 start_pc=0 + v9 LoadLocal { off=-2, kind=I64, volatile } -> x0 + v10 LoadLocal { off=-1, kind=I32, volatile } -> x2 + v11 BinopI { op=add, lhs=v10, rhs_imm=1 } -> x2 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x6 + v13 Extend { value=v11, kind=I32 } -> x6 + v14 Store { addr=v9, disp=0, value=v11, kind=I32, volatile } -> - + v15 Extend { value=v6, kind=I32 } -> x0 + v16 BinopI { op=add, lhs=v6, rhs_imm=1 } -> x1 + v17 Imm(0) -> x0 + v18 Extend { value=v16, kind=I32 } -> x0 + v19 BinopI { op=gt, lhs=v18, rhs_imm=10 } -> x0 + terminator Bz { cond=v19, target=b5, fall=b4 } (exit_acc=v19) + block 3 start_pc=0 + v20 Extend { value=v6, kind=I32 } -> x0 + v21 BinopI { op=eq, lhs=v20, rhs_imm=3 } -> x0 + terminator Bz { cond=v21, target=b7, fall=b6 } (exit_acc=v21) + block 4 start_pc=0 + v22 Imm(1) -> x0 + terminator Return(v22) (exit_acc=v22) + block 5 start_pc=0 + terminator Jmp(b1) + block 6 start_pc=0 + v23 Imm(0) -> x1 + v24 Imm(0) -> x0 + terminator Jmp(b8) (exit_acc=v23) + block 7 start_pc=0 + v25 Imm(2) -> x1 + v26 Imm(0) -> x0 + terminator Jmp(b8) (exit_acc=v25) + block 8 start_pc=0 + v27 Phi { incoming=[b6:v23, b7:v25], kind=I64 } -> x1 + v28 LoadLocal { off=-4, kind=I64 } -> x0 + terminator Return(v27) (exit_acc=v27) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/volatile_setjmp_longjmp.ssa b/tests/snapshots/ssa/volatile_setjmp_longjmp.ssa new file mode 100644 index 000000000..f36a666e6 --- /dev/null +++ b/tests/snapshots/ssa/volatile_setjmp_longjmp.ssa @@ -0,0 +1,82 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=4 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 Imm(1) -> x0 + v2 StoreLocal { off=-1, value=v1, kind=I32, volatile } -> - + v3 ImmData(24) -> x3 + v4 CallExt { binding_idx=0, args=[v3], fp_arg_mask=0x0 } -> x0 + v5 BinopI { op=eq, lhs=v4, rhs_imm=0 } -> x0 + terminator Bz { cond=v5, target=b2, fall=b1 } (exit_acc=v5) + block 1 start_pc=0 + v6 Imm(2) -> x0 + v7 StoreLocal { off=-1, value=v6, kind=I32, volatile } -> - + v8 ImmData(24) -> x0 + v9 Imm(1) -> x6 + v10 CallExt { binding_idx=1, args=[v3, v9], fp_arg_mask=0x0 } -> x0 + terminator Jmp(b2) (exit_acc=v10) + block 2 start_pc=0 + v11 LoadLocal { off=-1, kind=I32, volatile } -> x0 + v12 BinopI { op=eq, lhs=v11, rhs_imm=2 } -> x0 + terminator Bz { cond=v12, target=b4, fall=b3 } (exit_acc=v12) + block 3 start_pc=0 + v13 Imm(0) -> x1 + v14 Imm(0) -> x0 + terminator Jmp(b5) (exit_acc=v13) + block 4 start_pc=0 + v15 Imm(1) -> x1 + v16 Imm(0) -> x0 + terminator Jmp(b5) (exit_acc=v15) + block 5 start_pc=0 + v17 Phi { incoming=[b3:v13, b4:v15], kind=I64 } -> x1 + v18 LoadLocal { off=-4, kind=I64 } -> x0 + terminator Return(v17) (exit_acc=v17) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10) diff --git a/tests/snapshots/ssa/volatile_unused_read.ssa b/tests/snapshots/ssa/volatile_unused_read.ssa new file mode 100644 index 000000000..510a98760 --- /dev/null +++ b/tests/snapshots/ssa/volatile_unused_read.ssa @@ -0,0 +1,85 @@ +; --- SSA dump (ok=true) ent_pc=0 --- +; name=main +fn ent_pc=0 n_params=0 variadic=false locals=3 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ImmData(8) -> x0 + v2 Load { addr=v1, disp=0, kind=I32, volatile } -> x1 + v3 Imm(7) -> x1 + v4 StoreLocal { off=-1, value=v3, kind=I32, volatile } -> - + v5 LoadLocal { off=-1, kind=I32, volatile } -> x1 + v6 Load { addr=v1, disp=0, kind=I32, volatile } -> x0 + v7 BinopI { op=eq, lhs=v6, rhs_imm=5 } -> x1 + v8 Imm(0) -> x0 + terminator Bz { cond=v7, target=b6, fall=b1 } (exit_acc=v7) + block 1 start_pc=0 + v9 LoadLocal { off=-1, kind=I32, volatile } -> x0 + v10 BinopI { op=eq, lhs=v9, rhs_imm=7 } -> x1 + v11 Imm(0) -> x0 + terminator Jmp(b2) (exit_acc=v10) + block 2 start_pc=0 + v12 Phi { incoming=[b6:v7, b1:v10], kind=I64 } -> x1 + v13 LoadLocal { off=-2, kind=I64 } -> x0 + terminator Bz { cond=v12, target=b4, fall=b3 } (exit_acc=v12) + block 3 start_pc=0 + v14 Imm(0) -> x1 + v15 Imm(0) -> x0 + terminator Jmp(b5) (exit_acc=v14) + block 4 start_pc=0 + v16 Imm(1) -> x1 + v17 Imm(0) -> x0 + terminator Jmp(b5) (exit_acc=v16) + block 5 start_pc=0 + v18 Phi { incoming=[b3:v14, b4:v16], kind=I64 } -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x0 + terminator Return(v18) (exit_acc=v18) + block 6 start_pc=0 + terminator Jmp(b2) +; --- SSA dump (ok=true) ent_pc=0 --- +; name=__c5_exit +fn ent_pc=0 n_params=1 variadic=false locals=1 + spill_count=0 gpr_used=[] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I32) -> x7 + v2 Imm(0) -> x0 + v3 LoadLocal { off=2, kind=I32 } -> x0 + v4 CallExt { binding_idx=0, args=[v1], fp_arg_mask=0x0 } -> x0 + v5 Imm(0) -> x0 + terminator Return(v5) (exit_acc=v5) +; --- SSA dump (ok=true) ent_pc=1 --- +; name=__c5_entry +fn ent_pc=1 n_params=2 variadic=false locals=6 + spill_count=0 gpr_used=[3] fp_used=[] + block 0 start_pc=0 + v0 AllocaInit(0) -> - + v1 ParamRef(0, kind=I64) -> x7 + v2 Imm(0) -> x0 + v3 ParamRef(1, kind=I64) -> x6 + v4 Imm(0) -> x0 + v5 LoadLocal { off=3, kind=I64 } -> x0 + v6 BinopI { op=and, lhs=v3, rhs_imm=255 } -> x0 + v7 LoadLocal { off=2, kind=I64 } -> x0 + v8 Imm(0) -> x0 + v9 LoadLocal { off=-1, kind=I64 } -> x0 + v10 Imm(0) -> x3 + v11 Load { addr=v1, disp=0, kind=I64 } -> x0 + v12 BinopI { op=shl, lhs=v11, rhs_imm=32 } -> x1 + v13 Extend { value=v11, kind=I32 } -> x0 + v14 Imm(0) -> x1 + v15 Imm(8) -> x1 + v16 BinopI { op=add, lhs=v1, rhs_imm=8 } -> x6 + v17 Imm(0) -> x1 + v18 ImmData(24) -> x1 + v19 LoadLocal { off=-3, kind=I64 } -> x2 + v20 LoadLocal { off=-2, kind=I32 } -> x2 + v21 BinopI { op=shl, lhs=v13, rhs_imm=3 } -> x2 + v22 Binop { op=add, lhs=v16, rhs=v21 } -> x2 + v23 BinopI { op=add, lhs=v22, rhs_imm=8 } -> x2 + v24 Store { addr=v18, disp=0, value=v23, kind=I64 } -> - + v25 LoadLocal { off=-2, kind=I32 } -> x1 + v26 LoadLocal { off=-3, kind=I64 } -> x1 + v27 Call { target_pc=3, args=[v13, v16], fixed_args=2, fp_return=false, fp_arg_mask=0x0 } -> x7 + v28 Call { target_pc=0, args=[v27], fixed_args=1, fp_return=false, fp_arg_mask=0x0 } -> x0 + terminator Return(v10) (exit_acc=v10)