GitLab has been upgraded to 13.7.4 If you encounter any issues mail code@riscosopen.org

Proc 14.4 KB
Newer Older
Neil Turton's avatar
Neil Turton committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
; 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.
;
15

Neil Turton's avatar
Neil Turton committed
16 17 18 19 20 21 22
       SUBT     Useful procedure entry/exit macros => &.Hdr.Proc

OldOpt SETA     {OPT}
       OPT      OptNoList+OptNoP1List

       GBLS     Proc_RegList    ; Which registers to preserve
       GBLA     Proc_LocalStack ; And any ADJSP on entry/exit for local vars
23 24
       GBLL     Proc_SavedCPSR  ; CPSR was preserved
       GBLA     Proc_RegOffset  ; Offset of first register on stack
Neil Turton's avatar
Neil Turton committed
25 26

       GBLL     Proc_Debug      ; Whether to dump procedure name in image
27
Proc_Debug SETL {FALSE}
Neil Turton's avatar
Neil Turton committed
28

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
       GBLS     Proc_GetMachine
 [ :LNOT: :DEF: Included_Hdr_Machine_Machine
Proc_GetMachine SETS "GET Hdr:Machine.<Machine>"
 |
Proc_GetMachine SETS ""
 ]
       $Proc_GetMachine

       GBLS     Proc_GetCPU26
 [ :LNOT: :DEF: Included_Hdr_CPU_Generic26
Proc_GetCPU26 SETS "GET Hdr:CPU.Generic26"
 |
Proc_GetCPU26 SETS ""
 ]
        $Proc_GetCPU26

       GBLS     Proc_GetCPU32
 [ :LNOT: :DEF: Included_Hdr_CPU_Generic32
Proc_GetCPU32 SETS "GET Hdr:CPU.Generic32"
 |
Proc_GetCPU32 SETS ""
 ]
        $Proc_GetCPU32



Neil Turton's avatar
Neil Turton committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
; *****************************************************************************
; *** Keep a note of local stack and register use at the routine entry      ***
; *** point so that an exit may be effected anywhere in the body without    ***
; *** remembering how many (and which) registers to destack and ADJSP.      ***
; *** Also ensures that the code entry label is word-aligned.               ***
; *****************************************************************************
        MACRO
$label  Entry   $reglist,$framesize
        ALIGN
Proc_RegList SETS "$reglist"
 [ "$framesize" = ""
Proc_LocalStack SETA 0
 |
Proc_LocalStack SETA $framesize
 ]
