diff options
Diffstat (limited to 'tests/fixtures')
| -rw-r--r-- | tests/fixtures/argc-argv.s | 44 | ||||
| -rw-r--r-- | tests/fixtures/block-copy.s | 46 | ||||
| -rw-r--r-- | tests/fixtures/byte-swap.s | 15 | ||||
| -rw-r--r-- | tests/fixtures/call.s | 39 | ||||
| -rw-r--r-- | tests/fixtures/frame-pointer.s | 63 | ||||
| -rw-r--r-- | tests/fixtures/hll/libc-stub.S | 42 | ||||
| -rw-r--r-- | tests/fixtures/hll/model-pendulum-life.S | 133 | ||||
| -rw-r--r-- | tests/fixtures/hll/program-main.S | 48 | ||||
| -rw-r--r-- | tests/fixtures/indirect-control.s | 39 | ||||
| -rw-r--r-- | tests/fixtures/life-print.s | 30 | ||||
| -rw-r--r-- | tests/fixtures/model-lifecycle.s | 53 | ||||
| -rw-r--r-- | tests/fixtures/mpu-ops.s | 25 | ||||
| -rw-r--r-- | tests/fixtures/psw-call-abi.s | 36 | ||||
| -rw-r--r-- | tests/fixtures/radd-pi.s | 24 | ||||
| -rw-r--r-- | tests/fixtures/shared-libs/dynamic-liba.s | 18 | ||||
| -rw-r--r-- | tests/fixtures/shared-libs/dynamic-libb.s | 18 | ||||
| -rw-r--r-- | tests/fixtures/shared-libs/dynamic-main.s | 35 | ||||
| -rw-r--r-- | tests/fixtures/stack.s | 32 |
18 files changed, 740 insertions, 0 deletions
diff --git a/tests/fixtures/argc-argv.s b/tests/fixtures/argc-argv.s new file mode 100644 index 0000000..4c1d2ac --- /dev/null +++ b/tests/fixtures/argc-argv.s @@ -0,0 +1,44 @@ +; Minimal argc/argv and explicit "--" separator example. +; +; Assemble/link: +; ../utils/mcpu-as -o argc-argv.o argc-argv.s +; ../utils/mcpu-ld -o argc-argv --stack-size=4K argc-argv.o +; +; Run: +; ../utils/mcpu-run \ +; --on-step=print-int-regs:r64@0x00000,r8@0x00020,r8@0x00021 \ +; -- \ +; argc-argv --help -x +; +; Guest argv is: +; argv[0] = "argc-argv" +; argv[1] = "--help" +; argv[2] = "-x" +; +; The example prints argc, argv[1][2] ('h') and argv[2][1] ('x') as integers. +; Expected output: +; 3 104 120 + +.text +_start_life: +loop: + ; Persistent McpuStartup at SP: + ; SP+8 = argc + ; SP+16 = argv (PTR64 to argv[0]) + LDSP r64@0x00000, 8 + LDSP r64@0x00008, 16 + + ; argv[1] + PADDI r64@0x00010, r64@0x00008, 8 + LOADP r64@0x00018, r64@0x00010 + PADDI r64@0x00018, r64@0x00018, 2 + LOADP r8@0x00020, r64@0x00018 + + ; argv[2] + PADDI r64@0x00010, r64@0x00008, 16 + LOADP r64@0x00018, r64@0x00010 + PADDI r64@0x00018, r64@0x00018, 1 + LOADP r8@0x00021, r64@0x00018 + + END + JMP loop diff --git a/tests/fixtures/block-copy.s b/tests/fixtures/block-copy.s new file mode 100644 index 0000000..81422e2 --- /dev/null +++ b/tests/fixtures/block-copy.s @@ -0,0 +1,46 @@ +; Build/run from examples/: +; ../utils/mcpu-as -o block-copy.o block-copy.s +; ../utils/mcpu-ld --stack-size=512 -o block-copy block-copy.o +; ../utils/mcpu-run --int-reg=r64@0x00028 block-copy +; +; Expected output: 22 +; +; LibCPU block-copy example. +; +; 1. Copy a 32-byte object from DATA to a local STACK object with BMOVI. +; 2. Use BMOV with a runtime byte count to perform an overlapping move +; inside that STACK object. BMOV has memmove semantics. +; 3. Read the moved value back through LOADP. Expected result: 22. + +.data +.align 8 +source_object: + .integer 64, 11 + .integer 64, 22 + .integer 64, 33 + .integer 64, 44 + +.text +_start_life: + ; Source PTR64 -> DATA object. + LEA r64@0x00000, source_object + + ; Reserve 32 bytes for a local object and obtain its STACK PTR64. + ADJSP -32 + LEASP r64@0x00008, 0 + + ; Fixed-size structure copy: DATA -> STACK. + BMOVI r64@0x00008, r64@0x00000, 32 + + ; Overlapping move inside the local object: + ; bytes [0..15] -> [8..23]. memmove semantics are required. + PADDI r64@0x00010, r64@0x00008, 8 + LDI r64@0x00018, 16 + BMOV r64@0x00010, r64@0x00008, r64@0x00018 + + ; The third 64-bit slot now contains the old second slot: 22. + PADDI r64@0x00020, r64@0x00008, 16 + LOADP r64@0x00028, r64@0x00020 + + ADJSP 32 + HALT diff --git a/tests/fixtures/byte-swap.s b/tests/fixtures/byte-swap.s new file mode 100644 index 0000000..7f666d0 --- /dev/null +++ b/tests/fixtures/byte-swap.s @@ -0,0 +1,15 @@ +; Byte-swap example. +; +; Build/run from examples/: +; ../utils/mcpu-as -o byte-swap.o byte-swap.s +; ../utils/mcpu-ld --stack-size=512 -o byte-swap byte-swap.o +; ../utils/mcpu-run --int-reg=r64@0x00010 byte-swap +; +; Expected output: 42 +; +.text +_start_life: + LDI r64@0x00000, 42 + BSWAP r64@0x00008, r64@0x00000 + BSWAP r64@0x00010, r64@0x00008 + HALT diff --git a/tests/fixtures/call.s b/tests/fixtures/call.s new file mode 100644 index 0000000..bfc9965 --- /dev/null +++ b/tests/fixtures/call.s @@ -0,0 +1,39 @@ +; Build/run from examples/: +; ../utils/mcpu-as -o call.o call.s +; ../utils/mcpu-ld --stack-size=128 -o call call.o +; ../utils/mcpu-run --int-reg=r64@0x00010 call +; +; Expected output: 33 +; +; LibCPU CALL ABI example. +; +; add2(a,b): this two-r64 argument block is exactly 16 bytes, so the +; traditional right-to-left PUSH sequence also satisfies the formal ABI. +; CALL then pushes +; the 64-bit return PC, therefore on callee entry: +; SP+0 = return address +; SP+8 = first argument a +; SP+16 = second argument b +; +; Before CALL, SP is 16-byte aligned. The r64 result is returned in the canonical ABI return view +; r64@0x7fff8. The caller removes its own arguments with ADJSP. + +.text +_start_life: + + LDI r64@0x00000, 11 + LDI r64@0x00008, 22 + + PUSH r64@0x00008 ; second/rightmost argument b + PUSH r64@0x00000 ; first/leftmost argument a + CALL add2 + ADJSP 16 ; caller cleanup + + MOV r64@0x00010, r64@0x7fff8 + HALT + +add2: + LDSP r64@0x00100, 8 ; a + LDSP r64@0x00108, 16 ; b + IADD r64@0x7fff8, r64@0x00100, r64@0x00108 + RET diff --git a/tests/fixtures/frame-pointer.s b/tests/fixtures/frame-pointer.s new file mode 100644 index 0000000..6c6934b --- /dev/null +++ b/tests/fixtures/frame-pointer.s @@ -0,0 +1,63 @@ +; Build/run from examples/: +; ../utils/mcpu-as -o frame-pointer.o frame-pointer.s +; ../utils/mcpu-ld --stack-size=512 -o frame-pointer frame-pointer.o +; ../utils/mcpu-run --int-reg=r64@0x00008 frame-pointer +; +; Expected output: 42 +; +; LibCPU optional frame-pointer and dynamic STACK allocation example. +; +; demo(5) builds a fixed frame, creates a 24-byte dynamic object below it, +; accesses a fixed local through FP while SP is moving, and returns 42 in +; the canonical r64 return register. + +.text +_start_life: + LDI r64@0x00000, 5 + ADJSP -16 ; 16-byte ABI argument block + STSP 0, r64@0x00000 + CALL demo + ADJSP 16 + MOV r64@0x00008, r64@0x7fff8 + HALT + +demo: + PUSHFP + SETFP + ADJSP -16 + + ; First explicit argument. With FP in use the layout is: + ; FP+0 saved caller FP + ; FP+8 return PC + ; FP+16 first explicit argument + LDFP r64@0x00100, 16 + + ; Fixed local at FP-8. + STFP -8, r64@0x00100 + LEAFP r64@0x00108, -8 + + ; Save the current stack top as a dynamic-scope mark. + LEASP r64@0x00110, 0 + + ; Dynamically reserve 24 bytes: new_SP = old_SP - 24. + LDI r64@0x00118, 24 + PSUB r64@0x00120, r64@0x00110, r64@0x00118 + SETSP r64@0x00120 + + ; Put 37 in the dynamic object at current SP. + LDI r64@0x00128, 37 + LEASP r64@0x00130, 0 + STOREP r64@0x00130, r64@0x00128 + + ; FP-relative access is stable although SP moved dynamically. + LDFP r64@0x00138, -8 + LOADP r64@0x00140, r64@0x00130 + IADD r64@0x7fff8, r64@0x00138, r64@0x00140 + + ; Restore the nested dynamic scope explicitly. + SETSP r64@0x00110 + + ; Destroy the complete frame below FP, restore caller FP and return. + RESTSP + POPFP + RET diff --git a/tests/fixtures/hll/libc-stub.S b/tests/fixtures/hll/libc-stub.S new file mode 100644 index 0000000..d4fd878 --- /dev/null +++ b/tests/fixtures/hll/libc-stub.S @@ -0,0 +1,42 @@ +; Test/development MCPU Libc emulator. +; +; This source is NEVER installed. The register marker is intentionally a +; testing convention only; it is not part of the CRT <-> MCPU Libc ABI. + +.global __mcpu_libc_init +.global __mcpu_init_array +.global __mcpu_fini_array +.global __mcpu_libc_fini + +.text +__mcpu_libc_init: + CLR r64@0x70008 + ICMP r64@0x70000, r64@0x70008 + JNZ .L_stub_bad + LDI r64@0x70000, 1 + RET + +__mcpu_init_array: + LDI r64@0x70008, 1 + ICMP r64@0x70000, r64@0x70008 + JNZ .L_stub_bad + LDI r64@0x70000, 2 + RET + +__mcpu_fini_array: + LDI r64@0x70008, 4 + ICMP r64@0x70000, r64@0x70008 + JNZ .L_stub_bad + LDI r64@0x70000, 5 + RET + +__mcpu_libc_fini: + LDI r64@0x70008, 5 + ICMP r64@0x70000, r64@0x70008 + JNZ .L_stub_bad + LDI r64@0x70000, 6 + RET + +.L_stub_bad: + LDI r64@0x70000, 999 + RET diff --git a/tests/fixtures/hll/model-pendulum-life.S b/tests/fixtures/hll/model-pendulum-life.S new file mode 100644 index 0000000..5ad6ddb --- /dev/null +++ b/tests/fixtures/hll/model-pendulum-life.S @@ -0,0 +1,133 @@ +; Assembler emulator of future mcpu-cc MODEL output. +; +; The lifecycle shape is a compact pendulum-style MODEL regression fixture. +; INIT snapshots CONTROL +; into DATA, LIFE advances one model step and publishes one TRACE frame, and +; fini() marks graceful model finalization. +; +; This reduced fixture tests the HLL MODEL/CRT protocol, not RK4 numerics. + +.global init +.global life +.global fini + +.control +.align 8 +control_n: + .integer 64, 3 +control_error_step: + .integer 64, 0 + +.data +.align 8 +model_n: + .integer 64, 0 +model_error_step: + .integer 64, 0 +model_step: + .integer 64, 0 +model_fini_marker: + .integer 64, 0 + +.trace +.align 8 +trace_step: + .integer 64, 0 + +.text +; int32 init(int64 argc, PTR64 argv) +init: + LDI r64@0x70200, 2 + ICMP r64@0x70000, r64@0x70200 + JNZ .L_init_bad_order + + ; The test invokes the MODEL without extra arguments. + LDSP r64@0x70208, 8 + LDI r64@0x70210, 1 + ICMP r64@0x70208, r64@0x70210 + JNZ .L_init_bad_args + + ; Negative CONTROL.n deliberately requests an init failure. + LEA r64@0x70218, control_n + LOADP r64@0x70220, r64@0x70218 + CLR r64@0x70228 + ICMP r64@0x70220, r64@0x70228 + JS .L_init_fail + + STORE model_n, r64@0x70220 + LEA r64@0x70218, control_error_step + LOADP r64@0x70230, r64@0x70218 + STORE model_error_step, r64@0x70230 + + CLR r64@0x70238 + STORE model_step, r64@0x70238 + STORE model_fini_marker, r64@0x70238 + + LDI r64@0x70000, 3 + CLR r32@0x7fffc + RET + +.L_init_fail: + LDI r64@0x70000, 3 + LDI r32@0x7fffc, 17 + RET + +.L_init_bad_order: + LDI r64@0x70000, 910 + LDI r32@0x7fffc, 18 + RET + +.L_init_bad_args: + LDI r64@0x70000, 911 + LDI r32@0x7fffc, 19 + RET + +; int32 life(void) +life: + LOAD r64@0x70300, model_step + LDI r64@0x70308, 1 + IADD r64@0x70300, r64@0x70300, r64@0x70308 + STORE model_step, r64@0x70300 + + ; Optional positive LIFE error requested by CONTROL.error_step. + LOAD r64@0x70310, model_error_step + CLR r64@0x70318 + ICMP r64@0x70310, r64@0x70318 + JZ .L_no_life_error + ICMP r64@0x70300, r64@0x70310 + JNZ .L_no_life_error + LDI r32@0x7fffc, 9 + RET + +.L_no_life_error: + ; Pendulum-style sequential stop: step == n + 1 means natural end. + LOAD r64@0x70320, model_n + IADD r64@0x70328, r64@0x70320, r64@0x70308 + ICMP r64@0x70300, r64@0x70328 + JZ .L_life_end + + LEA r64@0x70330, trace_step + STOREP r64@0x70330, r64@0x70300 + + ; LIFE_CONTINUE == INT32_MIN. + LDI r32@0x7fffc, -2147483648 + RET + +.L_life_end: + CLR r32@0x7fffc + RET + +fini: + LDI r64@0x70200, 3 + ICMP r64@0x70000, r64@0x70200 + JNZ .L_model_fini_bad + + LDI r64@0x70000, 4 + LDI r64@0x70208, 1 + STORE model_fini_marker, r64@0x70208 + MOV r64@0x70010, r64@0x70208 + RET + +.L_model_fini_bad: + LDI r64@0x70000, 912 + RET diff --git a/tests/fixtures/hll/program-main.S b/tests/fixtures/hll/program-main.S new file mode 100644 index 0000000..3161343 --- /dev/null +++ b/tests/fixtures/hll/program-main.S @@ -0,0 +1,48 @@ +; Assembler emulator of future mcpu-cc PROGRAM output. +; +; It intentionally defines only main() and fini(); lifecycle symbols belong +; to CRT and must be inserted automatically by mcpu-ld. + +.global main +.global fini + +.text +main: + ; Startup hooks must already have completed. + LDI r64@0x70100, 2 + ICMP r64@0x70000, r64@0x70100 + JNZ .L_main_bad + + ; argc must include argv[0] plus the two test arguments. + LDSP r64@0x70108, 8 + LDI r64@0x70110, 3 + ICMP r64@0x70108, r64@0x70110 + JNZ .L_main_bad + + ; argv[argc] is the required NULL terminator. + LDSP r64@0x70118, 16 + PADDI r64@0x70120, r64@0x70118, 24 + LOADP r64@0x70128, r64@0x70120 + CLR r64@0x70130 + ICMP r64@0x70128, r64@0x70130 + JNZ .L_main_bad + + LDI r64@0x70000, 3 + LDI r32@0x7fffc, 42 + RET + +.L_main_bad: + LDI r64@0x70000, 900 + LDI r32@0x7fffc, 43 + RET + +fini: + LDI r64@0x70100, 3 + ICMP r64@0x70000, r64@0x70100 + JNZ .L_fini_bad + LDI r64@0x70000, 4 + RET + +.L_fini_bad: + LDI r64@0x70000, 901 + RET diff --git a/tests/fixtures/indirect-control.s b/tests/fixtures/indirect-control.s new file mode 100644 index 0000000..1e9d0e3 --- /dev/null +++ b/tests/fixtures/indirect-control.s @@ -0,0 +1,39 @@ +; Indirect CALLP/JMPP control-flow example. +; +; Build/run from examples/: +; ../utils/mcpu-as -o indirect-control.o indirect-control.s +; ../utils/mcpu-ld --stack-size=512 -o indirect-control indirect-control.o +; ../utils/mcpu-run --int-reg=r64@0x00020 indirect-control +; +; Expected output: 42 +; +.data + +.align 8 +dispatch: + .cptr indirect_function + .cptr done + +.text +_start_life: + + ; Load a PROGRAM PTR64 from DATA and call through it. + LEA r64@0x00000, dispatch + LOADP r64@0x00008, r64@0x00000 + CALLP r64@0x00008 + + ; Select the second entry and jump through it. + PADDI r64@0x00000, r64@0x00000, 8 + LOADP r64@0x00010, r64@0x00000 + JMPP r64@0x00010 + + ; JMPP must skip this path. + LDI r64@0x00020, 99 + HALT + +indirect_function: + LDI r64@0x00020, 42 + RET + +done: + HALT diff --git a/tests/fixtures/life-print.s b/tests/fixtures/life-print.s new file mode 100644 index 0000000..a1de41f --- /dev/null +++ b/tests/fixtures/life-print.s @@ -0,0 +1,30 @@ +; Minimal LIFE-stage action example. +; +; Assemble/link: +; ../utils/mcpu-as -o life-print.o life-print.s +; ../utils/mcpu-ld -o life-print --stack-size=1K life-print.o +; +; Run three LIFE cycles and print two registers on one line after each END: +; ../utils/mcpu-run \ +; --steps=3 \ +; --on-step=print-int-regs:r64@0x00000,r64@0x00008 \ +; -- \ +; life-print +; +; Expected output: +; 1 10 +; 2 20 +; 3 30 + +.text +_start_life: + LDI r64@0x00000, 1 + LDI r64@0x00008, 10 + LDI r64@0x00010, 1 + LDI r64@0x00018, 10 + +loop: + END + IADD r64@0x00000, r64@0x00000, r64@0x00010 + IADD r64@0x00008, r64@0x00008, r64@0x00018 + JMP loop diff --git a/tests/fixtures/model-lifecycle.s b/tests/fixtures/model-lifecycle.s new file mode 100644 index 0000000..4c190d5 --- /dev/null +++ b/tests/fixtures/model-lifecycle.s @@ -0,0 +1,53 @@ +; Build from examples/: +; ../utils/mcpu-as -o model-lifecycle.o model-lifecycle.s +; ../utils/mcpu-ld --stack-size=512 -o model-lifecycle model-lifecycle.o +; +; Run one INIT-only pass or one LIFE step: +; ../utils/mcpu-run --init-only --int-reg=r64@0x00000 model-lifecycle +; ../utils/mcpu-run --steps=1 --int-reg=r64@0x00000 model-lifecycle +; +; Expected outputs: 40 and 42 respectively. +; +; LibCPU lifecycle/model-segment example. +; cpu-run --steps=1 --int-reg=r64@0x00000 model-lifecycle -> 42 +; cpu-run --init-only --int-reg=r64@0x00000 model-lifecycle -> 40 + +.control +model_step: + .real 64, 1.0 + +.input +external_delta: + .integer 64, 2 + +.output +current_state: + .integer 64, 0 + +.trace +telemetry_state: + .integer 64, 0 + +.init +_start: + LDI r64@0x00000, 40 + END + +.text +_life: +loop: + LEA r64@0x00008, external_delta + LOADP r64@0x00010, r64@0x00008 + IADD r64@0x00000, r64@0x00000, r64@0x00010 + + LEA r64@0x00018, current_state + STOREP r64@0x00018, r64@0x00000 + LEA r64@0x00020, telemetry_state + STOREP r64@0x00020, r64@0x00000 + + END + JMP loop + +.fini +_fini: + END diff --git a/tests/fixtures/mpu-ops.s b/tests/fixtures/mpu-ops.s new file mode 100644 index 0000000..49d4f97 --- /dev/null +++ b/tests/fixtures/mpu-ops.s @@ -0,0 +1,25 @@ +; LibMPU-backed arithmetic/conversion operation example. +; +; Build/run from examples/: +; ../utils/mcpu-as -o mpu-ops.o mpu-ops.s +; ../utils/mcpu-ld --stack-size=512 -o mpu-ops mpu-ops.o +; ../utils/mcpu-run --int-reg=r64@0x00020 mpu-ops +; +; Expected output: 42 +; +.text +_start_life: + + LDI r64@0x00000, 6 + LDI r64@0x00008, 7 + IMUL r128@0x00010, r64@0x00000, r64@0x00008 + ICPY r64@0x00020, r128@0x00010 + + RCONST r64@0x00028, ONE + CRTOC c128@0x00030, r64@0x00028 + CISEQ r64@0x00040, c128@0x00030, c128@0x00030 + IINC r64@0x00048, r64@0x00040 + IDEC r64@0x00050, r64@0x00048 + ISUB r64@0x00020, r64@0x00020, r64@0x00050 + IADD r64@0x00020, r64@0x00020, r64@0x00040 + HALT diff --git a/tests/fixtures/psw-call-abi.s b/tests/fixtures/psw-call-abi.s new file mode 100644 index 0000000..3dccab3 --- /dev/null +++ b/tests/fixtures/psw-call-abi.s @@ -0,0 +1,36 @@ +; PSW volatility across the CALL ABI example. +; +; Build/run from examples/: +; ../utils/mcpu-as -o psw-call-abi.o psw-call-abi.s +; ../utils/mcpu-ld --stack-size=512 -o psw-call-abi psw-call-abi.o +; ../utils/mcpu-run --int-reg=r64@0x00010 psw-call-abi +; +; Expected output: 42 +; +.text +_start_life: + + ; Establish ZF=1 before the call: -1 + 1 -> 0 in signed r8. + LDI r8@0x00000, -1 + LDI r8@0x00001, 1 + IADD r8@0x00002, r8@0x00000, r8@0x00001 + + ; CALL itself preserves PSW, but the callee is free to clobber + ; PSW[15:0]. This function deliberately clears ZF with 1 + 1. + CALL clobber_status + + ; The old ZF is not part of the calling convention. Observe the + ; callee-produced ZF=0 and report 42. + JNZ status_is_volatile + LDI r64@0x00010, 99 + HALT + +clobber_status: + LDI r8@0x00003, 1 + LDI r8@0x00004, 1 + IADD r8@0x00005, r8@0x00003, r8@0x00004 + RET + +status_is_volatile: + LDI r64@0x00010, 42 + HALT diff --git a/tests/fixtures/radd-pi.s b/tests/fixtures/radd-pi.s new file mode 100644 index 0000000..2921d91 --- /dev/null +++ b/tests/fixtures/radd-pi.s @@ -0,0 +1,24 @@ +; High-precision real arithmetic example. +; +; Build/run from examples/: +; ../utils/mcpu-as -o radd-pi.o radd-pi.s +; ../utils/mcpu-ld --stack-size=512 -o radd-pi radd-pi.o +; ../utils/mcpu-run --digits=60 --real-reg=r4096@0x00400 radd-pi +; +; Expected output starts with: +; 5.14159265358979323846264338327950288419716939937510582097 +; +.data + +.align 16 +result: + .real 4096, 0.0 + +.text +_start_life: + + LDR r4096@0x00000, 2.0 + RCONST r4096@0x00200, PI + RADD r4096@0x00400, r4096@0x00000, r4096@0x00200 + STORE result, r4096@0x00400 + HALT diff --git a/tests/fixtures/shared-libs/dynamic-liba.s b/tests/fixtures/shared-libs/dynamic-liba.s new file mode 100644 index 0000000..f35cfe2 --- /dev/null +++ b/tests/fixtures/shared-libs/dynamic-liba.s @@ -0,0 +1,18 @@ +; Build/run from examples/shared-libs/: +; make +; make run +; +; make run prints, in order: +; 43 +; 43 +; 42 +; 42 +; 41 +; +; Shared-library implementation of foo: adds 2. +.global foo +.text +foo: + LDI r64@0x00008, 2 + IADD r64@0x00000, r64@0x00000, r64@0x00008 + RET diff --git a/tests/fixtures/shared-libs/dynamic-libb.s b/tests/fixtures/shared-libs/dynamic-libb.s new file mode 100644 index 0000000..348b358 --- /dev/null +++ b/tests/fixtures/shared-libs/dynamic-libb.s @@ -0,0 +1,18 @@ +; Build/run from examples/shared-libs/: +; make +; make run +; +; make run prints, in order: +; 43 +; 43 +; 42 +; 42 +; 41 +; +; Shared-library implementation of foo: adds 3. +.global foo +.text +foo: + LDI r64@0x00008, 3 + IADD r64@0x00000, r64@0x00000, r64@0x00008 + RET diff --git a/tests/fixtures/shared-libs/dynamic-main.s b/tests/fixtures/shared-libs/dynamic-main.s new file mode 100644 index 0000000..f296429 --- /dev/null +++ b/tests/fixtures/shared-libs/dynamic-main.s @@ -0,0 +1,35 @@ +; Build/run from examples/shared-libs/: +; make +; make run +; +; make run prints, in order: +; 43 +; 43 +; 42 +; 42 +; 41 +; +; ABI-v2 startup-dynamic executable example. +; main-program itself defines foo(), but cpu-ld --dynamic retains CALL foo as +; a preemptible runtime relocation. cpu-run --ldpreload can therefore replace +; it before _start executes. +; +; Without preload: foo adds 1 -> result 41. +; With dynamic-liba.so: foo adds 2 -> result 42. +; With dynamic-liba.so:dynamic-libb.so: rightmost strong GLOBAL wins, so +; dynamic-libb.so foo adds 3 -> result 43. +.global _life +.global foo + +.text +_start_life: + LDI r64@0x00000, 40 + CALL foo + MOV r64@0x00018, r64@0x00000 + LDI r32@0x00030, 0 + EXIT r32@0x00030 + +foo: + LDI r64@0x00008, 1 + IADD r64@0x00000, r64@0x00000, r64@0x00008 + RET diff --git a/tests/fixtures/stack.s b/tests/fixtures/stack.s new file mode 100644 index 0000000..9b45785 --- /dev/null +++ b/tests/fixtures/stack.s @@ -0,0 +1,32 @@ +; STACK instruction example. +; +; Build/run from examples/: +; ../utils/mcpu-as -o stack.o stack.s +; ../utils/mcpu-ld --stack-size=128 -o stack stack.o +; ../utils/mcpu-run --int-reg=r64@0x00028 stack +; +; Expected output: 22 +; +.text +_start_life: + LDI r64@0x00000, 11 + LDI r64@0x00008, 22 + + ; STACK grows downward. cpu-run initializes SP to stack_size. + PUSH r64@0x00000 + PUSH r64@0x00008 + + ; Current stack top contains 22, SP+8 contains 11. + LDSP r64@0x00010, 8 + STSP 0, r64@0x00000 + + POP r64@0x00018 + POP r64@0x00020 + + ; Reserve a 16-byte local frame without automatic padding. + ADJSP -16 + STSP 0, r64@0x00008 + LDSP r64@0x00028, 0 + ADJSP 16 + + HALT |
