summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2025-11-06 22:21:49 -0800
committerIrene Knapp <ireneista@irenes.space>2025-11-06 22:21:49 -0800
commit34840ee7f9e12fe2ac2e0e75d296e25ecdefdc87 (patch)
treedd2d9a95a47745a692d660dee80ee8dbf812bf03
parentd86f6b1441301618cc0c9ca124b65907e131485d (diff)
okay now all the conditional operations and jumps are implemented, too HEAD main
this completes the assembly-in-Forth stuff! yay

Force-Push: yes
Change-Id: I7f9466a3a71375c32991379fc040d6cc3d657302
-rw-r--r--quine.asm140
1 files changed, 134 insertions, 6 deletions
diff --git a/quine.asm b/quine.asm
index b828b90..00a57c1 100644
--- a/quine.asm
+++ b/quine.asm
@@ -2906,6 +2906,38 @@ defword dh, 0
   dq docol, lit, rsi, exit
 defword bh, 0
   dq docol, lit, rdi, exit
+defword cc_overflow, 0
+  dq docol, lit, cc_overflow, exit
+defword cc_no_overflow, 0
+  dq docol, lit, cc_no_overflow, exit
+defword cc_below, 0
+  dq docol, lit, cc_below, exit
+defword cc_above_equal, 0
+  dq docol, lit, cc_above_equal, exit
+defword cc_equal, 0
+  dq docol, lit, cc_equal, exit
+defword cc_not_equal, 0
+  dq docol, lit, cc_not_equal, exit
+defword cc_below_equal, 0
+  dq docol, lit, cc_below_equal, exit
+defword cc_above, 0
+  dq docol, lit, cc_above, exit
+defword cc_sign, 0
+  dq docol, lit, cc_sign, exit
+defword cc_not_sign, 0
+  dq docol, lit, cc_not_sign, exit
+defword cc_even, 0
+  dq docol, lit, cc_even, exit
+defword cc_odd, 0
+  dq docol, lit, cc_odd, exit
+defword cc_less, 0
+  dq docol, lit, cc_less, exit
+defword cc_greater_equal, 0
+  dq docol, lit, cc_greater_equal, exit
+defword cc_less_equal, 0
+  dq docol, lit, cc_less_equal, exit
+defword cc_greater, 0
+  dq docol, lit, cc_greater, exit
 
 ; Stack in:
 ;   register name
@@ -3004,6 +3036,35 @@ defword scalefield, 0
   dq litstring, "Parameter to scalefield is not 1, 2, 4, or 8.", emitstring
   dq lit, 1, sys_exit
 
+; [Intel] volume 2D, appendix B, section B-1.4.7, table B-10. Also see the
+; individual opcode pages.
+;
+; Stack in:
+;   condition name
+; Stack out:
+;   4-bit encoded value for condition code in opcodes
+defword conditioncode, 0
+  dq docol
+  dq dup, cc_overflow, eq, zbranch, 5*8, drop, lit, 0, exit
+  dq dup, cc_no_overflow, eq, zbranch, 5*8, drop, lit, 1, exit
+  dq dup, cc_below, eq, zbranch, 5*8, drop, lit, 2, exit
+  dq dup, cc_above_equal, eq, zbranch, 5*8, drop, lit, 3, exit
+  dq dup, cc_equal, eq, zbranch, 5*8, drop, lit, 4, exit
+  dq dup, cc_not_equal, eq, zbranch, 5*8, drop, lit, 5, exit
+  dq dup, cc_below_equal, eq, zbranch, 5*8, drop, lit, 6, exit
+  dq dup, cc_above, eq, zbranch, 5*8, drop, lit, 7, exit
+  dq dup, cc_sign, eq, zbranch, 5*8, drop, lit, 8, exit
+  dq dup, cc_not_sign, eq, zbranch, 5*8, drop, lit, 9, exit
+  dq dup, cc_even, eq, zbranch, 5*8, drop, lit, 10, exit
+  dq dup, cc_odd, eq, zbranch, 5*8, drop, lit, 11, exit
+  dq dup, cc_less, eq, zbranch, 5*8, drop, lit, 12, exit
+  dq dup, cc_greater_equal, eq, zbranch, 5*8, drop, lit, 13, exit
+  dq dup, cc_less_equal, eq, zbranch, 5*8, drop, lit, 14, exit
+  dq dup, cc_greater, eq, zbranch, 5*8, drop, lit, 15, exit
+  dq litstring, "Parameter to conditioncode is not a condition code."
+  dq emitstring
+  dq lit, 1, sys_exit
+
 ; Stack:
 ;   output point
 defword rex_w, 0
