Generic32 19.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
; Copyright 1999 Pace Micro Technology plc
;
; 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 32-bit CPU Specific Definitions

OldOpt  SETA    {OPT}
        OPT     OptNoList+OptNoP1List

 [ :LNOT: :DEF: Included_Hdr_CPU_Generic32
        GBLL    Included_Hdr_CPU_Generic32
Included_Hdr_CPU_Generic32 SETL {TRUE}

; ***********************************
; ***    C h a n g e   L i s t    ***
; ***********************************
;
; Date       Name          Description
; ----       ----          -----------
; 05-Nov-99  KBracey       Moved from ARM600.
;                          32-bit versions of Generic26 macros created.

33 34 35 36
 [ :LNOT: :DEF: Included_Hdr_Machine_Machine
        GET     Hdr:Machine.<Machine>
 ]

37 38 39 40
; 32-bit PSR transfer macros

; New positions of bits in 32-bit PSR

41
Q32_bit *       1 :SHL: 27
Ben Avison's avatar
Ben Avison committed
42 43 44 45 46 47 48 49 50
IT32_bits *     &0600FC00
J32_bit *       1 :SHL: 24
GE3_bit *       1 :SHL: 19
GE2_bit *       1 :SHL: 18
GE1_bit *       1 :SHL: 17
GE0_bit *       1 :SHL: 16
GE32_bits *     2_1111 :SHL: 16
E32_bit *       1 :SHL: 9
A32_bit *       1 :SHL: 8
51 52 53
I32_bit *       1 :SHL: 7
F32_bit *       1 :SHL: 6
T32_bit *       1 :SHL: 5
54
M32_bits *      2_11111
55 56 57 58 59 60 61 62 63 64 65 66 67

IF32_26Shift *  26-6

; Processor mode numbers

USR26_mode      *       2_00000
FIQ26_mode      *       2_00001
IRQ26_mode      *       2_00010
SVC26_mode      *       2_00011
USR32_mode      *       2_10000
FIQ32_mode      *       2_10001
IRQ32_mode      *       2_10010
SVC32_mode      *       2_10011
Ben Avison's avatar
Ben Avison committed
68
MON32_mode      *       2_10110
69 70 71 72 73 74
ABT32_mode      *       2_10111
UND32_mode      *       2_11011
SYS32_mode      *       2_11111

; New register names

Ben Avison's avatar
Ben Avison committed
75 76 77 78
r13_mon         RN      13
r14_mon         RN      14
lr_mon          RN      14

79 80 81 82
r13_abort       RN      13
r14_abort       RN      14
lr_abort        RN      14

83 84 85 86
r13_abt         RN      13
r14_abt         RN      14
lr_abt          RN      14

87 88 89 90
r13_undef       RN      13
r14_undef       RN      14
lr_undef        RN      14

91 92 93 94
r13_und         RN      13
r14_und         RN      14
lr_und          RN      14

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
 [ :LNOT: No32bitCode

        ; 32 bit versions of the macros in Generic26

        GBLA    CPU32_bits
        GBLA    CPU32_set
        GBLA    CPU32_clr

; ***************************************************
; ***  PSRto32 - Convert a PSR constant to a      ***
; ***  32-bit PSR value in variable psr32         ***
; ***  Shifts I and F into their 32-bit positions ***
; ***************************************************
        MACRO
$psr32  PSRto32 $psr
        [ (($psr) :AND: (:NOT: ARM_CC_Mask)) <> 0
	! 1, "Illegal PSR bits"
        ]
$psr32  SETA    (($psr) :AND: :NOT: (I_bit:OR:F_bit)) :OR: ((($psr) :AND: (I_bit:OR:F_bit)) :SHR: IF32_26Shift)
        MEND

; ************************************************
; ***  CLC - Clear carry flag - will set nzcv  ***
; ************************************************
        MACRO
$label  CLC     $cond
121
$label  MSR$cond CPSR_f, #0
122 123 124 125 126 127 128
        MEND

; ***********************************************
; ***  CLRPSR - Clear bits in PSR from the    ***
; ***  mask in $bits, using register $regtmp  ***
; ***********************************************
        MACRO
129 130 131 132 133 134 135
$label  CLRPSR  $bits, $regtmp, $cond, $oldpsr
	LCLS	srcreg
        [ "$oldpsr"=""
srcreg  SETS    "$regtmp"
        |
srcreg  SETS    "$oldpsr"
        ]
136 137
CPU32_bits PSRto32 $bits                ; Map to 32 bit PSR
$label  MRS$cond $srcreg, CPSR
138
        [ (CPU32_bits :AND: &F0000000) <> 0 :LAND: (CPU32_bits :AND: &F0) <> 0
139
        ; Can't be expressed as a single ARM immediate constant
140
        BIC$cond $regtmp, $srcreg, #CPU32_bits :AND: &F0000000
141 142
        BIC$cond $regtmp, $regtmp, #CPU32_bits :AND: &0FFFFFFF
        |
143
        BIC$cond $regtmp, $srcreg, #CPU32_bits
144
        ]
145
        somemsr $cond, CPSR, $regtmp, CPU32_bits, unsafe
146 147 148 149 150 151 152
        MEND

; **************************************************
; *** CLRV - Clear overflow flag - will set nzCv ***
; **************************************************
        MACRO
$label  CLRV    $cond
153
$label  MSR$cond CPSR_f, #C_bit
154 155 156 157 158 159 160 161 162
        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.  ***
; ***  Don't have to supply regtmp, but if you do, we save an instruction.       ***
; **********************************************************************************
        MACRO
$label  PHPSEI  $register=R14, $regtmp
163
        LCLS    usereg
164
  [ "$register" = ""
165
usereg  SETS    "R14"
166
  |
167
usereg  SETS    "$register"
168
  ]
169 170 171 172 173 174 175
$label
  [ "$regtmp" = "" :LOR: StrongARM_MSR_bug
        MRS     $usereg, CPSR
        TST     $usereg, #I32_bit              ; is I32_bit set?
        ORREQ   $usereg, $usereg, #I32_bit     ; no, then set it
        mymsr   EQ, CPSR_c, $usereg, , safe
        BICEQ   $usereg, $usereg, #I32_bit     ; $register contains original PSR
176
  |
177 178 179 180
        MRS     $usereg, CPSR
        TST     $usereg, #I32_bit              ; is I32_bit set?
        ORREQ   $regtmp, $usereg, #I32_bit     ; no, then set it
        mymsr   EQ, CPSR_c, $regtmp            ; $register contains original PSR
181 182 183 184 185 186 187 188 189
  ]
        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
190
        LCLS    usereg
191
  [ "$register" = ""
192
usereg  SETS    "R14"
193
  |
194
usereg  SETS    "$register"
195
  ]
196
$label  MSR     CPSR_c, $usereg
197 198 199 200 201 202 203 204
        MEND

; ******************
; ***  RETURNVC  ***
; ******************
        MACRO
$label  RETURNVC  $cond
$label
205 206 207
  [ "$cond" = "NV"
        ! 1, "Deprecated use of NV condition code in RETURNVC"
  ]
208 209
  [ "$cond" = "VC"
        MOVVC   pc, lr
210
  ]
211 212
  [ "$cond" = "NE" :LOR: "$cond"="CC" :LOR: "$cond"="LO" :LOR: "$cond"="PL" :LOR: "$cond"="LS" :LOR: "$cond"="GE" :LOR: "$cond"="GT" :LOR: "$cond"="AL" :LOR: "$cond"=""
        MSR$cond CPSR_f, #0
213 214 215
        MOV$cond pc, lr
  ]
  [ "$cond" = "EQ" :LOR: "$cond"="CS" :LOR: "$cond"="HS" :LOR: "$cond"="MI" :LOR: "$cond"="LT" :LOR: "$cond"="LE"
216
        MSR$cond CPSR_f, #N_bit + Z_bit + C_bit
217 218 219
        MOV$cond pc, lr
  ]
  [ "$cond" = "HI"
220
        MSR$cond CPSR_f, #C_bit
221 222
        MOV$cond pc, lr
  ]
223 224 225
  [ "$cond" = "VS"
        BVC     %FT01                   ; Skip on opposite condition
        MSR     CPSR_f, #0
226
        MOV     pc, lr
227
01
228
  ]
229 230 231 232 233 234 235 236
        MEND

; ******************
; ***  RETURNVS  ***
; ******************
        MACRO
$label  RETURNVS  $cond
$label
237 238 239
  [ "$cond" = "NV"
        ! 1, "Deprecated use of NV condition code in RETURNVC"
  ]
240 241
  [ "$cond" = "VS"
        MOVVS   pc, lr
242
  ]
243 244
  [ "$cond" = "NE" :LOR: "$cond"="CC" :LOR: "$cond"="LO" :LOR: "$cond"="PL" :LOR: "$cond"="LS" :LOR: "$cond"="AL" :LOR: "$cond"=""
        MSR$cond CPSR_f, #V_bit         ; Condition is still satisfied
245 246 247
        MOV$cond pc, lr
  ]
  [ "$cond" = "EQ" :LOR: "$cond"="CS" :LOR: "$cond"="HS" :LOR: "$cond"="MI" :LOR: "$cond"="GE" :LOR: "$cond"="LE"
248
        MSR$cond CPSR_f, #N_bit + Z_bit + C_bit + V_bit
249 250 251
        MOV$cond pc, lr
  ]
  [ "$cond" = "HI" :LOR: "$cond"="LT"
252
        MSR$cond CPSR_f, #C_bit + V_bit
253 254 255
        MOV$cond pc, lr
  ]
  [ "$cond" = "GT"
256
        MSR$cond CPSR_f, #N_bit + V_bit
257 258
        MOV$cond pc, lr
  ]
259 260 261
  [ "$cond" = "VC"
        BVS     %FT01                   ; Skip on opposite condition
        MSR     CPSR_f, #V_bit
262
        MOV     pc, lr
263
01
264
  ]
265 266 267 268 269 270 271
        MEND

; ****************************************************
; ***  SCPSR - Set and clear bits in PSR from the  ***
; ***  masks $set, $clr, using register $regtmp    ***
; ****************************************************
        MACRO
272 273
$label  SCPSR   $set, $clr, $regtmp, $cond, $oldpsr
        LCLS    srcreg
274 275
CPU32_set PSRto32 $set
CPU32_clr PSRto32 $clr
276 277 278 279 280
        [ "$oldpsr"=""
srcreg  SETS    "$regtmp"
        |
srcreg  SETS    "$oldpsr"
        ]
281 282 283
        [ (($set) :AND: ($clr)) <> 0
        ! 1, "Attempt to simultaneously set and clear a bit in SCPSR"
        ]
284
$label  MRS$cond $srcreg, CPSR
285
 [ (CPU32_set :AND: &F0000000) <> 0 :LAND: (CPU32_set :AND: &F0) <> 0
286
        ORR$cond $regtmp, $srcreg, #CPU32_set :AND: &F0000000
287
        ORR$cond $regtmp, $regtmp, #CPU32_set :AND: &0FFFFFFF
288
srcreg  SETS "$regtmp"
289 290
 |
 [ CPU32_set <> 0
291 292
        ORR$cond $regtmp, $srcreg, #CPU32_set
srcreg  SETS "$regtmp"
293 294 295
 ]
 ]
 [ (CPU32_clr :AND: &F0000000) <> 0 :LAND: (CPU32_clr :AND: &F0) <> 0
296
        BIC$cond $regtmp, $srcreg, #CPU32_clr :AND: &F0000000
297
        BIC$cond $regtmp, $regtmp, #CPU32_clr :AND: &0FFFFFFF
298
srcreg  SETS "$regtmp"
299 300
 |
 [ CPU32_clr <> 0
301 302
        BIC$cond $regtmp, $srcreg, #CPU32_clr
srcreg  SETS "$regtmp"
303 304
 ]
 ]
305
        somemsr  $cond, CPSR,$srcreg, CPU32_set:OR:CPU32_clr, unsafe
306 307 308 309
        MEND

; ****************************************************
; ***  SavePSR - Save the PSR in a register, to be ***
310
; ***  restored later using RestPSR                ***
311 312 313
; ****************************************************
        MACRO
$label  SavePSR $reg, $cond
314
$label  MRS$cond $reg, CPSR
315 316 317 318
        MEND

; ****************************************************
; ***  RestPSR - Restore the PSR from a register   ***
319
; ***  set up by SavePSR                           ***
320 321 322 323 324 325 326
; ***  $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.             ***
327 328 329
; ****************************************************
        MACRO
$label  RestPSR $reg, $cond, $fields
330 331 332
        LCLS    field
  [ "$fields"="" :LOR: "$fields"="cf" :LOR: "$fields"="fc"
field   SETS    "cf"
333
  |
334 335 336 337 338 339
  [ "$fields"="f"
field   SETS    "f"
  |
        !       0, "Unpredictable behaviour due to deprecated RestPSR fields parameter"
field   SETS    "$fields"
  ]
340
  ]
341
$label  mymsr   $cond, CPSR_$field, $reg, , unsafe
342 343 344 345 346 347 348
        MEND

; **********************************************
; ***  SEC - Set carry flag - will set nzCv  ***
; **********************************************
        MACRO
$label  SEC     $cond
349
$label  MSR$cond CPSR_f, #C_bit
350 351 352 353 354 355 356
        MEND

; ************************************************
; ***  SETPSR - Set bits in PSR from the mask  ***
; ***  in $bits, using register $regtmp        ***
; ************************************************
        MACRO
357 358 359 360 361 362 363
$label  SETPSR  $bits, $regtmp, $cond, $oldpsr
        LCLS    srcreg
        [ "$oldpsr"=""
srcreg  SETS    "$regtmp"
        |
srcreg  SETS    "$oldpsr"
        ]
364 365
CPU32_bits PSRto32 $bits                ; Map to 32 bit PSR
$label  MRS$cond $srcreg, CPSR
366
        [ (CPU32_bits :AND: &F0000000) <> 0 :LAND: (CPU32_bits :AND: &F0) <> 0
367
        ; Can't be expressed as a single ARM immediate constant
368
        ORR$cond $regtmp, $srcreg, #CPU32_bits :AND: &F0000000
369 370
        ORR$cond $regtmp, $regtmp, #CPU32_bits :AND: &0FFFFFFF
        |
371
        ORR$cond $regtmp, $srcreg, #CPU32_bits
372
        ]
373
        somemsr $cond, CPSR, $regtmp, CPU32_bits, unsafe
374 375 376 377 378 379 380
        MEND

; **************************************************
; ***  SETV - Set overflow flag - will set NzcV  ***
; **************************************************
        MACRO
$label  SETV    $cond
381
$label  MSR$cond CPSR_f, #N_bit+V_bit
382 383
        MEND

384 385 386 387
; *********************************************************
; ***  TOGPSR - Toggle bits in PSR from the            ***
; ***  immediate mask in $bits, using register $regtmp  ***
; *********************************************************
388
        MACRO
389
$label  TOGPSR  $bits, $regtmp, $cond, $oldpsr
Stewart Brodie's avatar
Stewart Brodie committed
390
        LCLS    srcreg
391 392 393 394 395
        [ "$oldpsr"=""
srcreg  SETS    "$regtmp"
        |
srcreg  SETS    "$oldpsr"
        ]
396 397
CPU32_bits PSRto32 $bits                ; Map to 32 bit PSR
$label  MRS$cond $srcreg, CPSR
398
        EOR$cond $regtmp, $srcreg, #CPU32_bits
399
        somemsr $cond, CPSR, $regtmp, CPU32_bits, unsafe
400 401
        MEND

402 403 404 405
; ************************************************
; ***  TOGPSRR - Toggle bits in PSR from the   ***
; ***  mask in $regtog, using register $regtmp ***
; ************************************************
Stewart Brodie's avatar
Stewart Brodie committed
406 407 408 409 410 411 412 413 414 415 416 417 418 419
        MACRO
$label  TOGPSRR $regtog, $regtmp, $cond, $oldpsr, $fields
        LCLS    srcreg
        LCLS    field
        [ "$fields"=""
field   SETS    "cxsf"
        |
field   SETS    "$fields"
        ]
        [ "$oldpsr"=""
srcreg  SETS    "$regtmp"
        |
srcreg  SETS    "$oldpsr"
        ]
420
$label  MRS$cond $srcreg, CPSR
Stewart Brodie's avatar
Stewart Brodie committed
421
        EOR$cond $regtmp, $srcreg, $regtog
422
        mymsr    $cond, CPSR_$field, $regtmp, , unsafe
Stewart Brodie's avatar
Stewart Brodie committed
423 424
        MEND

425 426 427 428 429 430 431 432 433 434
; *************************************************
; ***  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
435
$label  WritePSRc $value, $regtmp, $cond, $oldpsr
436 437 438
        [ ($value :AND::NOT: (I_bit+F_bit+SVC_mode)) <> 0
        ! 1, "Illegal flags for WritePSRc"
        ]
439
$label  SCPSR   $value, (I_bit+F_bit+SVC_mode):EOR:($value), $regtmp, $cond, $oldpsr
440 441 442 443
        MEND

 ] ; :LNOT: No32bitCode

444 445 446 447
; ****************************************************
; *** mrs/msr - Lowercase funny names for aasm.    ***
; *** Due for retirement, aasm is redundant now.   ***
;*****************************************************
448 449
        MACRO
$label  mrs     $cond, $rd, $psrs
450
$label  MRS$cond $rd, $psrs
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
        MEND

        MACRO
$label  msr     $cond, $psrl, $op2a, $op2b
$label  mymsr   $cond, $psrl, $op2a, $op2b
        MEND

; ***************************************************
; *** somemsr - Set some fields of the PSR from   ***
; *** $op, according to $mask. The mask should    ***
; *** indicate which bits have been modified.     ***
; *** This saves us writing the control field,    ***
; *** when it hasn't been modified, for example,  ***
; *** saving 2 cycles on some processors.         ***
; ***************************************************
        MACRO
467
$label  somemsr $cond, $psr, $op, $mask, $sabug
468 469 470 471 472 473 474 475 476 477 478 479 480 481
        LCLS    s
s       SETS    "$psr._"
 [ (($mask) :AND: &FF) <> 0
s       SETS    s:CC:"c"
 ]
 [ (($mask) :AND: &FF00) <> 0
s       SETS    s:CC:"x"
 ]
 [ (($mask) :AND: &FF0000) <> 0
s       SETS    s:CC:"s"
 ]
 [ (($mask) :AND: &FF000000) <> 0
s       SETS    s:CC:"f"
 ]
482
$label  mymsr   $cond, $s, $op, , $sabug
483 484
        MEND

485 486 487 488
; ****************************************************
; *** mymrs - Perform an MRS operation.            ***
; *** Due for retirement, objasm supports MRS now. ***
;*****************************************************
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
        MACRO
$label  mymrs   $cond, $rd, $psrs
$label
        LCLA    psrtype
psrtype SETA    -1
 [ "$psrs" = "CPSR_all" :LOR: "$psrs" = "SPSR_all"
        !       0, "Deprecated form of PSR field specifier used (use no suffix)"
 ]
 [ "$psrs" = "CPSR" :LOR: "$psrs" = "CPSR_all"
psrtype SETA    0 :SHL: 22
 ]
 [ "$psrs" = "SPSR" :LOR: "$psrs" = "SPSR_all"
psrtype SETA    1 :SHL: 22
 ]
        ASSERT  psrtype <> -1
        ASSERT  $rd <> 15
505
        DCI     Cond_$cond :OR: 2_00000001000011110000000000000000 :OR: psrtype :OR: ($rd :SHL: 12)
506 507
        MEND

508 509 510 511 512 513 514 515 516 517 518 519 520 521
; ****************************************************
; *** mymsr - Perform an MSR operation.            ***
; *** If $sabug is set to "safe", it's assumed the ***
; *** code around this operation is sufficiently   ***
; *** protected against the StrongARM conditional  ***
; *** MSR CPSR_c bug.                              ***
; *** If $sabug is set to "unsafe", a NOP will     ***
; *** automatically be inserted when generating an ***
; *** MSR that could trigger the bug (and we're    ***
; *** targeting a StrongARM machine type).         ***
; *** If $sabug is left unset, a warning and a NOP ***
; *** will be produced whenever a dangerous MSR is ***
; *** requested (if we're targeting StrongARM)     ***
; ****************************************************
522
        MACRO
523
$label  mymsr   $cond, $psrl, $op2a, $op2b, $sabug
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
$label
        LCLA    psrtype
        LCLS    op2as
        LCLA    op
        LCLA    shift
        LCLS    s
s       SETS    "$psrl"
 [ s:RIGHT:4 = "_ctl" :LOR: s:RIGHT:4 = "_flg"
        !       0, "Deprecated form of PSR field specifier used (use _cxsf)"
s       SETS    s:LEFT:(:LEN:s-2)
 ]
 [ s:RIGHT:4 = "_all"
        !       0, "Deprecated form of PSR field specifier used (use _cxsf)"
s       SETS    s:LEFT:(:LEN:s-3) :CC: "cf"
 ]
 [ s:RIGHT:3 = "PSR"
        !       0, "Deprecated form of PSR field specifier used (use _cxsf)"
s       SETS    s:CC:"_cf"
 ]
psrtype SETA    0
 [ s:RIGHT:1 = "f"
psrtype SETA    psrtype :OR: (1:SHL:19)
s       SETS    s :LEFT: (:LEN:s-1)
 ]
 [ s:RIGHT:1 = "s"
psrtype SETA    psrtype :OR: (1:SHL:18)
s       SETS    s :LEFT: (:LEN:s-1)
 ]
 [ s:RIGHT:1 = "x"
psrtype SETA    psrtype :OR: (1:SHL:17)
s       SETS    s :LEFT: (:LEN:s-1)
 ]
 [ s:RIGHT:1 = "c"
psrtype SETA    psrtype :OR: (1:SHL:16)
s       SETS    s :LEFT: (:LEN:s-1)
 ]
        ASSERT  s = "CPSR_" :LOR: s = "SPSR_"
 [ s = "SPSR_"
psrtype SETA    psrtype :OR: (1:SHL:22)
 |
psrtype SETA    psrtype :OR: (0:SHL:22)
 ]
 [ (psrtype :AND: (15:SHL:16)) = 0
        ! 0, "MSR that sets no fields"
 ]
 [ ("$op2a" :LEFT: 1) = "#"
 ; Immediate operand

op2as   SETS    "$op2a" :RIGHT: ((:LEN: "$op2a")-1)
op      SETA    $op2as

  [ "$op2b" = ""
  ; Rotate not specified in immediate operand
shift   SETA    0
        WHILE   (op :AND: &FFFFFF00)<>0 :LAND: shift<16
op      SETA    ((op:SHR:30):AND:3):OR:(op:SHL:2)
shift   SETA    shift + 1
        WEND
        ASSERT  (op :AND: &FFFFFF00)=0
  |
  ; Rotate of immediate operand specified explicitly
        ASSERT  (($op2b):AND:&FFFFFFE1)=0
shift   SETA    ($opt2b):SHR:1
  ]
op      SETA    (shift :SHL: 8) :OR: op :OR: (1:SHL:25)
 |

 ; Not an immediate operand
  [ "$op2b" = ""
  ; Unshifted register
op      SETA    ($op2a) :OR: (0:SHL:25)
  |
        ! 1, "Shifted register not yet implemented in this macro!"
  ]
 ]
599 600 601 602 603 604 605
        DCI     Cond_$cond :OR: 2_00000001001000001111000000000000 :OR: op :OR: psrtype
     [ StrongARM_MSR_bug :LAND: "$sabug" <> "safe" :LAND: "$cond" <> "AL" :LAND: "$cond" <> "" :LAND: ((psrtype :AND: &410000) = &10000)
      [ "$sabug" <> "unsafe"
        ! 0, "mymsr inserting NOP for StrongARM MSR CPSR_c bug"
      ]
        NOP
     ]
606 607
        MEND

608 609 610 611 612
; ****************************************************
; *** SetMode - sets processor mode to constant    ***
; *** value newmode using register regtmp as a     ***
; *** temporary.                                   ***
; ****************************************************
613
        MACRO
614 615 616 617 618 619 620 621 622 623 624 625
        SetMode $newmode, $regtmp, $oldpsr
      [ "$oldpsr"=""
        MRS     $regtmp, CPSR
        BIC     $regtmp, $regtmp, #M32_bits
        ORR     $regtmp, $regtmp, #$newmode
        MSR     CPSR_c, $regtmp
      |
        MRS     $oldpsr, CPSR
        BIC     $regtmp, $oldpsr, #M32_bits
        ORR     $regtmp, $regtmp, #$newmode
        MSR      CPSR_c, $regtmp
      ]
626 627
        MEND

628 629 630 631
 ] ; :LNOT: :DEF: Included_Hdr_CPU_Generic32

        OPT     OldOpt
        END