diff --git a/solutions/arm64-assembly/acronym/1/acronym.s b/solutions/arm64-assembly/acronym/1/acronym.s new file mode 100644 index 0000000..0f71949 --- /dev/null +++ b/solutions/arm64-assembly/acronym/1/acronym.s @@ -0,0 +1,33 @@ +// For Shree DR.MDD + +.text +.globl abbreviate + +abbreviate: + ldrb w5, [x1], #1 /* load byte, post-increment */ + cbz w5, .done_abbrev + + and w6, w5, #-33 /* force upper case */ + sub w7, w6, #'A' + cmp w7, #26 + bhs abbreviate /* jump if word has not yet started */ + + strb w6, [x0], #1 /* store byte, post-increment */ + +.scan_word: + ldrb w5, [x1], #1 /* load next byte */ + cbz w5, .done_abbrev + + cmp w5, #'\'' /* check for apostrophe */ + beq .scan_word + + and w6, w5, #-33 /* force upper case */ + sub w7, w6, #'A' + cmp w7, #26 + blo .scan_word /* keep scanning if letter */ + + b abbreviate /* move to next word */ + +.done_abbrev: + strb wzr, [x0] /* null-terminate output */ + ret diff --git a/solutions/arm64-assembly/affine-cipher/1/affine_cipher.s b/solutions/arm64-assembly/affine-cipher/1/affine_cipher.s new file mode 100644 index 0000000..c0072e6 --- /dev/null +++ b/solutions/arm64-assembly/affine-cipher/1/affine_cipher.s @@ -0,0 +1,68 @@ +// Dedicated to Shree DR.MDD + +.data +inverses: .byte 0, 1, 0, 9, 0, 21, 0, 15, 0, 3, 0, 19, 0, 0, 0, 7, 0, 23, 0, 11, 0, 5, 0, 17, 0, 25 + +.text +.globl encode +.globl decode + +encode: + adrp x14, inverses + add x14, x14, :lo12:inverses + ldrb w11, [x14, x2] + cbz w11, finish + + mov w11, w2 + mov w12, w3 + mov x2, #5 + b cipher_loop + +decode: + adrp x14, inverses + add x14, x14, :lo12:inverses + ldrb w11, [x14, x2] + cbz w11, finish + + sub w12, w3, #4082 + mneg w12, w12, w11 + mov x2, #-1 + b cipher_loop + +finish: + strb wzr, [x0] + ret + +cipher_loop: + mov x13, x2 + mov w8, #' ' + mov w9, #26 + +input_read: + ldrb w5, [x1], #1 + cbz w5, finish + + sub w10, w5, #'0' + cmp w10, #10 + blo .process_char + + orr w10, w5, #32 + sub w10, w10, #'a' + cmp w10, w9 + bhs input_read + + madd w10, w11, w10, w12 + udiv w15, w10, w9 + msub w5, w15, w9, w10 + add w5, w5, #'a' + +.process_char: + cbnz x13, .store_char + + strb w8, [x0], #1 + mov x13, x2 + +.store_char: + strb w5, [x0], #1 + sub x13, x13, 1 + b input_read diff --git a/solutions/arm64-assembly/all-your-base/1/all_your_base.s b/solutions/arm64-assembly/all-your-base/1/all_your_base.s new file mode 100644 index 0000000..fd62ce5 --- /dev/null +++ b/solutions/arm64-assembly/all-your-base/1/all_your_base.s @@ -0,0 +1,60 @@ +.equ BAD_BASE, -1 +.equ BAD_DIGIT, -2 + +.text +.globl rebase + +rebase: + cmp w0,#1 + b.le badbase + cmp w3,#1 + b.le badbase + eor x6,x6,x6 +inbaseloop: + cbz x2,outbase + ldr w5,[x1],#4 + cmp w5,#0 + b.lt baddigit + cmp w5,w0 + b.ge baddigit + madd w6,w6,w0,w5 + sub x2,x2,#1 + b.al inbaseloop +outbase: + mov x5,#0 + eor x9,x9,x9 +outbaseloop: + add x5,x5,#1 + udiv x7,x6,x3 + msub x8,x7,x3,x6 + str w8,[x4,x9] + cbz x7,reverse + mov x6,x7 + add x9,x9,#4 + b.al outbaseloop +reverse: + lsl x9,x5,#2 + sub x9,x9,#4 + eor x6,x6,x6 + mov x10,x5 + lsr x5,x5,#1 + cbz x5,endofproc +reverseloop: + ldr w7,[x4,x6] + ldr w8,[x4,x9] + str w7,[x4,x9] + str w8,[x4,x6] + add x6,x6,#4 + sub x9,x9,#4 + sub x5,x5,#1 + cbnz x5,reverseloop +endofproc: + mov x0,x10 + ret +badbase: + mov x0,BAD_BASE + ret +baddigit: + mov x0,BAD_DIGIT + ret + \ No newline at end of file diff --git a/solutions/arm64-assembly/allergies/1/allergies.s b/solutions/arm64-assembly/allergies/1/allergies.s new file mode 100644 index 0000000..0d8671d --- /dev/null +++ b/solutions/arm64-assembly/allergies/1/allergies.s @@ -0,0 +1,39 @@ +.text +.equ MAX_ITEMS, 8 + +.globl allergic_to +.globl list + +allergic_to: + mov x2, #1 + lsl x2, x2, x0 + and x0, x2, x1 + ret + +list: + mov x3, xzr + and x0, x0, #0xFF + cbz x0, .return + + mov x2, xzr + mov x4, #1 + +.next: + cmp x2, #MAX_ITEMS + beq .return + lsl x5, x4, x2 + and x6, x0, x5 + cbnz x6, .add + add x2, x2, #1 + b .next + +.add: + add x3, x3, #1 + lsl x6, x3, #2 + str w2, [x1, x6] + add x2, x2, #1 + b .next + +.return: + str w3, [x1] + ret diff --git a/solutions/arm64-assembly/anagram/1/anagram.s b/solutions/arm64-assembly/anagram/1/anagram.s new file mode 100644 index 0000000..849ff09 --- /dev/null +++ b/solutions/arm64-assembly/anagram/1/anagram.s @@ -0,0 +1,86 @@ +.text +.globl find_anagrams + +find_anagrams: + eor x5,x5,x5 +mainloop1: + ldrb w4,[x3,x5] + cbz w4,addcandidatemaybe + cmp w4,'A' + b.lt lower1 + cmp w4,'Z' + b.gt lower1 + add w4,w4,32 +lower1: + eor x8,x8,x8 + eor x9,x9,x9 + mov x6,x3 +innerloop2: + ldrb w7,[x6],#1 + cbz w7,endofinner2 + cmp w7,'A' + b.lt lower2 + cmp w7,'Z' + b.gt lower2 + add w7,w7,32 +lower2: + cmp w4,w7 + b.ne notequal2 + add x8,x8,#1 +notequal2: + add x9,x9,#1 + b.al innerloop2 +endofinner2: + ldr x6,[x1] +innerloop3: + ldrb w7,[x6],#1 + cbz w7,endofinner3 + cmp w7,'A' + b.lt lower3 + cmp w7,'Z' + b.gt lower3 + add w7,w7,32 +lower3: + cmp w4,w7 + b.ne notequal3 + sub x8,x8,#1 +notequal3: + sub x9,x9,#1 + b.al innerloop3 +endofinner3: + eor x4,x4,x4 + cbnz x8, donotadd + cbnz x9, donotadd + add x5,x5,#1 + b.al mainloop1 +addcandidatemaybe: + eor x5,x5,x5 + ldr x6,[x1] +cmploop: + ldrb w4, [x3, x5] + cbz w4,donotadd + ldrb w7, [x6, x5] + cmp w4,'A' + b.lt lower4 + cmp w4,'Z' + b.gt lower4 + add w4,w4,32 +lower4: + cmp w7,'A' + b.lt lower5 + cmp w7,'Z' + b.gt lower5 + add w7,w7,32 +lower5: + add x5,x5,#1 + cmp w4,w7 + b.eq cmploop +addcandidate: + mov x4,#1 +donotadd: + eor x5,x5,x5 + str w4,[x0],#4 + add x1,x1,#8 + sub x2,x2,#1 + cbnz x2,mainloop1 + ret \ No newline at end of file diff --git a/solutions/arm64-assembly/armstrong-numbers/1/armstrong_numbers.s b/solutions/arm64-assembly/armstrong-numbers/1/armstrong_numbers.s new file mode 100644 index 0000000..fbae345 --- /dev/null +++ b/solutions/arm64-assembly/armstrong-numbers/1/armstrong_numbers.s @@ -0,0 +1,40 @@ +// Dedicated to Shree DR.MDD + +.text +.globl is_armstrong_number + +is_armstrong_number: + mov x1, #10 + mov x8, x0 /* number */ + mov x11, xzr /* digit count */ + mov x12, xzr /* sum of digit powers */ + +.count_digits_loop: + add x11, x11, #1 + udiv x0, x0, x1 + cbnz x0, .count_digits_loop + + mov x0, x8 + +.extract_loop: + udiv x2, x0, x1 + msub x3, x2, x1, x0 + mov x0, x2 + mov x13, #1 + mov x14, x11 + +.power_loop: + mul x7, x13, x3 + tst x14, #1 + csel x13, x7, x13, ne + + mul x3, x3, x3 + lsr x14, x14, #1 + cbnz x14, .power_loop + + add x12, x12, x13 + cbnz x2, .extract_loop + + cmp x12, x8 + cset x0, eq + ret diff --git a/solutions/arm64-assembly/atbash-cipher/1/atbash_cipher.s b/solutions/arm64-assembly/atbash-cipher/1/atbash_cipher.s new file mode 100644 index 0000000..6816d78 --- /dev/null +++ b/solutions/arm64-assembly/atbash-cipher/1/atbash_cipher.s @@ -0,0 +1,51 @@ +// Dedicated to Shree DR.MDD + +.text +.globl encode +.globl decode + +encode: + mov x9, #5 + b core_process + ret + +decode: + mov x9, #-1 + b core_process + +core_process: + mov x10, x9 + mov w14, #' ' + mov w15, #'z' + +read_loop: + ldrb w12, [x1], #1 + cbz w12, end_loop + + sub w13, w12, #'0' + cmp w13, #10 + blo accept_char + + orr w13, w12, #32 + sub w13, w13, #'a' + cmp w13, #26 + bhs read_loop + + sub w13, w15, w13 + and w12, w12, #32 + orr w12, w12, w13 + +accept_char: + cbnz x10, write_char + + strb w14, [x0], #1 + mov x10, x9 + +write_char: + strb w12, [x0], #1 + sub x10, x10, 1 + b read_loop + +end_loop: + strb w12, [x0] + ret diff --git a/solutions/arm64-assembly/binary-search/1/binary_search.s b/solutions/arm64-assembly/binary-search/1/binary_search.s new file mode 100644 index 0000000..96eff1a --- /dev/null +++ b/solutions/arm64-assembly/binary-search/1/binary_search.s @@ -0,0 +1,38 @@ +// Dedicated to Shree DR.MDD + +.text +.globl find + +find: + mov x6, #0 + lsl x7, x2, #1 + +.loop_search: + cmp x6, x7 + beq .not_found + + add x8, x6, x7 + lsr x8, x8, #2 + lsl x8, x8, #1 + ldrh w9, [x1, x8] + + cmp w9, w0 + bgt .upper_half + + cmp w9, w0 + blt .lower_half + + lsr x0, x8, #1 + ret + +.not_found: + mov x0, #-1 + ret + +.upper_half: + mov x7, x8 + b .loop_search + +.lower_half: + add x6, x8, #2 + b .loop_search diff --git a/solutions/arm64-assembly/bob/1/bob.s b/solutions/arm64-assembly/bob/1/bob.s new file mode 100644 index 0000000..a1bde9f --- /dev/null +++ b/solutions/arm64-assembly/bob/1/bob.s @@ -0,0 +1,62 @@ +// Dedicated to Shree DR.MDD + +.section .rodata +sure: .string "Sure." +whoa: .string "Whoa, chill out!" +calm: .string "Calm down, I know what I'm doing!" +fine: .string "Fine. Be that way!" +whatever: .string "Whatever." + +.text +.globl response + +response: + mov x5, #0 /* most recent non-whitespace character */ + mov x6, #0 /* count upper case */ + mov x7, #0 /* count lower case */ + +.scan_loop: + ldrb w1, [x0], #1 + cbz x1, .choose_response + + cmp x1, #' ' + ble .scan_loop + + mov x5, x1 + sub x1, x1, #'A' + cmp x1, #26 + cinc x6, x6, lo + + sub x1, x1, #32 + cmp x1, #26 + cinc x7, x7, lo + + b .scan_loop + +.choose_response: + cbz x5, .handle_silence + + cbnz x7, .handle_normal + cbz x6, .handle_normal + + adrp x6, calm + add x6, x6, :lo12:calm + adrp x7, whoa + add x7, x7, :lo12:whoa + cmp x5, #'?' + csel x0, x6, x7, eq + ret + +.handle_normal: + adrp x6, sure + add x6, x6, :lo12:sure + adrp x7, whatever + add x7, x7, :lo12:whatever + cmp x5, #'?' + csel x0, x6, x7, eq + ret + +.handle_silence: + adrp x0, fine + add x0, x0, :lo12:fine + ret diff --git a/solutions/arm64-assembly/book-store/1/book_store.s b/solutions/arm64-assembly/book-store/1/book_store.s new file mode 100644 index 0000000..d49cfbe --- /dev/null +++ b/solutions/arm64-assembly/book-store/1/book_store.s @@ -0,0 +1,104 @@ +.text +.globl total + +count: + lsl x0, x0, #1 + cbz x0, .return + +.loop: + sub x0, x0, #2 + ldrh w10, [x1, x0] + lsl w10, w10, #1 + ldrh w11, [x2, x10] + add w11, w11, #1 + strh w11, [x2, x10] + cbnz x0, .loop + +.return: + ret + +sort: + mov w9, #4 + +.outer: + ldrh w12, [x0, x9] + mov w10, w9 + +.inner: + sub w11, w10, #2 + cbz w11, .exit + ldrh w13, [x0, x11] + cmp w13, w12 + bge .exit + strh w13, [x0, x10] + mov w10, w11 + b .inner + +.exit: + strh w12, [x0, x10] + add w9, w9, #2 + cmp w9, #10 + ble .outer + ret + +difference: + ldrh w10, [x0, #10] + ldrh w11, [x0, #8] + sub w12, w11, w10 + strh w12, [x0, #8] + ldrh w10, [x0, #6] + sub w12, w10, w11 + strh w12, [x0, #6] + ldrh w11, [x0, #4] + sub w12, w11, w10 + strh w12, [x0, #4] + ldrh w10, [x0, #2] + sub w12, w10, w11 + strh w12, [x0, #2] + ret + +adjust: + ldrh w11, [x0, #6] + ldrh w12, [x0, #8] + ldrh w13, [x0, #10] + cmp w11, w13 + csel w14, w11, w13, lt + sub w11, w11, w14 + sub w13, w13, w14 + lsl w14, w14, #1 + add w12, w12, w14 + strh w11, [x0, #6] + strh w12, [x0, #8] + strh w13, [x0, #10] + ret + +score: + ldrh w11, [x0, #2] + mov w10, #800 + mul w12, w10, w11 + ldrh w11, [x0, #4] + mov w10, #1520 + madd w12, w10, w11, w12 + ldrh w11, [x0, #6] + mov w10, #2160 + madd w12, w10, w11, w12 + ldrh w11, [x0, #8] + mov w10, #2560 + madd w12, w10, w11, w12 + ldrh w11, [x0, #10] + mov w10, #3000 + madd w0, w10, w11, w12 + ret + +total: + mov x15, lr + stp xzr, xzr, [sp, #-16]! + mov x2, sp + bl count + mov x0, sp + bl sort + bl difference + bl adjust + bl score + add sp, sp, #16 + ret x15 diff --git a/solutions/arm64-assembly/bottle-song/1/bottle_song.s b/solutions/arm64-assembly/bottle-song/1/bottle_song.s new file mode 100644 index 0000000..227e52a --- /dev/null +++ b/solutions/arm64-assembly/bottle-song/1/bottle_song.s @@ -0,0 +1,114 @@ +.data + +green_bottles: + .string " green bottles hanging on the wall" +green_bottle: + .string " green bottle hanging on the wall" +and: + .string "And if one green bottle should accidentally fall,\nThere'll be " +comma: .string ",\n" +stop: .string ".\n" + +no: .string "No" +one: .string "One" +two: .string "Two" +three: .string "Three" +four: .string "Four" +five: .string "Five" +six: .string "Six" +seven: .string "Seven" +eight: .string "Eight" +nine: .string "Nine" +ten: .string "Ten" + +number_array: + .dword no + .dword one + .dword two + .dword three + .dword four + .dword five + .dword six + .dword seven + .dword eight + .dword nine + .dword ten + +.macro LOAD register, label + adrp \register, \label + add \register, \register, :lo12:\label +.endm + +.macro APPEND str + +.copy_\str: + ldrb w15, [x14], #1 /* load byte, with post-increment */ + strb w15, [x0], #1 /* store byte, post-increment */ + cbnz w15, .copy_\str + + sub x0, x0, #1 +.endm + +.text +.globl recite + +/* extern void recite(char *buffer, int start_bottles, int take_down); */ +recite: + LOAD x3, green_bottles + LOAD x4, green_bottle + LOAD x5, and + LOAD x6, comma + LOAD x7, stop + LOAD x8, number_array + + lsl x1, x1, #3 + lsl x2, x2, #3 + sub x2, x1, x2 /* end bottles */ + +.verse: + ldr x14, [x8, x1] + APPEND number1 + + cmp x1, #8 + csel x14, x4, x3, eq + APPEND green1 + + mov x14, x6 + APPEND comma1 + + ldr x14, [x8, x1] + APPEND number2 + + cmp x1, #8 + csel x14, x4, x3, eq + APPEND green2 + + mov x14, x6 + APPEND comma2 + + mov x14, x5 + APPEND and + + sub x1, x1, #8 + ldr x14, [x8, x1] + ldrb w15, [x14], #1 /* load byte, with post-increment */ + orr w15, w15, #32 /* force lower case */ + strb w15, [x0], #1 /* store byte, post-increment */ + APPEND number3 + + cmp x1, #8 + csel x14, x4, x3, eq + APPEND green3 + + mov x14, x7 + APPEND stop1 + + cmp x1, x2 + beq .return + + mov w15, #'\n' + strb w15, [x0], #1 + b .verse + +.return: + ret \ No newline at end of file diff --git a/solutions/arm64-assembly/collatz-conjecture/1/collatz_conjecture.s b/solutions/arm64-assembly/collatz-conjecture/1/collatz_conjecture.s new file mode 100644 index 0000000..f488870 --- /dev/null +++ b/solutions/arm64-assembly/collatz-conjecture/1/collatz_conjecture.s @@ -0,0 +1,37 @@ +// Dedicated to Shree DR.MDD + +.equ INVALID_NUMBER, -1 + +.text +.globl steps + +steps: + subs xzr, x0, #0 + b.le steps.fail + eor x1, x1, x1 + + .loop: + subs xzr, x0, #1 + b.eq .finish + add x1, x1, #1 + ands xzr, x0, #1 + b.eq steps.even + b steps.odd + + .finish: + mov x0, x1 + ret + +steps.even: + lsr x0, x0, #1 + b .loop + +steps.odd: + mov x2, #3 + mov x3, #1 + madd x0, x0, x2, x3 + b .loop + +steps.fail: + mov x0, INVALID_NUMBER + ret diff --git a/solutions/arm64-assembly/crypto-square/1/crypto_square.s b/solutions/arm64-assembly/crypto-square/1/crypto_square.s new file mode 100644 index 0000000..0e91e2d --- /dev/null +++ b/solutions/arm64-assembly/crypto-square/1/crypto_square.s @@ -0,0 +1,88 @@ +.text +.globl ciphertext + +ciphertext: + mov w8, wzr + mov x9, x1 + b .scan + +.count: + sub w11, w10, #'0' + cmp w11, #10 + blo .accept + + orr w10, w10, #32 + sub w10, w10, #'a' + cmp w10, #26 + bhs .scan + +.accept: + add w8, w8, #1 + +.scan: + ldrb w10, [x9], #1 + cbnz w10, .count + + strb wzr, [x0] + cbz w8, .return + + mov w12, wzr + b .square + +.increment_columns: + add w12, w12, #1 + +.square: + mul w9, w12, w12 + cmp w9, w8 + blt .increment_columns + + add w13, w12, #-1 + mul w9, w13, w12 + cmp w9, w8 + csel w13, w12, w13, lt + + mul w14, w13, w12 + add w14, w14, w12 + add w14, w14, #-1 + + strb wzr, [x0, x14] + mov w7, #' ' + +.space: + add w14, w14, #-1 + strb w7, [x0, x14] + cbnz w14, .space + + add w13, w13, #1 + +.next_row: + mov w7, w12 + mov w6, wzr + +.read: + ldrb w10, [x1], #1 + sub w11, w10, #'0' + cmp w11, #10 + blo .write + + orr w10, w10, #32 + sub w11, w10, #'a' + cmp w11, #26 + bhs .read + +.write: + strb w10, [x0, x6] + + add w8, w8, #-1 + cbz w8, .return + + add w6, w6, w13 + add w7, w7, #-1 + cbnz w7, .read + + add x0, x0, #1 + b .next_row + +.return: + ret diff --git a/solutions/arm64-assembly/darts/1/darts.s b/solutions/arm64-assembly/darts/1/darts.s new file mode 100644 index 0000000..649ddf5 --- /dev/null +++ b/solutions/arm64-assembly/darts/1/darts.s @@ -0,0 +1,39 @@ +// Dedicated to Shree DR.MDD + +.text +.globl score + +score: + fmul d3, d0, d0 + fmadd d3, d1, d1, d3 + + mov w10, #100 + ucvtf d4, w10 + fcmpe d3, d4 + bgt .ret_zero + + mov w10, #25 + ucvtf d4, w10 + fcmpe d3, d4 + bgt .ret_one + + mov w10, #1 + ucvtf d4, w10 + fcmpe d3, d4 + bgt .ret_five + +.ret_ten: + mov x0, #10 + ret + +.ret_five: + mov x0, #5 + ret + +.ret_one: + mov x0, #1 + ret + +.ret_zero: + mov x0, #0 + ret diff --git a/solutions/arm64-assembly/diamond/1/diamond.s b/solutions/arm64-assembly/diamond/1/diamond.s new file mode 100644 index 0000000..d9c80be --- /dev/null +++ b/solutions/arm64-assembly/diamond/1/diamond.s @@ -0,0 +1,48 @@ +// Dedicated to Shree DR.MDD + +.text +.globl rows + +rows: + mov w16, #' ' + mov w17, #'\n' + mov x20, x0 + sub w5, w1, #'A' + lsl w6, w5, #1 + add w6, w6, #1 + add w7, w6, #2 + mov w8, w6 + +.row_loop: + mov w9, w6 + +.column_loop: + strb w16, [x20], #1 + sub w9, w9, #1 + cbnz w9, .column_loop + + strb w17, [x20], #1 + sub w8, w8, #1 + cbnz w8, .row_loop + + strb wzr, [x20], #-2 + mov w18, #'A' + add x21, x0, x5 + mov x22, x21 + sub x23, x20, x5 + mov x24, x23 + +.letter_loop: + strb w18, [x21] + strb w18, [x22] + strb w18, [x23] + strb w18, [x24] + add x21, x21, x6 + add x22, x22, x7 + sub x23, x23, x7 + sub x24, x24, x6 + add w18, w18, #1 + cmp w18, w1 + ble .letter_loop + + ret diff --git a/solutions/arm64-assembly/difference-of-squares/1/difference_of_squares.s b/solutions/arm64-assembly/difference-of-squares/1/difference_of_squares.s new file mode 100644 index 0000000..d55eb88 --- /dev/null +++ b/solutions/arm64-assembly/difference-of-squares/1/difference_of_squares.s @@ -0,0 +1,34 @@ +// Dedicated to Shree DR.MDD + +.text +.globl square_of_sum +.globl sum_of_squares +.globl difference_of_squares + +square_of_sum: + add x5, x0, #1 + mul x0, x0, x5 + lsr x0, x0, #1 + mul x0, x0, x0 + ret + +sum_of_squares: + add x5, x0, #1 + mul x6, x0, x5 + add x0, x0, x5 + mul x0, x0, x6 + mov x5, #6 + udiv x0, x0, x5 + ret + +difference_of_squares: + add x5, x0, #1 + add x6, x0, x5 + mul x0, x0, x5 + lsr x0, x0, #1 + mul x6, x0, x6 + mov x5, #3 + udiv x6, x6, x5 + mul x0, x0, x0 + sub x0, x0, x6 + ret diff --git a/solutions/arm64-assembly/dominoes/1/dominoes.s b/solutions/arm64-assembly/dominoes/1/dominoes.s new file mode 100644 index 0000000..1b89d62 --- /dev/null +++ b/solutions/arm64-assembly/dominoes/1/dominoes.s @@ -0,0 +1,85 @@ +/* Dedicated to Shree DR.MDD */ +.text +.globl can_chain + +root: + mov w3, w0 + ldrb w0, [x2, x0] + cmp w0, w3 + bne root + ret + +merge: + mov x8, lr + lsl w5, w0, #2 + +.merge_loop: + sub w5, w5, #2 + ldrh w0, [x1, x5] + bl root + mov w6, w0 + + sub w5, w5, #2 + ldrh w0, [x1, x5] + bl root + + strb w0, [x2, x6] + + cbnz w5, .merge_loop + ret x8 + +can_chain: + stp xzr, xzr, [sp, #-16]! + mov x12, lr + cmp w0, wzr + beq .accept + + mov x2, sp + lsl w4, w0, #2 + +.count_numbers: + sub w4, w4, #2 + ldrh w7, [x1, x4] + ldrb w13, [x2, x7] + add w13, w13, #1 + strb w13, [x2, x7] + cbnz w4, .count_numbers + + mov w4, #16 + mov w6, #255 + +.parity: + sub w4, w4, #1 + ldrb w5, [sp, x4] + tst w5, #1 + bne .reject + + tst w5, w5 + csel w7, w6, w4, eq + strb w7, [sp, x4] + cbnz w4, .parity + + bl merge + + mov w4, #16 + mov w7, wzr + +.count_roots: + sub w4, w4, #1 + ldrb w5, [x2, x4] + cmp w5, w4 + cinc w7, w7, eq + cbnz w4, .count_roots + + cmp w7, #1 + bne .reject + +.accept: + mov w0, #1 + add sp, sp, #16 + ret x12 + +.reject: + mov w0, wzr + add sp, sp, #16 + ret x12 diff --git a/solutions/arm64-assembly/eliuds-eggs/1/eliuds_eggs.s b/solutions/arm64-assembly/eliuds-eggs/1/eliuds_eggs.s new file mode 100644 index 0000000..8439532 --- /dev/null +++ b/solutions/arm64-assembly/eliuds-eggs/1/eliuds_eggs.s @@ -0,0 +1,22 @@ +.text +.globl egg_count + +/* extern int egg_count(uint64_t number); */ +egg_count: + mov x1, #1 + mov x2, x0 + ror x3, x1, #1 + mov x0, #0 + +.loop: + cmp x2, #0 + beq .return + + clz x4, x2 + ror x5, x3, x4 + eor x2, x2, x5 + add x0, x0, #1 + b .loop + +.return: + ret \ No newline at end of file diff --git a/solutions/arm64-assembly/flower-field/1/flower_field.s b/solutions/arm64-assembly/flower-field/1/flower_field.s new file mode 100644 index 0000000..0d22864 --- /dev/null +++ b/solutions/arm64-assembly/flower-field/1/flower_field.s @@ -0,0 +1,93 @@ +.text +.globl annotate + +annotate: + mov x2, x1 + ldrb w3, [x2] + cbz w3, .return + + mov w16, #'*' + mov w14, #'\n' + +.find_newline: + ldrb w3, [x2], #1 + cmp w3, w14 + bne .find_newline + + sub x4, x2, x1 + mov x2, x1 + +.find_null: + add x2, x2, x4 + ldrb w3, [x2] + cbnz w3, .find_null + + mov x5, x2 + mov x7, x1 + mov x8, x1 + +.next_row: + mov x10, xzr + mov x11, xzr + mov x6, x7 + mov x7, x8 + + add x8, x7, x4 + cmp x8, x5 + bne .first_column + + mov x8, x7 + +.first_column: + cmp x4, #1 + beq .write_newline + +.next_column: + mov x9, x10 + mov x10, x11 + add x11, x10, #2 + cmp x11, x4 + cset x11, ne + add x11, x10, x11 + + ldrb w3, [x7, x10] + cmp w3, w16 + beq .write_square + + mov w15, wzr + sub x12, x6, x4 + +.adjacent_row: + add x12, x12, x4 + sub x13, x9, #1 + +.adjacent_column: + add x13, x13, #1 + ldrb w3, [x12, x13] + cmp w3, w16 + cset x2, eq + add w15, w15, w2 + cmp x13, x11 + bne .adjacent_column + + cmp x12, x8 + bne .adjacent_row + + mov w3, #' ' + cbz w15, .write_square + + add w3, w15, #'0' + +.write_square: + strb w3, [x0], #1 + cmp x10, x11 + bne .next_column + +.write_newline: + strb w14, [x0], #1 + cmp x7, x8 + bne .next_row + +.return: + strb wzr, [x0] + ret diff --git a/solutions/arm64-assembly/food-chain/1/food_chain.s b/solutions/arm64-assembly/food-chain/1/food_chain.s new file mode 100644 index 0000000..6d44f6e --- /dev/null +++ b/solutions/arm64-assembly/food-chain/1/food_chain.s @@ -0,0 +1,146 @@ +// Dedicated to Shree DR.MDD + +.data + +i_know: .string "I know an old lady who swallowed a " +stop: .string ".\n" +shes: .string "She's dead, of course!\n" +i_dont: .string "I don't know why she swallowed the fly. Perhaps she'll die.\n" +she: .string "She swallowed the " +to: .string " to catch the " +that: .string " that wriggled and jiggled and tickled inside her" + +fly: .string "fly" +spider: .string "spider" +bird: .string "bird" +cat: .string "cat" +dog: .string "dog" +goat: .string "goat" +cow: .string "cow" +horse: .string "horse" + +spider2: + .string "It wriggled and jiggled and tickled inside her.\n" +bird2: .string "How absurd to swallow a bird!\n" +cat2: .string "Imagine that, to swallow a cat!\n" +dog2: .string "What a hog, to swallow a dog!\n" +goat2: .string "Just opened her throat and swallowed a goat!\n" +cow2: .string "I don't know how she swallowed a cow!\n" + +animal_array: + .dword 0 + .dword fly + .dword spider + .dword bird + .dword cat + .dword dog + .dword goat + .dword cow + .dword horse + +animal2_array: + .dword 0 + .dword 0 + .dword spider2 + .dword bird2 + .dword cat2 + .dword dog2 + .dword goat2 + .dword cow2 + +.macro LOAD reg, lbl + adrp \reg, \lbl + add \reg, \reg, :lo12:\lbl +.endm + +.macro APPEND str +.copy_\str: + ldrb w20, [x14], #1 + strb w20, [x0], #1 + cbnz w20, .copy_\str + sub x0, x0, #1 +.endm + +.text +.globl recite + +recite: + LOAD x3, i_know + LOAD x4, stop + LOAD x5, shes + LOAD x6, i_dont + LOAD x7, she + LOAD x8, to + LOAD x9, that + LOAD x10, animal_array + LOAD x11, animal2_array + + lsl x1, x1, #3 + lsl x2, x2, #3 + +.verse_loop: + mov x14, x3 + APPEND i_know + + ldr x14, [x10, x1] + APPEND animal + + mov x14, x4 + APPEND stop + + cmp x1, #64 + beq .shes_block + + cmp x1, #8 + beq .i_dont_block + + ldr x14, [x11, x1] + APPEND second + + mov x13, x1 + +.reason_loop: + mov x14, x7 + APPEND she + + ldr x14, [x10, x13] + APPEND animal2 + + mov x14, x8 + APPEND to + + sub x13, x13, #8 + ldr x14, [x10, x13] + APPEND animal3 + + cmp x13, #16 + bne .stop_block + + mov x14, x9 + APPEND that + +.stop_block: + mov x14, x4 + APPEND stop2 + + cmp x13, #8 + bne .reason_loop + +.i_dont_block: + mov x14, x6 + APPEND i_dont + + cmp x1, x2 + beq .return_block + + add x1, x1, #8 + mov w20, #'\n' + strb w20, [x0], #1 + b .verse_loop + +.shes_block: + mov x14, x5 + APPEND shes + +.return_block: + ret diff --git a/solutions/arm64-assembly/game-of-life/1/game_of_life.s b/solutions/arm64-assembly/game-of-life/1/game_of_life.s new file mode 100644 index 0000000..47b0ce7 --- /dev/null +++ b/solutions/arm64-assembly/game-of-life/1/game_of_life.s @@ -0,0 +1,75 @@ +# Dedicated to Shree DR.MDD + +.text +.globl tick + +tick: + stp x22, x23, [sp, #-48]! + stp x24, x25, [sp, #16] + stp x26, x27, [sp, #32] + cbz x2, .return + + mov x5, xzr + ldr x6, [x1], #8 + +.outer: + add x2, x2, #-1 + mov x4, x5 + mov x5, x6 + mov x6, xzr + cbz x2, .process_row + + ldr x6, [x1], #8 + +.process_row: + mov x17, xzr + mov x14, x4 + mov x15, x5 + mov x16, x6 + + and x23, x15, #1 + mov x25, xzr + and x26, x16, #1 + add x26, x26, x23 + and x9, x14, #1 + add x26, x26, x9 + + mov x13, x3 + cbz x3, .write + +.inner: + add x13, x13, #-1 + lsr x14, x14, #1 + lsr x15, x15, #1 + lsr x16, x16, #1 + + mov x22, x23 + and x23, x15, #1 + mov x24, x25 + mov x25, x26 + and x26, x16, #1 + add x26, x26, x23 + and x9, x14, #1 + add x26, x26, x9 + + add x27, x24, x25 + add x27, x27, x26 + sub x27, x27, x22 + orr x27, x27, x22 + cmp x27, #3 + cinc x17, x17, eq + + ror x17, x17, #1 + cbnz x13, .inner + +.write: + neg x9, x3 + rorv x17, x17, x9 + str x17, [x0], #8 + cbnz x2, .outer + +.return: + ldp x26, x27, [sp, #32] + ldp x24, x25, [sp, #16] + ldp x22, x23, [sp], #48 + ret diff --git a/solutions/arm64-assembly/grains/1/grains.s b/solutions/arm64-assembly/grains/1/grains.s new file mode 100644 index 0000000..da5134f --- /dev/null +++ b/solutions/arm64-assembly/grains/1/grains.s @@ -0,0 +1,16 @@ +.text +.globl square +.globl total +square: + sub x0, x0, #1 + cmp x0, #64 + bhs .invalid + mov x1, #1 + lsl x0, x1, x0 + ret +.invalid: + mov x0, #0 + ret +total: + mov x0, #-1 + ret \ No newline at end of file diff --git a/solutions/arm64-assembly/hamming/1/hamming.s b/solutions/arm64-assembly/hamming/1/hamming.s new file mode 100644 index 0000000..33faf87 --- /dev/null +++ b/solutions/arm64-assembly/hamming/1/hamming.s @@ -0,0 +1,30 @@ +// Dedicated to Shree DR.MDD + +.equ UNEQUAL_LENGTHS, -1 + +.text +.globl distance + +distance: + mov x5, x0 + mov x0, #0 + +.compare_loop: + ldrb w6, [x1], #1 + ldrb w7, [x5], #1 + + cbz w6, .end_check + cbz w7, .end_check + + cmp w6, w7 + cinc x0, x0, ne + b .compare_loop + +.end_check: + cmp w6, w7 + beq .finish + + mov x0, UNEQUAL_LENGTHS + +.finish: + ret diff --git a/solutions/arm64-assembly/hello-world/1/hello_world.s b/solutions/arm64-assembly/hello-world/1/hello_world.s new file mode 100644 index 0000000..fbced01 --- /dev/null +++ b/solutions/arm64-assembly/hello-world/1/hello_world.s @@ -0,0 +1,9 @@ +.section .rodata +msg: .string "Hello, World!" + +.text +.global hello +hello: + adrp x0, msg + add x0, x0, :lo12:msg + ret diff --git a/solutions/arm64-assembly/house/1/house.s b/solutions/arm64-assembly/house/1/house.s new file mode 100644 index 0000000..e25bd6a --- /dev/null +++ b/solutions/arm64-assembly/house/1/house.s @@ -0,0 +1,48 @@ +// Dedicated to Shree DR.MDD + +.data +lyrics: + .string "This is the horse and the hound and the horn that belonged to the farmer sowing his corn that kept the rooster that crowed in the morn that woke the priest all shaven and shorn that married the man all tattered and torn that kissed the maiden all forlorn that milked the cow with the crumpled horn that tossed the dog that worried the cat that killed the rat that ate the malt that lay in the house that Jack built.\n" + +table: + .hword -1, 388, 367, 350, 330, 309, 266, 231, 189, 144, 98, 61, 7 + +.text +.globl recite + +recite: + lsl x1, x1, #1 + lsl x2, x2, #1 + + adrp x5, table + add x5, x5, :lo12:table + + adrp x3, lyrics + add x3, x3, :lo12:lyrics + + add x1, x1, x5 + add x2, x2, x5 + add x4, x3, 7 + mov x6, x3 + +.line_loop: + ldrb w9, [x6], #1 + strb w9, [x0], #1 + cmp x6, x4 + bne .line_loop + + ldrh w10, [x1] + add x6, x3, x10, uxtw // Correctly extend 16-bit offset + +.copy_loop: + ldrb w9, [x6], #1 + strb w9, [x0], #1 + cbnz w9, .copy_loop + + sub x0, x0, #1 + mov x6, x3 + cmp x1, x2 + add x1, x1, #2 + bne .line_loop + + ret diff --git a/solutions/arm64-assembly/intergalactic-transmission/1/intergalactic_transmission.s b/solutions/arm64-assembly/intergalactic-transmission/1/intergalactic_transmission.s new file mode 100644 index 0000000..d76b21d --- /dev/null +++ b/solutions/arm64-assembly/intergalactic-transmission/1/intergalactic_transmission.s @@ -0,0 +1,108 @@ +.equ WRONG_PARITY, -1 + +.text +.globl transmit_sequence +.globl decode_message + +transmit_sequence: + mov x20, x0 + cbz x2, .success + + mov x7, 7 + mov x21, xzr + mov x22, xzr + b .read_next + +.odd_bit: + orr x6, x6, #1 + +.even_bit: + strb w6, [x0], #1 + + cmp x21, 7 + beq .encode_bits + + cbnz x2, .read_next + + cbz x21, .success + sub x14, x7, x21 + mov x21, x7 + lsl x22, x22, x14 + b .encode_bits + +.read_next: + lsl x22, x22, #8 + ldrb w11, [x1], #1 + add x2, x2, #-1 + orr x22, x22, x11 + add x21, x21, #8 + +.encode_bits: + add x21, x21, #-7 + lsr x13, x22, x21 + lsl x6, x13, #1 + and x13, x13, #127 + +.check_parity: + cbz x13, .even_bit + + neg x14, x13 + and x14, x13, x14 + sub x13, x13, x14 + cbz x13, .odd_bit + + neg x14, x13 + and x14, x13, x14 + sub x13, x13, x14 + b .check_parity + +.success: + sub x0, x0, x20 + ret + +decode_message: + mov x20, x0 + mov x21, xzr + mov x22, xzr + b .check_remaining + +.no_write: + mov x21, #7 + +.read_bits: + lsl x11, x22, #7 + ldrb w12, [x1], #1 + add x2, x2, #-1 + mov x13, x12 + cbz x12, .consume_bits + +.check_decode_parity: + neg x14, x13 + and x14, x13, x14 + sub x13, x13, x14 + cbz x13, .failure + + neg x14, x13 + and x14, x13, x14 + sub x13, x13, x14 + cbnz x13, .check_decode_parity + +.consume_bits: + lsr x22, x12, #1 + cbz x21, .no_write + + orr x11, x11, x22 + add x21, x21, #-1 + lsr x11, x11, x21 + strb w11, [x0], #1 + +.check_remaining: + cbnz x2, .read_bits + +.decode_success: + sub x0, x0, x20 + ret + +.failure: + mov x0, WRONG_PARITY + ret diff --git a/solutions/arm64-assembly/isbn-verifier/1/isbn_verifier.s b/solutions/arm64-assembly/isbn-verifier/1/isbn_verifier.s new file mode 100644 index 0000000..54fd64d --- /dev/null +++ b/solutions/arm64-assembly/isbn-verifier/1/isbn_verifier.s @@ -0,0 +1,47 @@ +// Dedicated to Shree DR.MDD + +.text +.globl is_valid + +is_valid: + mov w8, #10 + mov w9, #0 + mov w10, #0 + +validate_loop: + ldrb w6, [x0], #1 + cbz w6, finish_check + + cmp w6, #45 + beq validate_loop + + sub w8, w8, #1 + sub w7, w6, #'0' + cmp w7, #10 + bhs handle_non_digit + +accumulate: + add w9, w9, w7 + add w10, w10, w9 + b validate_loop + +handle_non_digit: + cbnz w8, reject_isbn + + mov w7, #10 + cmp w6, #'X' + beq accumulate + +reject_isbn: + mov w0, #0 + ret + +finish_check: + cbnz w8, reject_isbn + + mov w8, #11 + udiv w9, w10, w8 + msub w7, w9, w8, w10 + tst w7, w7 + cset w0, eq + ret diff --git a/solutions/arm64-assembly/isogram/1/isogram.s b/solutions/arm64-assembly/isogram/1/isogram.s new file mode 100644 index 0000000..c2ba5f1 --- /dev/null +++ b/solutions/arm64-assembly/isogram/1/isogram.s @@ -0,0 +1,32 @@ +// Dedicated to Shree DR.MDD + +.text +.globl is_isogram + +is_isogram: + mov w5, #1 // One bit to shift for letter mask + mov w6, wzr // Clear letter flags + mov w7, #0xDF // Upper case bit mask + +.scan_byte: + ldrb w8, [x0], #1 // Get current byte and increment pointer + cbz w8, .return_true + + and w8, w8, w7 // Force upper case + sub w8, w8, #'A' // Convert to letter index + cmp w8, #25 // Check if byte is a letter + bhi .scan_byte + + lsl w8, w5, w8 // Shift bit to set letter mask + tst w8, w6 + bne .return_false + orr w6, w6, w8 + b .scan_byte + +.return_false: + mov x0, xzr + ret + +.return_true: + mov x0, #1 + ret diff --git a/solutions/arm64-assembly/kindergarten-garden/1/kindergarten_garden.s b/solutions/arm64-assembly/kindergarten-garden/1/kindergarten_garden.s new file mode 100644 index 0000000..2434f2e --- /dev/null +++ b/solutions/arm64-assembly/kindergarten-garden/1/kindergarten_garden.s @@ -0,0 +1,48 @@ +.data +names: .string " clover, grass, radishes, violets, " + +.text +.globl plants + +plants: + adrp x9, names + add x9, x9, :lo12:names + + ldrb w2, [x2] + sub w2, w2, #'A' + lsl w2, w2, #1 + add w3, w2, #1 + mov x4, x1 + +.scan: + ldrb w5, [x4], #1 + cbnz w5, .scan + + sub x4, x4, x1 + lsr x4, x4, #1 + mov x7, sp + stp w2, w3, [sp, #-16]! + add w2, w2, w4 + add w3, w3, w4 + stp w2, w3, [sp, #8] + mov x6, sp + +.next: + ldr w2, [x6], #4 + ldrb w2, [x1, x2] + sub w2, w2, #'A' + lsl w2, w2, #2 + add x2, x9, x2 + +.copy: + ldrb w3, [x2], #1 + strb w3, [x0], #1 + cmp w3, #' ' + bne .copy + + cmp x6, x7 + bne .next + + strb wzr, [x0, #-2] + mov sp, x7 + ret diff --git a/solutions/arm64-assembly/knapsack/1/knapsack.s b/solutions/arm64-assembly/knapsack/1/knapsack.s new file mode 100644 index 0000000..9f710c4 --- /dev/null +++ b/solutions/arm64-assembly/knapsack/1/knapsack.s @@ -0,0 +1,48 @@ +.text +.globl maximum_value + +maximum_value: + lsl x2, x2, #3 + add x2, x1, x2 + lsl x0, x0, #2 + add x3, x0, #16 + and x3, x3, #-16 + mov x4, sp + sub sp, sp, x3 + mov x5, sp + +.clear: + stp xzr, xzr, [x4, #-16]! + cmp x4, x5 + bne .clear + +.next_item: + cmp x1, x2 + beq .report + + ldr w9, [x1], #4 + ldr w10, [x1], #4 + lsl x9, x9, 2 + mov x7, x0 + subs x11, x7, x9 + blt .next_item + +.loop: + ldr w12, [sp, x11] + add w12, w12, w10 + ldr w13, [sp, x7] + cmp w13, w12 + bhs .skip + + str w12, [sp, x7] + +.skip: + cbz x11, .next_item + sub x7, x7, #4 + sub x11, x11, #4 + b .loop + +.report: + ldr w0, [sp, x0] + add sp, sp, x3 + ret diff --git a/solutions/arm64-assembly/largest-series-product/1/largest_series_product.s b/solutions/arm64-assembly/largest-series-product/1/largest_series_product.s new file mode 100644 index 0000000..34f08e0 --- /dev/null +++ b/solutions/arm64-assembly/largest-series-product/1/largest_series_product.s @@ -0,0 +1,65 @@ +.equ INVALID_CHARACTER, -1 +.equ NEGATIVE_SPAN, -2 +.equ INSUFFICIENT_DIGITS, -3 + +.text +.globl largest_product + +/* extern int64_t largest_product(int span, const char *digits); */ +largest_product: + mov x2, x1 /* input pointer */ + +.scan: + ldrb w3, [x2], #1 /* load byte, with post-increment */ + cbz w3, .check_length + + sub w3, w3, #'0' + cmp w3, #10 + blo .scan /* unsigned < */ + + mov x0, INVALID_CHARACTER + ret + +.check_length: + sub x2, x2, #1 /* address of null terminator */ + + cmp w0, wzr /* compare with zero */ + blt .negative_span + + sub x3, x2, x1 /* number of digits */ + cmp x3, x0 + blt .insufficient_digits + + mov x4, x0 /* span */ + mov x0, xzr /* largest product */ + +.series: + add x5, x1, x4 /* end of series */ + mov x6, #1 /* current product */ + mov x7, x1 /* input pointer */ + +.digit: + cmp x7, x5 + beq .update_largest + + ldrb w8, [x7], #1 /* load digit */ + sub w8, w8, #'0' + mul x6, x6, x8 + b .digit + +.update_largest: + cmp x6, x0 + csel x0, x6, x0, hi + cmp x7, x2 + add x1, x1, #1 /* start of next series */ + bne .series + + ret + +.negative_span: + mov x0, NEGATIVE_SPAN + ret + +.insufficient_digits: + mov x0, INSUFFICIENT_DIGITS + ret \ No newline at end of file diff --git a/solutions/arm64-assembly/leap/1/leap.s b/solutions/arm64-assembly/leap/1/leap.s new file mode 100644 index 0000000..04362fc --- /dev/null +++ b/solutions/arm64-assembly/leap/1/leap.s @@ -0,0 +1,23 @@ +.text +.globl leap_year +leap_year: + mov x9, #4 + udiv x1, x0, x9 + msub x1, x1, x9, x0 + cbnz x1, no_leap + + mov x9, #400 + udiv x1, x0, x9 + msub x1, x1, x9, x0 + cbz x1, leap + + mov x9, #100 + udiv x1, x0, x9 + msub x1, x1, x9, x0 + cbz x1, no_leap +leap: + mov x0, 1 + ret +no_leap: + mov x0, 0 + ret \ No newline at end of file diff --git a/solutions/arm64-assembly/list-ops/1/list_ops.s b/solutions/arm64-assembly/list-ops/1/list_ops.s new file mode 100644 index 0000000..47302b5 --- /dev/null +++ b/solutions/arm64-assembly/list-ops/1/list_ops.s @@ -0,0 +1,160 @@ +.text +.globl append +.globl filter +.globl map +.globl foldl +.globl foldr +.globl reverse + +append: + mov x9, x0 + cbz x2, .append_check_list2_count + lsl x2, x2, #3 + add x2, x1, x2 + +.append_copy_list1: + ldr x10, [x1], #8 + str x10, [x0], #8 + cmp x1, x2 + bne .append_copy_list1 + +.append_check_list2_count: + cbz x4, .append_return + lsl x4, x4, #3 + add x4, x3, x4 + +.append_copy_list2: + ldr x10, [x3], #8 + str x10, [x0], #8 + cmp x3, x4 + bne .append_copy_list2 + +.append_return: + sub x0, x0, x9 + lsr x0, x0, #3 + ret + +filter: + stp x19, x20, [sp, #-64]! + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp x25, x26, [sp, #48] + mov x19, x0 + mov x20, x1 + mov x21, x2 + mov x22, x3 + mov x23, x0 + mov x24, x1 + mov x25, lr + +.filter_loop: + cbz x21, .filter_return + ldr x26, [x24], #8 + mov x0, x26 + add x21, x21, #-1 + blr x22 + cbz x0, .filter_loop + str x26, [x23], #8 + b .filter_loop + +.filter_return: + sub x0, x23, x19 + lsr x0, x0, #3 + mov lr, x25 + ldp x25, x26, [sp, #48] + ldp x23, x24, [sp, #32] + ldp x21, x22, [sp, #16] + ldp x19, x20, [sp], #64 + ret + +map: + stp x19, x20, [sp, #-64]! + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp x25, x26, [sp, #48] + mov x19, x0 + mov x20, x1 + mov x21, x2 + mov x22, x3 + mov x23, x0 + mov x24, x1 + mov x25, lr + +.map_loop: + cbz x21, .map_return + ldr x0, [x24], #8 + add x21, x21, #-1 + blr x22 + str x0, [x23], #8 + b .map_loop + +.map_return: + sub x0, x23, x19 + lsr x0, x0, #3 + mov lr, x25 + ldp x25, x26, [sp, #48] + ldp x23, x24, [sp, #32] + ldp x21, x22, [sp, #16] + ldp x19, x20, [sp], #64 + ret + +foldl: + stp x19, x20, [sp, #-32]! + stp x21, x22, [sp, #16] + mov x19, x0 + mov x20, x1 + mov x21, x3 + mov x22, lr + mov x0, x2 + +.foldl_loop: + cbz x20, .foldl_return + ldr x1, [x19], #8 + add x20, x20, #-1 + blr x21 + b .foldl_loop + +.foldl_return: + mov lr, x22 + ldp x21, x22, [sp, #16] + ldp x19, x20, [sp], #32 + ret + +foldr: + stp x19, x20, [sp, #-32]! + stp x21, x22, [sp, #16] + mov x20, x1 + lsl x1, x1, #3 + add x19, x0, x1 + mov x21, x3 + mov x22, lr + mov x0, x2 + cbz x20, .foldr_return + +.foldr_loop: + ldr x1, [x19, #-8]! + add x20, x20, #-1 + blr x21 + cbnz x20, .foldr_loop + +.foldr_return: + mov lr, x22 + ldp x21, x22, [sp, #16] + ldp x19, x20, [sp], #32 + ret + +reverse: + mov x15, x2 + cbz x2, .reverse_return + lsl x9, x2, #3 + add x9, x1, x9 + +.reverse_loop: + ldr x10, [x9, #-8]! + str x10, [x0], #8 + add x2, x2, #-1 + cbnz x2, .reverse_loop + +.reverse_return: + mov x0, x15 + ret diff --git a/solutions/arm64-assembly/luhn/1/luhn.s b/solutions/arm64-assembly/luhn/1/luhn.s new file mode 100644 index 0000000..8a50ee6 --- /dev/null +++ b/solutions/arm64-assembly/luhn/1/luhn.s @@ -0,0 +1,61 @@ +.text +.globl valid + +valid: + mov x1, x0 + mov x2, #0 + mov x3, #0 + +first_scan: + ldrb w4, [x1], #1 + cbz w4, end_first_scan + + cmp w4, #' ' + beq first_scan + + sub w4, w4, #'0' + cmp w4, #10 + bhs reject + + add x2, x2, #1 + b first_scan + +end_first_scan: + mov x1, x0 + cmp x2, #2 + blt reject + +second_scan: + ldrb w4, [x1], #1 + cbz w4, end_second_scan + + cmp w4, #' ' + beq second_scan + + sub w4, w4, #'0' + tst x2, #1 + bne double_digit + + lsl w4, w4, #1 + cmp w4, #10 + blo add_sum + sub w4, w4, #9 + +double_digit: +add_sum: + add x3, x3, x4 + sub x2, x2, #1 + b second_scan + +end_second_scan: + mov x4, #10 + udiv x5, x3, x4 + msub x0, x5, x4, x3 + + cmp x0, xzr + cset x0, eq + ret + +reject: + mov x0, #0 + ret diff --git a/solutions/arm64-assembly/matching-brackets/1/matching_brackets.s b/solutions/arm64-assembly/matching-brackets/1/matching_brackets.s new file mode 100644 index 0000000..dc9a84e --- /dev/null +++ b/solutions/arm64-assembly/matching-brackets/1/matching_brackets.s @@ -0,0 +1,72 @@ +.text +.globl is_paired + +is_paired: + mov x10, x0 + +.scan_loop: + ldrb w11, [x10], #1 + cbnz w11, .scan_loop + + sub x10, x10, x0 + add x10, x10, #16 + and x10, x10, #-16 + sub sp, sp, x10 + mov x12, sp + mov x14, sp + +.read_loop: + ldrb w11, [x0], #1 + cbz w11, .finish + + cmp w11, #'[' + beq .push_bracket + + cmp w11, #'{' + beq .push_brace + + cmp w11, #'(' + beq .push_parenthesis + + cmp w11, #']' + beq .pop_check + + cmp w11, #'}' + beq .pop_check + + cmp w11, #')' + bne .read_loop + +.pop_check: + cmp x12, x14 + beq .fail + ldrb w13, [x12, #-1]! + cmp w11, w13 + beq .read_loop + +.fail: + mov x0, #0 + b .end + +.finish: + cmp x12, x14 + cset x0, eq + +.end: + add sp, sp, x10 + ret + +.push_bracket: + mov w11, #']' + strb w11, [x12], #1 + b .read_loop + +.push_brace: + mov w11, #'}' + strb w11, [x12], #1 + b .read_loop + +.push_parenthesis: + mov w11, #')' + strb w11, [x12], #1 + b .read_loop diff --git a/solutions/arm64-assembly/meetup/1/meetup.s b/solutions/arm64-assembly/meetup/1/meetup.s new file mode 100644 index 0000000..465fcfe --- /dev/null +++ b/solutions/arm64-assembly/meetup/1/meetup.s @@ -0,0 +1,181 @@ +/* Dedicated to Shree DR.MDD */ +.equ PRIME, 1 +.equ DOUBLE, 2 +.equ TRIPLE, 3 +.equ QUAD, 4 +.equ TEENPOINT, 5 +.equ ULTIMATE, 6 + +.equ MON, 1 +.equ TUE, 2 +.equ WED, 3 +.equ THU, 4 +.equ FRI, 5 +.equ SAT, 6 +.equ SUN, 7 + +.data +month_shift_tbl: + .hword -1 + .hword 307 + .hword 338 + .hword 1 + .hword 32 + .hword 62 + .hword 93 + .hword 123 + .hword 154 + .hword 185 + .hword 215 + .hword 246 + .hword 276 + .hword 307 + .hword 338 + +week_end_tbl: + .byte -1 + .byte 7 + .byte 14 + .byte 21 + .byte 28 + .byte 19 + +.text +.globl meetup + +print_date: + mov w19, #'-' + mov w20, 10 + + udiv w21, w1, w20 + msub w23, w21, w20, w1 + add w23, w23, #'0' + strb w23, [x0, #3] + + udiv w22, w21, w20 + msub w23, w22, w20, w21 + add w23, w23, #'0' + strb w23, [x0, #2] + + udiv w21, w22, w20 + msub w23, w21, w20, w22 + add w23, w23, #'0' + strb w23, [x0, #1] + add w21, w21, #'0' + strb w21, [x0] + + strb w19, [x0, #4] + + udiv w21, w2, w20 + msub w23, w21, w20, w2 + add w23, w23, #'0' + strb w23, [x0, #6] + add w21, w21, #'0' + strb w21, [x0, #5] + + strb w19, [x0, #7] + + udiv w21, w3, w20 + msub w23, w21, w20, w3 + add w23, w23, #'0' + strb w23, [x0, #9] + add w21, w21, #'0' + strb w21, [x0, #8] + + strb wzr, [x0, #10] + ret + +leap_year: + mov w20, #100 + udiv w22, w1, w20 + msub w23, w22, w20, w1 + tst w23, w23 + csel w0, w22, w23, eq + tst w0, #3 + cset w0, eq + ret + +days_in_month: + cmp w2, #2 + beq .febcase + + adrp x19, month_shift_tbl + add x19, x19, :lo12:month_shift_tbl + + lsl w20, w2, #1 + ldrh w21, [x19, x20] + + add w20, w20, #2 + ldrh w0, [x19, x20] + + sub w0, w0, w21 + ret + +.febcase: + mov x21, lr + bl leap_year + add w0, w0, #28 + ret x21 + +week_concludes: + cmp w3, ULTIMATE + beq days_in_month + + adrp x19, week_end_tbl + add x19, x19, :lo12:week_end_tbl + ldrb w0, [x19, x3] + ret + +day_of_week: + mov w22, w2 + mov w21, w1 + + add w20, w22, #12 + sub w19, w21, #1 + cmp w2, #2 + csel w22, w22, w20, hi + csel w21, w21, w19, hi + + lsl w22, w22, #1 + adrp x19, month_shift_tbl + add x19, x19, :lo12:month_shift_tbl + ldrh w23, [x19, x22] + + mov w0, w21 + + lsr w21, w21, #2 + add w0, w0, w21 + + mov w19, #25 + udiv w21, w21, w19 + sub w0, w0, w21 + + lsr w21, w21, #2 + add w0, w0, w21 + + add w0, w0, w23 + add w0, w0, w3 + + mov w19, #7 + udiv w20, w0, w19 + msub w0, w20, w19, w0 + add w0, w0, #1 + ret + +meetup: + mov x24, x0 + mov x25, lr + bl week_concludes + + mov w3, w0 + bl day_of_week + + sub w0, w4, w0 + sub w19, w0, #7 + cmp w0, wzr + csel w0, w0, w19, le + add w3, w3, w0 + mov x0, x24 + bl print_date + + ret x25 diff --git a/solutions/arm64-assembly/micro-blog/1/micro_blog.s b/solutions/arm64-assembly/micro-blog/1/micro_blog.s new file mode 100644 index 0000000..efdd389 --- /dev/null +++ b/solutions/arm64-assembly/micro-blog/1/micro_blog.s @@ -0,0 +1,23 @@ +// Dedicated to Shree DR.MDD + +.text +.globl truncate + +truncate: + mov x5, #6 + +.scan_loop: + ldrb w6, [x1], #1 + strb w6, [x0], #1 + cbz w6, .finish + + and w7, w6, #0xC0 + cmp w7, #0x80 + beq .scan_loop + + sub x5, x5, #1 + cbnz x5, .scan_loop + +.finish: + strb wzr, [x0, #-1] + ret diff --git a/solutions/arm64-assembly/nth-prime/1/nth_prime.s b/solutions/arm64-assembly/nth-prime/1/nth_prime.s new file mode 100644 index 0000000..05b96a9 --- /dev/null +++ b/solutions/arm64-assembly/nth-prime/1/nth_prime.s @@ -0,0 +1,55 @@ +.text +.globl prime + +prime: + cmp x0, #3 + blt .prime_small + + clz x7, x0 + mov x8, #64 + sub x7, x8, x7 + mul x7, x0, x7 + lsr x7, x7, #1 + add x7, x7, #15 + and x7, x7, #-16 + mov x9, sp + sub sp, sp, x7 + mov x10, #-1 + mov x11, sp + +.fill_loop: + stp x10, x10, [x9, #-16]! + cmp x9, x11 + bne .fill_loop + + mov x12, #1 + sub x0, x0, #1 + +.search_loop: + add x12, x12, #2 + lsr x13, x12, #1 + ldrb w14, [sp, x13] + cbz w14, .search_loop + + sub x0, x0, #1 + cbz x0, .prime_exit + + mul x15, x12, x12 + lsr x15, x15, #1 + +.mark_loop: + cmp x15, x7 + bhs .search_loop + + strb wzr, [sp, x15] + add x15, x15, x12 + b .mark_loop + +.prime_exit: + mov x0, x12 + add sp, sp, x7 + ret + +.prime_small: + add x0, x0, #1 + ret diff --git a/solutions/arm64-assembly/nucleotide-count/1/nucleotide_count.s b/solutions/arm64-assembly/nucleotide-count/1/nucleotide_count.s new file mode 100644 index 0000000..f9c7a29 --- /dev/null +++ b/solutions/arm64-assembly/nucleotide-count/1/nucleotide_count.s @@ -0,0 +1,56 @@ +// Dedicated to Shree DR.MDD + +.text +.globl nucleotide_counts + +nucleotide_counts: + mov w8, wzr + mov w9, wzr + mov w10, wzr + mov w11, wzr + +.scan_loop: + ldrb w6, [x1], #1 + cbz w6, .output_counts + + cmp w6, #'A' + beq .add_adenine + + cmp w6, #'C' + beq .add_cytosine + + cmp w6, #'G' + beq .add_guanine + + cmp w6, #'T' + beq .add_thymine + + mov w6, #-1 + strh w6, [x0], #2 + strh w6, [x0], #2 + strh w6, [x0], #2 + strh w6, [x0] + ret + +.output_counts: + strh w8, [x0], #2 + strh w9, [x0], #2 + strh w10, [x0], #2 + strh w11, [x0] + ret + +.add_adenine: + add w8, w8, #1 + b .scan_loop + +.add_cytosine: + add w9, w9, #1 + b .scan_loop + +.add_guanine: + add w10, w10, #1 + b .scan_loop + +.add_thymine: + add w11, w11, #1 + b .scan_loop diff --git a/solutions/arm64-assembly/pangram/1/pangram.s b/solutions/arm64-assembly/pangram/1/pangram.s new file mode 100644 index 0000000..d86408b --- /dev/null +++ b/solutions/arm64-assembly/pangram/1/pangram.s @@ -0,0 +1,27 @@ +// Dedicated to Shree DR.MDD + +.text +.globl is_pangram + +is_pangram: + mov x5, x0 + mov x0, #0 + mov w6, #1 // 32-bit mask for shift + +.scan_loop: + ldrb w7, [x5], #1 + cbz w7, .finish + + orr w7, w7, #32 + sub w7, w7, #'a' + cmp w7, #26 + bhs .scan_loop + + lsl w7, w6, w7 // shift using 32-bit registers + orr w0, w0, w7 + b .scan_loop + +.finish: + add w0, w0, #1 + lsr w0, w0, #26 + ret diff --git a/solutions/arm64-assembly/pascals-triangle/1/pascals_triangle.s b/solutions/arm64-assembly/pascals-triangle/1/pascals_triangle.s new file mode 100644 index 0000000..36cdb8d --- /dev/null +++ b/solutions/arm64-assembly/pascals-triangle/1/pascals_triangle.s @@ -0,0 +1,37 @@ +.text +.globl rows + +rows: + mov x10, x0 + cbz x1, .rows_done + + lsl x1, x1, #3 + mov x11, xzr + mov x12, #1 + +.row_loop: + mov x13, x10 + add x14, x10, x11 + add x11, x11, #8 + mov x15, xzr + cmp x10, x14 + beq .final_column + +.col_loop: + ldr x12, [x5], #8 + add x16, x15, x12 + mov x15, x12 + str x16, [x10], #8 + cmp x10, x14 + bne .col_loop + +.final_column: + str x12, [x10], #8 + mov x5, x13 + cmp x11, x1 + bne .row_loop + +.rows_done: + sub x0, x10, x0 + lsr x0, x0, #3 + ret diff --git a/solutions/arm64-assembly/perfect-numbers/1/perfect_numbers.s b/solutions/arm64-assembly/perfect-numbers/1/perfect_numbers.s new file mode 100644 index 0000000..b4999ca --- /dev/null +++ b/solutions/arm64-assembly/perfect-numbers/1/perfect_numbers.s @@ -0,0 +1,62 @@ +# Dedicated to Shree DR.MDD + +.equ DEFICIENT, 1 +.equ PERFECT, 2 +.equ ABUNDANT, 3 +.equ INVALID, -1 + +.text +.globl classify + +classify: + cmp x0, #1 + ble .le_one + + mov x9, #1 + mov x10, #1 + lsl x12, x0, #1 + +.next: + add x10, x10, #1 + mov x11, #1 + mul x13, x10, x10 + cmp x13, x0 + csel x10, x0, x10, hi + + udiv x14, x0, x10 + msub x15, x14, x10, x0 + cbnz x15, .next + +.repeat: + mul x11, x11, x10 + add x11, x11, #1 + mov x0, x14 + + udiv x14, x0, x10 + msub x15, x14, x10, x0 + cbz x15, .repeat + + mul x9, x9, x11 + cmp x0, #1 + bne .next + + cmp x9, x12 + beq .perfect + blo .deficient + +.abundant: + mov x0, ABUNDANT + ret + +.perfect: + mov x0, PERFECT + ret + +.deficient: + mov x0, DEFICIENT + ret + +.le_one: + beq .deficient + mov x0, INVALID + ret diff --git a/solutions/arm64-assembly/phone-number/1/phone_number.s b/solutions/arm64-assembly/phone-number/1/phone_number.s new file mode 100644 index 0000000..4b9cfaf --- /dev/null +++ b/solutions/arm64-assembly/phone-number/1/phone_number.s @@ -0,0 +1,75 @@ +.text +.globl clean + +clean: + mov x1, x0 + mov x2, x0 + +.read: + ldrb w3, [x2], #1 + cbz w3, .validate + + cmp w3, #' ' + beq .read + + cmp w3, #'(' + beq .read + + cmp w3, #')' + beq .read + + cmp w3, #'+' + beq .read + + cmp w3, #'-' + beq .read + + cmp w3, #'.' + beq .read + + sub w4, w3, #'0' + cmp w4, #10 + bhs .reject + + strb w3, [x1], #1 + b .read + +.reject: + strb wzr, [x0] + ret + +.validate: + strb wzr, [x1] + sub x1, x1, x0 + cmp x1, #11 + beq .eleven + + cmp x1, #10 + bne .reject + +.ten: + ldrb w3, [x0] + sub w4, w3, #'0' + cmp w4, #2 + blt .reject + + ldrb w3, [x0, #3] + sub w4, w3, #'0' + cmp w4, #2 + blt .reject + + ret + +.eleven: + mov x1, x0 + mov x2, x0 + ldrb w3, [x2], #1 + cmp w3, #'1' + bne .reject + +.move: + ldrb w3, [x2], #1 + strb w3, [x1], #1 + cbnz w3, .move + + b .ten diff --git a/solutions/arm64-assembly/pig-latin/1/pig_latin.s b/solutions/arm64-assembly/pig-latin/1/pig_latin.s new file mode 100644 index 0000000..017eb04 --- /dev/null +++ b/solutions/arm64-assembly/pig-latin/1/pig_latin.s @@ -0,0 +1,80 @@ +.data +vowels: + .byte 1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0 + +.text +.globl translate + +translate: + mov w7, #'a' + mov w8, #'y' + adrp x9, vowels + add x9, x9, :lo12:vowels + sub x9, x9, x7 + +start_word: + mov x10, x1 + ldrb w4, [x1] + cbz w4, return + + ldrb w5, [x1, #1] + ldrb w6, [x9, x4] + cbnz w6, check_yt + +check_xr: + cmp w4, #'x' + bne consonant + cmp w5, 'r' + bne consonant + b vowel + +check_yt: + cmp w4, #'y' + bne vowel + cmp w5, #'t' + beq vowel + +consonant: + mov w3, w4 + ldrb w4, [x10, #1]! + cmp w4, w7 + blt vowel + ldrb w6, [x9, x4] + cbz w6, consonant + cmp w4, #'u' + bne vowel + cmp w3, #'q' + bne vowel + add x10, x10, #1 + +vowel: + mov x11, x10 + b check_for_remaining_letters + +copy_remaining_letters: + add x11, x11, #1 + strb w4, [x0], #1 + +check_for_remaining_letters: + ldrb w4, [x11] + cmp w4, w7 + bge copy_remaining_letters + b check_for_leading_consonants + +copy_leading_consonants: + ldrb w5, [x1], #1 + strb w5, [x0], #1 + +check_for_leading_consonants: + cmp x1, x10 + bne copy_leading_consonants + strb w7, [x0], #1 + strb w8, [x0], #1 + cbz w4, return + strb w4, [x0], #1 + add x1, x11, #1 + b start_word + +return: + strb wzr, [x0] + ret diff --git a/solutions/arm64-assembly/prime-factors/1/prime_factors.s b/solutions/arm64-assembly/prime-factors/1/prime_factors.s new file mode 100644 index 0000000..cc3cb2c --- /dev/null +++ b/solutions/arm64-assembly/prime-factors/1/prime_factors.s @@ -0,0 +1,35 @@ +// Dedicated to Shree DR.MDD +.text +.globl factors + +factors: + mov x6, x0 + mov x7, #2 + +.loop_search: + cmp x1, #1 + beq .end + + udiv x8, x1, x7 + msub x9, x7, x8, x1 + cbz x9, .store_factor + + cmp x7, x8 + bgt .final_factor + + add x7, x7, 1 + b .loop_search + +.final_factor: + mov x7, x1 + mov x8, #1 + +.store_factor: + str x7, [x0], #8 + mov x1, x8 + b .loop_search + +.end: + sub x0, x0, x6 + lsr x0, x0, #3 + ret diff --git a/solutions/arm64-assembly/protein-translation/1/protein_translation.s b/solutions/arm64-assembly/protein-translation/1/protein_translation.s new file mode 100644 index 0000000..20f398a --- /dev/null +++ b/solutions/arm64-assembly/protein-translation/1/protein_translation.s @@ -0,0 +1,118 @@ +.equ A, 0x41 +.equ U, 0x55 + +.equ AUG, 0x4755 +.equ UUU, 0x5555 +.equ UUC, 0x4355 +.equ UUA, 0x4155 +.equ UUG, 0x4755 +.equ UCU, 0x5543 +.equ UCC, 0x4343 +.equ UCA, 0x4143 +.equ UCG, 0x4743 +.equ UAU, 0x5541 +.equ UAC, 0x4341 +.equ UGU, 0x5547 +.equ UGC, 0x4347 +.equ UGG, 0x4747 +.equ UAA, 0x4141 +.equ UAG, 0x4741 +.equ UGA, 0x4147 + +.macro LOAD str + adrp x9, \str + add x9, x9, :lo12:\str +.endm + +.macro CHECK codon + mov w13, \codon + cmp w12, w13 + beq .copy_string +.endm + +.macro CHECKS codon + mov w13, \codon + cmp w12, w13 + beq .stop +.endm + +.section .rodata +methionine: .string "Methionine\n" +phenylalanine: .string "Phenylalanine\n" +leucine: .string "Leucine\n" +serine: .string "Serine\n" +tyrosine: .string "Tyrosine\n" +cysteine: .string "Cysteine\n" +tryptophan: .string "Tryptophan\n" + +.text +.globl proteins +proteins: + mov x10, x0 + strb wzr, [x10] + b .read_codon + +.copy_string: + ldrb w11, [x9], #1 + strb w11, [x10], #1 + cbnz w11, .copy_string + add x10, x10, #-1 + add x1, x1, #3 + +.read_codon: + ldrb w11, [x1] + cbz w11, .stop + ldrb w12, [x1, #1] + cbz w12, .invalid + ldrh w12, [x1, #1] + + mov w13, A + cmp w11, w13 + beq .a + + mov w13, U + cmp w11, w13 + beq .u + + b .invalid + +.a: + LOAD methionine + CHECK AUG + b .invalid + +.u: + LOAD phenylalanine + CHECK UUU + CHECK UUC + + LOAD leucine + CHECK UUA + CHECK UUG + + LOAD serine + CHECK UCU + CHECK UCC + CHECK UCA + CHECK UCG + + LOAD tyrosine + CHECK UAU + CHECK UAC + + LOAD cysteine + CHECK UGU + CHECK UGC + + LOAD tryptophan + CHECK UGG + + CHECKS UAA + CHECKS UAG + CHECKS UGA + +.invalid: + strb wzr, [x0] + +.stop: + ret diff --git a/solutions/arm64-assembly/proverb/1/proverb.s b/solutions/arm64-assembly/proverb/1/proverb.s new file mode 100644 index 0000000..3dc4797 --- /dev/null +++ b/solutions/arm64-assembly/proverb/1/proverb.s @@ -0,0 +1,63 @@ +// Dedicated to Shree DR.MDD +.data +for: .string "For want of a " +the: .string " the " +was: .string " was lost.\n" +and: .string "And all for the want of a " +end: .string ".\n" + +.macro APPEND str + adrp x9, \str + add x9, x9, :lo12:\str + bl append +.endm + +.text +.globl recite + +append: + ldrb w10, [x9], #1 + strb w10, [x0], #1 + cbnz w10, append + + sub x0, x0, #1 + ret + +recite: + mov x8, lr + mov x11, x1 + ldr x12, [x11], #8 + cbz x12, .empty + +.next_line: + ldr x13, [x11], #8 + cbz x13, .last + + APPEND for + + mov x9, x12 + bl append + + APPEND the + + mov x9, x13 + bl append + + APPEND was + + mov x12, x13 + b .next_line + +.last: + APPEND and + + ldr x9, [x1] + bl append + + APPEND end + + mov lr, x8 + +.empty: + strb wzr, [x0] + ret diff --git a/solutions/arm64-assembly/pythagorean-triplet/1/pythagorean_triplet.s b/solutions/arm64-assembly/pythagorean-triplet/1/pythagorean_triplet.s new file mode 100644 index 0000000..5e8fb8e --- /dev/null +++ b/solutions/arm64-assembly/pythagorean-triplet/1/pythagorean_triplet.s @@ -0,0 +1,34 @@ +/* Dedicated to Shree DR.MDD */ +.text +.globl triplets_with_sum + +triplets_with_sum: + mov x15, #0 + mov x14, x0 + mov x0, #0 + cmp x14, #2 + blo .exit_here + +.loop_iter: + add x15, x15, #1 + sub x19, x14, x15 + sub x20, x19, x15 + lsl x21, x19, #1 + mul x20, x14, x20 + + udiv x16, x20, x21 + msub x22, x16, x21, x20 + cmp x15, x16 + bhs .exit_here + + cbnz x22, .loop_iter + + sub x17, x19, x16 + str x15, [x1], #8 + str x16, [x2], #8 + str x17, [x3], #8 + add x0, x0, #1 + b .loop_iter + +.exit_here: + ret diff --git a/solutions/arm64-assembly/queen-attack/1/queen_attack.s b/solutions/arm64-assembly/queen-attack/1/queen_attack.s new file mode 100644 index 0000000..01d862f --- /dev/null +++ b/solutions/arm64-assembly/queen-attack/1/queen_attack.s @@ -0,0 +1,33 @@ +.text +.globl can_create +.globl can_attack + +can_create: + cmp w0, #8 + bhs reject + + cmp w1, #8 + bhs reject + +accept: + mov x0, #1 + ret + +reject: + mov x0, #0 + ret + +can_attack: + sub x0, x0, x2 + cbz x0, accept + + sub x1, x1, x3 + cbz x1, accept + + cmp x0, x1 + beq accept + + add x0, x0, x1 + cmp x0, xzr + cset x0, eq + ret diff --git a/solutions/arm64-assembly/rail-fence-cipher/1/rail_fence_cipher.s b/solutions/arm64-assembly/rail-fence-cipher/1/rail_fence_cipher.s new file mode 100644 index 0000000..ececfdb --- /dev/null +++ b/solutions/arm64-assembly/rail-fence-cipher/1/rail_fence_cipher.s @@ -0,0 +1,79 @@ +/* Dedicated to Shree DR.MDD */ +.text +.globl encode +.globl decode + +encode: + mov x3, xzr + b process + +decode: + mov x3, #1 + b process + +process: + lsl x2, x2, #4 + mov x9, x2 + +.zero: + stp xzr, xzr, [sp, -16]! + add x9, x9, #-16 + cbnz x9, .zero + add x19, x2, #-16 + mov x4, #1 + +.traverse: + mov x21, xzr + mov x22, xzr + mov x23, #16 + +.next: + ldrb w9, [x1, x21] + cbz w9, .null_terminator + + ldr x25, [sp, x22] + add x24, x25, #1 + str x24, [sp, x22] + + mov x24, x21 + add x21, x21, #1 + + cbnz x4, .advance + + cbz x3, .write + + eor x24, x24, x25 + eor x25, x24, x25 + eor x24, x24, x25 + +.write: + ldrb w28, [x1, x24] + strb w28, [x0, x25] + +.advance: + adds x22, x22, x23 + ccmp x22, x19, #4, ne + cneg x23, x23, eq + b .next + +.null_terminator: + cbz x4, .return + + mov x26, xzr + mov x20, xzr + +.calculate_offsets: + ldr x27, [sp, x20] + str x26, [sp, x20] + add x26, x26, x27 + add x20, x20, #16 + cmp x20, x2 + bne .calculate_offsets + + mov x4, xzr + b .traverse + +.return: + strb wzr, [x0, x21] + add sp, sp, x2 + ret diff --git a/solutions/arm64-assembly/raindrops/1/raindrops.s b/solutions/arm64-assembly/raindrops/1/raindrops.s new file mode 100644 index 0000000..6f1edcd --- /dev/null +++ b/solutions/arm64-assembly/raindrops/1/raindrops.s @@ -0,0 +1,70 @@ +// Dedicated to Shree DR.MDD + +.section .rodata +pling: .string "Pling" +plang: .string "Plang" +plong: .string "Plong" + +.text +.globl convert + +.macro check_sound sound, next_check + adr x6, \sound + udiv x8, x1, x7 + msub x8, x8, x7, x1 + cbnz x8, \next_check + bl copy_string +.endm + +convert: + stp x29, x30, [sp, #-16]! + mov x29, sp + mov x11, x0 + + mov x7, #3 + check_sound pling, .check_plang + +.check_plang: + mov x7, #5 + check_sound plang, .check_plong + +.check_plong: + mov x7, #7 + check_sound plong, .check_number + +.check_number: + ldrb w6, [x11] + cmp w6, #'P' + beq .done + + mov x6, #10 + mov x7, xzr + +.next_digit: + add x7, x7, #1 + udiv x8, x1, x6 + msub x9, x8, x6, x1 + str x9, [sp, #-16]! + mov x1, x8 + cbnz x1, .next_digit + +.unwind: + ldr x1, [sp], #16 + add w1, w1, #'0' + strb w1, [x0], #1 + sub x7, x7, #1 + cbnz x7, .unwind + +.done: + strb wzr, [x0] + mov sp, x29 + ldp x29, x30, [sp], #16 + ret + +copy_string: + ldrb w7, [x6], #1 + cbz w7, .finish_copy + strb w7, [x0], #1 + b copy_string +.finish_copy: + ret diff --git a/solutions/arm64-assembly/rectangles/1/rectangles.s b/solutions/arm64-assembly/rectangles/1/rectangles.s new file mode 100644 index 0000000..f69cc2e --- /dev/null +++ b/solutions/arm64-assembly/rectangles/1/rectangles.s @@ -0,0 +1,85 @@ +/* Dedicated to Shree DR.MDD */ +.text +.globl rectangles + +rectangles: + mov x1, x0 + mov x0, xzr + +.top_row: + ldr x9, [x1], #8 + cbz x9, .return + + mov x10, x9 + +.left_column: + ldrb w11, [x10], #1 + cbz w11, .top_row + + cmp w11, #'+' + bne .left_column + + mov x12, x10 + +.right_column: + ldrb w13, [x12], #1 + cmp w13, #'-' + beq .right_column + + cmp w13, #'+' + bne .left_column + + sub x14, x10, x9 + sub x14, x14, #1 + sub x15, x12, x9 + sub x15, x15, #1 + mov x16, x1 + +.bottom_row: + ldr x17, [x16], #8 + cbz x17, .right_column + + mov w18, wzr + mov w19, wzr + + ldrb w20, [x17, x14] + cmp w20, #'|' + cinc w18, w18, eq + cmp w20, #'+' + cinc w19, w19, eq + + ldrb w20, [x17, x15] + cmp w20, #'|' + cinc w18, w18, eq + cmp w20, #'+' + cinc w19, w19, eq + + add w18, w18, w19 + cmp w18, #2 + bne .right_column + + cmp w19, #2 + bne .bottom_row + + mov x21, x14 + +.scan_bottom: + add x21, x21, #1 + cmp x21, x15 + beq .accept + + ldrb w20, [x17, x21] + cmp w20, #'-' + beq .scan_bottom + + cmp w20, #'+' + beq .scan_bottom + + b .bottom_row + +.accept: + add x0, x0, #1 + b .bottom_row + +.return: + ret diff --git a/solutions/arm64-assembly/resistor-color-duo/1/resistor_color_duo.s b/solutions/arm64-assembly/resistor-color-duo/1/resistor_color_duo.s new file mode 100644 index 0000000..3d0802a --- /dev/null +++ b/solutions/arm64-assembly/resistor-color-duo/1/resistor_color_duo.s @@ -0,0 +1,104 @@ +// Dedicated to Shree DR.MDD + +.section .rodata + +blk: .string "black" +brn: .string "brown" +redc: .string "red" +org: .string "orange" +ylw: .string "yellow" +grn: .string "green" +blu: .string "blue" +vio: .string "violet" +gry: .string "grey" +wht: .string "white" + +res_colors: + .quad blk + .quad brn + .quad redc + .quad org + .quad ylw + .quad grn + .quad blu + .quad vio + .quad gry + .quad wht + .quad 0 + +.text +.globl value + +value: + stp x29, x30, [sp, #-16]! + mov x29, sp + + ldr x1, [x0] + cbz x1, .invalid_val + ldr x2, [x0, #8] + cbz x2, .invalid_val + + sub sp, sp, #8 + str x2, [sp] + + mov x0, x1 + bl color_idx + + cmp x0, #-1 + beq .invalid_val + + ldr x1, [sp] + str x0, [sp] + + mov x0, x1 + bl color_idx + + cmp x0, #-1 + beq .invalid_val + + ldr x1, [sp] + add sp, sp, #8 + + mov x2, #10 + madd x0, x1, x2, x0 + + mov sp, x29 + ldp x29, x30, [sp], #16 + ret + +color_idx: + mov x1, x0 + mov x2, xzr + mov x8, #8 + +.next_col: + adrp x3, res_colors + add x3, x3, :lo12:res_colors + madd x4, x2, x8, x3 + ldr x3, [x4] + cbz x3, .invalid_idx + +.next_chr: + ldrb w4, [x1], #1 + ldrb w5, [x3], #1 + cbz w4, .check_match + cmp w4, w5 + bne .not_match + b .next_chr + +.check_match: + cbz w5, .done_idx + +.not_match: + mov x1, x0 + add x2, x2, #1 + b .next_col + +.done_idx: + mov x0, x2 + ret + +.invalid_val: +.invalid_idx: + mov x0, #-1 + ret diff --git a/solutions/arm64-assembly/resistor-color-trio/1/resistor_color_trio.s b/solutions/arm64-assembly/resistor-color-trio/1/resistor_color_trio.s new file mode 100644 index 0000000..89b4e3d --- /dev/null +++ b/solutions/arm64-assembly/resistor-color-trio/1/resistor_color_trio.s @@ -0,0 +1,122 @@ +// Dedicated to Shree DR.MDD + +.data +blk: .string "black" +brn: .string "brown" +rd: .string "red" +orgn: .string "orange" +ylw: .string "yellow" +grn: .string "green" +blu: .string "blue" +vio: .string "violet" +gry: .string "grey" +wht: .string "white" + +ohm: .string " ohms" +kohm: .string " kiloohms" +Mohm: .string " megaohms" +Gohm: .string " gigaohms" + +color_list: + .dword blk + .dword brn + .dword rd + .dword orgn + .dword ylw + .dword grn + .dword blu + .dword vio + .dword gry + .dword wht + .dword 0 + +unit_list: + .dword ohm + .dword kohm + .dword Mohm + .dword Gohm + .dword 0 + +.text +.globl color_code +.globl label + +color_code: + adrp x1, color_list + add x1, x1, :lo12:color_list + mov x2, x1 + +.next_color: + mov x3, x0 + ldr x4, [x2], #8 + +.compare_bytes: + ldrb w5, [x3], #1 + ldrb w6, [x4], #1 + cmp w5, w6 + bne .next_color + cbnz w5, .compare_bytes + + sub x2, x2, #8 + sub x0, x2, x1 + lsr x0, x0, #3 + ret + +label: + mov x10, x0 + mov x11, x1 + mov x12, lr + mov x13, #10 + + ldr x0, [x11], #8 + bl color_code + mov w14, w0 + + ldr x0, [x11], #8 + bl color_code + mov w15, w0 + + ldr x0, [x11] + bl color_code + add w0, w0, #1 + mov w16, #3 + udiv w17, w0, w16 + msub w18, w17, w16, w0 + + cbz w18, .div_exact + + cbz w14, .skip_first_digit + add w14, w14, #'0' + strb w14, [x10], #1 + +.skip_first_digit: + add w15, w15, #'0' + strb w15, [x10], #1 + cmp w18, #1 + beq .append_units + mov w15, #'0' + strb w15, [x10], #1 + b .append_units + +.div_exact: + add w14, w14, #'0' + strb w14, [x10], #1 + cbz w15, .append_units + mov w14, #'.' + strb w14, [x10], #1 + add w15, w15, #'0' + strb w15, [x10], #1 + +.append_units: + adrp x1, unit_list + add x1, x1, :lo12:unit_list + lsl w17, w17, #3 + ldr x2, [x1, x17] + +.copy_units: + ldrb w3, [x2], #1 + strb w3, [x10], #1 + cbnz w3, .copy_units + + mov lr, x12 + ret diff --git a/solutions/arm64-assembly/resistor-color/1/resistor_color.s b/solutions/arm64-assembly/resistor-color/1/resistor_color.s new file mode 100644 index 0000000..eb427e2 --- /dev/null +++ b/solutions/arm64-assembly/resistor-color/1/resistor_color.s @@ -0,0 +1,61 @@ +// Dedicated to Shree DR.MDD + +.data +blk: .string "black" +brn: .string "brown" +redc: .string "red" +org: .string "orange" +ylw: .string "yellow" +grn: .string "green" +blu: .string "blue" +vio: .string "violet" +gry: .string "grey" +wht: .string "white" + +color_tbl: + .dword blk + .dword brn + .dword redc + .dword org + .dword ylw + .dword grn + .dword blu + .dword vio + .dword gry + .dword wht + .dword 0 + +.text +.globl color_code +.globl colors + +color_code: + adrp x1, color_tbl + add x1, x1, :lo12:color_tbl + mov x2, x1 + +.next_color: + mov x3, x0 + ldr x4, [x2], #8 + cbz x4, .invalid_color + +.compare_chars: + ldrb w5, [x3], #1 + ldrb w6, [x4], #1 + cmp w5, w6 + bne .next_color + cbnz w5, .compare_chars + + sub x2, x2, #8 + sub x0, x2, x1 + lsr x0, x0, #3 + ret + +.invalid_color: + mov x0, #-1 + ret + +colors: + adrp x0, color_tbl + add x0, x0, :lo12:color_tbl + ret diff --git a/solutions/arm64-assembly/reverse-string/1/reverse_string.s b/solutions/arm64-assembly/reverse-string/1/reverse_string.s new file mode 100644 index 0000000..b011aa9 --- /dev/null +++ b/solutions/arm64-assembly/reverse-string/1/reverse_string.s @@ -0,0 +1,24 @@ +.text +.globl reverse +reverse: + mov x1, x0 +.scan: + ldrb w2, [x1], #1 + cbnz w2, .scan + + sub x1, x1, #1 + cmp x1, x0 + beq .done +.reverse: + sub x1, x1, #1 + cmp x1, x0 + beq .done + + ldrb w2, [x1] + ldrb w3, [x0] + strb w3, [x1] + strb w2, [x0], #1 + cmp x1, x0 + bne .reverse +.done: + ret \ No newline at end of file diff --git a/solutions/arm64-assembly/rna-transcription/1/rna_transcription.s b/solutions/arm64-assembly/rna-transcription/1/rna_transcription.s new file mode 100644 index 0000000..75dc01a --- /dev/null +++ b/solutions/arm64-assembly/rna-transcription/1/rna_transcription.s @@ -0,0 +1,22 @@ +// Dedicated to Shree DR.MDD + +.text +.globl to_rna + +.macro TRANSLATE from, to + mov w5, \to + cmp w3, \from + csel w4, w5, w4, eq +.endm + +to_rna: + ldrb w3, [x1], #1 + mov w4, w3 + TRANSLATE #'G', #'C' + TRANSLATE #'C', #'G' + TRANSLATE #'T', #'A' + TRANSLATE #'A', #'U' + strb w4, [x0], #1 + cbnz w3, to_rna + + ret diff --git a/solutions/arm64-assembly/roman-numerals/1/roman_numerals.s b/solutions/arm64-assembly/roman-numerals/1/roman_numerals.s new file mode 100644 index 0000000..29b150f --- /dev/null +++ b/solutions/arm64-assembly/roman-numerals/1/roman_numerals.s @@ -0,0 +1,51 @@ +// For my Shree DR.MDD +.macro ONE_SYMBOL tag, val, charcode + mov x5, \val + mov w6, \charcode + +.check_\tag: + cmp x1, x5 + blt .done_\tag + + strb w6, [x0], #1 + sub x1, x1, x5 + b .check_\tag + +.done_\tag: +.endm + +.macro TWO_SYMBOL tag, val, firstcode, secondcode + mov x5, \val + +.check_\tag: + cmp x1, x5 + blt .done_\tag + + mov w6, \firstcode + mov w7, \secondcode + strb w6, [x0], #1 + strb w7, [x0], #1 + sub x1, x1, x5 + +.done_\tag: +.endm + +.text +.globl roman + +roman: + ONE_SYMBOL M, #1000, #'M' + TWO_SYMBOL CM, #900, #'C', #'M' + ONE_SYMBOL D, #500, #'D' + TWO_SYMBOL CD, #400, #'C', #'D' + ONE_SYMBOL C, #100, #'C' + TWO_SYMBOL XC, #90, #'X', #'C' + ONE_SYMBOL L, #50, #'L' + TWO_SYMBOL XL, #40, #'X', #'L' + ONE_SYMBOL X, #10, #'X' + TWO_SYMBOL IX, #9, #'I', #'X' + ONE_SYMBOL V, #5, #'V' + TWO_SYMBOL IV, #4, #'I', #'V' + ONE_SYMBOL I, #1, #'I' + strb wzr, [x0] + ret diff --git a/solutions/arm64-assembly/rotational-cipher/1/rotational_cipher.s b/solutions/arm64-assembly/rotational-cipher/1/rotational_cipher.s new file mode 100644 index 0000000..0dd4f21 --- /dev/null +++ b/solutions/arm64-assembly/rotational-cipher/1/rotational_cipher.s @@ -0,0 +1,27 @@ +// Dedicated to Shree DR.MDD +.text +.globl rotate + +rotate: + +.read_loop: + ldrb w9, [x1], #1 + and w12, w9, #32 + sub w10, w9, w12 + sub w10, w10, #'A' + cmp w10, #26 + bhs .store_byte + + add w10, w10, #'A' + add w10, w10, w2 + sub w11, w10, #26 + cmp w10, #'Z' + csel w10, w10, w11, le + + orr w9, w10, w12 + +.store_byte: + strb w9, [x0], #1 + cbnz w9, .read_loop + + ret diff --git a/solutions/arm64-assembly/run-length-encoding/1/run_length_encoding.s b/solutions/arm64-assembly/run-length-encoding/1/run_length_encoding.s new file mode 100644 index 0000000..d54dd26 --- /dev/null +++ b/solutions/arm64-assembly/run-length-encoding/1/run_length_encoding.s @@ -0,0 +1,83 @@ +.text +.globl encode +.globl decode + +/* extern void encode(char *buffer, const char *string); */ +encode: + mov w10, #10 + +.encode_next: + mov x2, x1 /* address at start of run */ + ldrb w3, [x1], #1 /* read byte, post-increment */ + cbz w3, terminate + +.encode_read: + ldrb w4, [x1], #1 /* read byte, post-increment */ + cmp w4, w3 + beq .encode_read + + sub x1, x1, #1 /* address of first byte after run */ + mov x4, x0 + sub x2, x1, x2 /* length of run */ + cmp x2, #1 + beq .encode_write + +.encode_digit: + udiv w5, w2, w10 /* quotient */ + msub w6, w5, w10, w2 /* remainder */ + mov w2, w5 + add w6, w6, #'0' + strb w6, [x0], #1 + cbnz w2, .encode_digit + + mov x5, x0 + +.encode_reverse: + sub x5, x5, #1 + cmp x5, x4 + beq .encode_write /* middle byte of odd length string */ + + ldrb w6, [x5] + ldrb w7, [x4] + strb w6, [x4], #1 /* store byte, post-increment */ + strb w7, [x5] + cmp x5, x4 + bne .encode_reverse + /* middle bytes of even length string */ + +.encode_write: + strb w3, [x0], #1 + b .encode_next + +terminate: + strb wzr, [x0] + ret + +/* extern void decode(char *buffer, const char *string); */ +decode: + mov w10, #10 + +.decode_next: + mov w2, wzr /* count */ + +.decode_read: + ldrb w3, [x1], #1 /* read byte, post-increment */ + cbz w3, terminate + + sub w4, w3, #'0' + cmp w4, w10 + blo .decode_digit + + cmp w2, wzr + cinc w2, w2, eq + +.decode_write: + strb w3, [x0], #1 /* write byte, post-increment */ + sub w2, w2, #1 + cbnz w2, .decode_write + + b .decode_next + +.decode_digit: + madd w2, w2, w10, w4 + b .decode_read \ No newline at end of file diff --git a/solutions/arm64-assembly/say/1/say.s b/solutions/arm64-assembly/say/1/say.s new file mode 100644 index 0000000..e81ad1e --- /dev/null +++ b/solutions/arm64-assembly/say/1/say.s @@ -0,0 +1,206 @@ +.data + +zero: .string "zero" +one: .string "one" +two: .string "two" +three: .string "three" +four: .string "four" +five: .string "five" +six: .string "six" +seven: .string "seven" +eight: .string "eight" +nine: .string "nine" +ten: .string "ten" +eleven: .string "eleven" +twelve: .string "twelve" +thirteen: + .string "thirteen" +fourteen: + .string "fourteen" +fifteen: + .string "fifteen" +sixteen: + .string "sixteen" +seventeen: + .string "seventeen" +eighteen: + .string "eighteen" +nineteen: + .string "nineteen" +twenty: .string "twenty" +thirty: .string "thirty" +forty: .string "forty" +fifty: .string "fifty" +sixty: .string "sixty" +seventy: + .string "seventy" +eighty: .string "eighty" +ninety: .string "ninety" +hundred: + .string "hundred" +thousand: + .string "thousand" +million: + .string "million" +billion: + .string "billion" + +number_array: + .dword zero + .dword one + .dword two + .dword three + .dword four + .dword five + .dword six + .dword seven + .dword eight + .dword nine + .dword ten + .dword eleven + .dword twelve + .dword thirteen + .dword fourteen + .dword fifteen + .dword sixteen + .dword seventeen + .dword eighteen + .dword nineteen + .dword twenty + .dword thirty + .dword forty + .dword fifty + .dword sixty + .dword seventy + .dword eighty + .dword ninety + +.macro LOAD register, label + adrp \register, \label + add \register, \register, :lo12:\label +.endm + +/* register must be the address of a non-empty word */ +.macro APPEND register + ldrb w8, [\register], #1 /* load byte, post-increment */ + +.copy_\@: + strb w8, [x0], #1 /* store byte, post-increment */ + ldrb w8, [\register], #1 /* load byte, post-increment */ + cbnz w8, .copy_\@ + + strb w23, [x0], #1 /* ' ' */ +.endm + +/* quotient must not be the same register as dividend or divisor */ +.macro DIVIDE quotient, remainder, dividend, divisor + udiv \quotient, \dividend, \divisor + msub \remainder, \quotient, \divisor, \dividend +.endm + + +.text +.globl say + + +/* void say_digit_group(char *buffer, int64_t number, const char* place); */ +say_digit_group: + cbz x1, .say_digit_group_return + + DIVIDE x3, x9, x1, x26 /* divide by 100 */ + cbz x3, .say_digit_group_tens + + lsl x3, x3, #3 + ldr x3, [x19, x3] + APPEND x3 + + mov x3, x21 + APPEND x3 + +.say_digit_group_tens: + cbz x9, .say_digit_group_place + + cmp x9, 20 + ble .say_digit_group_units + + DIVIDE x3, x9, x9, x25 /* divide by 10 */ + + lsl x3, x3, #3 + ldr x3, [x20, x3] + APPEND x3 + + cbz x9, .say_digit_group_place + + strb w24, [x0, #-1] /* replace space with '-' */ + +.say_digit_group_units: + lsl x3, x9, #3 + ldr x3, [x19, x3] + APPEND x3 + +.say_digit_group_place: + cbz x2, .say_digit_group_return + APPEND x2 + +.say_digit_group_return: + ret + + +/* extern void say(char *buffer, int64_t number); */ +say: + stp x19, x20, [sp, #-64]! /* preserve registers */ + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp x25, x26, [sp, #48] + + LOAD x19, number_array + add x20, x19, #144 /* tens array */ + LOAD x21, hundred + mov x22, lr /* preserve return address */ + mov w23, #' ' + mov w24, #'-' + mov x25, #10 + mov x26, #100 + + cbz x1, .zero + + mov x8, #1000 + DIVIDE x12, x11, x1, x8 /* x11 ones */ + DIVIDE x13, x12, x12, x8 /* x12 thousands */ + DIVIDE x1, x13, x13, x8 /* x13 millions, x1 billions */ + + cmp x1, x8 + bpl .out_of_range + + LOAD x2, billion + bl say_digit_group + + mov x1, x13 + LOAD x2, million + bl say_digit_group + + mov x1, x12 + LOAD x2, thousand + bl say_digit_group + + mov x1, x11 + mov x2, xzr /* units */ + bl say_digit_group + +.return: + strb wzr, [x0, #-1] /* remove trailing space */ + mov lr, x22 + ldp x25, x26, [sp, #48] /* restore registers */ + ldp x23, x24, [sp, #32] + ldp x21, x22, [sp, #16] + ldp x19, x20, [sp], #64 + ret + +.zero: + ldr x3, [x19] + APPEND x3 + b .return + +.out_of_range: + add x0, x0, #1 /* .return expects trailing "space" */ + b .return diff --git a/solutions/arm64-assembly/scrabble-score/1/scrabble_score.s b/solutions/arm64-assembly/scrabble-score/1/scrabble_score.s new file mode 100644 index 0000000..38f4a06 --- /dev/null +++ b/solutions/arm64-assembly/scrabble-score/1/scrabble_score.s @@ -0,0 +1,51 @@ +.section .rodata + +letter_scores: + .byte 1 // A + .byte 3 // B + .byte 3 // C + .byte 2 // D + .byte 1 // E + .byte 4 // F + .byte 2 // G + .byte 4 // H + .byte 1 // I + .byte 8 // J + .byte 5 // K + .byte 1 // L + .byte 3 // M + .byte 1 // N + .byte 1 // O + .byte 3 // P + .byte 10 // Q + .byte 1 // R + .byte 1 // S + .byte 1 // T + .byte 1 // U + .byte 4 // V + .byte 4 // W + .byte 8 // X + .byte 4 // Y + .byte 10 // Z + +.text +.globl score + +score: + mov x1, x0 // Copy input address + mov x0, xzr // Initialize output + adr x2, letter_scores // Load address of letter scores array + +.next: + ldrb w3, [x1], #1 // Get next input byte + cbz w3, .return // More input letters? + orr w3, w3, #32 // Convert English letter to lower case + sub w3, w3, #'a' // Convert to letter score index + cmp w3, #25 // Array bounds check (skip non-letters) + bhi .next // Unsigned > comparison + ldrb w4, [x2, x3] // Get score of current letter + add x0, x0, x4 // Add to total word score + b .next + +.return: + ret \ No newline at end of file diff --git a/solutions/arm64-assembly/secret-handshake/1/secret_handshake.s b/solutions/arm64-assembly/secret-handshake/1/secret_handshake.s new file mode 100644 index 0000000..fac42dc --- /dev/null +++ b/solutions/arm64-assembly/secret-handshake/1/secret_handshake.s @@ -0,0 +1,57 @@ +// Dedicated to Shree DR.MDD +.data +wink: .string "wink, " +double: .string "double blink, " +close: .string "close your eyes, " +jump: .string "jump, " + +forwards: + .dword wink + .dword double + .dword close + .dword jump + +backwards: + .dword jump + .dword close + .dword double + .dword wink + +.text +.globl commands + +commands: + and x7, x1, #31 + adrp x8, forwards + add x8, x8, :lo12:forwards + tst x7, #16 + beq .begin + + adrp x8, backwards + add x8, x8, :lo12:backwards + rbit w7, w7 + lsr w7, w7, #28 + +.begin: + cbz x7, .empty_cmd + +.next_check: + ldr x9, [x8], #8 + and x10, x7, #1 + lsr x7, x7, #1 + cbz x10, .next_check + +.copy_loop: + ldrb w11, [x9], #1 + strb w11, [x0], #1 + cbnz w11, .copy_loop + + sub x0, x0, #1 + cbnz x7, .next_check + + strb wzr, [x0, #-2] + ret + +.empty_cmd: + strb wzr, [x0] + ret diff --git a/solutions/arm64-assembly/sieve/1/sieve.s b/solutions/arm64-assembly/sieve/1/sieve.s new file mode 100644 index 0000000..b97bc4b --- /dev/null +++ b/solutions/arm64-assembly/sieve/1/sieve.s @@ -0,0 +1,43 @@ +.text +.globl sieve + +sieve: + add x2, x1, #16 + and x2, x2, #-16 + mov x3, sp + sub sp, sp, x2 + mov x4, #-1 + mov x5, sp + +.fill: + stp x4, x4, [x3, #-16]! + cmp x3, x5 + bne .fill + + mov x3, x0 + mov x4, #1 + +.search: + add x4, x4, #1 + cmp x1, x4 + blo .exit + + ldrb w5, [sp, x4] + cbz w5, .search + + str x4, [x3], #8 + mul x5, x4, x4 + +.mark: + cmp x1, x5 + blo .search + + strb wzr, [sp, x5] + add x5, x5, x4 + b .mark + +.exit: + sub x0, x3, x0 + lsr x0, x0, #3 + add sp, sp, x2 + ret diff --git a/solutions/arm64-assembly/space-age/1/space_age.s b/solutions/arm64-assembly/space-age/1/space_age.s new file mode 100644 index 0000000..92cdc1f --- /dev/null +++ b/solutions/arm64-assembly/space-age/1/space_age.s @@ -0,0 +1,31 @@ +.equ MERCURY, 1 +.equ VENUS, 2 +.equ EARTH, 3 +.equ MARS, 4 +.equ JUPITER, 5 +.equ SATURN, 6 +.equ URANUS, 7 +.equ NEPTUNE, 8 +.section .data +year: .double 31557600.0 + .double 0.2408467 + .double 0.61519726 + .double 1.0 + .double 1.8808158 + .double 11.862615 + .double 29.447498 + .double 84.016846 + .double 164.79132 +.text +.globl age +age: + scvtf d0, w1 + adrp x9, year + add x9, x9, :lo12:year + ldr d1, [x9] + fdiv d0, d0, d1 + lsl w0, w0, #3 + add x9, x9, x0 + ldr d1, [x9] + fdiv d0, d0, d1 + ret \ No newline at end of file diff --git a/solutions/arm64-assembly/spiral-matrix/1/spiral_matrix.s b/solutions/arm64-assembly/spiral-matrix/1/spiral_matrix.s new file mode 100644 index 0000000..532fdf6 --- /dev/null +++ b/solutions/arm64-assembly/spiral-matrix/1/spiral_matrix.s @@ -0,0 +1,40 @@ +// For my Shree DR.MDD +.text +.globl spiral_matrix + +spiral_matrix: + mul w4, w1, w1 + mov w5, #1 + mov x6, #4 + mov x7, x6 + lsl x8, x1, #2 + add x9, x7, x8 + add w1, w1, #-1 + +.outer_loop: + mov w10, w1 + +.inner_loop: + cmp w5, w4 + bgt .return_label + + str w5, [x0] + add w5, w5, #1 + add x0, x0, x7 + add w10, w10, #-1 + cbnz w10, .inner_loop + + neg x11, x7 + mov x7, x8 + mov x8, x11 + + cmp x7, x6 + bne .outer_loop + + add x0, x0, x9 + add w1, w1, #-2 + b .outer_loop + +.return_label: + mov w0, w4 + ret diff --git a/solutions/arm64-assembly/square-root/1/square_root.s b/solutions/arm64-assembly/square-root/1/square_root.s new file mode 100644 index 0000000..9ba69d0 --- /dev/null +++ b/solutions/arm64-assembly/square-root/1/square_root.s @@ -0,0 +1,25 @@ +// For Shree DR.MDD + +.text +.globl square_root + +square_root: + mov x5, x0 /* radicand */ + + clz x0, x5 /* count leading zero bits */ + mov x6, #64 + sub x0, x6, x0 /* number of bits excluding leading zeros */ + lsr x0, x0, #1 /* halve the bit count */ + mov x6, #1 + lsl x0, x6, x0 /* initial estimate */ + +.iterate: + mov x6, x0 /* current estimate */ + add x7, x6, #1 + madd x7, x7, x6, x5 /* (estimate+1)*estimate + radicand */ + lsl x8, x6, #1 /* 2*estimate */ + udiv x0, x7, x8 /* new estimate */ + cmp x0, x6 + bne .iterate + + ret diff --git a/solutions/arm64-assembly/state-of-tic-tac-toe/1/state_of_tic_tac_toe.s b/solutions/arm64-assembly/state-of-tic-tac-toe/1/state_of_tic_tac_toe.s new file mode 100644 index 0000000..e06ddbb --- /dev/null +++ b/solutions/arm64-assembly/state-of-tic-tac-toe/1/state_of_tic_tac_toe.s @@ -0,0 +1,87 @@ +// For my Shree DR.MDD +.equ ONGOING, 0 +.equ DRAW, 1 +.equ WIN, 2 +.equ INVALID, 3 + +.data +lines: .hword 0x007, 0x070, 0x700, 0x111, 0x222, 0x444, 0x124, 0x421, 0 + +.text +.globl gamestate + +gamestate: + adrp x10, lines + add x10, x10, :lo12:lines + + mov w11, wzr /* X bitset */ + mov w12, wzr /* O bitset */ + mov w13, wzr /* X count */ + mov w14, wzr /* O count */ + +.read_next_row: + ldr x15, [x0], #8 + cbz x15, .check_count + + lsl w11, w11, #1 + lsl w12, w12, #1 + +.read_next_mark: + ldrb w16, [x15], #1 + cbz w16, .read_next_row + + lsl w11, w11, #1 + lsl w12, w12, #1 + cmp w16, #'X' + cinc w11, w11, eq + cinc w13, w13, eq + cmp w16, #'O' + cinc w12, w12, eq + cinc w14, w14, eq + b .read_next_mark + +.check_count: + cmp w14, w13 + bgt .return_invalid + + add w16, w14, #1 + cmp w13, w16 + bgt .return_invalid + + mov w17, wzr /* X won */ + mov w18, wzr /* O won */ + mov w19, #1 + +.scan_lines: + ldrh w20, [x10], #2 + cbz w20, .determine_state + + and w21, w11, w20 + cmp w21, w20 + csel w17, w19, w17, eq + and w21, w12, w20 + cmp w21, w20 + csel w18, w19, w18, eq + b .scan_lines + +.determine_state: + orr w21, w17, w18 + cbnz w21, .win_detected + + mov x0, ONGOING + mov x1, DRAW + add w13, w13, w14 + cmp w13, #9 + csel x0, x1, x0, eq + ret + +.win_detected: + mov x2, WIN + mov x3, INVALID + cmp w17, w18 + csel x0, x3, x2, eq + ret + +.return_invalid: + mov x0, INVALID + ret diff --git a/solutions/arm64-assembly/sublist/1/sublist.s b/solutions/arm64-assembly/sublist/1/sublist.s new file mode 100644 index 0000000..c7b25f8 --- /dev/null +++ b/solutions/arm64-assembly/sublist/1/sublist.s @@ -0,0 +1,79 @@ +// Dedicated to Shree DR.MDD + +.equ UNEQUAL, 0 +.equ EQUAL, 1 +.equ SUBLIST, 2 +.equ SUPERLIST, 3 + +.text +.globl sublist + +sublist: + cmp w1, w3 + bne .len_mismatch + + cbz w1, .lists_equal + + lsl x15, x1, #3 + add x15, x0, x15 + +.scan_full: + ldr x20, [x0], #8 + ldr x21, [x2], #8 + + cmp x20, x21 + bne .lists_unequal + + cmp x0, x15 + bne .scan_full + +.lists_equal: + mov x0, EQUAL + ret + +.len_mismatch: + mov x22, SUBLIST + cmp x1, x3 + blt .start_nested_check + + mov x22, SUPERLIST + mov x15, x0 + mov x0, x2 + mov x2, x15 + mov x16, x1 + mov x1, x3 + mov x3, x16 + +.start_nested_check: + cbz x1, .prefix_match + + lsl x15, x1, #3 + add x15, x0, x15 + b .prepare_scan + +.drop_head: + add x2, x2, #8 + add x3, x3, #-1 + cmp x3, x1 + blt .lists_unequal + +.prepare_scan: + mov x17, x0 + mov x18, x2 + +.prefix_loop: + ldr x19, [x17], #8 + ldr x23, [x18], #8 + cmp x19, x23 + bne .drop_head + + cmp x17, x15 + bne .prefix_loop + +.prefix_match: + mov x0, x22 + ret + +.lists_unequal: + mov x0, UNEQUAL + ret diff --git a/solutions/arm64-assembly/sum-of-multiples/1/sum_of_multiples.s b/solutions/arm64-assembly/sum-of-multiples/1/sum_of_multiples.s new file mode 100644 index 0000000..d3b59c3 --- /dev/null +++ b/solutions/arm64-assembly/sum-of-multiples/1/sum_of_multiples.s @@ -0,0 +1,32 @@ +// For Shree DR.MDD + +.text +.globl sum + +sum: + lsl x6, x2, #3 /* size of factors array in bytes */ + add x6, x1, x6 /* end pointer of factors array */ + mov x7, x0 /* store original limit */ + mov x0, xzr /* initialize total sum */ + cbz x7, .done + +.check_number: + sub x7, x7, #1 /* current number to check */ + cbz x7, .done + + mov x8, x1 /* start of factors array */ + +.check_factor: + cmp x8, x6 + beq .check_number + + ldr x9, [x8], #8 /* load factor and increment pointer */ + udiv x10, x7, x9 /* compute quotient */ + msub x11, x10, x9, x7 /* compute remainder */ + cbnz x11, .check_factor + + add x0, x0, x7 /* add multiple to total */ + b .check_number + +.done: + ret diff --git a/solutions/arm64-assembly/triangle/1/triangle.s b/solutions/arm64-assembly/triangle/1/triangle.s new file mode 100644 index 0000000..d2fddc3 --- /dev/null +++ b/solutions/arm64-assembly/triangle/1/triangle.s @@ -0,0 +1,62 @@ +// For Shree DR.MDD + +.text +.globl equilateral +.globl isosceles +.globl scalene + +equilateral: + cbz x0, reject_tri + + cmp x0, x1 + bne reject_tri + + cmp x0, x2 + bne reject_tri + +accept_tri: + mov x0, #1 + ret + +isosceles: + cmp x0, x1 + beq triangle_check + + cmp x0, x2 + beq triangle_check + + cmp x1, x2 + beq triangle_check + +reject_tri: + mov x0, xzr + ret + +scalene: + cmp x0, x1 + beq reject_tri + + cmp x0, x2 + beq reject_tri + + cmp x1, x2 + beq reject_tri + +triangle_check: + cbz x0, reject_tri + cbz x1, reject_tri + cbz x2, reject_tri + + add x4, x1, x2 + cmp x0, x4 + bgt reject_tri + + add x4, x0, x2 + cmp x1, x4 + bgt reject_tri + + add x4, x0, x1 + cmp x2, x4 + bgt reject_tri + + b accept_tri diff --git a/solutions/arm64-assembly/twelve-days/1/twelve_days.s b/solutions/arm64-assembly/twelve-days/1/twelve_days.s new file mode 100644 index 0000000..1f67d17 --- /dev/null +++ b/solutions/arm64-assembly/twelve-days/1/twelve_days.s @@ -0,0 +1,96 @@ +// Dedicated to Shree DR.MDD + +.data +on: .string "On the " +day: .string " day of Christmas my true love gave to me: " +gifts: .string "twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + +first: .string "first" +second: .string "second" +third: .string "third" +fourth: .string "fourth" +fifth: .string "fifth" +sixth: .string "sixth" +seventh: + .string "seventh" +eighth: .string "eighth" +ninth: .string "ninth" +tenth: .string "tenth" +eleventh: + .string "eleventh" +twelfth: + .string "twelfth" + +ordinals: + .dword 0 + .dword first + .dword second + .dword third + .dword fourth + .dword fifth + .dword sixth + .dword seventh + .dword eighth + .dword ninth + .dword tenth + .dword eleventh + .dword twelfth + +offsets: + .dword 0 + .dword 235 + .dword 213 + .dword 194 + .dword 174 + .dword 157 + .dword 137 + .dword 113 + .dword 90 + .dword 69 + .dword 48 + .dword 26 + .dword 0 + +.macro LOAD_REG reg, lbl + adrp \reg, \lbl + add \reg, \reg, :lo12:\lbl +.endm + +.macro COPY_STRING name +.copy_loop_\name: + ldrb w20, [x9], #1 + strb w20, [x0], #1 + cbnz w20, .copy_loop_\name + sub x0, x0, #1 +.endm + +.text +.globl recite + +recite: + LOAD_REG x3, on + LOAD_REG x4, day + LOAD_REG x5, gifts + LOAD_REG x6, ordinals + LOAD_REG x7, offsets + lsl x1, x1, #3 + lsl x2, x2, #3 + +.loop_line: + mov x9, x3 + COPY_STRING on + + ldr x9, [x6, x1] + COPY_STRING ordinal + + mov x9, x4 + COPY_STRING day + + ldr x9, [x7, x1] + add x9, x5, x9 + COPY_STRING gift + + cmp x1, x2 + add x1, x1, #8 + bne .loop_line + ret diff --git a/solutions/arm64-assembly/two-fer/1/two_fer.s b/solutions/arm64-assembly/two-fer/1/two_fer.s new file mode 100644 index 0000000..536af3a --- /dev/null +++ b/solutions/arm64-assembly/two-fer/1/two_fer.s @@ -0,0 +1,38 @@ +// Dedicated to Shree DR.MDD + +.section .rodata +prefix: .string "One for " +you: .string "you" +suffix: .string ", one for me." + +.macro LOAD str + adrp x4, \str + add x4, x4, :lo12:\str +.endm + +.macro APPEND str + +.copy_loop_\str: + ldrb w5, [x4], #1 + strb w5, [x0], #1 + cbnz w5, .copy_loop_\str + + sub x0, x0, #1 +.endm + +.text +.globl two_fer + +two_fer: + LOAD prefix + APPEND prefix + + LOAD you + tst x1, x1 + csel x4, x1, x4, ne + APPEND you + + LOAD suffix + APPEND suffix + + ret diff --git a/solutions/arm64-assembly/variable-length-quantity/1/variable_length_quantity.s b/solutions/arm64-assembly/variable-length-quantity/1/variable_length_quantity.s new file mode 100644 index 0000000..f8c502e --- /dev/null +++ b/solutions/arm64-assembly/variable-length-quantity/1/variable_length_quantity.s @@ -0,0 +1,79 @@ +// For my Shree DR.MDD +.text +.globl encode +.globl decode + +encode: + lsl x4, x2, #2 /* size in bytes */ + add x4, x1, x4 /* end of input */ + mov x5, x0 /* output start */ + +.encode_loop: + cmp x1, x4 + beq .encode_done + + ldr w6, [x1], #4 + cmp w6, #127 + bls .single + + lsr w7, w6, #7 + cmp w7, #127 + bls .double + + lsr w8, w7, #7 + cmp w8, #127 + bls .triple + + lsr w9, w8, #7 + cmp w9, #127 + bls .quad + + lsr w10, w9, #7 + orr w10, w10, #128 + strb w10, [x0], #1 + +.quad: + orr w9, w9, #128 + strb w9, [x0], #1 + +.triple: + orr w8, w8, #128 + strb w8, [x0], #1 + +.double: + orr w7, w7, #128 + strb w7, [x0], #1 + +.single: + and w6, w6, #127 + strb w6, [x0], #1 + b .encode_loop + +.encode_done: + sub x0, x0, x5 + ret + +decode: + add x4, x1, x2 /* end of input */ + mov x5, x0 /* output start */ + +.decode_loop: + mov w6, wzr + cmp x1, x4 + beq .decode_done + +.read_byte: + ldrb w7, [x1], #1 + lsl w6, w6, #7 + and w8, w7, #127 + orr w6, w6, w8 + tst w7, #128 + bne .read_byte + + str w6, [x0], #4 + b .decode_loop + +.decode_done: + sub x0, x0, x5 + lsr x0, x0, #2 + ret diff --git a/solutions/arm64-assembly/wordy/1/wordy.s b/solutions/arm64-assembly/wordy/1/wordy.s new file mode 100644 index 0000000..5ffb54d --- /dev/null +++ b/solutions/arm64-assembly/wordy/1/wordy.s @@ -0,0 +1,118 @@ +.equ WHAT_IS, 8 +.equ PLUS, 8 +.equ MINUS, 16 +.equ MULTIPLIED_BY, 24 +.equ DIVIDED_BY, 32 +.equ QUESTION_MARK, 40 + +.data +what_is: .string "What is " +plus: .string " plus " +minus: .string " minus " +multiplied_by: .string " multiplied by " +divided_by: .string " divided by " +question_mark: .string "?" + +word_array: + .quad what_is + .quad 0 + .quad plus + .quad minus + .quad multiplied_by + .quad divided_by + .quad question_mark + .quad 0 + +.text +.globl answer + +read_word: + mov x9, x1 + mov x2, x14 + b .next + +.compare: + ldrb w11, [x10], #1 + cbz w11, .match + ldrb w12, [x1], #1 + cmp w12, w11 + beq .compare + +.next: + mov x1, x9 + ldr x10, [x2], #8 + cbnz x10, .compare + b reject + +.match: + sub x2, x2, x14 + ret + +read_number: + mov w10, #10 + ldrb w11, [x1] + cmp w11, #'-' + cset x9, eq + cinc x1, x1, eq + mov x3, xzr + ldrb w11, [x1], #1 + add w11, w11, #-48 + cmp w11, w10 + bhs reject + +.accept_digit: + madd x3, x3, x10, x11 + ldrb w11, [x1], #1 + add w11, w11, #-48 + cmp w11, w10 + blo .accept_digit + add x1, x1, #-1 + cmp x9, xzr + cneg x3, x3, ne + ret + +answer: + mov x15, lr + adrp x14, word_array + add x14, x14, :lo12:word_array + bl read_word + add x14, x14, #16 + bl read_number + mov x4, x3 + +.read_operation: + bl read_word + cmp x2, QUESTION_MARK + beq .success + bl read_number + cmp x2, MINUS + beq .subtract + cmp x2, MULTIPLIED_BY + beq .multiply + cmp x2, DIVIDED_BY + beq .divide + +.add: + add x4, x4, x3 + b .read_operation + +.subtract: + sub x4, x4, x3 + b .read_operation + +.multiply: + mul x4, x4, x3 + b .read_operation + +.divide: + sdiv x4, x4, x3 + b .read_operation + +.success: + str x4, [x0] + mov x0, #1 + ret x15 + +reject: + mov x0, xzr + ret x15 diff --git a/solutions/arm64-assembly/yacht/1/yacht.s b/solutions/arm64-assembly/yacht/1/yacht.s new file mode 100644 index 0000000..822882d --- /dev/null +++ b/solutions/arm64-assembly/yacht/1/yacht.s @@ -0,0 +1,154 @@ +.equ CHOICE, 0 +.equ ONES, 1 +.equ TWOS, 2 +.equ THREES, 3 +.equ FOURS, 4 +.equ FIVES, 5 +.equ SIXES, 6 +.equ LITTLE_STRAIGHT, 7 +.equ BIG_STRAIGHT, 8 +.equ FULL_HOUSE, 9 +.equ FOUR_OF_A_KIND, 10 +.equ YACHT, 11 + +.text +.globl score + + +/* void sort(uint16_t *dice) */ +sort: + mov w9, #2 + +.outer: + ldrh w12, [x0, x9] + mov w10, w9 + +.inner: + cbz w10, .exit + sub w11, w10, #2 + + ldrh w13, [x0, x11] + cmp w13, w12 + ble .exit + + strh w13, [x0, x10] + mov w10, w11 + b .inner + +.exit: + strh w12, [x0, x10] + + add w9, w9, #2 + cmp w9, #8 + ble .outer + + ret + + + +score: + mov w2, w0 + mov x15, lr + + ldr x10, [x1] + ldrh w11, [x1, #8] + stp x10, x11, [sp, #-16]! + mov x0, sp + bl sort + + mov x3, sp + add x4, x3, #10 + mov x0, xzr + mov w9, SIXES + cmp w2, w9 + ble .total + + ldrh w10, [x3] + ldrh w11, [x3, #2] + ldrh w12, [x3, #4] + ldrh w13, [x3, #6] + ldrh w14, [x3, #8] + + mov w9, LITTLE_STRAIGHT + cmp w2, w9 + beq .little_straight + + mov w9, BIG_STRAIGHT + cmp w2, w9 + beq .big_straight + + mov w9, FULL_HOUSE + cmp w2, w9 + beq .full_house + + mov w9, FOUR_OF_A_KIND + cmp w2, w9 + beq .four_of_a_kind + +.yacht: + mov w9, #50 + cmp w10, w14 + csel w0, w9, wzr, eq + b .return + +.little_straight: + mov w9, #30 + cmp w10, 1 + ccmp w11, 2, #0, eq + ccmp w12, 3, #0, eq + ccmp w13, 4, #0, eq + ccmp w14, 5, #0, eq + csel w0, w9, wzr, eq + b .return + +.big_straight: + mov w9, #30 + cmp w10, 2 + ccmp w11, 3, #0, eq + ccmp w12, 4, #0, eq + ccmp w13, 5, #0, eq + ccmp w14, 6, #0, eq + csel w0, w9, wzr, eq + b .return + +.full_house: + cmp w10, w11 + ccmp w13, w14, #0, eq + ccmp w11, w13, #4, eq + beq .return + + mov w2, wzr + cmp w11, w12 + ccmp w12, w13, #4, ne + beq .total + + b .return + +.four_of_a_kind: + mov w2, w12 + + neg w0, w12 + cmp w10, w14 + csel w0, w0, wzr, eq + + cmp w10, w13 + ccmp w11, w14, #4, ne + bne .return + +.total: + ldrh w10, [x3], #2 + cbz w2, .add + + cmp w10, w2 + bne .next + +.add: + add w0, w0, w10 + +.next: + cmp x3, x4 + bne .total + +.return: + add sp, sp, #16 + ret x15 \ No newline at end of file