@@ -3018,6 +3079,13 @@ defword rex_wb, 0
 defword opcodereg, 0
   dq docol, or, pack8, exit
 
+; Stack:
+;   output point
+;   4-bit encoded value for condition code
+;   opcode byte
+defword opcodecc, 0
+  dq docol, or, pack8, exit
+
 ;   The low-level word that outputs a modrm byte given fully-processed,
 ; numeric values for its fields. Most code will want to call one of the
 ; higher-level modrm_* words, instead.
@@ -3404,6 +3472,31 @@ defword lodsq, 0
 
 ; Stack:
 ;   output point
+defword rep_movsb, 0
+  dq docol, lit, 0xF3, pack8, lit, 0xA4, pack8, exit
+
+; Stack:
+;   output point
+defword rep_movsw, 0
+  dq docol, lit, 0xF3, pack8, lit, 0x66, pack8, lit, 0xA5, pack8, exit
+
+; Stack:
+;   output point
+defword rep_movsd, 0
+  dq docol, lit, 0xF3, pack8, lit, 0xA5, pack8, exit
+
+; Stack:
+;   output point
+defword rep_movsq, 0
+  dq docol, lit, 0xF3, pack8, rex_w, lit, 0xA5, pack8, exit
+
+; Stack:
+;   output point
+defword repnz_scasb, 0
+  dq docol, lit, 0xF2, pack8, lit, 0xAE, pack8, exit
+
+; Stack:
+;   output point
 ;   source register name
 ;   target register name
 defword add_reg64_reg64, 0
@@ -3594,6 +3687,38 @@ defword test_reg64_reg64, 0
 
 ; Stack:
 ;   output point
+;   target register name
+;   condition code name
+defword set_reg8_cc, 0
+  dq docol
+  dq unroll3, lit, 0x0F, pack8
+  dq swap, conditioncode, lit, 0x90, opcodecc
+  dq swap, reg8, lit, 3, lit, 0, roll3, modrm
+  dq exit
+
+; Stack:
+;   output point
+;   address offset value
+;   condition code name
+defword jmp_cc_rel_imm8, 0
+  dq docol
+  dq unroll3, swap, conditioncode, lit, 0x70, opcodecc
+  dq swap, pack8
+  dq exit
+
+; Stack:
+;   output point
+;   address offset value
+;   condition code name
+defword jmp_cc_rel_imm32, 0
+  dq docol
+  dq unroll3, lit, 0x0F, pack8
+  dq swap, conditioncode, lit, 0x70, opcodecc
+  dq swap, pack32
+  dq exit
+
+; Stack:
+;   output point
 ;   register name
 defword jmp_abs_indirect_reg64, 0
   dq docol
@@ -3603,15 +3728,18 @@ defword jmp_abs_indirect_reg64, 0
 
 ; Stack:
 ;   output point
+;   address offset value
+defword jmp_rel_imm32, 0
+  dq docol
+  dq swap, lit, 0xE9, pack8
+  dq swap, pack32
+  dq exit
+
+; Stack:
+;   output point
 defword syscall, 0
   dq docol, lit, 0x0F, pack8, lit, 0x05, pack8, exit
 
-; TODO rep movsb
-; TODO rep movsq
-; TODO repnz scasb
-; TODO set_reg8_cc
-;   (and condition codes)
-; TODO jmp_cc_rel_imm8
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Runtime word definition ;;;