M fs/asm/arm.fs => fs/asm/arm.fs +4 -2
@@ 33,8 33,9 @@ $18 op orr) $1a op mov) $1c op bic) $1e op mvn)
: i) ( op n -- op )
#? if abort" invalid immediate value" then or $02000000 or ;
-\ Single Data Transfer (LDR, STR)
+\ Single Data Transfer (LDR, STR, SWP)
$05000000 al) const str) str) $00100000 or const ldr)
+$01000090 al) const swp)
: pre) $01000000 or ;
: post) $feffffff and ;
@@ 90,7 91,8 @@ $90 al) const mul)
\ HAL
\ "opcode+mod" structure (close to ARM structure)
-\ b3:0 Number bank index
+\ b2:0 Number bank index
+\ b3 Has an nonzero offset
\ b4 Rn is an absolute memory addr in bank if set
\ b11:5 Zeroes
\ b15:12 Rd
M fs/doc/asm/arm.txt => fs/doc/asm/arm.txt +9 -0
@@ 104,6 104,15 @@ words:
8b) op -- op Load/Store operation is 8-bit
!) op -- op Write effective address back to rn)
+## Swap
+
+The swp) instruction has the same base semantics as ldr) and str), that is, that
+rn) is the base address, but it doesn't support any kind of indexing. Only the
+8b) flag can be used.
+
+ swp) r1 rd) r2 rn) r1 rm) ,) \ Swaps the value at address r2 with r1
+ swp) r1 rd) r2 rn) r3 rm) ,) \ r3 --> [r2] --> r1
+
## Branching
The b) bl) and bx) branching words differ from other mnemonic words because they
M fs/tests/asm/arm.fs => fs/tests/asm/arm.fs +2 -0
@@ 9,6 9,8 @@ mov) r0 rd) 42 i)
$e3a0002a #eq \ mov r0, #42
ldr) r1 rd) r2 rn) r3 +r) pre) 1 lsr)
$e79210a3 #eq \ ldr r1, [r2, r3 lsr #1]
+swp) r1 rd) r2 rn) r3 rm)
+ $e1021093 #eq \ swp r1, r3, [r2]
mov) r3 rd) $3f0000 i)
$e3a039fc #eq \ mov r3, #3f0000
mul) r1 rd) r2 rm) r3 rs)
M fs/xcomp/arm/rpi/kernel.fs => fs/xcomp/arm/rpi/kernel.fs +21 -2
@@ 322,7 322,7 @@ pc to lblcwrite \ r0=char
str) r1 rd) r2 rn) ,)
exit,
-pc to lbldwrite \ r0=n
+pc to lbldwrite \ r0=n. Destroys r1 and r2, preserves rest
lblhere r2 pc>reg,
ldr) r1 rd) r2 rn) ,)
str) r0 rd) r1 rn) 4 +i) post) ,)
@@ 398,6 398,7 @@ xcode +) ( operand n -- operand )
lblhbank r0 pc>reg,
str) rTOP rd) r0 rn) ,)
xdrop,
+ orr) rTOP rdn) $8 i) ,)
exit,
xcode 8b) ( operand -- operand )
@@ 444,13 445,31 @@ xcode LIT>W, ( n -- )
pc to L2 ( operand -- ) \ r0=base instr
lblhbank r1 pc@>reg,
- orr) rTOP rdn) r1 rm) ,)
+ tst) rTOP rn) $8 i) ,)
+ bic) rTOP rdn) $3f i) ,)
+ orr) nz) rTOP rdn) r1 rm) ,)
L1 abs>rel b) ,)
pc ldr) rTOP rd) 0 +i) ,)
xcode @, ( operand -- )
( pc ) r0 pc@>reg, L2 abs>rel b) ,)
+pc str) rTOP rd) 0 +i) ,)
+xcode !, ( operand -- )
+ ( pc ) r0 pc@>reg, L2 abs>rel b) ,)
+
+pc swp) rTOP rd) rTOP rm) ,) add) r0 rd) rPSP rn) 0 i) ,)
+xcode @!, pushret, ( operand -- )
+ dup ( pc ) 4 + r1 pc@>reg,
+ lblhbank r0 pc@>reg,
+ orr) r0 rdn) r1 rm) ,) \ r0=add instr
+ tst) rTOP rn) $8 i) ,)
+ lbldwrite abs>rel bl) nz) ,)
+ bic) nz) rTOP rdn) $f0000 i) ,) \ set operand's rn) to r0
+ ( pc ) r0 pc@>reg,
+ bic) rTOP rdn) $04000000 i) ,) \ remove 32b flag
+ popret, L1 abs>rel b) ,)
+
pc pushret,
xcode pushret,
( pc ) r0 pc@>reg, lbldwrite abs>rel b) ,)
M fs/xcomp/rpiboot.fs => fs/xcomp/rpiboot.fs +6 -0
@@ 1,8 1,14 @@
code : pushret, ] code pushret, ] ;
code noop exit,
code dup dup, exit,
+: swap, PSP) @!, ; code swap swap, exit,
: nip, 4 ps+, ; code nip nip, exit,
: drop, PSP) @, nip, ; code drop drop, exit,
: 2drop, PSP) 4 +) @, 8 ps+, ; code 2drop 2drop, exit,
+: rot, PSP) @!, PSP) 4 +) @!, ; code rot rot, exit,
+code rot> PSP) 4 +) @!, PSP) @!, exit,
+: over, dup, PSP) 4 +) @, ; code over over, exit,
+code tuck swap, over, exit,
+code 2dup -8 ps+, PSP) 4 +) !, PSP) 8 +) @, PSP) !, PSP) 4 +) @, exit,
uartinit prompt interactive!