diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..82a0201 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,25 @@ +# Contributing + +## Code of Conduct +Be nice, we are all just doing this to have fun + +## General rules +- All text (names, comments, etc.) has to be in English +- You are responsible for ensuring that you have the rights for us to use the code you contribute to the project +- follow the guidelines, for code, documentation, etc. +- all code has to work with the standard symphony ISA + +## Documenting Functions +All functions in the standard library should follow the following outline: +``` +; +; Arguments: +; Result: +; Clobbers: +fn_label: <;SHOULD BE INLINED> + CODE + +``` + +Functions should be in the appropriate asm file, if you are unsure where functionality fits make a seperate file and ask in the pull request +Functions that are provided for convenience/reference but should be inlined in production code should be marked with `;SHOULD BE INLINED` after their label diff --git a/README.md b/README.md index 44ed975..1a3d693 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,46 @@ -# symphony_stdlib +# Symphony Stdlib -standard library for symphony \ No newline at end of file +This is a standard library for symphony. +It is both intended as a practical toolkit to develop more complex software as well as a teaching resource. + +If you just want to use the standard library [[stdlib.asm]] is your main header, include it after your code. + +If you are using it as a learning resource have a look at the [teaching folder](teaching). + +If you are intersted in contributing have a look at [[CONTRIBUTING.md]] + +--- + +## ABI + +### Calling Convention +| class | registers | +| ----- | --------- | +| n.a. | zr | +| preserved | sp, r8 - r12 | +| scratch | flags, r1 - r7 | +| arguments | r1 - r7 | +| result | r1-r7 | +| return address | r13 | + +Arguments not fitting into the 7 registers should be passed on the top of the stack, meaning they should be the last values pushed before the function call. +Arguments are passed in reverse order with the stack so: +lowest address = 1st stack arg +highest address = last stack arg + +Should a function return more values than fit into the 7 registers, the caller has to allocate space on the stack for them, and pass the pointer to that space in the next free argument register. +This reduces the amount of argument registers to 6 and all arguments above that shall go on the stack, the pointer to the result stack shall **always** be passed in an argument register. +This register points at the highest available address for results, with the 8th result being stored there, the 9th below it and so on. + +### Stack +Grows downwards from 0xXXFE_0000 (so top of memory -0x1_0000). + +### Types + +#### String +Strings are stored in memory as null terminated sequences of bytes encoding ascii characters. +They should be passed by reference. + +#### Array +Arrays are stored in memory with a reference to them being the tuple (pointer, length) stored in a register pair. +Array elements may only have a size of 8/16/32 bits diff --git a/bit.asm b/bit.asm index f015315..3cba7a6 100644 --- a/bit.asm +++ b/bit.asm @@ -70,3 +70,25 @@ pub popc: add r4, r4, r2 and r1, r4, 0xFF ; mask out end result in lowest byte jmp r13 + +; Calculates the parity of the value provided in the r1 register +; i.e. 0 means even bits set, 1 means odd bits set +; Based on Stanford's BitHacks +; Clobbers r2 +pub parity: + ; v ^= v >> 16; + lsr r2, r1, 16 + xor r1, r1, r2 + ; v ^= v >> 8; + lsr r2, r1, 8 + xor r1, r1, r2 + ; v ^= v >> 4; + lsr r2, r1, 4 + xor r1, r1, r2 + ; v &= 0xf; + and r1, r1, 0x0F + ; return (0x6996 >> v) & 1; + mov r2, 0x6996 + lsr r1, r2, r1 + and r1, r1, 0x01 + jmp r13 \ No newline at end of file diff --git a/imath.asm b/imath.asm index 3262321..0c08923 100644 --- a/imath.asm +++ b/imath.asm @@ -1,8 +1,15 @@ +; Multiplies r1 and r2, returning the lower part of the result +; Arguments: +; r1 - The first value +; r2 - The second value +; Result: +; r1 - The lower 32 bits of the result +; Clobbers: r2, r3, r4, r5 pub mul_low: mov r3, 0 ; result mov r4, 31 ; loop counter - mull_loop: + mul_low_loop: asr r5, r2, 31 and r5, r5, r1 lsl r5, r5, r4 @@ -10,7 +17,67 @@ pub mul_low: lsl r2, r2, 1 sub r4, r4, 1 cmp r4, 0 - jge mull_loop + jge mul_low_loop mov r1, r3 + jmp r13 + +; Calculates the absolute value of the value provided in the r1 register +; Arguments: +; r1 - The value for which we want the absolute value +; Result: +; r1 - The calculated absolute value +; Clobbers: r2 +; Info: Based on Stanford's BitHacks +pub abs: ; SHOULD BE INLINED + ; mask = v >> 31 + asr r2, r1, 31 + ; v + mask + add r1, r1, r2 + ; return (v + mask) ^ mask + xor r1, r1, r2 + jmp r13 + +; Calculates the minimum value of the two values provided in the r1 and r2 registers +; Arguments: +; r1 - The first value +; r2 - The second value +; Result: +; r1 - The smaller value +; Clobbers: Nothing +; Info: Based on Stanford's BitHacks +pub min: ; SHOULD BE INLINED + ; x < y + cmp r1, r2 + lsr flags, flags, 2 + ; -(x < y) + neg flags, flags + ; x ^ y + xor r1, r1, r2 + ; (x ^ y) & -(x < y) + and r1, r1, flags + ; return y ^ ((x ^ y) & -(x < y)) + xor r1, r2, r1 + jmp r13 + +; Calculates the maximum value of the two values provided in the r1 and r2 registers +; Arguments: +; r1 - The first value +; r2 - The second value +; Result: +; r1 - The smaller value +; Clobbers: r2 +; Info: Based on Stanford's BitHacks +pub max: ; SHOULD BE INLINED + ; x < y + cmp r1, r2 + lsr flags, flags, 2 + ; -(x < y) + neg flags, flags + ; x ^ y + xor r2, r1, r2 + ; (x ^ y) & -(x < y) + and r2, r2, flags + ; return x ^ ((x ^ y) & -(x < y)) + xor r1, r1, r2 jmp r13 \ No newline at end of file diff --git a/stdlib.asm b/stdlib.asm index fdb3385..a17a956 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -1,29 +1,6 @@ -; ===== INTRODUCTION ===== -; This is supposed to provide some standard library functionality for stock symphony. -; In particular its supposed to work with an unmodified ISA, that means some choices are not -; optimal (RA being stored in flags for example) - -; ===== ABI ===== - -; ----- CALLING CONVENTION ----- -; n.a. zr -; preserved: sp, r8 - r12 -; scratch: flags, r1 - r7 -; arguments: r1 - r7 (r1 = 1st argument, r6 = 6th arg/stack args, r7 = 7th arg/stack res) -; result: r1, r2 (r1 = low word, r2 = high word) -; return address: r13 - -; ----- STACK ----- -; grows downwards from top of memory -; arguments are passed in reverse order with the stack so: -; lowest address = 1st stack arg -; highest address = last stack arg - -; ===== TYPES ===== - pub include bit pub include imath pub include console ; Needs to be last! -pub include LUTs \ No newline at end of file +pub include LUTs diff --git a/teaching/README.md b/teaching/README.md new file mode 100644 index 0000000..67ae43d --- /dev/null +++ b/teaching/README.md @@ -0,0 +1,5 @@ +# Teaching + +This is a collection of teaching advice regarding the stdlib. + +**WIP**