Skip to content

Instantly share code, notes, and snippets.

@wheremyfoodat
Last active December 3, 2021 20:29
Show Gist options
  • Save wheremyfoodat/c0516875893d5a0823e9613ca69acc8b to your computer and use it in GitHub Desktop.
Save wheremyfoodat/c0516875893d5a0823e9613ca69acc8b to your computer and use it in GitHub Desktop.
Day 2 of AoC in aa64
#include <iostream>
__attribute__ ((naked)) void asm_main() {
__asm__ volatile (R"(
// x19: Pointer to file
// x20: xpos
// x21: depth
// x22: aim
part1:
stp x19, x30, [sp, -16]! // save return address and x19, lower stack
stp x20, x21, [sp, -16]! // Back up x20 and x21 for use too
stp x22, x23, [sp, -16]! // Same for x22 and x23
sub sp, sp, 32 // Reserve some stack space for whatever use
sub sp, sp, 4096 // Reserve 4096 bytes for strings
mov x20, 0 // Init depth and xpos to 0
mov x21, 0
adr x0, filename
adr x1, file_perms
bl fopen // x0 = file pointer
mov x19, x0
loop:
bl feof // Check for eof as a sanity check
cbnz x0, end
mov x0, x19
adr x1, input_fmt // Read entry
add x2, sp, 4096
add x3, x2, 32
bl fscanf
add x0, sp, 4096 // Check if string is "up"
adr x1, up_str
bl string_cmp
cbz w0, is_up
add x0, sp, 4096 // Check if string is "down"
adr x1, down_str
bl string_cmp
cbz w0, is_down
// if it's none of those then it's forward
ldr w0, [sp, 4096 + 32]
add w20, w20, w0 // add to xpos
mov x0, x19 // x0 = file
b loop
end:
// print result
adr x0, result1_fmt
mul w1, w20, w21 // result = xpos * depth
mov w2, w20
mov w3, w21
bl printf
part2:
// Reset depth, xpos and aim
mov w20, 0
mov w21, 0
mov w22, 0
// Rewind filestream
mov x0, x19
bl rewind
mov x0, x19
loop2:
bl feof // Check for eof as a sanity check
cbnz x0, end2
mov x0, x19
adr x1, input_fmt // Read entry
add x2, sp, 4096
add x3, x2, 32
bl fscanf
add x0, sp, 4096 // Check if string is "up"
adr x1, up_str
bl string_cmp
cbz w0, is_up2
add x0, sp, 4096 // Check if string is "down"
adr x1, down_str
bl string_cmp
cbz w0, is_down2
// if it's none of those then it's forward
ldr w0, [sp, 4096 + 32]
add w20, w20, w0 // add to xpos
mul w0, w0, w22 // w0 = aim * number
add w21, w21, w0 // add to depth
mov x0, x19 // x0 = file
b loop2
end2:
// print result
adr x0, result2_fmt
mul w1, w20, w21 // result = xpos * depth
mov w2, w20
mov w3, w21
mov w4, w22
bl printf
// undo the mess we made
cleanup:
add sp, sp, 4096
add sp, sp, 32
ldp x22, x23, [sp], 16
ldp x20, x21, [sp], 16
ldp x19, x30, [sp], 16
ret
is_up:
ldr w0, [sp, 4096 + 32]
sub w21, w21, w0 // sub from depth
mov x0, x19 // x0 = file
b loop
is_down:
ldr w0, [sp, 4096 + 32]
add w21, w21, w0 // add to depth
mov x0, x19 // x0 = file
b loop
is_up2:
ldr w0, [sp, 4096 + 32]
sub w22, w22, w0 // sub from aim
mov x0, x19 // x0 = file
b loop2
is_down2:
ldr w0, [sp, 4096 + 32]
add w22, w22, w0 // add to aim
mov x0, x19 // x0 = file
b loop2
// bool string_cmp (const char* a, const char* b)
// w0 = 0 if equal, w0 = 1 if not equal
string_cmp:
ldrb w2, [x0], 1 // Read char from string 1
ldrb w3, [x1], 1 // Read char from string 2
cmp w2, w3 // If the characters are not equal then the strings are not equal
b.ne not_equal
cbz w2, equal // If they're equal and one of them is the null terminator, the strings are equal
b string_cmp
not_equal:
mov w0, 1
ret
equal:
mov w0, 0
ret
filename:
.asciz "input.in"
file_perms:
.asciz "r"
input_fmt:
.asciz "%s %d\n"
result1_fmt:
.asciz "Result of part 1: %d\nXpos: %d Depth: %d\n"
result2_fmt:
.asciz "Result of part 2: %d\nXpos: %d Depth: %d\nAim: %d\n"
down_str:
.asciz "down"
up_str:
.asciz "up"
)");
}
int main() {
asm_main();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment