diff --git a/stdlib/core.sl b/stdlib/core.sl index 4bd173b..356c734 100644 --- a/stdlib/core.sl +++ b/stdlib/core.sl @@ -473,3 +473,165 @@ mov [r12], rax ; store result } ; + +# : band ( x1 x2 -- x3 ) +:asm band { + mov rax, [r12] ; get top + add r12, 8 ; pop + and qword [r12], rax ; bitwise and +} +; + +# : bor ( x1 x2 -- x3 ) +:asm bor { + mov rax, [r12] ; get top + add r12, 8 ; pop + or qword [r12], rax ; bitwise or +} +; + +# : bxor ( x1 x2 -- x3 ) +:asm bxor { + mov rax, [r12] ; get top + add r12, 8 ; pop + xor qword [r12], rax ; bitwise xor +} +; + +# : bnot ( x -- x ) +:asm bnot { + not qword [r12] ; bitwise not +} +; + +# : shl ( x1 x2 -- x3 ) +:asm shl { + mov rcx, [r12] ; shift count + add r12, 8 ; pop + shl qword [r12], cl ; logical left shift +} +; + +# : sal ( x1 x2 -- x3 ) +:asm sal { + mov rcx, [r12] ; shift count + add r12, 8 ; pop + sal qword [r12], cl ; arithmetic left shift (same as shl) +} +; + +# : shr ( x1 x2 -- x3 ) +:asm shr { + mov rcx, [r12] ; shift count + add r12, 8 ; pop + shr qword [r12], cl ; logical right shift +} +; + +# : sar ( x1 x2 -- x3 ) +:asm sar { + mov rcx, [r12] ; shift count + add r12, 8 ; pop + sar qword [r12], cl ; arithmetic right shift +} +; + +# : rol ( x1 x2 -- x3 ) +:asm rol { + mov rcx, [r12] ; shift count + add r12, 8 ; pop + rol qword [r12], cl ; rotate left +} +; + +# : ror ( x1 x2 -- x3 ) +:asm ror { + mov rcx, [r12] ; shift count + add r12, 8 ; pop + ror qword [r12], cl ; rotate right +} +; + +# : inc ( x -- x+1 ) +:asm inc { + inc qword [r12] +} +; + +# : dec ( x -- x-1 ) +:asm dec { + dec qword [r12] +} +; + +# : min ( x1 x2 -- x3 ) +:asm min { + mov rax, [r12] ; x2 + add r12, 8 ; pop + mov rbx, [r12] ; x1 + cmp rbx, rax + cmovg rbx, rax ; if x1 > x2, pick x2 + mov [r12], rbx +} +; + +# : max ( x1 x2 -- x3 ) +:asm max { + mov rax, [r12] ; x2 + add r12, 8 ; pop + mov rbx, [r12] ; x1 + cmp rbx, rax + cmovl rbx, rax ; if x1 < x2, pick x2 + mov [r12], rbx +} +; + +# : clamp ( x lo hi -- y ) +:asm clamp { + mov rax, [r12] ; hi + mov rbx, [r12 + 8] ; lo + mov rcx, [r12 + 16] ; x + cmp rcx, rbx + cmovl rcx, rbx ; if x < lo -> lo + cmp rcx, rax + cmovg rcx, rax ; if x > hi -> hi + mov [r12 + 16], rcx + add r12, 16 ; drop lo, hi +} +; + +# : time ( -- t ) +:asm time { + mov rax, 201 ; syscall: time + xor rdi, rdi + syscall + sub r12, 8 + mov [r12], rax + ret +} +; + +# : rand ( -- n ) +:asm rand { + lea rbx, [rel persistent] + mov rax, [rbx] ; state + test rax, rax + jne .seeded + ; seed with time() + mov rax, 201 ; syscall: time + xor rdi, rdi + syscall + mov [rbx], rax +.seeded: + mov rax, [rbx] + mov rcx, 1103515245 + imul rax, rcx + add rax, 12345 + mov [rbx], rax + shr rax, 16 + and rax, 0x7fff + sub r12, 8 + mov [r12], rax + ret +} +; diff --git a/tests/core_bitops.expected b/tests/core_bitops.expected new file mode 100644 index 0000000..1591f46 --- /dev/null +++ b/tests/core_bitops.expected @@ -0,0 +1,19 @@ +2 +7 +5 +-1 +8 +8 +4 +-4 +6 +4 +3 +7 +8 +4 +4 +1 +3 +1 +16838 diff --git a/tests/core_bitops.sl b/tests/core_bitops.sl new file mode 100644 index 0000000..24042c7 --- /dev/null +++ b/tests/core_bitops.sl @@ -0,0 +1,26 @@ +import ../stdlib/stdlib.sl +import ../stdlib/io.sl + +word main + 6 3 band puti cr + 6 3 bor puti cr + 6 3 bxor puti cr + 0 bnot puti cr + 1 3 shl puti cr + 1 3 sal puti cr + 8 1 shr puti cr + 8 neg 1 sar puti cr + 5 inc puti cr + 5 dec puti cr + 3 7 min puti cr + 3 7 max puti cr + 1 3 rol puti cr + 8 1 ror puti cr + 5 1 4 clamp puti cr + 0 1 4 clamp puti cr + 3 1 4 clamp puti cr + time 0 > puti cr + 1 mem swap ! + rand puti cr + 0 +end diff --git a/tests/core_bitops.test b/tests/core_bitops.test new file mode 100644 index 0000000..f111241 --- /dev/null +++ b/tests/core_bitops.test @@ -0,0 +1 @@ +python main.py tests/core_bitops.sl -o ./build/core_bitops > /dev/null && ./build/core_bitops