2025-12-20 23:20:53 +01:00
|
|
|
# L2 Floating Point Library (Double Precision)
|
|
|
|
|
|
|
|
|
|
# Arithmetic
|
2026-02-18 13:58:08 +01:00
|
|
|
#f+ [*, x1 | x2] -> [* | x3]
|
2025-12-20 23:20:53 +01:00
|
|
|
:asm f+ {
|
|
|
|
|
movq xmm0, [r12]
|
|
|
|
|
add r12, 8
|
|
|
|
|
movq xmm1, [r12]
|
|
|
|
|
addsd xmm1, xmm0
|
|
|
|
|
movq [r12], xmm1
|
|
|
|
|
} ;
|
|
|
|
|
|
2026-02-18 13:58:08 +01:00
|
|
|
#f- [*, x1 | x2] -> [* | x3]
|
2025-12-20 23:20:53 +01:00
|
|
|
:asm f- {
|
|
|
|
|
movq xmm0, [r12]
|
|
|
|
|
add r12, 8
|
|
|
|
|
movq xmm1, [r12]
|
|
|
|
|
subsd xmm1, xmm0
|
|
|
|
|
movq [r12], xmm1
|
|
|
|
|
} ;
|
|
|
|
|
|
2026-02-18 13:58:08 +01:00
|
|
|
#f* [*, x1 | x2] -> [* | x3]
|
2025-12-20 23:20:53 +01:00
|
|
|
:asm f* {
|
|
|
|
|
movq xmm0, [r12]
|
|
|
|
|
add r12, 8
|
|
|
|
|
movq xmm1, [r12]
|
|
|
|
|
mulsd xmm1, xmm0
|
|
|
|
|
movq [r12], xmm1
|
|
|
|
|
} ;
|
|
|
|
|
|
2026-02-18 13:58:08 +01:00
|
|
|
#f/ [*, x1 | x2] -> [* | x3]
|
2025-12-20 23:20:53 +01:00
|
|
|
:asm f/ {
|
|
|
|
|
movq xmm0, [r12]
|
|
|
|
|
add r12, 8
|
|
|
|
|
movq xmm1, [r12]
|
|
|
|
|
divsd xmm1, xmm0
|
|
|
|
|
movq [r12], xmm1
|
|
|
|
|
} ;
|
|
|
|
|
|
2026-02-18 13:58:08 +01:00
|
|
|
#fneg [* | x] -> [* | -x]
|
2025-12-20 23:20:53 +01:00
|
|
|
:asm fneg {
|
|
|
|
|
movq xmm0, [r12]
|
|
|
|
|
mov rax, 0x8000000000000000
|
|
|
|
|
movq xmm1, rax
|
|
|
|
|
xorpd xmm0, xmm1
|
|
|
|
|
movq [r12], xmm0
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
# Comparison
|
2026-02-18 13:58:08 +01:00
|
|
|
#f== [*, x1 | x2] -> [* | flag]
|
2025-12-20 23:20:53 +01:00
|
|
|
:asm f== {
|
|
|
|
|
movq xmm0, [r12]
|
|
|
|
|
add r12, 8
|
|
|
|
|
movq xmm1, [r12]
|
|
|
|
|
ucomisd xmm0, xmm1
|
|
|
|
|
mov rax, 0
|
|
|
|
|
setz al
|
|
|
|
|
mov [r12], rax
|
|
|
|
|
} ;
|
|
|
|
|
|
2026-02-18 13:58:08 +01:00
|
|
|
#f< [*, x1 | x2] -> [* | flag]
|
2025-12-20 23:20:53 +01:00
|
|
|
:asm f< {
|
|
|
|
|
movq xmm0, [r12] ; a
|
|
|
|
|
add r12, 8
|
|
|
|
|
movq xmm1, [r12] ; b
|
|
|
|
|
ucomisd xmm0, xmm1
|
|
|
|
|
mov rax, 0
|
|
|
|
|
seta al ; Above (a > b) -> b < a
|
|
|
|
|
mov [r12], rax
|
|
|
|
|
} ;
|
|
|
|
|
|
2026-02-18 13:58:08 +01:00
|
|
|
#f> [*, x1 | x2] -> [* | flag]
|
2025-12-20 23:20:53 +01:00
|
|
|
:asm f> {
|
|
|
|
|
movq xmm0, [r12] ; a
|
|
|
|
|
add r12, 8
|
|
|
|
|
movq xmm1, [r12] ; b
|
|
|
|
|
ucomisd xmm1, xmm0
|
|
|
|
|
mov rax, 0
|
|
|
|
|
seta al ; b > a
|
|
|
|
|
mov [r12], rax
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
# Conversion
|
2026-02-18 13:58:08 +01:00
|
|
|
#int>float [* | x] -> [* | xf]
|
2025-12-20 23:20:53 +01:00
|
|
|
:asm int>float {
|
|
|
|
|
cvtsi2sd xmm0, [r12]
|
|
|
|
|
movq [r12], xmm0
|
|
|
|
|
} ;
|
|
|
|
|
|
2026-02-18 13:58:08 +01:00
|
|
|
#float>int [* | xf] -> [* | x]
|
2025-12-20 23:20:53 +01:00
|
|
|
:asm float>int {
|
|
|
|
|
cvttsd2si rax, [r12]
|
|
|
|
|
mov [r12], rax
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
# Output
|
2026-02-18 13:58:08 +01:00
|
|
|
# extern declarations are required for runtime linking
|
2025-12-20 23:20:53 +01:00
|
|
|
extern int printf(char* fmt, double x)
|
2026-02-16 14:32:13 +01:00
|
|
|
extern int fflush(void* stream)
|
2025-12-20 23:20:53 +01:00
|
|
|
|
2026-02-18 13:58:08 +01:00
|
|
|
#fput [* | xf] -> [*]
|
2026-01-08 15:28:10 +01:00
|
|
|
word fput
|
2025-12-20 23:20:53 +01:00
|
|
|
"%f" drop swap printf drop
|
2026-02-16 14:32:13 +01:00
|
|
|
0 fflush drop
|
2026-01-08 15:28:10 +01:00
|
|
|
end
|
2025-12-20 23:20:53 +01:00
|
|
|
|
2026-02-18 13:58:08 +01:00
|
|
|
#fputln [* | xf] -> [*]
|
2026-01-08 15:28:10 +01:00
|
|
|
word fputln
|
2025-12-20 23:20:53 +01:00
|
|
|
"%f\n" drop swap printf drop
|
2026-02-16 14:32:13 +01:00
|
|
|
0 fflush drop
|
2026-01-08 15:28:10 +01:00
|
|
|
end
|