duskos

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

commit 9ed028ebcb746633f76fc1d4d835523ec2c8d390
parent 43ab35f9f20e1eb463efffa52579efb923d3b571
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sun, 28 May 2023 08:30:01 -0400

asm/arm: add mul)

Diffstat:
Mfs/asm/arm.fs | 50+++++++++++++++++++++++++++++---------------------
Mfs/doc/asm/arm.txt | 27++++++++++++++++++++++++++-
Mfs/tests/asm/arm.fs | 3+++
3 files changed, 58 insertions(+), 22 deletions(-)

diff --git a/fs/asm/arm.fs b/fs/asm/arm.fs @@ -9,31 +9,14 @@ : ,) ( op -- ) le, ; -0 const r0 1 const r1 2 const r2 3 const r3 -4 const r4 5 const r5 6 const r6 7 const r7 -8 const r8 9 const r9 10 const r10 11 const r11 -12 const r12 13 const r13 14 const r14 15 const r15 - 9 const rTOP 10 const rPSP 11 const rA -12 const rIP 13 const rSP 14 const rLR 15 const rPC -: rn) ( op r -- op ) 16 lshift or ; -: rd) ( op r -- op ) 12 lshift or ; -: rm) ( op r -- op ) or ; -: rdn) tuck rd) swap rn) ; - -\ immediate shift operations ( op n -- op ) -: _ ( op n type -- op ) dip 3 lshift | << or 4 lshift or ; -: lsl) 0 _ ; : lsr) 1 _ ; : asr) 2 _ ; : ror) 3 _ ; -\ register shift operations ( op r -- op ) -: _ ( op r type -- op ) dip 4 lshift | << 1+ or 4 lshift or ; -: rlsl) 0 _ ; : rlsr) 1 _ ; : rasr) 2 _ ; : rror) 3 _ ; - : cond doer , does> @ 28 lshift swap $0fffffff and or ; 0 cond eq) 1 cond ne) 2 cond cs) 3 cond cc) +0 cond z) 1 cond nz) 2 cond hs) 3 cond lo) 4 cond mi) 5 cond pl) 6 cond vs) 7 cond vc) 8 cond hi) 9 cond ls) 10 cond ge) 11 cond lt) -12 cond gt) 13 cond le) +12 cond gt) 13 cond le) 14 cond al) -: op doer , does> @ 20 lshift $e0000000 or ; +: op doer , does> @ 20 lshift al) ; $00 op and) $02 op eor) $04 op sub) $06 op rsb) $08 op add) $0a op adc) $0c op sbc) $0e op rsc) $11 op tst) $13 op teq) $15 op cmp) $17 op cmn) @@ -51,7 +34,7 @@ $18 op orr) $1a op mov) $1c op bic) $1e op mvn) #? if abort" invalid immediate value" then or $02000000 or ; \ Single Data Transfer (LDR, STR) -$e5000000 const str) $e5100000 const ldr) +$05000000 al) const str) str) $00100000 or const ldr) : pre) $01000000 or ; : post) $feffffff and ; @@ -63,6 +46,31 @@ $e5000000 const str) $e5100000 const ldr) : 8b) $00400000 or ; : !) $00200000 or ; +\ Multiply +$90 al) const mul) +: ismul? ( op -- f ) $0fcf00f0 and $90 = ; +: acc) ( op r -- op ) 12 lshift or $00200000 or ; + +\ Parameters +0 const r0 1 const r1 2 const r2 3 const r3 +4 const r4 5 const r5 6 const r6 7 const r7 +8 const r8 9 const r9 10 const r10 11 const r11 +12 const r12 13 const r13 14 const r14 15 const r15 + 9 const rTOP 10 const rPSP 11 const rA +12 const rIP 13 const rSP 14 const rLR 15 const rPC +: rn) ( op r -- op ) 16 lshift or ; +: rd) ( op r -- op ) over ismul? 4 * 12 + lshift or ; +: rs) ( op r -- op ) 8 lshift or ; +: rm) ( op r -- op ) or ; +: rdn) tuck rd) swap rn) ; + +\ immediate shift operations ( op n -- op ) +: _ ( op n type -- op ) dip 3 lshift | << or 4 lshift or ; +: lsl) 0 _ ; : lsr) 1 _ ; : asr) 2 _ ; : ror) 3 _ ; +\ register shift operations ( op r -- op ) +: _ ( op r type -- op ) dip 4 lshift | << 1+ or 4 lshift or ; +: rlsl) 0 _ ; : rlsr) 1 _ ; : rasr) 2 _ ; : rror) 3 _ ; + \ Branching : _rel>off >> >> 2 - $ffffff and ; : b) ( rel32 -- op ) _rel>off $ea000000 or ; diff --git a/fs/doc/asm/arm.txt b/fs/doc/asm/arm.txt @@ -15,6 +15,11 @@ the first operand (Rn) and 42 as an immediate, we would do: Symbol-wise, ")" means "accumulate", where the final ",)" means "write what has been accumulated". +WARNING: this assembler will not prevent you from assembling nonsensical +instructions, checks are minimal (it does check immediate ranges though). For +example, this means that using "rn)" on "mov)" or "rd)" on "cmp)" results in a +broken instruction. + ## Generic words All operations work on registers and they pretty much all have a destination @@ -29,6 +34,8 @@ words: rd) Destination register rn) First operand register rm) Second operand register + rs) Used only for Multiply + rdn) Shortcut for rd) rn) when they're the same Whenever there's a second operand register, the barrel shifter can be configured with these words which all have the ( op n -- op ) signature, "op" being the @@ -44,7 +51,7 @@ if the specified immediate can't be encoded. All operations can be conditionally executed. This condition is activated by one of these words: - eq) ne) cs) cc) mi) pl) vs) vc) hi) ls) ge) lt) gt) le) + eq) ne) cs) cc) z) nz) hs) lo) mi) pl) vs) vc) hi) ls) ge) lt) gt) le) al) ## Data processing instructions @@ -60,6 +67,24 @@ To have the operation set the CPSR flags, you can use the word f) which sets the tst) teq) cmp) and cmn) have an implied "f)". +## Multiply + +The multiply instruction, mul), has a different structure than other data +processing instructions and does Rd := Rm * Rs. For this instruction, rn) can't +be used and there's a rs) parameter word just for this instruction (Rs is +generally set with the lsl), lsr), etc. family of words). + +Additionally, there's the possibility of making a Multiply+Add through the acc) +word, which takes a register ID in parameter. + +Rd cannot be the same as Rm and rPC can't be used. + +The f) flag works with mul). Example usages: + + mul) r0 rd) r1 rm) r2 rs) ,) + mul) r0 rd) r1 rm) r2 rs) r3 acc) ,) + mul) r0 rd) r1 rm) r2 rs) f) ,) + ## Single Data Transfer The str) and ldr) operations only use rd) and rn), with rd) being the register diff --git a/fs/tests/asm/arm.fs b/fs/tests/asm/arm.fs @@ -11,4 +11,7 @@ ldr) r1 rd) r2 rn) r3 +r) pre) 1 lsr) $e79210a3 #eq \ ldr r1, [r2, r3 lsr #1] mov) r3 rd) $3f0000 i) $e3a039fc #eq \ mov r3, #3f0000 +mul) r1 rd) r2 rm) r3 rs) + $e0010392 over #eq \ mul r1, r2, r3 +r4 acc) $e0214392 #eq \ mla r1, r2, r3, r4 testend