]> gitweb.factorcode.org Git - factor.git/commitdiff
cpu.arm.assembler: Optimize shifting immediates, qualify immediates
authorGiftpflanze <gifti@tools.wmflabs.org>
Tue, 31 Jan 2023 17:16:09 +0000 (17:16 +0000)
committerGiftpflanze <gifti@tools.wmflabs.org>
Tue, 31 Jan 2023 17:21:16 +0000 (17:21 +0000)
basis/cpu/arm/assembler/32/32.factor
basis/cpu/arm/assembler/64/64.factor
basis/cpu/arm/assembler/assembler.factor
basis/cpu/arm/assembler/opcodes/opcodes.factor

index a81ebfa0867ab460d83c25683fcbdc821f001c3d..e9ac53579869b7bc44bb0bc3792cb4846bbf2a1d 100644 (file)
@@ -6,16 +6,15 @@ IN: cpu.arm.assembler.32
 : 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 ;
index 5e9611a1cd15574f4d61dcd3f7881c27c6a78f64..837c4a062b6289970a16b8902600e584f90fd064 100644 (file)
@@ -9,26 +9,26 @@ IN: cpu.arm.assembler.64
 : 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 ;
@@ -36,31 +36,31 @@ IN: cpu.arm.assembler.64
 : 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 ;
 
@@ -82,16 +82,16 @@ IN: cpu.arm.assembler.64
 
 : 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 ;
index 472ce127fc28bab65d013a9c5c0ae4df91a5767f..ff9a81a511803d8aa78fc9ebc8bf41a2009a22f9 100644 (file)
@@ -19,13 +19,17 @@ ERROR: arm64-encoding-imm original n-bits-requested truncated ;
     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? )
@@ -35,7 +39,7 @@ ERROR: imm-out-of-range imm n ;
         [ 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 )
@@ -68,20 +72,20 @@ ERROR: illegal-bitmask-element n ;
     [ ?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 ;
index 793925677871aaadaca2a7b397a4aaf308e4d9c7..461bb027e73851fa5237a2d9708fa59e9d546122 100644 (file)
@@ -241,25 +241,24 @@ SINGLETONS: SPSR_EL1 SPSR_EL2 SPSR_EL3 ;
 ! 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 ;