: ADC ( Rm Rn Rd -- ) ADC32-encode ;
: ADCS ( Rm Rn Rd -- ) ADCS32-encode ;
-: ADDi ( imm12 Rn Rd -- ) [ split-imm ] 2dip ADDi32-encode ;
+: ADDi ( uimm24 Rn Rd -- ) [ split-imm ] 2dip ADDi32-encode ;
-: ASRi ( imm6 Rn Rd -- ) [ 6 ?ubits ] 2dip ASRi32-encode ;
+: ASRi ( uimm6 Rn Rd -- ) [ 6 ?ubits ] 2dip ASRi32-encode ;
-: CMPi ( imm12 Rd -- ) [ split-imm ] dip CMPi32-encode ;
+: CMPi ( uimm24 Rd -- ) [ split-imm ] dip CMPi32-encode ;
-: LSLi ( imm6 Rn Rd -- ) [ 6 ?ubits ] 2dip LSLi32-encode ;
-: LSRi ( imm6 Rn Rd -- ) [ 6 ?ubits ] 2dip LSRi32-encode ;
+: LSLi ( uimm6 Rn Rd -- ) [ 6 ?ubits ] 2dip LSLi32-encode ;
+: LSRi ( uimm6 Rn Rd -- ) [ 6 ?ubits ] 2dip LSRi32-encode ;
-: STRuoff ( imm14 Rn Rt -- ) [ 4 / 12 ?ubits ] 2dip STRuoff32-encode ;
-
-: SUBi ( imm12 Rn Rd -- ) [ split-imm ] 2dip SUBi32-encode ;
+: STRuoff ( uimm14 Rn Rt -- ) [ 2 ?>> 12 ?ubits ] 2dip STRuoff32-encode ;
+: SUBi ( uimm24 Rn Rd -- ) [ split-imm ] 2dip SUBi32-encode ;
: ADC ( Rm Rn Rd -- ) ADC64-encode ;
: ADCS ( Rm Rn Rd -- ) ADCS64-encode ;
-: ADDi ( imm12 Rn Rd -- ) [ split-imm ] 2dip ADDi64-encode ;
+: ADDi ( uimm24 Rn Rd -- ) [ split-imm ] 2dip ADDi64-encode ;
: ADDr ( Rm Rn Rd -- ) [ 3 0 ] 2dip ADDer64-encode ;
: ANDi ( imm64 Rn Rd -- ) [ encode-bitmask ] 2dip ANDi64-encode ;
: ANDr ( Rm Rn Rd -- ) [ [ 0 ] dip 0 ] 2dip ANDsr64-encode ;
-: ASRi ( imm6 Rn Rd -- ) [ 6 ?ubits ] 2dip ASRi64-encode ;
+: ASRi ( uimm6 Rn Rd -- ) [ 6 ?ubits ] 2dip ASRi64-encode ;
: ASRr ( Rm Rn Rd -- ) ASRr64-encode ;
: BIC ( Rm Rn Rd -- ) [ [ 0 ] dip 0 ] 2dip BIC64-encode ;
-: CBNZ ( imm21 Rt -- ) [ 4 / 19 ?ubits ] dip CBNZ64-encode ;
+: CBNZ ( simm21 Rt -- ) [ 2 ?>> 19 ?sbits ] dip CBNZ64-encode ;
-: CMPi ( imm12 Rd -- ) [ split-imm ] dip CMPi64-encode ;
+: CMPi ( imm24 Rd -- ) [ split-imm ] dip CMPi64-encode ;
: CMPr ( Rm Rn -- ) [ 3 0 ] dip CMPer64-encode ;
-! cond4 is EQ NE CS HS CC LO MI PL VS VC HI LS GE LT GT LE AL NV
-: CSEL ( Rm Rn Rd cond4 -- ) -rot CSEL64-encode ;
-: CSET ( Rd cond4 -- ) swap CSET64-encode ;
-: CSETM ( Rd cond4 -- ) swap CSETM64-encode ;
+! cond is EQ NE CS HS CC LO MI PL VS VC HI LS GE LT GT LE AL NV
+: CSEL ( Rm Rn Rd cond -- ) -rot CSEL64-encode ;
+: CSET ( Rd cond -- ) swap CSET64-encode ;
+: CSETM ( Rd cond -- ) swap CSETM64-encode ;
: EORi ( imm64 Rn Rd -- ) [ encode-bitmask ] 2dip EORi64-encode ;
: EORr ( Rm Rn Rd -- ) [ [ 0 ] dip 0 ] 2dip EORsr64-encode ;
: FPCR ( -- op0 op1 CRn CRm op2 ) 3 3 4 4 0 ;
: FPSR ( -- op0 op1 CRn CRm op2 ) 3 3 4 4 1 ;
-: LDPpost ( imm10 Rn Rt2 Rt -- ) [ 8 / 7 ?sbits ] 3dip swapd LDPpost64-encode ;
-: LDPpre ( imm10 Rn Rt2 Rt -- ) [ 8 / 7 ?sbits ] 3dip swapd LDPpre64-encode ;
-: LDPsoff ( imm10 Rn Rt2 Rt -- ) [ 8 / 7 ?sbits ] 3dip swapd LDPsoff64-encode ;
+: LDPpost ( simm10 Rn Rt2 Rt -- ) [ 3 ?>> 7 ?sbits ] 3dip swapd LDPpost64-encode ;
+: LDPpre ( simm10 Rn Rt2 Rt -- ) [ 3 ?>> 7 ?sbits ] 3dip swapd LDPpre64-encode ;
+: LDPsoff ( simm10 Rn Rt2 Rt -- ) [ 3 ?>> 7 ?sbits ] 3dip swapd LDPsoff64-encode ;
-: LDRl ( imm21 Rt -- ) [ 4 / 19 ?sbits ] dip LDRl64-encode ;
-: LDRpost ( imm9 Rn Rt -- ) [ 9 ?sbits ] 2dip LDRpost64-encode ;
-: LDRpre ( imm9 Rn Rt -- ) [ 9 ?sbits ] 2dip LDRpre64-encode ;
+: LDRl ( simm21 Rt -- ) [ 2 ?>> 19 ?sbits ] dip LDRl64-encode ;
+: LDRpost ( simm9 Rn Rt -- ) [ 9 ?sbits ] 2dip LDRpost64-encode ;
+: LDRpre ( simm9 Rn Rt -- ) [ 9 ?sbits ] 2dip LDRpre64-encode ;
: LDRr ( Rm Rn Rt -- ) [ 3 0 ] 2dip LDRr64-encode ;
-: LDRuoff ( imm15 Rn Rt -- ) [ 8 / 12 ?ubits ] 2dip LDRuoff64-encode ;
+: LDRuoff ( uimm15 Rn Rt -- ) [ 3 ?>> 12 ?ubits ] 2dip LDRuoff64-encode ;
: LDRBr ( Rm Rn Rt -- ) [ 0 ] 2dip LDRBsr-encode ;
-: LDRBuoff ( imm12 Rn Rt -- ) [ 12 ?ubits ] 2dip LDRBuoff-encode ;
+: LDRBuoff ( uimm12 Rn Rt -- ) [ 12 ?ubits ] 2dip LDRBuoff-encode ;
-: LDRHuoff ( imm13 Rn Rt -- ) [ 2 / 12 ?ubits ] 2dip LDRHuoff-encode ;
+: LDRHuoff ( uimm13 Rn Rt -- ) [ 1 ?>> 12 ?ubits ] 2dip LDRHuoff-encode ;
-: LDUR ( imm9 Rn Rt -- ) [ 9 ?sbits ] 2dip LDUR64-encode ;
+: LDUR ( simm9 Rn Rt -- ) [ 9 ?sbits ] 2dip LDUR64-encode ;
-: LSLi ( imm6 Rn Rd -- ) [ 6 ?ubits ] 2dip LSLi64-encode ;
+: LSLi ( uimm6 Rn Rd -- ) [ 6 ?ubits ] 2dip LSLi64-encode ;
: LSLr ( Rm Rn Rd -- ) LSLr64-encode ;
-: LSRi ( imm6 Rn Rd -- ) [ 6 ?ubits ] 2dip LSRi64-encode ;
+: LSRi ( uimm6 Rn Rd -- ) [ 6 ?ubits ] 2dip LSRi64-encode ;
: MOVr ( Rn Rd -- ) MOVr64-encode ;
: MOVsp ( Rn Rd -- ) [ 0 ] 2dip MOVsp64-encode ;
-: MOVwi ( imm Rt -- ) [ 0 ] 2dip MOVwi64-encode ;
+: MOVwi ( imm16 Rt -- ) [ [ 0 ] dip 16 bits ] dip MOVwi64-encode ;
: MRS ( op0 op1 CRn CRm op2 Rt -- ) MRS-encode ;
: STADD ( Rs Rn -- ) STADD64-encode ;
-: STPpost ( imm10 Rn Rt2 Rt -- ) [ 8 / 7 ?sbits ] 3dip swapd STPpost64-encode ;
-: STPpre ( imm10 Rn Rt2 Rt -- ) [ 8 / 7 ?sbits ] 3dip swapd STPpre64-encode ;
-: STPsoff ( imm10 Rn Rt2 Rt -- ) [ 8 / 7 ?sbits ] 3dip swapd STPsoff64-encode ;
+: STPpost ( simm10 Rn Rt2 Rt -- ) [ 3 ?>> 7 ?sbits ] 3dip swapd STPpost64-encode ;
+: STPpre ( simm10 Rn Rt2 Rt -- ) [ 3 ?>> 7 ?sbits ] 3dip swapd STPpre64-encode ;
+: STPsoff ( simm10 Rn Rt2 Rt -- ) [ 3 ?>> 7 ?sbits ] 3dip swapd STPsoff64-encode ;
-: STRpre ( imm9 Rn Rt -- ) [ 9 ?sbits ] 2dip STRpre64-encode ;
-: STRpost ( imm9 Rn Rt -- ) [ 9 ?sbits ] 2dip STRpost64-encode ;
+: STRpre ( simm9 Rn Rt -- ) [ 9 ?sbits ] 2dip STRpre64-encode ;
+: STRpost ( simm9 Rn Rt -- ) [ 9 ?sbits ] 2dip STRpost64-encode ;
: STRr ( Rm Rn Rt -- ) [ 3 0 ] 2dip STRr64-encode ;
-: STRuoff ( imm15 Rn Rt -- ) [ 8 / 12 ?ubits ] 2dip STRuoff64-encode ;
+: STRuoff ( uimm15 Rn Rt -- ) [ 3 ?>> 12 ?ubits ] 2dip STRuoff64-encode ;
-: SUBi ( imm12 Rn Rd -- ) [ split-imm ] 2dip SUBi64-encode ;
+: SUBi ( uimm24 Rn Rd -- ) [ split-imm ] 2dip SUBi64-encode ;
: SUBr ( Rm Rn Rd -- ) [ 3 0 ] 2dip SUBer64-encode ;
: TSTi ( imm64 Rn -- ) [ encode-bitmask ] dip TSTi64-encode ;
2dup >signed dup reach =
[ drop bits ] [ arm64-encoding-imm ] if ; inline
+ERROR: scaling-error original n-bits-shifted rest ;
+: ?>> ( x n -- x )
+ 2dup bits [ neg shift ] [ scaling-error ] if-zero ;
+
! Some instructions allow an immediate literal of n bits
! or n bits shifted. This means there are invalid immediate
! values, e.g. imm12 of 1, 4096, but not 4097
ERROR: imm-out-of-range imm n ;
: imm-lower? ( imm n -- ? ) on-bits unmask 0 > not ;
- : imm-upper? ( imm n -- ? )
+: imm-upper? ( imm n -- ? )
[ on-bits ] [ shift ] bi unmask 0 > not ;
: (split-imm) ( imm n -- imm upper? )
[ imm-out-of-range ]
} cond ;
-: split-imm ( imm -- shift imm' ) 12 (split-imm) 1 0 ? swap ;
+: split-imm ( imm -- shift imm ) 12 (split-imm) 1 0 ? swap ;
ERROR: illegal-bitmask-immediate n ;
: ?bitmask ( imm imm-size -- imm )
[ ?element ] keep [ >Nimms ] [ >immr ] 2bi
{ 12 0 6 } bitfield* ;
-: ADR ( imm21 Rd -- ) [ [ 2 bits ] [ -2 shift 19 ?sbits ] bi ] dip ADR-encode ;
+: ADR ( simm21 Rd -- ) [ [ 2 bits ] [ -2 shift 19 ?sbits ] bi ] dip ADR-encode ;
-: ADRP ( imm21 Rd -- ) [ 4096 / [ 2 bits ] [ -2 shift 19 ?sbits ] bi ] dip ADRP-encode ;
+: ADRP ( simm21 Rd -- ) [ 4096 / [ 2 bits ] [ -2 shift 19 ?sbits ] bi ] dip ADRP-encode ;
-: RET ( register/f -- ) X30 or RET-encode ;
+: RET ( Rn/f -- ) X30 or RET-encode ;
-: SVC ( imm16 -- ) 16 ?ubits SVC-encode ;
+: SVC ( uimm16 -- ) 16 ?ubits SVC-encode ;
-: BRK ( imm16 -- ) 16 ?ubits BRK-encode ;
-: HLT ( imm16 -- ) 16 ?ubits HLT-encode ;
+: BRK ( uimm16 -- ) 16 ?ubits BRK-encode ;
+: HLT ( uimm16 -- ) 16 ?ubits HLT-encode ;
! B but that is breakpoint
-: Br ( imm28 -- ) 4 / 26 ?sbits B-encode ;
-: B.cond ( imm21 cond4 -- ) [ 4 / 19 ?sbits ] dip B.cond-encode ;
-: BL ( imm28 -- ) 4 / 26 ?sbits BL-encode ;
+: Br ( simm28 -- ) 2 ?>> 26 ?sbits B-encode ;
+: B.cond ( simm21 cond -- ) [ 2 ?>> 19 ?sbits ] dip B.cond-encode ;
+: BL ( simm28 -- ) 2 ?>> 26 ?sbits BL-encode ;
: BR ( Rn -- ) BR-encode ;
: BLR ( Rn -- ) BLR-encode ;
! https://community.element14.com/products/devtools/technicallibrary/m/files/10863
! pg 16
! cond code set in previous arm assembly instruction
-: >CC ( x -- x ) >dec bin> ; inline
-: EQ ( -- n ) 0000 >CC ; inline ! Z set: equal
-: NE ( -- n ) 0001 >CC ; inline ! Z clear: not equal
-: CS ( -- n ) 0010 >CC ; inline ! C set: unsigned higher or same
-: HS ( -- n ) 0010 >CC ; inline !
-: CC ( -- n ) 0011 >CC ; inline ! C clear: unsigned lower
-: LO ( -- n ) 0011 >CC ; inline !
-: MI ( -- n ) 0100 >CC ; inline ! N set: negative
-: PL ( -- n ) 0101 >CC ; inline ! N clear: positive or zero
-: VS ( -- n ) 0110 >CC ; inline ! V set: overflow
-: VC ( -- n ) 0111 >CC ; inline ! V clear: no overflow
-: HI ( -- n ) 1000 >CC ; inline ! C set and Z clear: unsigned higher
-: LS ( -- n ) 1001 >CC ; inline ! C clear or Z set: unsigned lower or same
-: GE ( -- n ) 1010 >CC ; inline ! N equals V: greater or equal
-: LT ( -- n ) 1011 >CC ; inline ! N not equal to V: less than
-: GT ( -- n ) 1100 >CC ; inline ! Z clear AND (N equals V): greater than
-: LE ( -- n ) 1101 >CC ; inline ! Z set OR (N not equal to V): less than or equal
-: AL ( -- n ) 1110 >CC ; inline ! always
-: NV ( -- n ) 1111 >CC ; inline ! always
+: EQ ( -- n ) 0b0000 ; inline ! Z set: equal
+: NE ( -- n ) 0b0001 ; inline ! Z clear: not equal
+: CS ( -- n ) 0b0010 ; inline ! C set: unsigned higher or same
+: HS ( -- n ) 0b0010 ; inline !
+: CC ( -- n ) 0b0011 ; inline ! C clear: unsigned lower
+: LO ( -- n ) 0b0011 ; inline !
+: MI ( -- n ) 0b0100 ; inline ! N set: negative
+: PL ( -- n ) 0b0101 ; inline ! N clear: positive or zero
+: VS ( -- n ) 0b0110 ; inline ! V set: overflow
+: VC ( -- n ) 0b0111 ; inline ! V clear: no overflow
+: HI ( -- n ) 0b1000 ; inline ! C set and Z clear: unsigned higher
+: LS ( -- n ) 0b1001 ; inline ! C clear or Z set: unsigned lower or same
+: GE ( -- n ) 0b1010 ; inline ! N equals V: greater or equal
+: LT ( -- n ) 0b1011 ; inline ! N not equal to V: less than
+: GT ( -- n ) 0b1100 ; inline ! Z clear AND (N equals V): greater than
+: LE ( -- n ) 0b1101 ; inline ! Z set OR (N not equal to V): less than or equal
+: AL ( -- n ) 0b1110 ; inline ! always
+: NV ( -- n ) 0b1111 ; inline ! always
ERROR: no-field-word vocab name ;