# TARM thumb ARM TARM thumb ARM TARM thumb ARM TARM thumb ARM TARM
thumb ARM
########## internals, and meta-noise like thumb
# wants ../shasm for $bit14, $b11100011, ad, aq, ab...
A=0 B=1 C=2 D=3 E=4 SI=5 DI=6
SP=13 # thumb SP is 13, but we use r7 for internals in jump,
call...
LR=14
PC=15
spsp ( ) { # copy the pa SP to the ARM "SP" prior to pop and such
# mov(3)
ad $(( $bit14 | 3 << 9 | $bit6 | 7 << 3 | 13 ))
}
# wide 2-thumb-insn bl calcs
# mask = $bit11-1 = 2047 = 0x7ff
# 2-insn thumb wide branch and link
BLwide ( ) { # BLwide exact_byte-addr_o/s
# internal macro given o/s for 2 insn bl
# for call, enter...
local HI LO
HI=`rpn $1 1 d 11 d 0x7ff a`
LO=`rpn $1 1 d 0x7ff a`
ad $(( 7 << 13 | 2 << 11 | $HI ))
ad $(( 7 << 13 | 3 << 11 | $LO ))
}
bx2arm ( ) { # jump from here to here, but switch to RISC 32 ARM
insns
### ALIGN for 32 first, yo.
ad $(( $_I___III << 8 | 15 << 3 )) # bx PC, which reads right in
thumb
}
thumb ( ) { ## call this protruberance after ELF to get into pa/
thumb
## well worth it.
## Also used to get out of RISC in e.g. mult
# pc -> lr
aq 0xe1a0e00f # mov lr, pc
# +5 or so to lr to turn on thumb (bit0)
# ARM PC reads 4 bytes too far ahead.
aq 0xe28ee005 # add lr, lr, #5
# bx to there, which is here
aq $(( $b00010010 << 20 | $bit4 | $LR )) # bx LR
}
########### pa-visible pa-visible pa-visible pa-visible pa-
visible pa-visible
= () { # = srcreg destreg mov/copy/clobber
ab $(($1<<3|$2)) 0x1c
}
1+ () { # 1+ reg
ab 1 $((0x30|$1)) # see why I went thumb?
}
1- () { # 1- reg
ab 1 $((0x38|$1))
}
+ () { # + reg destreg
ad $(( $b00001100 << 9 | $1 << 6 | $2 << 3 | $2 ))
}
+byte () { # num destreg sign-ext lit and add to destreg
ad $(( 3<<12 | $2 << 8 | $1 ))
}
+carry () { # +carry src dest
ad $(($bit14 | $bit8 | $bit6 | $1 << 3 | $2 ))
}
- () { # - srcreg destreg d - s -> d
# sub(3)
ad $(( $bit12 | $bit11 | $bit9 | $1 << 6 | $2 << 3 | $2 ))
}
-borrow () { # srcreg destreg
ad $(( $bit14 | 3 << 8 | $1 <<3 | $1 ))
}
AND () { # AND reg destreg
ad $(( $bit14 | $1 << 3 | $2 ))
}
call () { # call imm
# return is pop PC
# Given that, I have a 4 insn call. That's 8, maybe 10 bytes,
plus a
# 32-bit literal. Its worth this monstrosity because ...
# Its not my fault ARM doesn't know how computers work
# its standard jsr/rts semantics
# it's a 32 bit range
# it doesn't require anything in the callee besides
# return
# its as good as RISC ARM, or better
#
# using the ARM thumb SP is OK since it's about names.
# We therefor can use r7 for such things.
# And you can break pa whenever you want.
align 4 # zero sets the Z flag. I'm OK with that.
# offset_past_lit(x4) + PC --> r7
ad $(( $bit15|$bit13| 7<<8 | 3 ))
# push r7
ad 0xb480
# 4 meg bl
ad $(( $bit14 | $bit11 | 7 << 8 | 1 )) # load pc-rel literal 4 bytes
ahead into r7
ad $(( $bit14 | 3 << 9 | $bit7 | 7<<3 | 7 )) # mov(3) r7 to PC
ad 0
aq $1
}
callr () { # callr reg abs. o/s
# with this you can call an execution array.
# offset_past_lit(x4) + PC --> r7
ad $(( $bit15|$bit13| 7<<8 | 1 ))
# push r7
ad 0xb480
ad $(( $bit14 | 3 << 9 | $bit7 | $1<<3 | 7 )) # mov(3) r7 to PC
}
divmod () { # reg ( one arg in A, mod in HIGH, )
}
down () { # reg impl. shift in C
# LSR(2)
ad $(( $bit14 | 3 << 6 | C << 3 | $1 ))
}
downi () { # downi reg imm imm shift byte
# lsr(1)
ad $(( $bit11 | $2 << 6 | $1 << 3 | $1 ))
}
downroll () { # reg bits in C, r
ad $(( $bit14 | 7<<6 | C << 3 | $1 ))
}
downrollc () { # reg bits in C, include carry in roll
ad $(( ))
}
downs () { # downs reg downshift reg by C, sign-fill
high side
ad $(( $bit14 | $bit8 | $C << 3 | $1 ))
}
downwide () { # impl. D=HI E=low C=shift
}
h0bit () { # h0bit countee count count high-side 0 bits
# call RISC?
ad $(( ))
}
jump () { # jump num absolute wide
# load pc-rel
align 4 # zero isn't a strict nop, it just sets Z
ad $(( $bit14 | $bit11 | 7 << 8 | 1 )) # load pc-rel literal 4 bytes
ahead into r7
ad $(( $bit14 | 3 << 9 | $bit7 | 7<<3 | 7 )) # mov(3) r7 to PC
ad 0
aq $1
}
jumpr () { # jumpr reg jump reg. wide abs.
# mov(3) reg to PC
ad $(( $bit14 | 3<<9 | $1 << 3 | $bit7 | 7 ))
}
l () { # l BASE imm5 DEST no imm, give it a 0
# immediate offset is upshifted by 2 by insn
# ldr(1)
ad $(( $b00001101 << 11 | $2 << 6 | $1 <<3 | $3 ))
}
lb () { # lb regb num dest give it a 0 for no offset
# ldrb(1)
ad $(( 15 << 11 | $2 << 6 | $1 <<3 | $3 ))
}
lib () { # lib num reg sign extended on arm?
# mov(1) ambiguous as to extension
ad $(( $bit13 | $2 << 8 | $1 ))
}
lpi () { # load post-incrementing [SI++] --> A int (4) incr
# ldmia
ad $(( $b00011001 << 11 | SI << 8 | 1 ))
}
msxb () { # move and sign-extend byte msxb bytereg dest
ad $(( ))
}
mult () { # mult reg reg * A --> D:A
# switch to RARM for this
bx2arm
thumb
}
neg () { # neg reg
# neg
ad $(( $bit14 | 9 << 6 | $1 << 3 | $1 ))
}
nop () { # --- sets Z flag, but encodes to 0, which I like.
ad 0
}
NOT () { # NOT reg
# MVN
ad $(( $bit14 | 15 << 6 | $1 << 3 | $1 ))
}
OR () { # OR reg dest
# ORR
ad $(( $bit14 | 12 << 6 | $1 <<3 | $2 ))
}
pull () { # pull reg
# pop
ab $(( $b10111100<<8 | 1 << $1 ))
}
push () { # reg
# push
ab $(( $b10110100<<8 | 1 << $1 ))
}
pullem () { # ---
ab $(( $b10111100<<8 | 255 ))
}
pushem () { # ---
ab $(( $b10110100<<8 | 255 ))
}
return () { # --- (framedrop version maybe later
leave)
# pop PC
ad $(( 11<<12 | 1 << 11 | 2 << 9 | $bit8 ))
}
s () { # s sreg addrreg imm give it a 0 if no o/s
# srt(1)
ad $(( $bit14|$bit13 | $3<< 6 | $2 << 3 | $1 ))
}
sb () { # s sreg addrreg imm give it a 0 if no o/s
# strb(1)
ad $(( 7<<12 | $3 << 6 | $2 << 3 | $1 ))
}
spi () { # store post-incrementing A --> [DI+4]!
# stmia
ad $(( $b00011000 << 11 | DI << 8 | 1 ))
}
submit () { # submit IRQ# trap to supervisor. Syscall.
ad $(( $b11011111 << 8 | $1 ))
}
TAND () { # TAND reg reg AND regs for flags only
ad $(( $bit14 | $bit9 | $1 << 3 | $2 ))
}
tsub () { # tsub minuend subtrahend test subtract
# cmp
ad $(( $bit14 | $bit9 | $bit7 | $1 <<3 | $2 ))
}
up () { # up shiftee/dest upshift reg by C, zero-fill
# lsl(2)
ad $(( $bit14 | $bit7 | $C <<3 | $1 ))
}
upi () { # upi imm shiftee/dest
# lsl(1)
ad $(( $1 << 6 | $2 << 3 | $2 ))
}
upwide () { # upshift wide
}
when () { # when CC num [raw] abs(num)<512
local offset
if test $3 ; then
let offset=$3>>1
else
let offset=$(( 255 & ( ($H-$3) >>1 ) )) # don't OR a big neg.
fi
ad $(( $b00001101 << 12 | $1 << 8 | $offset ))
}
XOR () { # XOR srcreg destreg
ad $(( $bit14 | $bit6 | $1 << 3 | $2 ))
}
###########() # plurals etc.
copy () { # move C ints from [SI++] to [DI++]
}
fill () { # fill C copies of int A into [DI++]
}
rangematch () { # compare C ints of [SI++] - [DI++], C=0 if ranges
match
}
find () { # compare C ints from [DI++] against A; C holds count of
1st match
}
findnot () { # compare C ints from [DI++] against A; C holds count
of 1st mismatch
}
sum () { # uses A, C, SI; sum in A
}
xsum () { # uses A, C, SI; sum in A
}
scale () { # reg mult reg * A, downshift double result D:A by C
}
timesdiv () { # arg arg * A double, div double by C Forth
*/
}
#Sun Apr 29 23:47:49 EDT 2012
# Rick arrest Bush deport Obama Hohensee
rick_h...@email.com
#
http://presidentbyamendment.com ftp.gwdg.de/pub/cLIeNUX/
interim
# presidentbyamendment on facebook and youtube
# shasm H3sm cLIeNUX libsys.a scale
LAAETTR :o)
# TARM thumb ARM TARM thumb ARM TARM thumb ARM TARM thumb ARM TARM
thumb ARM