aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-08-31 23:14:26 +0200
committerhachem <im@hachem.wtf>2026-08-31 23:14:26 +0200
commit9dc06d01c2224ee1dbeb11ebee7c8afecfac8b05 (patch)
tree110fe30b5b1f228568087a8fe7b0f7e0ca43fbb1 /examples
parent5b06b0e4b8effaacd23308d6a6b26c525e7d3af4 (diff)
feat: add support for floats through xmm registers
Diffstat (limited to 'examples')
-rw-r--r--examples/circle.hdass17
-rw-r--r--examples/fibonacci.hdass2
-rw-r--r--examples/hello_world.hdass2
-rw-r--r--examples/load.hdass6
-rw-r--r--examples/logical.hdass10
-rw-r--r--examples/loop_sum.hdass4
-rw-r--r--examples/mandelbrot.hdass144
-rw-r--r--examples/records.hdass2
8 files changed, 174 insertions, 13 deletions
diff --git a/examples/circle.hdass b/examples/circle.hdass
new file mode 100644
index 0000000..8a4edaa
--- /dev/null
+++ b/examples/circle.hdass
@@ -0,0 +1,17 @@
+[entry: main]
+
+// Floating-point math on the SSE registers. Computes the area of a circle
+// (pi * r * r) with r = 3, then exits with the truncated result (28).
+const SYS_EXIT = 60
+
+proc main
+{
+ xmm0 = 3.0 // radius
+ xmm0 *= xmm0 // r * r = 9.0
+ xmm1 = 3.14159 // pi
+ xmm0 *= xmm1 // area ~= 28.27
+
+ rdi = xmm0 // truncate to int -> 28
+ rax = SYS_EXIT
+ syscall
+}
diff --git a/examples/fibonacci.hdass b/examples/fibonacci.hdass
index 95a59c8..9436580 100644
--- a/examples/fibonacci.hdass
+++ b/examples/fibonacci.hdass
@@ -43,7 +43,7 @@ proc main
{
r12 = 0
r13 = 1
- r15 = 10 // syscall clobbers rcx/r11, so keep the counter in r15
+ r15 = 10 // syscall clobbers rcx/r11, so keep the counter in r15
loop:
print_number(r12)
diff --git a/examples/hello_world.hdass b/examples/hello_world.hdass
index da6b2b5..149c856 100644
--- a/examples/hello_world.hdass
+++ b/examples/hello_world.hdass
@@ -14,7 +14,7 @@ proc main
rsi = message
rdx = message.len
syscall
-
+
rax = SYS_EXIT
rdi = 0
syscall
diff --git a/examples/load.hdass b/examples/load.hdass
index 6e68ffc..8d29358 100644
--- a/examples/load.hdass
+++ b/examples/load.hdass
@@ -8,9 +8,9 @@ proc main
stack cell[8]
rbx = 7
- rsi = cell // address of the cell
- ^rsi = rbx // store
- rdi = ^rsi // load it back
+ rsi = cell // address of the cell
+ ^rsi = rbx // store
+ rdi = ^rsi // load it back
rax = SYS_EXIT
syscall
diff --git a/examples/logical.hdass b/examples/logical.hdass
index 5e82b42..5fb27fc 100644
--- a/examples/logical.hdass
+++ b/examples/logical.hdass
@@ -8,12 +8,12 @@ const SYS_EXIT = 60
proc main
{
- r1 = 4 // rax
- r2 = 3 // rbx
- r1 += r2 // 7
- r1 *= r2 // 21
+ r1 = 4 // rax
+ r2 = 3 // rbx
+ r1 += r2 // 7
+ r1 *= r2 // 21
- r6 = r1 // rdi = 21 (the exit status)
+ r6 = r1 // rdi = 21 (the exit status)
r1 = SYS_EXIT
syscall
}
diff --git a/examples/loop_sum.hdass b/examples/loop_sum.hdass
index 5976914..2427b17 100644
--- a/examples/loop_sum.hdass
+++ b/examples/loop_sum.hdass
@@ -5,8 +5,8 @@ const SYS_EXIT = 60
proc main
{
- rbx = 0 // running total
- rcx = 5 // counter
+ rbx = 0 // running total
+ rcx = 5 // counter
loop:
rbx += rcx
diff --git a/examples/mandelbrot.hdass b/examples/mandelbrot.hdass
new file mode 100644
index 0000000..9054c15
--- /dev/null
+++ b/examples/mandelbrot.hdass
@@ -0,0 +1,144 @@
+[entry: main]
+[enable: logical_registers]
+
+// Renders the Mandelbrot set as ASCII art. The evolving z value is kept in a
+// Complex struct on the stack (accessed through its field offsets), while the
+// per-pixel constant c stays in xmm2/xmm3. Uses double-precision floats and the
+// logical_registers extension (r1..r14 name the general-purpose registers).
+
+const SYS_WRITE = 1
+const SYS_EXIT = 60
+const STDOUT = 1
+
+const W = 80
+const H = 30
+const MAX_ITER = 32
+
+struct Complex
+{
+ re: qword
+ im: qword
+}
+
+data palette = " .:-=+*#%@"
+
+proc main
+{
+ stack z[Complex.size]
+ stack row[W + 1]
+
+ r11 = 0 // py
+
+row_loop:
+ // ci = py * 0.08 - 1.2
+ xmm3 = r11
+ xmm7 = 0.08
+ xmm3 *= xmm7
+ xmm7 = 1.2
+ xmm3 -= xmm7
+
+ r12 = 0 // px
+
+col_loop:
+ // cr = px * 0.04375 - 2.5
+ xmm2 = r12
+ xmm7 = 0.04375
+ xmm2 *= xmm7
+ xmm7 = 2.5
+ xmm2 -= xmm7
+
+ // z = 0 + 0i
+ xmm0 = 0.0
+ r5 = z
+ r5 += Complex.re
+ ^r5 = xmm0 // z.re = 0
+ r5 = z
+ r5 += Complex.im
+ ^r5 = xmm0 // z.im = 0
+
+ r2 = 0 // iteration count
+
+iter_loop:
+ // load z into xmm0 (zr) and xmm1 (zi)
+ r5 = z
+ r5 += Complex.re
+ xmm0 = ^r5
+ r5 = z
+ r5 += Complex.im
+ xmm1 = ^r5
+
+ // zr2 = zr*zr, zi2 = zi*zi
+ xmm4 = xmm0
+ xmm4 *= xmm0
+ xmm5 = xmm1
+ xmm5 *= xmm1
+
+ // escape when zr2 + zi2 > 4.0
+ xmm6 = xmm4
+ xmm6 += xmm5
+ if xmm6 > 4.0
+ goto plot
+
+ // new_zi = 2*zr*zi + ci (uses the old zr and zi)
+ xmm6 = xmm0
+ xmm6 *= xmm1
+ xmm6 += xmm6
+ xmm6 += xmm3
+ xmm7 = xmm6 // stash new_zi
+
+ // new_zr = zr2 - zi2 + cr
+ xmm4 -= xmm5
+ xmm4 += xmm2
+
+ // store the new z back into the struct
+ r5 = z
+ r5 += Complex.re
+ ^r5 = xmm4 // z.re = new_zr
+ r5 = z
+ r5 += Complex.im
+ ^r5 = xmm7 // z.im = new_zi
+
+ r2 += 1
+ if r2 < MAX_ITER
+ goto iter_loop
+
+plot:
+ // index = iter * 9 / MAX_ITER, then char = palette[index]
+ r1 = r2
+ r1 *= 9
+ r3 = MAX_ITER
+ r1 /= r3
+
+ r5 = palette
+ r5 += r1
+ r4 = ^byte r5
+
+ r6 = row
+ r6 += r12
+ ^byte r6 = r4
+
+ r12 += 1
+ if r12 < W
+ goto col_loop
+
+ // terminate the row with a newline and write it
+ r6 = row
+ r6 += W
+ r1 = 10
+ ^byte r6 = r1
+
+ r1 = SYS_WRITE
+ r6 = STDOUT
+ r5 = row
+ r4 = W
+ r4 += 1
+ syscall
+
+ r11 += 1
+ if r11 < H
+ goto row_loop
+
+ r1 = SYS_EXIT
+ r6 = 0
+ syscall
+}
diff --git a/examples/records.hdass b/examples/records.hdass
index 9800839..f8553d6 100644
--- a/examples/records.hdass
+++ b/examples/records.hdass
@@ -19,7 +19,7 @@ const SYS_EXIT = 60
proc main
{
- stack pair[16] // Pair.size
+ stack pair[Pair.size]
rsi = pair
rbx = 40