diff --git a/macros/README.md b/macros/README.md index 3126143..5e8591e 100644 --- a/macros/README.md +++ b/macros/README.md @@ -79,7 +79,13 @@ These resolve to: `.cfi_startproc` and `.cfi_endproc` respectively. ### MIN and MAX -Handy more readable macros for determining minima and maxima. +Handy more readable macros for determining minima and maxima. Note that +the macro performs a `cmp` which subtracts `src_b` from `src_a` +(discarding the results) in order to set the flags to be interpreted by +the following `csel`. + +Thank you to u/TNorthover for nudge to add the cmp directly into the +macro. Signature: diff --git a/macros/README.pdf b/macros/README.pdf index 8ee66da..dd12446 100644 Binary files a/macros/README.pdf and b/macros/README.pdf differ diff --git a/macros/double.S b/macros/double.S index 8c772c4..58c334c 100644 --- a/macros/double.S +++ b/macros/double.S @@ -1,3 +1,6 @@ +/* A test program. +*/ + #include "apple-linux-convergence.S" .text @@ -23,7 +26,6 @@ MAIN END_PROC dbl: .double -0.55 -flt: .float 0.125 -fmt: .asciz "%f\n" +fmt: .asciz "Should print -0.550000: %f\n" .end diff --git a/macros/float.S b/macros/float.S index 3d04278..611d390 100644 --- a/macros/float.S +++ b/macros/float.S @@ -1,3 +1,5 @@ +/* A test program. +*/ #include "apple-linux-convergence.S" .text @@ -24,6 +26,6 @@ MAIN END_PROC flt: .float 0.125 -fmt: .asciz "%f\n" +fmt: .asciz "Should print 0.125000: %f\n" .end diff --git a/macros/minmax.S b/macros/minmax.S new file mode 100644 index 0000000..d1f1563 --- /dev/null +++ b/macros/minmax.S @@ -0,0 +1,96 @@ +/* A test program. Tests MIN and MAX +*/ +#include "apple-linux-convergence.S" + + .text + .align 2 + GLABEL main + +MAIN + START_PROC + PUSH_P x29, x30 + PUSH_P x20, x21 + mov x29, sp + + // Generate two numbers to compare. + + mov x0, xzr + CRT time // time(nullptr) + CRT srand + + CRT rand + and x20, x0, 0xFF + + CRT rand + and x21, x0, 0xFF + + bl PrintLegend + bl DoMin + bl DoMax + + POP_P x20, x21 + POP_P x29, x30 + mov w0, wzr + ret + END_PROC + +DoMin: + START_PROC + PUSH_P x29, x30 + mov x29, sp + LLD_ADDR x0, fmtls + MIN x20, x21, x1 +#if defined(__APPLE__) + PUSH_R x1 + CRT printf + add sp, sp, 16 +#else + CRT printf +#endif + POP_P x29, x30 + ret + END_PROC + +DoMax: + START_PROC + PUSH_P x29, x30 + mov x29, sp + LLD_ADDR x0, fmtgt + MAX x20, x21, x1 +#if defined(__APPLE__) + PUSH_R x1 + CRT printf + add sp, sp, 16 +#else + CRT printf +#endif + POP_P x29, x30 + ret + END_PROC + +PrintLegend: + START_PROC + PUSH_P x29, x30 + mov x29, sp + LLD_ADDR x0, fmt +#if defined(__APPLE__) + PUSH_P x20, x21 + CRT printf + add sp, sp, 16 +#else + mov x1, x20 + mov x2, x21 + CRT printf +#endif + POP_P x29, x30 + ret + END_PROC + + .p2align 2 +fmt: .asciz "Values to compare: %d and %d\n" + .p2align 2 +fmtgt: .asciz "Greater value is: %d\n" + .p2align 2 +fmtls: .asciz "Lesser value is: %d\n" + + .end diff --git a/more/apple_silicon/README.pdf b/more/apple_silicon/README.pdf index 696a470..13333a4 100644 Binary files a/more/apple_silicon/README.pdf and b/more/apple_silicon/README.pdf differ diff --git a/more/apple_silicon/apple-linux-convergence.S b/more/apple_silicon/apple-linux-convergence.S index 8d283a7..f804854 100644 --- a/more/apple_silicon/apple-linux-convergence.S +++ b/more/apple_silicon/apple-linux-convergence.S @@ -119,10 +119,28 @@ main: ldr \a, [sp], 16 .endm -.macro MIN src_a, src_b, dest - csel \dest, \src_a, \src_b, GT -.endm +/* The smaller of src_a and src_b is put into dest. A cmp instruction + or other instruction that sets the flags must be performed first. + This macro makes it easy to remember which register does what in the + csel. + + Thank you to u/TNorthover for nudge to add the cmp. +*/ -.macro MAX src_a, src_b, dest +.macro MIN src_a, src_b, dest + cmp \src_a, \src_b csel \dest, \src_a, \src_b, LT .endm + +/* The larger of src_a and src_b is put into dest. A cmp instruction + or other instruction that sets the flags must be performed first. + This macro makes it easy to remember which register does what in the + csel. + + Thank you to u/TNorthover for nudge to add the cmp. +*/ + +.macro MAX src_a, src_b, dest + cmp \src_a, \src_b + csel \dest, \src_a, \src_b, GT +.endm diff --git a/python/apple-linux-convergence.S b/python/apple-linux-convergence.S index 8d283a7..f804854 100644 --- a/python/apple-linux-convergence.S +++ b/python/apple-linux-convergence.S @@ -119,10 +119,28 @@ main: ldr \a, [sp], 16 .endm -.macro MIN src_a, src_b, dest - csel \dest, \src_a, \src_b, GT -.endm +/* The smaller of src_a and src_b is put into dest. A cmp instruction + or other instruction that sets the flags must be performed first. + This macro makes it easy to remember which register does what in the + csel. + + Thank you to u/TNorthover for nudge to add the cmp. +*/ -.macro MAX src_a, src_b, dest +.macro MIN src_a, src_b, dest + cmp \src_a, \src_b csel \dest, \src_a, \src_b, LT .endm + +/* The larger of src_a and src_b is put into dest. A cmp instruction + or other instruction that sets the flags must be performed first. + This macro makes it easy to remember which register does what in the + csel. + + Thank you to u/TNorthover for nudge to add the cmp. +*/ + +.macro MAX src_a, src_b, dest + cmp \src_a, \src_b + csel \dest, \src_a, \src_b, GT +.endm diff --git a/section_1/hello_world/apple-linux-convergence.S b/section_1/hello_world/apple-linux-convergence.S index 8d283a7..f804854 100644 --- a/section_1/hello_world/apple-linux-convergence.S +++ b/section_1/hello_world/apple-linux-convergence.S @@ -119,10 +119,28 @@ main: ldr \a, [sp], 16 .endm -.macro MIN src_a, src_b, dest - csel \dest, \src_a, \src_b, GT -.endm +/* The smaller of src_a and src_b is put into dest. A cmp instruction + or other instruction that sets the flags must be performed first. + This macro makes it easy to remember which register does what in the + csel. + + Thank you to u/TNorthover for nudge to add the cmp. +*/ -.macro MAX src_a, src_b, dest +.macro MIN src_a, src_b, dest + cmp \src_a, \src_b csel \dest, \src_a, \src_b, LT .endm + +/* The larger of src_a and src_b is put into dest. A cmp instruction + or other instruction that sets the flags must be performed first. + This macro makes it easy to remember which register does what in the + csel. + + Thank you to u/TNorthover for nudge to add the cmp. +*/ + +.macro MAX src_a, src_b, dest + cmp \src_a, \src_b + csel \dest, \src_a, \src_b, GT +.endm diff --git a/section_1/regs/quinn.S b/section_1/regs/quinn.S new file mode 100644 index 0000000..8e5c2a4 --- /dev/null +++ b/section_1/regs/quinn.S @@ -0,0 +1,27 @@ + .p2align 2 + .text + .global main + +main: stp x29, x30, [sp, -16]! + str x20, [sp, -16]! + mov x29, sp + mov x20, xzr + +1: cmp x20, 10 + beq 2f + ldr x0, =fmt + mov x1, x20 + bl printf + add x20, x20, 1 + b 1b + +2: ldr x20, [sp], 16 + ldp x29, x30, [sp], 16 + mov w0, wzr + ret + + .data + +fmt: .asciz "Number: %d\n" + .end + diff --git a/section_2/float/apple-linux-convergence.S b/section_2/float/apple-linux-convergence.S index 8d283a7..f804854 100644 --- a/section_2/float/apple-linux-convergence.S +++ b/section_2/float/apple-linux-convergence.S @@ -119,10 +119,28 @@ main: ldr \a, [sp], 16 .endm -.macro MIN src_a, src_b, dest - csel \dest, \src_a, \src_b, GT -.endm +/* The smaller of src_a and src_b is put into dest. A cmp instruction + or other instruction that sets the flags must be performed first. + This macro makes it easy to remember which register does what in the + csel. + + Thank you to u/TNorthover for nudge to add the cmp. +*/ -.macro MAX src_a, src_b, dest +.macro MIN src_a, src_b, dest + cmp \src_a, \src_b csel \dest, \src_a, \src_b, LT .endm + +/* The larger of src_a and src_b is put into dest. A cmp instruction + or other instruction that sets the flags must be performed first. + This macro makes it easy to remember which register does what in the + csel. + + Thank you to u/TNorthover for nudge to add the cmp. +*/ + +.macro MAX src_a, src_b, dest + cmp \src_a, \src_b + csel \dest, \src_a, \src_b, GT +.endm