; 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. ; ; Copyright (C) Acorn Computers Ltd., 1988 GBLS VBar GBLS XXModuleName GBLL CV_Entries GBLA CV_Entry ; :OR: this with the library segment tag to bind with ROM applications only library_segment_is_ROM_only * &80000000 ; To make ROM version ; library_segment_is_ROM_only * 0 ; To make RAM version CV_Entries SETL {FALSE} CV_Entry SETA 3 ; see CV_Code below VBar SETS "|" MACRO Module $name XXModuleName SETS "_":CC:"$name":CC:"_" MEND MACRO LoadStaticAddress $Addr, $Reg, $Reg2 LCLS reg2 [ "$Reg2"="" reg2 SETS "ip" | reg2 SETS "$Reg2" ] LDR $Reg, =$Addr LDR $reg2, [sl, #SL_Lib_Offset] ADD $Reg, $Reg, $reg2 MEND MACRO LoadStaticBase $Reg, $Reg2 LoadStaticAddress StaticData, $Reg, $Reg2 MEND MACRO $Label Variable $Size LCLS Temps LCLA Tempa [ "$Size"="" Tempa SETA 1 | Tempa SETA $Size ] Temps SETS VBar:CC:XXModuleName:CC:"$Label":CC:VBar KEEP $Temps ALIGN O_$Label * .-StaticData $Temps % &$Tempa*4 MEND MACRO $Label ExportedVariable $Size LCLS Temps LCLA Tempa [ "$Size"="" Tempa SETA 1 | Tempa SETA $Size ] Temps SETS VBar:CC:"$Label":CC:VBar EXPORT $Temps ALIGN O_$Label * .-StaticData $Temps % &$Tempa*4 MEND MACRO $Label ExportedWord $Value LCLS Temps Temps SETS VBar:CC:"$Label":CC:VBar EXPORT $Temps ALIGN O_$Label * .-StaticData $Temps & $Value MEND MACRO $Label VariableByte $Size LCLS Temps LCLA Tempa [ "$Size"="" Tempa SETA 1 | Tempa SETA $Size ] Temps SETS VBar:CC:XXModuleName:CC:"$Label":CC:VBar KEEP $Temps O_$Label * .-StaticData $Temps % &$Tempa MEND MACRO $Label InitByte $Value $Label = $Value MEND MACRO $Label InitWord $Value $Label & $Value MEND MACRO $Label Keep $Arg LCLS Temps $Label $Arg Temps SETS VBar:CC:XXModuleName:CC:"$Label":CC:VBar KEEP $Temps $Temps MEND ; Macro for generating the library end of entrypoint tables ; import non-null if the entry isn't defined in the assembler part ; of the library (conventionally has the value 'import') ; sym2 non-null if the stub is to be patched to branch to a symbol ; other than the entry name ; direct null APCS_A compatibility veneer to be used ; 'direct' APCS_A compatibility entry may branch directly to ; the entry (which does not use sp, fp, ip) ; other APCS_A compatibility entry branches directly to ; this symbol. ; 'unveneered' no compatibility veneer entry (subsequent ; addition). ; args argument count or 'varargs'. Selects which compatability ; veneer should be used (if direct is null). ; directlocal if direct is , and this is null, then ; is a local symbol, otherwise the value should be either ; "EXPORT" or "IMPORT" MACRO Entry $sym, $import, $sym2, $direct, $args, $directlocal LCLS Temps [ Calling_Standard = "APCS_U" :LAND: CV_Entries [ "$direct" <> "unveneered" [ "$direct" = "direct" [ "$sym2" <> "" Temps SETS "$sym2" | Temps SETS "$sym" ] Temps SETS "$VBar":CC:Temps:CC:"$VBar" B $Temps & 0 | [ "$direct" <> "" Temps SETS "$VBar":CC:"$direct":CC:"$VBar" [ "$directlocal" <> "" $directlocal $Temps ] B $Temps & 0 | MOV r11, #&$CV_Entry [ "$args" = "varargs" B Compatibility_VeneerV | [ $args > 4 B Compatibility_VeneerV | B Compatibility_Veneer ] ] ] ] CV_Entry SETA CV_Entry + 1 ] | [ "$sym2" <> "" Temps SETS "$sym2" | Temps SETS "$sym" ] Temps SETS "$VBar":CC:Temps:CC:"$VBar" [ "$import"<>"" IMPORT $Temps ] B $Temps ] MEND MACRO Entry2 $sym, $import, $sym2, $direct, $args, $directlocal, $ignore LCLS Temps [ Calling_Standard = "APCS_U" :LAND: CV_Entries [ "$direct" <> "unveneered" [ "$direct" = "direct" [ "$sym2" <> "" Temps SETS "$sym2" | Temps SETS "$sym" ] Temps SETS "$VBar":CC:Temps:CC:"$VBar" B $Temps & 0 | [ "$direct" <> "" Temps SETS "$VBar":CC:"$direct":CC:"$VBar" [ "$directlocal" <> "" $directlocal $Temps ] B $Temps & 0 | MOV r11, #&$CV_Entry [ "$args" = "varargs" B Compatibility_VeneerV | [ $args > 4 B Compatibility_VeneerV | B Compatibility_Veneer ] ] ] ] CV_Entry SETA CV_Entry + 1 ] | [ "$sym2" <> "" Temps SETS "$sym2" | Temps SETS "$sym" ] Temps SETS "$VBar":CC:Temps:CC:"$VBar" [ "$import"<>"" IMPORT $Temps ] B $Temps ] MEND MACRO CV_Code $VarargEntries [ "$VarargEntries" <> "" Compatibility_VeneerV STMFD r12!, {r11, lr} ; entry number and link (pro tem) ORR r11, r10, #APCSChange ; fp MOV r10, r13 ; sl MOV r13, r12 ; sp LDMFD r13!, {ip, lr} ; recover entry and link STR r14, [sl, #SC_veneerStaticLink-SC_SLOffset] ADD ip, ip, #(CV_L-CV_LV) / 4 MOV lr, pc ADD pc, pc, ip, ASL #2 CV_LV MOV r12, r13 ; sp MOV r13, r10 ; sl BIC r10, r11, #APCSChange ; fp LDR r14, [r13, #SC_veneerStaticLink-SC_SLOffset] MOVS pc, r14 ] Compatibility_Veneer STMFD r12!, {lr} MOV r14, r11 ORR r11, r10, #APCSChange ; fp MOV r10, r13 ; sl MOV r13, r12 ; sp MOV r12, lr MOV lr, pc ADD pc, pc, ip, ASL #2 CV_L MOV r12, r13 ; sp MOV r13, r10 ; sl BIC r10, r11, #APCSChange ; fp LDMFD r12!, {pc}^ MEND END