summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-04-05 08:54:16 -0700
committerIrene Knapp <ireneista@irenes.space>2026-04-05 08:54:16 -0700
commit929fd6251b7b18952bb58299ab58aa49305a8b92 (patch)
tree5ebb31d3afddce1727da05aa91c828ad419fb38b
parent9b27f0bdc250279a41b46a5b8139f9fad22e59dc (diff)
make sure the logarithms work with really big numbers
Force-Push: yes
Change-Id: Ic084e13b4fe715bc08ac9ceb0e97f75d2fe7fedd
-rw-r--r--quine.asm111
1 files changed, 106 insertions, 5 deletions
diff --git a/quine.asm b/quine.asm
index f2be4fe..0525cf4 100644
--- a/quine.asm
+++ b/quine.asm
@@ -2246,6 +2246,50 @@ cold_start:
   dq rax, push_reg64
   dq pack_next, lit, 8, packalign, early_here_store
 
+  ; This was "gt_unsigned".
+  dq litstring, ">unsigned", early_create
+  dq early_self_codeword, early_here, fetch
+  dq rax, pop_reg64
+  dq rbx, pop_reg64
+  dq rbx, rax, cmp_reg64_reg64
+  dq cc_above, al, set_reg8_cc
+  dq lit, 0x01, rax, and_reg64_imm8
+  dq rax, push_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
+
+  ; This was "lt_unsigned".
+  dq litstring, "<unsigned", early_create
+  dq early_self_codeword, early_here, fetch
+  dq rax, pop_reg64
+  dq rbx, pop_reg64
+  dq rbx, rax, cmp_reg64_reg64
+  dq cc_below, al, set_reg8_cc
+  dq lit, 0x01, rax, and_reg64_imm8
+  dq rax, push_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
+
+  ; This was "ge_unsigned".
+  dq litstring, ">=unsigned", early_create
+  dq early_self_codeword, early_here, fetch
+  dq rax, pop_reg64
+  dq rbx, pop_reg64
+  dq rbx, rax, cmp_reg64_reg64
+  dq cc_above_equal, al, set_reg8_cc
+  dq lit, 0x01, rax, and_reg64_imm8
+  dq rax, push_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
+
+  ; This was "le_unsigned".
+  dq litstring, "<=unsigned", early_create
+  dq early_self_codeword, early_here, fetch
+  dq rax, pop_reg64
+  dq rbx, pop_reg64
+  dq rbx, rax, cmp_reg64_reg64
+  dq cc_below_equal, al, set_reg8_cc
+  dq lit, 0x01, rax, and_reg64_imm8
+  dq rax, push_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
+
   dq litstring, "and", early_create, early_self_codeword, early_here, fetch
   dq rbx, pop_reg64
   dq rax, pop_reg64
@@ -3122,6 +3166,46 @@ defword le, 0
   push.qreg rax
   next
 
+defword gt_unsigned, 0
+  dq $ + 8
+  pop.qreg rax
+  pop.qreg rbx
+  cmp.qreg.qreg rax, rbx
+  set.breg.cc al, above
+  and.qreg.bimm rax, 0x01
+  push.qreg rax
+  next
+
+defword lt_unsigned, 0
+  dq $ + 8
+  pop.qreg rax
+  pop.qreg rbx
+  cmp.qreg.qreg rax, rbx
+  set.breg.cc al, below
+  and.qreg.bimm rax, 0x01
+  push.qreg rax
+  next
+
+defword ge_unsigned, 0
+  dq $ + 8
+  pop.qreg rax
+  pop.qreg rbx
+  cmp.qreg.qreg rax, rbx
+  set.breg.cc al, above_equal
+  and.qreg.bimm rax, 0x01
+  push.qreg rax
+  next
+
+defword le_unsigned, 0
+  dq $ + 8
+  pop.qreg rax
+  pop.qreg rbx
+  cmp.qreg.qreg rax, rbx
+  set.breg.cc al, below_equal
+  and.qreg.bimm rax, 0x01
+  push.qreg rax
+  next
+
 ;;;
 ;;; Bitwise routines
 ;;; ----------------
@@ -3685,10 +3769,11 @@ defword emitstring, 0
 ; constructs we already have.
 ;
 ; In:
-;   integer
+;   integer to print
 defword dot, 0
   dq docol
 
+  ; Deal with negative numbers.
   dq dup, lit, 0, gt, zbranch, 7*8
   dq lit, -1, mul
   dq litstring, "-", emitstring
@@ -3754,7 +3839,7 @@ defword logfloor, 0
   ; (base, value, product so far, count of powers included so far)
   dq unroll3, dup2
   ; (base, count so far, value, product so far)
-  dq gt, zbranch, 6*8
+  dq gt_unsigned, zbranch, 6*8
 
   ; If we get here, we're done.
   ; (base, count so far, value, product so far)
@@ -3764,7 +3849,15 @@ defword logfloor, 0
   ; (base, count so far, value, product so far)
   dq lit, 4, roll, dup, lit, 5, unroll, mul, roll3, lit, 1, add
   ; (base, value, updated product so far, updated count so far)
-  dq branch, -23*8
+
+  ; If the product is less than the base, we overflowed. In that case, the
+  ; product-so-far is the maximum, so just return it.
+  dq lit, 4, roll, dup, lit, 5, unroll, roll3, dup, lit, 4, unroll
+  dq lt, zbranch, 8*8
+  dq lit, 4, unroll, drop, drop, drop, exit
+
+  ; Nothing else weird going on, so loop.
+  dq branch, -45*8
 
 ; In:
 ;   base
@@ -3781,7 +3874,7 @@ defword logceil, 0
   ; (base, value, product so far, count of powers included so far)
   dq unroll3, dup2
   ; (base, count so far, value, product so far)
-  dq ge, zbranch, 6*8
+  dq ge_unsigned, zbranch, 6*8
 
   ; If we get here, we're done.
   ; (base, count so far, value, product so far)
@@ -3791,7 +3884,15 @@ defword logceil, 0
   ; (base, count so far, value, product so far)
   dq lit, 4, roll, dup, lit, 5, unroll, mul, roll3, lit, 1, add
   ; (base, value, updated product so far, updated count so far)
-  dq branch, -23*8
+
+  ; If the product is less than the base, we overflowed. In that case, the
+  ; product-so-far is the maximum, so just return it.
+  dq lit, 4, roll, dup, lit, 5, unroll, roll3, dup, lit, 4, unroll
+  dq lt, zbranch, 8*8
+  dq lit, 4, unroll, drop, drop, drop, exit
+
+  ; Nothing else weird going on, so loop.
+  dq branch, -45*8
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;