70
Proc_SavedCPSR SETL {FALSE}
71
Proc_RegOffset SETA Proc_LocalStack
Neil Turton's avatar
Neil Turton committed
72 73 74 75 76 77 78 79 80
 [ "$label" <> ""
  [ Proc_Debug
        B       $label
        DCB     "$label", 0
        ALIGN
  ]
$label  ROUT
 ]
 [ "$Proc_RegList" = ""
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
        STR     lr, [sp, #-4]!
 |
        Push    "$Proc_RegList, lr"
 ]
 [ Proc_LocalStack <> 0
        SUB     sp, sp, #Proc_LocalStack
 ]
        MEND

; *****************************************************************************
; *** Keep a note of local stack and register use at the routine entry      ***
; *** point so that an exit may be effected anywhere in the body without    ***
; *** remembering how many (and which) registers to destack and ADJSP.      ***
; *** Also ensures that the code entry label is word-aligned.               ***
; *** You must use this macro if you want to use EXITS in 32-bit mode.      ***
; *****************************************************************************
        MACRO
$label  EntryS  $reglist,$framesize
        ALIGN
 [ No32bitCode
101
$label  Entry   "$reglist",$framesize
102 103 104 105 106 107 108
 |
Proc_RegList SETS "$reglist"
 [ "$framesize" = ""
Proc_LocalStack SETA 0
 |
Proc_LocalStack SETA $framesize
 ]
109
Proc_SavedCPSR SETL {TRUE}
110 111 112 113 114 115 116 117 118 119 120
Proc_RegOffset SETA Proc_LocalStack + 4
 [ "$label" <> ""
  [ Proc_Debug
        B       $label
        DCB     "$label", 0
        ALIGN
  ]
$label  ROUT
 ]
 [ "$Proc_RegList" = ""
        STR     lr, [sp, #-4]!
Neil Turton's avatar
Neil Turton committed
121 122 123
 |
        Push    "$Proc_RegList, lr"
 ]
124 125
        mymrs   AL, lr, CPSR
        STR     lr, [sp, #-4]!
Neil Turton's avatar
Neil Turton committed
126 127
 [ Proc_LocalStack <> 0
        SUB     sp, sp, #Proc_LocalStack
128
 ]
Neil Turton's avatar
Neil Turton committed
129 130 131
 ]
        MEND

132

Neil Turton's avatar
Neil Turton committed
133 134 135 136 137
; *****************************************************************************
; *** Another entry point so we can use the same routine body. NOROUT also  ***
; *** Stacks the same registers as does the corresponding ENTRY macro       ***
; *****************************************************************************
        MACRO
138
$label  AltEntry
Neil Turton's avatar
Neil Turton committed
139 140 141 142 143 144 145 146 147 148
        ALIGN
 [ "$label" <> ""
  [ Proc_Debug
        B       $label
        DCB     "$label", 0
        ALIGN
  ]
$label ; NOROUT
 ]
 [ "$Proc_RegList" = ""
149
        STR     lr, [sp, #-4]!
Neil Turton's avatar
Neil Turton committed
150 151 152
 |
        Push    "$Proc_RegList, lr"
 ]
153 154 155 156
 [ Proc_SavedCPSR
        mymrs   AL, lr, CPSR
        STR     lr, [sp, #-4]!
 ]
Neil Turton's avatar
Neil Turton committed
157 158 159 160 161
 [ Proc_LocalStack <> 0
        SUB     sp, sp, #Proc_LocalStack
 ]
        MEND

162 163 164 165 166
        MACRO
$label  ALTENTRY
$label  AltEntry
        MEND

Neil Turton's avatar
Neil Turton committed
167 168 169 170
; *****************************************************************************
; *** Exit procedure, restore stack and saved registers to values on entry  ***
; *****************************************************************************
        MACRO
171
$label  Exit    $cond
Neil Turton's avatar
Neil Turton committed
172
$label
173 174 175
 [ Proc_SavedCPSR
        ADD$cond sp, sp, #Proc_LocalStack + 4
 |
Neil Turton's avatar
Neil Turton committed
176 177 178
 [ Proc_LocalStack <> 0
        ADD$cond sp, sp, #Proc_LocalStack
 ]
179
 ]
Neil Turton's avatar
Neil Turton committed
180
 [ "$Proc_RegList" = ""
181
        LDR$cond pc, [sp], #4
Neil Turton's avatar
Neil Turton committed
182 183 184 185 186
 |
        Pull    "$Proc_RegList, pc",$cond
 ]
        MEND

187 188 189 190 191
        MACRO
$label  EXIT    $cond
$label  Exit    $cond
        MEND

Neil Turton's avatar
Neil Turton committed
192 193 194 195 196
; *****************************************************************************
; *** Exit procedure : restore stack and saved registers + psr to values on ***
; *** entry. No longer copes with 3um ARM bug fix (world is 2um'ised)       ***
; *****************************************************************************
        MACRO
197
$label  ExitS   $cond,$fields
Neil Turton's avatar
Neil Turton committed
198
$label
199 200 201 202 203 204 205 206 207
 [ Proc_SavedCPSR
  [ "$cond" <> "AL" :LAND: "$cond" <> ""
        ; branch over on opposite condition
        DCD     &1A000000 :EOR: Cond_$cond + ((%FT01 - (. + 8))/4)
  ]
 [ Proc_LocalStack <> 0
        ADD     sp, sp, #Proc_LocalStack
 ]
        LDR     lr, [sp], #4
208 209 210 211 212
 [ "$fields"=""
        mymsr  ,CPSR_f, lr
 |
        mymsr  ,CPSR_$fields, lr
 ]
213 214 215 216 217 218 219 220 221
 [ "$Proc_RegList" = ""
        LDR     pc, [sp], #4
 |
        Pull    "$Proc_RegList, pc"
 ]
01
 |
 ; 26-bit version
 [ No26bitCode
222
        ! 1, "ExitS without EntryS"
223
 ]
Neil Turton's avatar
Neil Turton committed
224 225 226 227 228 229 230
 [ Proc_LocalStack <> 0
        ADD$cond sp, sp, #Proc_LocalStack
 ]
 [ "$Proc_RegList" = ""
        Pull    pc,$cond,^
 |
        Pull    "$Proc_RegList, pc",$cond,^
231 232 233 234
 ]
 ]
        MEND

235 236 237 238 239
        MACRO
$label  EXITS   $cond,$fields
$label  ExitS   $cond,$fields
        MEND

240 241 242 243 244
; *****************************************************************************
; *** Exit procedure : restore stack and saved registers + psr (except V)   ***
; *** to values on entry. Return with V unaltered from current state.       ***
; *****************************************************************************
        MACRO
245
$label  ExitV   $fields
246 247 248 249 250 251 252 253
$label
 [ Proc_LocalStack <> 0
        ADD     sp, sp, #Proc_LocalStack
 ]
 [ Proc_SavedCPSR
        LDR     lr, [sp], #4
        BICVC   lr, lr, #V_bit
        ORRVS   lr, lr, #V_bit
254 255 256 257 258
 [ "$fields"=""
        mymsr  ,CPSR_f, lr
 |
        mymsr  ,CPSR_$fields, lr
 ]
259 260 261 262 263 264 265
 [ "$Proc_RegList" = ""
        LDR     pc, [sp], #4
 |
        Pull    "$Proc_RegList, pc"
 ]
 |
 [ No26bitCode
266
        ! 1, "ExitV without EntryS"
267 268 269 270 271 272 273 274 275 276 277
 ]
 [ "$Proc_RegList" = ""
        LDR     lr, [sp], #4
 |
        Pull    "$Proc_RegList, lr"
 ]
        BICVCS  pc, lr, #V_bit
        ORRVSS  pc, lr, #V_bit
 ]
        MEND

278 279 280 281 282
        MACRO
$label  EXITV   $fields
$label  ExitV   $fields
        MEND

283 284 285 286 287
; *****************************************************************************
; *** Exit procedure : restore stack and saved registers + psr (except V)   ***
; *** to values on entry. Return with V clear.                              ***
; *****************************************************************************
        MACRO
288
$label  ExitVC  $fields
289 290 291 292 293 294 295
$label
 [ Proc_LocalStack <> 0
        ADD     sp, sp, #Proc_LocalStack
 ]
 [ Proc_SavedCPSR
        LDR     lr, [sp], #4
        BIC     lr, lr, #V_bit
296 297 298 299 300
 [ "$fields"=""
        mymsr  ,CPSR_f, lr
 |
        mymsr  ,CPSR_$fields, lr
 ]
301 302 303 304 305 306 307
 [ "$Proc_RegList" = ""
        LDR     pc, [sp], #4
 |
        Pull    "$Proc_RegList, pc"
 ]
 |
 [ No26bitCode
308
        ! 1, "ExitVC without EntryS"
309 310 311 312 313 314 315 316 317 318
 ]
 [ "$Proc_RegList" = ""
        LDR     lr, [sp], #4
 |
        Pull    "$Proc_RegList, lr"
 ]
        BICS    pc, lr, #V_bit
 ]
        MEND

319 320 321 322 323
        MACRO
$label  EXITVC  $fields
$label  ExitVC  $fields
        MEND

324 325 326 327 328
; *****************************************************************************
; *** Exit procedure : restore stack and saved registers + psr (except V)   ***
; *** to values on entry. Return with V set.                                ***
; *****************************************************************************
        MACRO
329
$label  ExitVS  $fields
330 331 332 333 334 335 336
$label
 [ Proc_LocalStack <> 0
        ADD     sp, sp, #Proc_LocalStack
 ]
 [ Proc_SavedCPSR
        LDR     lr, [sp], #4
        ORR     lr, lr, #V_bit
337 338 339 340 341
 [ "$fields"=""
        mymsr  ,CPSR_f, lr
 |
        mymsr  ,CPSR_$fields, lr
 ]
342 343 344 345 346 347 348
 [ "$Proc_RegList" = ""
        LDR     pc, [sp], #4
 |
        Pull    "$Proc_RegList, pc"
 ]
 |
 [ No26bitCode
349
        ! 1, "ExitVS without EntryS"
350 351 352 353 354 355 356
 ]
 [ "$Proc_RegList" = ""
        LDR     lr, [sp], #4
 |
        Pull    "$Proc_RegList, lr"
 ]
        ORRS    pc, lr, #V_bit
Neil Turton's avatar
Neil Turton committed
357 358 359
 ]
        MEND

360 361 362 363 364
        MACRO
$label  EXITVS  $fields
$label  ExitVS  $fields
        MEND

Neil Turton's avatar
Neil Turton committed
365 366 367 368 369 370
; *****************************************************************************
; *** Restore stack and saved registers, lr to values on entry to procedure ***
; *****************************************************************************
        MACRO
$label  PullEnv $cond
$label
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
 [ Proc_RegOffset <> 0
        ADD$cond sp, sp, #Proc_RegOffset
 ]
 [ "$Proc_RegList" = ""
        LDR$cond lr, [sp], #4
 |
        Pull    "$Proc_RegList, lr", $cond
 ]
        MEND

; *****************************************************************************
; *** Restore stack and saved registers, lr and CPSR to values on entry to  ***
; *** procedure                                                             ***
; *****************************************************************************
        MACRO
386
$label  PullEnvS $cond,$fields
387 388 389 390 391 392 393 394 395 396
$label
 [ Proc_SavedCPSR
  [ "$cond" <> "AL" :LAND: "$cond" <> ""
        ; branch over on opposite condition
        DCD     &1A000000 :EOR: Cond_$cond + ((%FT01 - (. + 8))/4)
  ]
 [ Proc_LocalStack <> 0
        ADD     sp, sp, #Proc_LocalStack
 ]
        LDR     lr, [sp], #4
397 398 399 400 401
 [ "$fields"=""
        mymsr  ,CPSR_f, lr
 |
        mymsr  ,CPSR_$fields, lr
 ]
402 403 404 405 406 407 408 409
 [ "$Proc_RegList" = ""
        LDR     lr, [sp], #4
 |
        Pull    "$Proc_RegList, lr"
 ]
01
 |
; 26-bit form
Neil Turton's avatar
Neil Turton committed
410 411 412 413
 [ Proc_LocalStack <> 0
        ADD$cond sp, sp, #Proc_LocalStack
 ]
 [ "$Proc_RegList" = ""
414
        LDR$cond lr, [sp], #4
Neil Turton's avatar
Neil Turton committed
415 416
 |
        Pull    "$Proc_RegList, lr", $cond
417
 ]
Neil Turton's avatar
Neil Turton committed
418 419 420 421 422
 ]
        MEND

; *****************************************************************************

Steve Revill's avatar
Steve Revill committed
423 424

; *****************************************************************************
425
; *** FramLDR/FramSTR macros                                                ***
Steve Revill's avatar
Steve Revill committed
426 427 428 429 430 431
; *** That let you access the register values stacked on Entry              ***
; *** to replace LDR     r1, [sp, #Proc_LocalStack + 1*4]                   ***
; ***                                                                       ***
; *** The new macros allow non-continuous regs to be used, and will generate***
; *** an error if you try to access a register not stored on the stack      ***
; ***                                                                       ***
432 433 434 435
; *** FramLDR r0         load r0 stored on stack frame by Entry macro       ***
; *** FramLDR r5,CS      load r5 from stack frame if CS                     ***
; *** FramLDR r0,,r8     load r8 on stack frame into r0                     ***
; *** FramLDR r0,HI,r10  load r10 on stack frame into r0 if HI              ***
Steve Revill's avatar
Steve Revill committed
436 437
; ***                                                                       ***
; *** A particularly useful way of using this macro is:                     ***
438
; *** FramSTR r8,,r0     change r0 value that will be restored on Exit      ***
Steve Revill's avatar
Steve Revill committed
439
; *** ...more code                                                          ***
440
; *** Exit                                                                  ***
Steve Revill's avatar
Steve Revill committed
441 442 443 444 445 446 447 448
; *****************************************************************************

        GBLA Fram_SpecRegOffset  ;offset to load/store particular reg
        GBLS Fram_RegStr
        GBLS Fram_CopyRegs
        GBLS Fram_LowRegStr

        MACRO
449
        FramSPL $origvar,$newvar,$sep
Steve Revill's avatar
Steve Revill committed
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466

$newvar SETS ""
        WHILE (($origvar):CC:" ":LEFT:1 <> "$sep"):LAND:($origvar >"")
$newvar SETS $newvar:CC:($origvar:LEFT:1)
 [ ($origvar >"")
$origvar SETS $origvar:RIGHT:(:LEN:$origvar-1)
 ]

        WEND
        ;skip remaining seperator
 [ ($origvar >"")
$origvar SETS $origvar:RIGHT:(:LEN:$origvar-1)
 ]

        MEND

        MACRO
467
        FramCOM $dstreg,$framereg
Steve Revill's avatar
Steve Revill committed
468 469 470 471 472 473 474 475 476 477 478 479
        LCLA actframe
        LCLA counter

actframe SETA $dstreg
 [ "$framereg" <>""
actframe SETA $framereg
 ]

        LCLA regmask
Fram_CopyRegs SETS Proc_RegList
        WHILE Fram_CopyRegs > ""

480
        FramSPL "Fram_CopyRegs","Fram_RegStr",","
Steve Revill's avatar
Steve Revill committed
481 482 483 484 485

        ;regno =r0-r8 or a single reg r5
        LCLA lowreg
        LCLA highreg

486
        FramSPL "Fram_RegStr","Fram_LowRegStr","-"
Steve Revill's avatar
Steve Revill committed
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
lowreg  SETA $Fram_LowRegStr
 [ Fram_RegStr =""
highreg SETA lowreg
 |
highreg SETA $Fram_RegStr
 ]

        ;set bits between lowreg and highreg in our mask
        WHILE lowreg <=highreg
regmask SETA regmask:OR:(1:SHL:lowreg)
lowreg  SETA lowreg +1
        WEND

        WEND

        ;calculate Fram_SpecRegOffset using regmask
Fram_SpecRegOffset SETA 0
        LCLA counter

        WHILE counter <actframe
 [ (regmask:AND:(1:SHL:counter)) >0
Fram_SpecRegOffset SETA Fram_SpecRegOffset+4
 ]
counter SETA counter +1
        WEND

 [ (regmask:AND:(1:SHL:counter)) =0
        LCLS tempstr
  [ actframe >9
actframe SETA actframe -10
tempstr SETS "1"
  ]
        !       1,"r$tempstr":CC:("$actframe":RIGHT:1):CC:" not in frame!"
 ]

        MEND

        MACRO
525 526
$label  FramLDR $dstreg,$cond,$framereg
$label  FramCOM $dstreg,$framereg
Steve Revill's avatar
Steve Revill committed
527 528 529 530
        LDR$cond $dstreg,[sp ,#Proc_RegOffset +Fram_SpecRegOffset]
        MEND

        MACRO
531 532 533 534 535 536 537
$label  FRAMLDR $dstreg,$cond,$framereg
$label  FramLDR $dstreg,$cond,$framereg
        MEND

        MACRO
$label  FramSTR $dstreg,$cond,$framereg
$label  FramCOM $dstreg,$framereg
Steve Revill's avatar
Steve Revill committed
538 539
        STR$cond $dstreg,[sp ,#Proc_RegOffset +Fram_SpecRegOffset]
        MEND
540 541 542 543 544

        MACRO
$label  FRAMSTR $dstreg,$cond,$framereg
$label  FramSTR $dstreg,$cond,$framereg
        MEND
Steve Revill's avatar
Steve Revill committed
545 546
; *****************************************************************************

Neil Turton's avatar
Neil Turton committed
547 548
        OPT     OldOpt
        END