This commit is contained in:
2025-12-04 00:45:42 -06:00
parent 4ca5884255
commit 28d44f2bbf
13 changed files with 851 additions and 31 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
*.txt
*.elf
*.o
blink.log
compile_commands.json

View File

@@ -2,14 +2,27 @@ FILES = $(wildcard ./*)
SRCS = $(filter %.c,$(FILES))
BINS = $(SRCS:%.c=%.elf)
CFLAGS = -Wall -Werror -pedantic -Wno-unused -D_GNU_SOURCE -std=gnu2y\
-O3 -g -Ttext=C475000 -static -nostartfiles -fno-stack-protector\
-march=x86-64 -msse2 -msse3 -mssse3 -mpclmul -mpopcnt -madx -mbmi2 -mrdrnd -mrdseed
MUSLFILES = $(wildcard ./musl/*)
MUSLSRCS = $(filter %.s,$(MUSLFILES))
MUSLOBJS = $(MUSLSRCS:%.s=%.o)
CFLAGS = -Wall -Werror -pedantic -Wno-unused -std=gnu2y\
-O3 -c -g -fno-stack-protector -fno-pie\
-fno-semantic-interposition -fno-trapping-math\
-march=x86-64 -mprefer-vector-width=128 -mpopcnt -malign-data=compat -malign-stringops
LFLAGS = -Ttext=C475000 -static -nostdlib -no-pie
all: $(BINS)
%.elf: %.c
%.elf: %.o start.o | %.c lib.h $(MUSLOBJS)
ld -o $@ $(LFLAGS) start.o $< $(MUSLOBJS)
start.o: start.s
nasm -f elf64 -o $@ $<
%.o: %.c
gcc-tree -o $@ $(CFLAGS) $<
clean:
rm ./*.elf
rm -f *.elf *.o

92
day0.h Normal file
View File

@@ -0,0 +1,92 @@
#include "lib.h"
#define DBG 0
static
unsigned char input[] = {
#embed "day0_input.txt"
};
static
unsigned char test[] = {
#embed "day0_test.txt"
};
static
unsigned long do_part1(size_t file_len, unsigned char file[file_len]) {
unsigned char *s = file;
unsigned long result = 0;
#if DBG
print("\n");
#endif
do {
s++;
} while (s != &file[file_len]);
return result;
}
static
unsigned long do_part2(size_t file_len, unsigned char file[file_len]) {
unsigned char *s = file;
unsigned long result = 0;
#if DBG
print("\n");
#endif
do {
s++;
} while (s != &file[file_len]);
return result;
}
#define RUN_TEST1 1
#define RUN_PART1 0
#define RUN_TEST2 0
#define RUN_PART2 0
#define TEST1_EXPECT -1
#define TEST2_EXPECT -1
void run() {
#if RUN_TEST1
print("PART 1 TEST: ");
if (unsigned long v = do_part1(countof(test), test); v != TEST1_EXPECT) {
print("FAILED (got ");
printd(v);
print(", expected " xstr(TEST1_EXPECT) ")\n");
} else {
print("PASSED\n");
}
#endif
#if RUN_PART1
print("PART 1 RESULT: ");
printd(do_part1(countof(input), input));
print("\n");
#endif
#if RUN_TEST2
print("PART 2 TEST: ");
if (unsigned long v = do_part2(countof(test), test); v != TEST2_EXPECT) {
print("FAILED (got ");
printd(v);
print(", expected " xstr(TEST2_EXPECT) ")\n");
} else {
print("PASSED\n");
}
#endif
#if RUN_PART2
print("PART 2 RESULT: ");
printd(do_part2(countof(input), input));
print("\n");
#endif
exit_group(0);
}

67
day1.c
View File

@@ -1,4 +1,65 @@
#include "lib.h"
#include <stdlib.h>
#include <stdcountof.h>
#include <stdint.h>
#include <string.h>
#define SYS_write 1
#define SYS_exit_group 231
#define STDOUT_FILENO 1
static
void write(uint64_t fileno, void *buffer, size_t len) {
uint64_t a,d;
asm volatile("syscall"
:"=a"(a),"=d"(d):"a"(SYS_write),"D"(fileno),"S"(buffer),"d"(len):"memory");
}
[[noreturn]] static
void exit_group() {
asm volatile(
"syscall\n"
"ud2"
::"a"(SYS_exit_group),"D"(0));
for (;;);
}
#define xstr(s) str(s)
#define str(s) #s
static
void print_many_char(size_t len, char chars[len]) {
write(STDOUT_FILENO, chars, len);
}
#define print(string) print_many_char(sizeof(string)-1, string)
static
void printd(unsigned long v) {
if (!v) {
print("0");
return;
}
char buf[32];
char *p = buf+32;
unsigned count = 0;
while (v) {
p--;
*p = '0' + (v % 10);
v /= 10;
count++;
}
write(STDOUT_FILENO, p, count);
}
static
unsigned grabnum(const char *s, const char **end) {
unsigned r = 0;
for (; *s >= '0' && *s <= '9'; s++)
r = r * 10 + (*s - '0');
*end = s;
return r;
}
#define DBG 1
@@ -74,7 +135,7 @@ unsigned do_part2(size_t src_len, const char src[src_len]) {
return count;
}
void _start() {
void run() {
#if RUN_TEST1
print("PART 1 TEST: ");
if (unsigned long v = do_part1(countof(test), test); v != TEST1_EXPECT) {
@@ -109,5 +170,5 @@ void _start() {
print("\n");
#endif
syscall(SYS_exit_group, 0);
exit_group();
}

8
day2.c
View File

@@ -251,13 +251,13 @@ no_len_change:
#define RUN_TEST1 1
#define RUN_PART1 1
#define RUN_TEST2 1
#define RUN_PART2 1
#define RUN_TEST2 0
#define RUN_PART2 0
#define TEST1_EXPECT 0x1227775554l
#define TEST2_EXPECT 0x4174379265l
void _start() {
void run() {
#if RUN_TEST1
print("PART 1 TEST: ");
if (bcdint v = do_part1(countof(test), test); v != TEST1_EXPECT) {
@@ -292,5 +292,5 @@ void _start() {
print("\n");
#endif
syscall(SYS_exit_group, 0);
exit_group(0);
}

130
day2_plasl.c Normal file
View File

@@ -0,0 +1,130 @@
#include "lib.h"
#define DBG 0
static
unsigned char input[] = {
#embed "day2_input.txt"
};
static
unsigned char test[] = {
#embed "day2_test.txt"
};
uint64_t ipow(uint64_t a, uint64_t b) {
uint64_t m = a;
for (;b;b--) m += a;
return m;
}
static
uint64_t range(uint64_t start, uint64_t end, uint64_t len) {
#if DBG
print("==\n");
printd(start); print(" "); printd(end); print("\n");
#endif
if ((len & 1) == 1) {
return 0;
}
uint64_t divisor = ipow(10, len / 2);
uint64_t first = (start + divisor - 1) / divisor;
uint64_t second = end / divisor;
#if DBG
print("\n");
printd(divisor); print("\n");
printd(first); print(" "); printd(second); print("\n");
#endif
uint64_t r = (((second + first) * (second + 1 - first)) / 2) * divisor;
#if DBG
printd(r); print("\n");
#endif
return r;
}
static
uint64_t do_part1(size_t file_len, unsigned char file[file_len]) {
unsigned char buffer[65535];
memcpy(buffer, file, file_len);
size_t size = file_len;
buffer[file_len-1] = ',';
uint64_t out = 0;
uint64_t i = 0;
while (i < size) {
#if DBG
print("--------------\n");
#endif
uint64_t startlen = 0, endlen = 0;
uint64_t start = grabnum(buffer+i, NULL);
while (buffer[i] != '-') {
i++;
startlen++;
}
i++;
uint64_t end = grabnum(buffer+i, NULL);
while (buffer[i] != ',') {
i++;
endlen++;
}
i++;
#if DBG
printd(startlen); print(" "); printd(start); print((char[]){ 10 });
printd(startlen); print(" "); printd(start); print((char[]){ 10 });
#endif
if (endlen != startlen) {
out += range(start, ipow(10, startlen) - 1, startlen)
+ range(ipow(10, startlen), end, endlen);
} else {
out += range(start, end, startlen);
}
#if DBG
print((char[]) { 10 });
#endif
}
return out;
}
#define RUN_TEST1 1
#define RUN_PART1 1
#define TEST1_EXPECT 0x1227775554l
void run() {
volatile uintptr_t s = (uintptr_t)&s;
printh(s);
print("\n");
#if RUN_TEST1
print("PART 1 TEST: ");
if (uint64_t v = do_part1(countof(test), test); v != TEST1_EXPECT) {
print("FAILED (got ");
printd(v);
print(", expected " xstr(TEST1_EXPECT) ")\n");
} else {
print("PASSED\n");
}
#endif
#if RUN_PART1
print("PART 1 RESULT: ");
printd(do_part1(countof(input), input));
print("\n");
#endif
exit_group(0);
}

14
day3.c
View File

@@ -8,7 +8,7 @@ unsigned char input[] = {
};
static
unsigned char test[] = {
unsigned char test_input[] = {
#embed "day3_test.txt"
};
@@ -78,15 +78,15 @@ unsigned long do_part2(size_t file_len, unsigned char file[file_len]) {
return result;
}
#define RUN_TEST1 1
#define RUN_PART1 1
#define RUN_TEST1 0
#define RUN_PART1 0
#define RUN_TEST2 1
#define RUN_PART2 1
#define TEST1_EXPECT 357
#define TEST2_EXPECT 3121910778619
#define TEST2_EXPECT 3121910778619l
void _start() {
void run() {
#if RUN_TEST1
print("PART 1 TEST: ");
if (unsigned long v = do_part1(countof(test), test); v != TEST1_EXPECT) {
@@ -106,7 +106,7 @@ void _start() {
#if RUN_TEST2
print("PART 2 TEST: ");
if (unsigned long v = do_part2(countof(test), test); v != TEST2_EXPECT) {
if (unsigned long v = do_part2(countof(test_input), test_input); v != TEST2_EXPECT) {
print("FAILED (got ");
printd(v);
print(", expected " xstr(TEST2_EXPECT) ")\n");
@@ -121,5 +121,5 @@ void _start() {
print("\n");
#endif
syscall(SYS_exit_group, 0);
exit_group(0);
}

207
day4.c Normal file
View File

@@ -0,0 +1,207 @@
#include "lib.h"
#define DBG 0
static
unsigned char input[] = {
#embed "day4_input.txt"
};
static
unsigned char test[] = {
#embed "day4_test.txt"
};
static
unsigned char buf[UINT16_MAX];
static
unsigned long do_part1(size_t file_len, unsigned char file[file_len]) {
unsigned char *s = file, *d = buf;
unsigned long result = 0;
#if DBG
print("\n");
#endif
unsigned file_stride;
while (*s != '\n') s++;
file_stride = s - file + 1;
s = file;
unsigned line_count = file_len / file_stride;
unsigned line_stride = file_stride + 1;
memset(d, '0', sizeof(buf));
#if DBG
printh(file_stride); print("\n");
printh(line_stride * (line_count + 2)); print("\n");
#endif
#if DBG
printns(line_stride, d); print("\n");
#endif
d += line_stride;
do {
memcpy(d + 1, s, file_stride - 1);
#if DBG
printns(line_stride, d); print("\n");
#endif
d += line_stride;
s += file_stride;
} while (s != &file[file_len]);
#if DBG
printns(line_stride, d); print("\n");
#endif
unsigned char *l = buf + line_stride + 1;
for (unsigned i = line_count; i; i--) {
d = l;
for (unsigned j = line_stride - 2; j; j--) {
if (*d == '@') {
unsigned neighbors = 0
+ (*(d - 1 - line_stride) == '@')
+ (*(d - 0 - line_stride) == '@')
+ (*(d + 1 - line_stride) == '@')
+ (*(d - 1 - 0) == '@')
+ (*(d + 1 - 0) == '@')
+ (*(d - 1 + line_stride) == '@')
+ (*(d - 0 + line_stride) == '@')
+ (*(d + 1 + line_stride) == '@');
if (neighbors < 4) {
result++;
}
}
d++;
}
l += line_stride;
}
return result;
}
static
unsigned long do_part2(size_t file_len, unsigned char file[file_len]) {
unsigned char *s = file, *d = buf;
unsigned long result = 0;
#if DBG
print("\n");
#endif
unsigned file_stride;
while (*s != '\n') s++;
file_stride = s - file + 1;
s = file;
unsigned line_count = file_len / file_stride;
unsigned line_stride = file_stride + 1;
memset(d, '0', sizeof(buf));
#if DBG
printh(file_stride); print("\n");
printh(line_stride * (line_count + 2)); print("\n");
#endif
#if DBG
printns(line_stride, d); print("\n");
#endif
d += line_stride;
do {
memcpy(d + 1, s, file_stride - 1);
#if DBG
printns(line_stride, d); print("\n");
#endif
d += line_stride;
s += file_stride;
} while (s != &file[file_len]);
#if DBG
printns(line_stride, d); print("\n");
#endif
unsigned char *l = buf + line_stride + 1;
for (unsigned i = line_count; i; i--) {
line_start:
d = l;
for (unsigned j = line_stride - 2; j; j--) {
if (*d == '@') {
unsigned neighbors = 0
+ (*(d - 1 - line_stride) == '@')
+ (*(d - 0 - line_stride) == '@')
+ (*(d + 1 - line_stride) == '@')
+ (*(d - 1 - 0) == '@')
+ (*(d + 1 - 0) == '@')
+ (*(d - 1 + line_stride) == '@')
+ (*(d - 0 + line_stride) == '@')
+ (*(d + 1 + line_stride) == '@');
if (neighbors < 4) {
*d = '.';
result++;
if (i > line_count-1) {
i = line_count;
l = buf + line_stride + 1;
goto line_start;
} else {
i += 1;
l -= line_stride * 1;
goto line_start;
}
}
}
d++;
}
l += line_stride;
}
return result;
}
#define RUN_TEST1 1
#define RUN_PART1 1
#define RUN_TEST2 1
#define RUN_PART2 1
#define TEST1_EXPECT 13
#define TEST2_EXPECT 43
void run() {
#if RUN_TEST1
print("PART 1 TEST: ");
if (unsigned long v = do_part1(countof(test), test); v != TEST1_EXPECT) {
print("FAILED (got ");
printd(v);
print(", expected " xstr(TEST1_EXPECT) ")\n");
} else {
print("PASSED\n");
}
#endif
#if RUN_PART1
print("PART 1 RESULT: ");
printd(do_part1(countof(input), input));
print("\n");
#endif
#if RUN_TEST2
print("PART 2 TEST: ");
if (unsigned long v = do_part2(countof(test), test); v != TEST2_EXPECT) {
print("FAILED (got ");
printd(v);
print(", expected " xstr(TEST2_EXPECT) ")\n");
} else {
print("PASSED\n");
}
#endif
#if RUN_PART2
print("PART 2 RESULT: ");
printd(do_part2(countof(input), input));
print("\n");
#endif
exit_group(0);
}

43
lib.h
View File

@@ -1,11 +1,30 @@
#pragma once
#include <stdlib.h>
#include <stddef.h>
#include <stdcountof.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#define SYS_write 1
#define SYS_exit_group 231
#define STDOUT_FILENO 1
static
void write(uint64_t fileno, void *buffer, size_t len) {
uint64_t a,d;
asm volatile("syscall"
:"=a"(a),"=d"(d):"a"(SYS_write),"D"(fileno),"S"(buffer),"d"(len):"memory");
}
[[noreturn]] static
void exit_group(uint64_t code) {
asm volatile(
"syscall\n"
"ud2"
::"a"(SYS_exit_group),"D"(code));
for (;;);
}
#define xstr(s) str(s)
#define str(s) #s
@@ -13,7 +32,7 @@ typedef uint64_t bcdint;
static
void printns(size_t len, unsigned char chars[len]) {
syscall(SYS_write, STDOUT_FILENO, chars, len);
write(STDOUT_FILENO, chars, len);
}
static
@@ -29,12 +48,12 @@ void printptr(uintptr_t v) {
}
v >>= 4;
}
syscall(SYS_write, STDOUT_FILENO, p, countof(buf));
write(STDOUT_FILENO, p, countof(buf));
}
static
void print_many_char(size_t len, char chars[len]) {
syscall(SYS_write, STDOUT_FILENO, chars, len);
write(STDOUT_FILENO, chars, len);
}
#define print(string) print_many_char(sizeof(string)-1, string)
@@ -54,7 +73,7 @@ void printd(unsigned long v) {
v /= 10;
count++;
}
syscall(SYS_write, STDOUT_FILENO, p, count);
write(STDOUT_FILENO, p, count);
}
static
@@ -76,7 +95,7 @@ void printh(unsigned long v) {
v >>= 4;
count++;
}
syscall(SYS_write, STDOUT_FILENO, p, count);
write(STDOUT_FILENO, p, count);
}
static
@@ -95,7 +114,7 @@ void print_hex_char(unsigned char v) {
buf[1] = 'A' - 0xA + (v & 0x0F);
}
syscall(SYS_write, STDOUT_FILENO, buf, sizeof(buf));
write(STDOUT_FILENO, buf, sizeof(buf));
}
static
@@ -125,11 +144,11 @@ bcdint grabbcd(unsigned char *s, unsigned char **end) {
}
static
unsigned grabnum(const char *s, const char **end) {
unsigned r = 0;
unsigned long grabnum(unsigned char *s, unsigned char **end) {
unsigned long r = 0;
for (; *s >= '0' && *s <= '9'; s++)
r = r * 10 + (*s - '0');
*end = s;
if (end) *end = s;
return r;
}

193
musl/COPYRIGHT Normal file
View File

@@ -0,0 +1,193 @@
musl as a whole is licensed under the following standard MIT license:
----------------------------------------------------------------------
Copyright © 2005-2020 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
Authors/contributors include:
A. Wilcox
Ada Worcester
Alex Dowad
Alex Suykov
Alexander Monakov
Andre McCurdy
Andrew Kelley
Anthony G. Basile
Aric Belsito
Arvid Picciani
Bartosz Brachaczek
Benjamin Peterson
Bobby Bingham
Boris Brezillon
Brent Cook
Chris Spiegel
Clément Vasseur
Daniel Micay
Daniel Sabogal
Daurnimator
David Carlier
David Edelsohn
Denys Vlasenko
Dmitry Ivanov
Dmitry V. Levin
Drew DeVault
Emil Renner Berthing
Fangrui Song
Felix Fietkau
Felix Janda
Gianluca Anzolin
Hauke Mehrtens
He X
Hiltjo Posthuma
Isaac Dunham
Jaydeep Patil
Jens Gustedt
Jeremy Huntwork
Jo-Philipp Wich
Joakim Sindholt
John Spencer
Julien Ramseier
Justin Cormack
Kaarle Ritvanen
Khem Raj
Kylie McClain
Leah Neukirchen
Luca Barbato
Luka Perkov
Lynn Ochs
M Farkas-Dyck (Strake)
Mahesh Bodapati
Markus Wichmann
Masanori Ogino
Michael Clark
Michael Forney
Mikhail Kremnyov
Natanael Copa
Nicholas J. Kain
orc
Pascal Cuoq
Patrick Oppenlander
Petr Hosek
Petr Skocik
Pierre Carrier
Reini Urban
Rich Felker
Richard Pennington
Ryan Fairfax
Samuel Holland
Segev Finer
Shiz
sin
Solar Designer
Stefan Kristiansson
Stefan O'Rear
Szabolcs Nagy
Timo Teräs
Trutz Behn
Will Dietz
William Haddon
William Pitcock
Portions of this software are derived from third-party works licensed
under terms compatible with the above MIT license:
The TRE regular expression implementation (src/regex/reg* and
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
under a 2-clause BSD license (license text in the source files). The
included version has been heavily modified by Rich Felker in 2012, in
the interests of size, simplicity, and namespace cleanliness.
Much of the math library code (src/math/* and src/complex/*) is
Copyright © 1993,2004 Sun Microsystems or
Copyright © 2003-2011 David Schultz or
Copyright © 2003-2009 Steven G. Kargl or
Copyright © 2003-2009 Bruce D. Evans or
Copyright © 2008 Stephen L. Moshier or
Copyright © 2017-2018 Arm Limited
and labelled as such in comments in the individual source files. All
have been licensed under extremely permissive terms.
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
The Android Open Source Project and is licensed under a two-clause BSD
license. It was taken from Bionic libc, used on Android.
The AArch64 memcpy and memset code (src/string/aarch64/*) are
Copyright © 1999-2019, Arm Limited.
The implementation of DES for crypt (src/crypt/crypt_des.c) is
Copyright © 1994 David Burren. It is licensed under a BSD license.
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
originally written by Solar Designer and placed into the public
domain. The code also comes with a fallback permissive license for use
in jurisdictions that may not recognize the public domain.
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
Lynn Ochs and is licensed under an MIT-style license.
The x86_64 port was written by Nicholas J. Kain and is licensed under
the standard MIT terms.
The mips and microblaze ports were originally written by Richard
Pennington for use in the ellcc project. The original code was adapted
by Rich Felker for build system and code conventions during upstream
integration. It is licensed under the standard MIT terms.
The mips64 port was contributed by Imagination Technologies and is
licensed under the standard MIT terms.
The powerpc port was also originally written by Richard Pennington,
and later supplemented and integrated by John Spencer. It is licensed
under the standard MIT terms.
All other files which have no copyright comments are original works
produced specifically for use as part of this library, written either
by Rich Felker, the main author of the library, or by one or more
contibutors listed above. Details on authorship of individual files
can be found in the git version control history of the project. The
omission of copyright and license comments in each file is in the
interest of source tree size.
In addition, permission is hereby granted for all public header files
(include/* and arch/*/bits/*) and crt files intended to be linked into
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
the copyright notice and permission notice otherwise required by the
license, and to use these files without any requirement of
attribution. These files include substantial contributions from:
Bobby Bingham
John Spencer
Nicholas J. Kain
Rich Felker
Richard Pennington
Stefan Kristiansson
Szabolcs Nagy
all of whom have explicitly granted such permission.
This file previously contained text expressing a belief that most of
the files covered by the above exception were sufficiently trivial not
to be subject to copyright, resulting in confusion over whether it
negated the permissions granted in the license. In the spirit of
permissive licensing, and of not having licensing issues being an
obstacle to adoption, that text has been removed.

25
musl/memcpy.s Normal file
View File

@@ -0,0 +1,25 @@
.global memcpy
.global __memcpy_fwd
.hidden __memcpy_fwd
.type memcpy,@function
memcpy:
__memcpy_fwd:
mov %rdi,%rax
cmp $8,%rdx
jc 1f
test $7,%edi
jz 1f
2: movsb
dec %rdx
test $7,%edi
jnz 2b
1: mov %rdx,%rcx
shr $3,%rcx
rep
movsq
and $7,%edx
jz 1f
2: movsb
dec %edx
jnz 2b
1: ret

72
musl/memset.s Normal file
View File

@@ -0,0 +1,72 @@
.global memset
.type memset,@function
memset:
movzbq %sil,%rax
mov $0x101010101010101,%r8
imul %r8,%rax
cmp $126,%rdx
ja 2f
test %edx,%edx
jz 1f
mov %sil,(%rdi)
mov %sil,-1(%rdi,%rdx)
cmp $2,%edx
jbe 1f
mov %ax,1(%rdi)
mov %ax,(-1-2)(%rdi,%rdx)
cmp $6,%edx
jbe 1f
mov %eax,(1+2)(%rdi)
mov %eax,(-1-2-4)(%rdi,%rdx)
cmp $14,%edx
jbe 1f
mov %rax,(1+2+4)(%rdi)
mov %rax,(-1-2-4-8)(%rdi,%rdx)
cmp $30,%edx
jbe 1f
mov %rax,(1+2+4+8)(%rdi)
mov %rax,(1+2+4+8+8)(%rdi)
mov %rax,(-1-2-4-8-16)(%rdi,%rdx)
mov %rax,(-1-2-4-8-8)(%rdi,%rdx)
cmp $62,%edx
jbe 1f
mov %rax,(1+2+4+8+16)(%rdi)
mov %rax,(1+2+4+8+16+8)(%rdi)
mov %rax,(1+2+4+8+16+16)(%rdi)
mov %rax,(1+2+4+8+16+24)(%rdi)
mov %rax,(-1-2-4-8-16-32)(%rdi,%rdx)
mov %rax,(-1-2-4-8-16-24)(%rdi,%rdx)
mov %rax,(-1-2-4-8-16-16)(%rdi,%rdx)
mov %rax,(-1-2-4-8-16-8)(%rdi,%rdx)
1: mov %rdi,%rax
ret
2: test $15,%edi
mov %rdi,%r8
mov %rax,-8(%rdi,%rdx)
mov %rdx,%rcx
jnz 2f
1: shr $3,%rcx
rep
stosq
mov %r8,%rax
ret
2: xor %edx,%edx
sub %edi,%edx
and $15,%edx
mov %rax,(%rdi)
mov %rax,8(%rdi)
sub %rdx,%rcx
add %rdx,%rdi
jmp 1b

7
start.s Normal file
View File

@@ -0,0 +1,7 @@
extern run
global _start
_start:
sub rsp,0x1000
and rsp,~0xfff
call run
ud2