135 lines
2.1 KiB
ArmAsm
135 lines
2.1 KiB
ArmAsm
.global _start
|
|
_start:
|
|
mova stack_top,r0
|
|
mov r0,r15
|
|
|
|
/* part1 */
|
|
mova _part1,r0
|
|
mov r0,r14
|
|
mova solve,r0
|
|
jsr @r0
|
|
nop
|
|
/* move part1 answer to GBR */
|
|
ldc r13,gbr
|
|
|
|
/* part2 */
|
|
mova _part2,r0
|
|
mov r0,r14
|
|
mova solve,r0
|
|
jsr @r0
|
|
nop
|
|
/* move part2 answer to VBR */
|
|
ldc r13,vbr
|
|
|
|
trapa #0
|
|
|
|
/* return number of valid passwords in r13 */
|
|
.balign 4
|
|
solve:
|
|
sts.l pr,@-r15
|
|
|
|
mov.l start,r8
|
|
mov.l end,r9
|
|
|
|
/* password is from r1 to r8, excluding r8; next line is at r8 */
|
|
mov #0,r13
|
|
line_loop:
|
|
mova _parse_line,r0
|
|
jsr @r0
|
|
nop
|
|
jsr @r14
|
|
nop
|
|
cmp/eq r8,r9
|
|
bf/s line_loop
|
|
add r1,r13
|
|
|
|
lds.l @r15+,pr
|
|
rts
|
|
nop
|
|
|
|
/* return: valid as `1` in r1 */
|
|
/* r10: test position 1 */
|
|
/* r11: test position 2 */
|
|
/* r12: test character */
|
|
.balign 4
|
|
_part2:
|
|
add #-1,r1 /* offset for 1-based indexing */
|
|
mov r10,r0
|
|
mov.b @(r0,r1),r3 /* r3: character */
|
|
cmp/eq r3,r12
|
|
movt r2
|
|
mov r11,r0
|
|
mov.b @(r0,r1),r3 /* r3: character */
|
|
cmp/eq r3,r12
|
|
movt r1
|
|
rts
|
|
xor r2,r1
|
|
|
|
/* return: valid as `1` in r1 */
|
|
/* r10: count >= lower bound */
|
|
/* r11: count <= upper bound */
|
|
/* r12: test character */
|
|
.balign 4
|
|
_part1:
|
|
mov #0,r2 /* r2: count */
|
|
part1_loop:
|
|
cmp/eq r1,r8
|
|
bt part1_break
|
|
mov.b @r1+,r3 /* r3: character */
|
|
cmp/eq r3,r12
|
|
movt r0
|
|
bra part1_loop
|
|
add r0,r2
|
|
part1_break:
|
|
/* lower bound */
|
|
cmp/hs r10,r2 /* Rn ≥ Rm (unsigned) ; r2 >= r10 */
|
|
movt r0
|
|
cmp/hs r2,r11 /* Rn ≥ Rm (unsigned) ; r11 >= r2 */
|
|
movt r1
|
|
rts
|
|
and r0,r1
|
|
|
|
.balign 4
|
|
_parse_line:
|
|
/* save PR */
|
|
sts.l pr,@-r15
|
|
|
|
mov.l parse_base10_ptr,r0
|
|
jsr @r0
|
|
nop
|
|
mov r1,r10 /* r10: first number */
|
|
mov.l parse_base10_ptr,r0
|
|
jsr @r0
|
|
nop
|
|
mov r1,r11 /* r11: second number */
|
|
|
|
mov.b @r8+,r12 /* r12: character */
|
|
/* skip colon character ; skip space character */
|
|
add #2,r8
|
|
/* advance until newline */
|
|
mov r8,r1
|
|
newline_loop:
|
|
mov.b @r8+,r0
|
|
cmp/eq #0xa,r0
|
|
bf newline_loop
|
|
|
|
/* restore PR */
|
|
lds.l @r15+,pr
|
|
rts
|
|
nop
|
|
|
|
.balign 4
|
|
parse_base10_ptr: /* r8 = pointer to text ; r1 = returned number */
|
|
.long _parse_base10
|
|
|
|
.balign 4
|
|
start: .long _binary_2020_day2_input_txt_start
|
|
end: .long _binary_2020_day2_input_txt_end
|
|
|
|
.balign 4
|
|
stack_bot:
|
|
.rept 16
|
|
.long 0
|
|
.endr
|
|
stack_top:
|