; Copyright 1996 Acorn Computers Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; SUBT Generic CPU Specific Definitions OldOpt SETA {OPT} OPT OptNoList+OptNoP1List [ :LNOT: :DEF: Included_Hdr_CPU_Generic26 GBLL Included_Hdr_CPU_Generic26 Included_Hdr_CPU_Generic26 SETL {TRUE} ; *********************************** ; *** C h a n g e L i s t *** ; *********************************** ; ; Date Name Description ; ---- ---- ----------- ; 13-Jul-93 JRoach Created ; 30-Jun-94 AMcC Restore OPT ; 05-Nov-99 KBracey Keep an eye on No26bitCode flag [ :LNOT: :DEF: Included_Hdr_Machine_Machine GET Hdr:Machine. ] ; Standard register names r0 RN 0 R0 RN r0 r1 RN 1 R1 RN r1 r2 RN 2 R2 RN r2 r3 RN 3 R3 RN r3 r4 RN 4 R4 RN r4 r5 RN 5 R5 RN r5 r6 RN 6 R6 RN r6 r7 RN 7 R7 RN r7 r8 RN 8 R8 RN r8 r9 RN 9 R9 RN r9 r10 RN 10 R10 RN r10 r11 RN 11 R11 RN r11 r12 RN 12 R12 RN r12 r13 RN 13 R13 RN r13 r14 RN 14 R14 RN r14 r15 RN 15 R15 RN r15 ; Special names for the banked registers r13_usr RN 13 r14_usr RN 14 r8_fiq RN 8 r9_fiq RN 9 r10_fiq RN 10 r11_fiq RN 11 r12_fiq RN 12 r13_fiq RN 13 r14_fiq RN 14 r13_irq RN 13 r14_irq RN 14 r13_svc RN 13 r14_svc RN 14 ; Standard register synonyms lr RN r14 ; Link Register LR RN r14 lr_usr RN r14_usr lr_fiq RN r14_fiq lr_irq RN r14_irq lr_svc RN r14_svc link RN r14 LINK RN r14 pc RN r15 ; Program Counter PC RN r15 [ :LNOT: No26bitCode psr RN r15 ; Processor Status Register PSR RN r15 ] ; Registers for the ARM Procedure Calling Standard sl RN 10 SL RN 10 fp RN 11 FP RN 11 IP RN 12 ip RN 12 ; Condition code symbols Cond_EQ * 0 :SHL: 28 Cond_NE * 1 :SHL: 28 Cond_CS * 2 :SHL: 28 Cond_HS * Cond_CS Cond_CC * 3 :SHL: 28 Cond_LO * Cond_CC Cond_MI * 4 :SHL: 28 Cond_PL * 5 :SHL: 28 Cond_VS * 6 :SHL: 28 Cond_VC * 7 :SHL: 28 Cond_HI * 8 :SHL: 28 Cond_LS * 9 :SHL: 28 Cond_GE * 10 :SHL: 28 Cond_LT * 11 :SHL: 28 Cond_GT * 12 :SHL: 28 Cond_LE * 13 :SHL: 28 Cond_AL * 14 :SHL: 28 Cond_ * Cond_AL Cond_NV * 15 :SHL: 28 ; Flag position specifiers for the PSR N_bit_number * 31 Z_bit_number * 30 C_bit_number * 29 V_bit_number * 28 I_bit_number * 27 F_bit_number * 26 ; Flag value specifiers for the PSR N_bit * 1 :SHL: N_bit_number Z_bit * 1 :SHL: Z_bit_number C_bit * 1 :SHL: C_bit_number V_bit * 1 :SHL: V_bit_number I_bit * 1 :SHL: I_bit_number F_bit * 1 :SHL: F_bit_number M_bits * 2_11 ; Processor mode values for the PSR USR_mode * 2_00 FIQ_mode * 2_01 IRQ_mode * 2_10 SVC_mode * 2_11 ARM_CC_Mask * &FC000003 ; Processor condition flags + mode bits ; Co_processor number allocations ^ 0 ARMCoProc_Reserved # 1 ; 0, Reserved by Acorn ARMCoProc_FPU # 1 ; 1, All floating point systems ARMCoProc_FPUextra # 1 ; 2, For extra FP instructions ARMCoProc_3 # 1 ; 3, ARMCoProc_4 # 1 ; 4, ARMCoProc_5 # 1 ; 5, ARMCoProc_6 # 1 ; 6, ARMCoProc_OMBRA # 1 ; 7, Olivetti/Acorn 80x86 ARMCoProc_TestHardware # 1 ; 8, Acorn ARMCoProc_9 # 1 ; 9, ARMCoProc_10 # 1 ; 10, ARMCoProc_11 # 1 ; 11, ARMCoProc_12 # 1 ; 12, ARMCoProc_13 # 1 ; 13, ARMCoProc_14 # 1 ; 14, ARMCoProc_CacheControl # 1 ; 15, Part of the ARM3 CPU ; 26 bit processor specific macro definitions ; ************************************************************ ; *** BSR - Branch to subroutine saving R14 on the stack *** ; ************************************************************ MACRO $label BSR $dest $label Push R14 BL $dest Pull R14 MEND [ No32bitCode ; ************************************************ ; *** CLC - Clear carry flag - will set nzcv *** ; ************************************************ MACRO $label CLC $cond $label CMN$cond pc, #0 MEND ; *********************************************** ; *** CLRPSR - Clear bits in PSR from the *** ; *** mask in $bits, using register $regtmp *** ; *********************************************** MACRO $label CLRPSR $bits, $regtmp, $cond, $oldpsr $label [ "$oldpsr" <> "" MOV$cond $oldpsr, pc ] MVN$cond $regtmp, #$bits TST$cond.P $regtmp, pc MEND ; ************************************************** ; *** CLRV - Clear overflow flag - will set nzCv *** ; ************************************************** MACRO $label CLRV $cond $label CMP$cond pc, #0 MEND ; ********************************************************************************** ; *** PHPSEI - Disable IRQs, saving an old interrupt state indicator in a *** ; *** register, default R14. Note that this code preserves the C and V flags. *** ; ********************************************************************************** MACRO $label PHPSEI $register=R14, $regtmp ; (we don't use regtmp, 32-bit one does) LCLS usereg [ "$register" = "" usereg SETS "R14" | usereg SETS "$register" ] $label MOV $usereg, #I_bit TST $usereg, PC ; is I_bit set ? TEQEQP $usereg, PC ; no, then set it (and $register = I_bit) MOVNE $usereg, #0 ; yes, then leave alone (and $register = 0) MEND ; ************************************************************************** ; *** PLP - Restore IRQ state from the indicator in a register (set up *** ; *** by PHPSEI). Note that this code preserves the C and V flags. *** ; ************************************************************************** MACRO $label PLP $register=R14 LCLS usereg [ "$register" = "" usereg SETS "R14" | usereg SETS "$register" ] $label TEQP $usereg, PC MEND ] ; **************** ; *** RETURN *** ; **************** MACRO $label RETURN $cond $label MOV$cond pc, lr MEND ; ***************** ; *** RETURNS *** ; ***************** MACRO $label RETURNS $cond, $nowarn [ "$nowarn"="" ! 0, "RETURNS macro indicates possible 32-bit incompatibility", 1 ] $label MOV$cond.S pc, lr MEND [ No32bitCode ; ****************** ; *** RETURNVC *** ; ****************** MACRO $label RETURNVC $cond $label BIC$cond.S pc, lr, #V_bit MEND ; ****************** ; *** RETURNVS *** ; ****************** MACRO $label RETURNVS $cond $label ORR$cond.S pc, lr, #V_bit MEND ; **************************************************** ; *** SavePSR - Save the PSR in a register, to be *** ; *** restored later using RestorePSR *** ; **************************************************** MACRO $label SavePSR $reg, $cond $label MOV$cond $reg, pc MEND ; **************************************************** ; *** RestPSR - Restore the PSR from a register *** ; *** set up by SavePSR *** ; *** $fields may be set to "f" if the PSR fields *** ; *** c,x,s do not need restoring, which will *** ; *** save a few cycles on newer ARMs (but the *** ; *** No32bitCode version of the macro will set *** ; *** the c field anyway). Values other than "f", *** ; *** "cf", "fc" and unset are deprecated for *** ; *** compatibility with No32bitCode. *** ; **************************************************** MACRO $label RestPSR $reg, $cond, $fields [ "$fields"<>"" :LAND: "$fields"<>"cf" :LAND: "$fields"<>"fc" :LAND: "$fields"<>"f" ! 0, "Unpredictable behaviour due to deprecated RestPSR fields parameter" ] $label TEQ$cond.P pc, $reg MEND ; **************************************************** ; *** SCPSR - Set and clear bits in PSR from the *** ; *** masks $set, $clr, using register $regtmp *** ; **************************************************** MACRO $label SCPSR $set, $clr, $regtmp, $cond, $oldpsr LCLS srcreg [ "$oldpsr"="" srcreg SETS "$regtmp" | srcreg SETS "$oldpsr" ] [ (($set) :AND: ($clr)) <> 0 ! 1, "Attempt to simultaneously set and clear a bit in SCPSR" ] $label MOV$cond $srcreg, pc ORR$cond $regtmp, $srcreg, #($set) :OR: ($clr) TEQ$cond.P $regtmp, #$clr MEND ; ********************************************** ; *** SEC - Set carry flag - will set nzCv *** ; ********************************************** MACRO $label SEC $cond $label CMP$cond pc, #0 MEND ; ************************************************ ; *** SETPSR - Set bits in PSR from the mask *** ; *** in $bits, using register $regtmp *** ; ************************************************ MACRO $label SETPSR $bits, $regtmp, $cond, $oldpsr LCLS srcreg [ "$oldpsr"="" srcreg SETS "$regtmp" | srcreg SETS "$oldpsr" ] $label MOV$cond $srcreg, pc ORR$cond $regtmp, $srcreg, #$bits TEQ$cond.P $regtmp, #0 MEND ; ************************************************** ; *** SETV - Set overflow flag - will set NzcV *** ; ************************************************** MACRO $label SETV $cond $label CMP$cond pc, #&80000000 MEND ; *********************************************** ; *** TOGPSR - Toggle bits in PSR from the *** ; *** mask in $bits, using register $regtmp *** ; *********************************************** MACRO $label TOGPSR $bits, $regtmp, $cond, $oldpsr LCLS srcreg [ "$oldpsr"="" srcreg SETS "$regtmp" | srcreg SETS "$oldpsr" ] $label MOV$cond $srcreg, pc TEQ$cond.P $srcreg, #$bits MEND ; *********************************************** ; *** TOGPSRR - Toggle bits in PSR from the *** ; *** mask in $regtog, using reg $regtmp *** ; *********************************************** MACRO $label TOGPSRR $regtog, $regtmp, $cond, $oldpsr, $fields [ "$oldpsr"<>"" $label MOV$cond $oldpsr, pc TEQ$cond.P $regtog, pc | $label TEQ$cond.P $regtog, pc ] MEND ; ************************************************* ; *** WritePSRc - Set the PSR control bits to *** ; *** an absolute value. *** ; *** Sets I,F,M[0:1], corrupts NZVC. *** ; *** Preserves 32-bitness. *** ; *** Only use in IRQ26/32,FIQ26/32,SVC26/32 *** ; *** Ignored in USR modes, illegal in others *** ; *** Use instead of TEQP PC,#$value *** ; ************************************************* MACRO $label WritePSRc $value, $regtmp, $cond, $oldpsr [ ($value :AND::NOT: (I_bit+F_bit+SVC_mode)) <> 0 ! 1, "Illegal flags for WritePSRc" ] [ "$oldpsr" <> "" SavePSR $oldpsr, $cond ] $label TEQ$cond.P PC, #$value MEND ] ; No32bitCode ; ************************************************* ; *** RemovePSRFromReg - remove PSR bits from *** ; *** a PC (or register holding a PC, eg. lr) *** ; *** Preserves all PSR bits *** ; ************************************************* MACRO $label RemovePSRFromReg $pcr, $tmp, $dest ; If $dest is supplied, it denotes an alternative target ; register from $pcr. $dest and $tmp may be the same register. ; ; MRS is safe as it is a NOP if the processor doesn't understand it. The code ; takes bit 4 of the CPSR (always set in 32-bit modes, always clear in 26-bit ; modes), shifts it to the bottom bit and inverts it, then shifts it to the ; top bit so it can use ASR to duplicate it into 8 bits, and then ROR#30 to ; turn it into &FC000003 if you are in a 26-bit bit, 0 if you are in 32-bit ; mode. This value can be BIC'ed with lr to strip the PSR bits if they are ; there, or be a NOP if they are not. ; ; Must be in a known mode (currently USR26,USR32,IRQ26,IRQ32,FIQ26,FIQ32, ; SVC26,SVC32,ABT32,UND32,SYS32) - future modes may have bit 4 clear, yet ; they won't be 26-bit. ASSERT (1 :SHL: 4) = (USR32_mode - USR26_mode) $label LCLS dst [ "$dest" <> "" dst SETS "$dest" | dst SETS "$pcr" ] [ No32bitCode BIC $dst, $pcr, #ARM_CC_Mask ; 32-bit OK: inside No32bitCode macro | MRS $tmp, CPSR MVN $tmp, $tmp, LSR #4 ; bit 0 set in *26, clear in *32 MOV $tmp, $tmp, LSL #31 ; shift to top bit MOV $tmp, $tmp, ASR #7 ; duplicate to top 8 bits BIC $dst, $pcr, $tmp, ROR #30 ; remove PSR bits if in 26-bit mode ] MEND ] ; :LNOT: :DEF: Included_Hdr_CPU_Generic26 OPT OldOpt END