duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 34d5f6375a2a57d6cb5d55fff6fedf235122830c
parent df2a6f97cd432cbd79a6936abfd3c45691bf6c64
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri, 22 Jul 2022 07:57:30 -0400

asm/i386: add ability to MOV to/from special (CR*, DR*, TR*) registers

Diffstat:
Mfs/asm/i386.fs | 29+++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/fs/asm/i386.fs b/fs/asm/i386.fs @@ -12,7 +12,7 @@ 4 const SIB \ mod 0/1/2 + r/m 4 == SIB 0 value op8b \ is current op in 8bit mode? -0 value opsreg \ is current op an Sreg? +0 value opsreg \ if we have a "special" reg, this contains the override opcode. 1 value opdirec \ 1: reg=tgt r/m=src 0: reg=src r/m=tgt 3 value opmod \ by default, we're in "direct reg" mode -1 value opreg \ -1 = unset @@ -33,6 +33,7 @@ : is16bit? realmode ; \ in 16bit, abs mem = mod0 + rm 6, in 32-bit, it's rm 5 : memoprm 5 is16bit? + ; +: maybe8b ( opcode -- opcode ) op8b not or ; : dw, is16bit? if w, else , then ; : dwc, op8b if c, else dw, then ; @@ -53,7 +54,7 @@ \ "opcode" needs to habe bits 1 and 0 *unset* : op, ( opcode -- ) \ write "opcode", mixing it with opdirec and op8b - opdirec << or op8b not or dup $ff > if w, else c, then ; + opdirec << or dup 8 rshift $ff and ?dup if c, then c, ; : modrm, ( -- ) \ write down modrm, errors out if not all parts are there. opmod 3 lshift opreg or 3 lshift oprm or dup $100 < _assert c, ; @@ -78,7 +79,7 @@ : opimm, ( opcode opreg -- ) \ write the operation in "immediate" mode 0 to opdirec \ TODO: allow sign-extend by making this logic variable - opreg! op, msd, imm, asm$ ; + opreg! maybe8b op, msd, imm, asm$ ; \ Setting arguments @@ -111,9 +112,18 @@ AX _ ax BX _ bx CX _ cx DX _ dx SP _ sp BP _ bp SI _ si DI _ di : _ doer ( reg -- ) c, does> c@ ( reg ) r! 1 to op8b ; AL _ al BL _ bl CL _ cl DL _ dl AH _ ah BH _ bh CH _ ch DH _ dh -: _ doer ( reg -- ) c, does> c@ ( reg ) opreg! 1 to opsreg ; +: _ doer ( reg -- ) c, does> c@ ( reg ) opreg! $8c to opsreg ; ES _ es SS _ ss DS _ ds FS _ fs GS _ gs +: _ doer ( reg -- ) c, does> c@ ( reg ) opreg! $0f20 to opsreg ; +0 _ cr0 2 _ cr2 3 _ cr3 + +: _ doer ( reg -- ) c, does> c@ ( reg ) opreg! $0f21 to opsreg ; +0 _ dr0 1 _ dr1 2 _ dr2 3 _ dr3 6 _ dr6 7 _ dr7 + +: _ doer ( reg -- ) c, does> c@ ( reg ) opreg! $0f24 to opsreg ; +6 _ tr6 7 _ tr7 + : i) ( imm -- ) 1 to imm? to imm ; : 16breg>[oprm] ( reg ) case @@ -163,7 +173,7 @@ $c3 op ret, $fa op cli, $fc op cld, \ Conditional jumps : op ( opcode -- ) doer , does> ( rel32-or-16 a -- ) @ op, rel, ; -$840f op jz, $850f op jnz, +$0f84 op jz, $0f85 op jnz, \ JMP and CALL \ These are special. They can either be called with a modrm tgt, or with *no @@ -186,8 +196,8 @@ $04e9 op jmp, $02e8 op call, dup 16 rshift opreg! $ffff and opmodrm, ; $0400f7 op mul, $0300f7 op neg, $0200f7 op not, $0100ff op dec, $0000ff op inc, -$009f0f op setg, $009c0f op setl, $00940f op setz, $00950f op setnz, -$02010f op lgdt, $03010f op lidt, +$000f9f op setg, $000f9c op setl, $000f94 op setz, $000f95 op setnz, +$020f01 op lgdt, $030f01 op lidt, \ Two operands \ opcode format 00000000 ssssssss iiiiirrr mmmmmm00 @@ -198,7 +208,7 @@ $02010f op lgdt, $03010f op lidt, : op ( opcode -- ) doer , does> @ ( opcode ) imm? if 8 rshift dup >> $fc and $80 or swap 7 and ( opcode opreg ) opimm, - else $ff and opmodrm, then ; + else $ff and maybe8b opmodrm, then ; $040000 op add, $3c0738 op cmp, $2c0528 op sub, $a8f084 op _test, $240420 op and, $0c0108 op or, $340630 op xor, @@ -231,8 +241,7 @@ $58 op pop, $50 op _push, $b0 op8b not 3 lshift or ( b0 or b8 ) opreg or c, imm, asm$ else $c7 c, 0 opreg! msd, imm, asm$ then else - opsreg if $8c opdirec << or c, msd, asm$ else - $88 opmodrm, then then ; + opsreg if opsreg else $88 maybe8b then opmodrm, then ; \ INT is special : int, ( n -- ) $cd c, c, ;