diff options
| author | Irene Knapp <ireneista@irenes.space> | 2025-11-06 18:07:24 -0800 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2025-11-06 18:07:24 -0800 |
| commit | 71e5dbbc3c8f720dae0ccac531fe49c15af62b63 (patch) | |
| tree | ff9e9ef122a722bbea0d2ec5fa66462e15da977d /quine.asm | |
| parent | 7c0227c5b6466b911add5afec0accaca368131a5 (diff) | |
did all the pending instructions that use indexed addressing modes
we're starting to feel vaguely proficient in stack juggling, but it will still be quite a thing if these don't need fixing later Force-Push: yes Change-Id: Ic1285d01cc42c6e8a30d36fc53e67135d8d9e175
Diffstat (limited to 'quine.asm')
| -rw-r--r-- | quine.asm | 91 |
1 files changed, 86 insertions, 5 deletions
diff --git a/quine.asm b/quine.asm index 9dedc18..77360f8 100644 --- a/quine.asm +++ b/quine.asm @@ -2893,6 +2893,19 @@ defword extrareg64, 0 dq litstring, "Parameter to extrareg64 is not an extrareg64.", emitstring dq lit, 1, sys_exit +; Stack in: +; scale factor, as a count of bytes +; Stack out: +; 2-bit encoded value for scale field in SIB byte +defword scalefield, 0 + dq docol + dq dup, 1, eq, zbranch, 5*8, drop, lit, 0, exit + dq dup, 2, eq, zbranch, 5*8, drop, lit, 1, exit + dq dup, 4, eq, zbranch, 5*8, drop, lit, 2, exit + dq dup, 8, eq, zbranch, 5*8, drop, lit, 3, exit + dq litstring, "Parameter to scalefield is not 1, 2, 4, or 8.", emitstring + dq lit, 1, sys_exit + ; Stack: ; output point defword rex_w, 0 @@ -2971,8 +2984,6 @@ defword addressing_indirect_reg64, 0 dq emitstring dq lit, 1, sys_exit -; This mode can do rbp fine, rsp is the only unusual case. -; ; Stack: ; output point ; reg/op field value (raw number) @@ -2980,6 +2991,7 @@ defword addressing_indirect_reg64, 0 ; displacement value defword addressing_disp8_reg64, 0 dq docol + ; This mode can do rbp fine, so no need to check for that. ; Check whether the R/M register is rsp; save the test result for later. dq swap, dup, rsp, eq, lit, 5, unroll, swap ; Stash the displacement value out of the way, too. @@ -2993,6 +3005,40 @@ defword addressing_disp8_reg64, 0 ; Stack: ; output point +; reg/op field value (raw number) +; scale factor, as a count of bytes +; index register name +; base field register name +defword addressing_indexed_reg64, 0 + dq docol + ; Exit with an error if the base register is rbp. + dq dup, rbp, ne, zbranch, 17*8 + ; Reg/mem value 4 means to use an SIB byte (at least, with this mode). + dq lit, 5, roll, lit, 0, lit, 6, roll, lit, 4, modrm, lit, 4, unroll + dq reg64, unroll3, reg64, unroll3, scalefield, unroll3, sib + dq exit + dq litstring, "Base parameter to addressing_indexed_reg64 is rbp." + dq emitstring + dq lit, 1, sys_exit + +; Stack: +; output point +; reg/op field value (raw number) +; scale factor, as a count of bytes +; index register name +; base field register name +; displacement value +defword addressing_disp8_indexed_reg64, 0 + dq docol + ; This mode can do rbp fine, so no need to check for that. + ; Reg/mem value 4 means to use an SIB byte (at least, with this mode). + dq lit, 6, roll, lit, 1, lit, 7, roll, lit, 4, modrm, lit, 5, unroll + dq lit, 5, unroll, reg64, unroll3, reg64, unroll3, scalefield, unroll3, sib + dq swap, pack8 + dq exit + +; Stack: +; output point defword cld, 0 dq docol, lit, 0xFC, pack8, exit @@ -3069,6 +3115,18 @@ defword mov_reg64_disp8_reg64, 0 ; Stack: ; output point ; source register name +; source index register name +; source index scale factor, as a count of bytes +; target register name +defword mov_reg64_indexed_reg64, 0 + dq docol + dq lit, 5, roll, rex_w, lit, 0x8B, pack8, lit, 5, unroll + dq reg64, lit, 4, unroll, unroll3, swap, addressing_indexed_reg64 + dq exit + +; Stack: +; output point +; source register name ; source displacement value ; target register name defword lea_reg64_disp8_reg64, 0 @@ -3080,6 +3138,32 @@ defword lea_reg64_disp8_reg64, 0 ; Stack: ; output point ; source register name +; source index register name +; source index scale factor, as a count of bytes +; target register name +defword lea_reg64_indexed_reg64, 0 + dq docol + dq lit, 5, roll, rex_w, lit, 0x8D, pack8, lit, 5, unroll + dq reg64, lit, 4, unroll, unroll3, swap, addressing_indexed_reg64 + dq exit + +; Stack: +; output point +; source register name +; source index register name +; source index scale factor, as a count of bytes +; source displacement value +; target register name +defword lea_reg64_disp8_indexed_reg64, 0 + dq docol + dq lit, 6, roll, rex_w, lit, 0x8D, pack8, lit, 6, unroll + dq reg64, lit, 5, unroll, lit, 3, roll, lit, 4, roll, lit, 3, roll + dq addressing_disp8_indexed_reg64 + dq exit + +; Stack: +; output point +; source register name defword push_reg64, 0 dq docol, reg64, lit, 0x50, opcodereg, exit @@ -3298,15 +3382,12 @@ defword jmp_abs_indirect_reg64, 0 defword syscall, 0 dq docol, lit, 0x0F, pack8, lit, 0x05, pack8, exit -; TODO mov_reg64_indexed_reg64 ; TODO mov_indirect_reg64_reg8 ; TODO mov_reg8_indirect_qreg ; TODO mov_indirect_reg64_reg16 ; TODO mov_reg16_indirect_reg64 ; TODO mov_indirect_reg64_reg32 ; TODO mov_reg32_indirect_reg64 -; TODO lea_reg64_indexed_reg64 -; TODO lea_reg64_disp8_indexed_reg64 ; TODO rep movsb ; TODO rep movsq ; TODO repnz scasb |