1 ;// 2 ;// 3 ;// File Name: armCOMM_s.h 4 ;// OpenMAX DL: v1.0.2 5 ;// Revision: 12290 6 ;// Date: Wednesday, April 9, 2008 7 ;// 8 ;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. 9 ;// 10 ;// 11 ;// 12 ;// ARM optimized OpenMAX common header file 13 ;// 14 15 ;// Protect against multiple inclusion 16 IF :LNOT::DEF:ARMCOMM_S_H 17 GBLL ARMCOMM_S_H 18 19 REQUIRE8 ;// Requires 8-byte stack alignment 20 PRESERVE8 ;// Preserves 8-byte stack alignment 21 22 GBLL ARM_ERRORCHECK 23 ARM_ERRORCHECK SETL {FALSE} 24 25 ;// Globals 26 27 GBLS _RRegList ;// R saved register list 28 GBLS _DRegList ;// D saved register list 29 GBLS _Variant ;// Selected processor variant 30 GBLS _CPU ;// CPU name 31 GBLS _Struct ;// Structure name 32 33 GBLL _InFunc ;// Inside function assembly flag 34 GBLL _SwLong ;// Long switch flag 35 36 GBLA _RBytes ;// Number of register bytes on stack 37 GBLA _SBytes ;// Number of scratch bytes on stack 38 GBLA _ABytes ;// Stack offset of next argument 39 GBLA _Workspace ;// Stack offset of scratch workspace 40 GBLA _F ;// Function number 41 GBLA _StOff ;// Struct offset 42 GBLA _SwNum ;// Switch number 43 GBLS _32 ;// Suffix for 32 byte alignmnet 44 GBLS _16 ;// Suffix for 16 byte alignmnet 45 46 _InFunc SETL {FALSE} 47 _SBytes SETA 0 48 _F SETA 0 49 _SwNum SETA 0 50 _32 SETS "ALIGN32" 51 _16 SETS "ALIGN16" 52 53 ;///////////////////////////////////////////////////////// 54 ;// Override the tools settings of the CPU if the #define 55 ;// USECPU is set, otherwise use the CPU defined by the 56 ;// assembler settings. 57 ;///////////////////////////////////////////////////////// 58 59 IF :DEF: OVERRIDECPU 60 _CPU SETS OVERRIDECPU 61 ELSE 62 _CPU SETS {CPU} 63 ENDIF 64 65 66 67 ;///////////////////////////////////////////////////////// 68 ;// Work out which code to build 69 ;///////////////////////////////////////////////////////// 70 71 IF :DEF:ARM1136JS:LOR::DEF:CortexA8:LOR::DEF:ARM_GENERIC 72 INFO 1,"Please switch to using M_VARIANTS" 73 ENDIF 74 75 ;// Define and reset all officially recongnised variants 76 MACRO 77 _M_DEF_VARIANTS 78 _M_DEF_VARIANT ARM926EJS 79 _M_DEF_VARIANT ARM1136JS 80 _M_DEF_VARIANT ARM1136JS_U 81 _M_DEF_VARIANT CortexA8 82 _M_DEF_VARIANT ARM7TDMI 83 MEND 84 85 MACRO 86 _M_DEF_VARIANT $var 87 GBLL $var 88 GBLL _ok$var 89 $var SETL {FALSE} 90 MEND 91 92 93 ;// Variant declaration 94 ;// 95 ;// Define a list of code variants supported by this 96 ;// source file. This macro then chooses the most 97 ;// appropriate variant to build for the currently configured 98 ;// core. 99 ;// 100 MACRO 101 M_VARIANTS $v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7 102 ;// Set to TRUE variants that are supported 103 _M_DEF_VARIANTS 104 _M_VARIANT $v0 105 _M_VARIANT $v1 106 _M_VARIANT $v2 107 _M_VARIANT $v3 108 _M_VARIANT $v4 109 _M_VARIANT $v5 110 _M_VARIANT $v6 111 _M_VARIANT $v7 112 113 ;// Look for first available variant to match a CPU 114 ;// _M_TRY cpu, variant fall back list 115 _Variant SETS "" 116 _M_TRY ARM926EJ-S, ARM926EJS 117 _M_TRY ARM1176JZ-S, ARM1136JS 118 _M_TRY ARM1176JZF-S, ARM1136JS 119 _M_TRY ARM1156T2-S, ARM1136JS 120 _M_TRY ARM1156T2F-S, ARM1136JS 121 _M_TRY ARM1136J-S, ARM1136JS 122 _M_TRY ARM1136JF-S, ARM1136JS 123 _M_TRY MPCore, ARM1136JS 124 _M_TRY falcon-vfp, ARM1136JS 125 _M_TRY falcon-full-neon, CortexA8 126 _M_TRY Cortex-A8NoNeon, ARM1136JS 127 _M_TRY Cortex-A8, CortexA8, ARM1136JS 128 _M_TRY Cortex-R4, ARM1136JS 129 _M_TRY ARM7TDMI 130 131 ;// Select the correct variant 132 _M_DEF_VARIANTS 133 IF _Variant="" 134 INFO 1, "No match found for CPU '$_CPU'" 135 ELSE 136 $_Variant SETL {TRUE} 137 ENDIF 138 MEND 139 140 ;// Register a variant as available 141 MACRO 142 _M_VARIANT $var 143 IF "$var"="" 144 MEXIT 145 ENDIF 146 IF :LNOT::DEF:_ok$var 147 INFO 1, "Unrecognized variant '$var'" 148 ENDIF 149 $var SETL {TRUE} 150 MEND 151 152 ;// For a given CPU, see if any of the variants supporting 153 ;// this CPU are available. The first available variant is 154 ;// chosen 155 MACRO 156 _M_TRY $cpu, $v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7 157 IF "$cpu"<>_CPU 158 MEXIT 159 ENDIF 160 _M_TRY1 $v0 161 _M_TRY1 $v1 162 _M_TRY1 $v2 163 _M_TRY1 $v3 164 _M_TRY1 $v4 165 _M_TRY1 $v5 166 _M_TRY1 $v6 167 _M_TRY1 $v7 168 ;// Check a match was found 169 IF _Variant="" 170 INFO 1, "No variant match found for CPU '$_CPU'" 171 ENDIF 172 MEND 173 174 MACRO 175 _M_TRY1 $var 176 IF "$var"="" 177 MEXIT 178 ENDIF 179 IF (_Variant=""):LAND:$var 180 _Variant SETS "$var" 181 ENDIF 182 MEND 183 184 ;//////////////////////////////////////////////////////// 185 ;// Structure definition 186 ;//////////////////////////////////////////////////////// 187 188 ;// Declare a structure of given name 189 MACRO 190 M_STRUCT $sname 191 _Struct SETS "$sname" 192 _StOff SETA 0 193 MEND 194 195 ;// Declare a structure field 196 ;// The field is called $sname_$fname 197 ;// $size = the size of each entry, must be power of 2 198 ;// $number = (if provided) the number of entries for an array 199 MACRO 200 M_FIELD $fname, $size, $number 201 IF (_StOff:AND:($size-1))!=0 202 _StOff SETA _StOff + ($size - (_StOff:AND:($size-1))) 203 ENDIF 204 $_Struct._$fname EQU _StOff 205 IF "$number"<>"" 206 _StOff SETA _StOff + $size*$number 207 ELSE 208 _StOff SETA _StOff + $size 209 ENDIF 210 MEND 211 212 213 MACRO 214 M_ENDSTRUCT 215 sizeof_$_Struct EQU _StOff 216 _Struct SETS "" 217 MEND 218 219 ;////////////////////////////////////////////////////////// 220 ;// Switch and table macros 221 ;////////////////////////////////////////////////////////// 222 223 ;// Start a relative switch table with register to switch on 224 ;// 225 ;// $v = the register to switch on 226 ;// $s = if specified must be "L" to indicate long 227 ;// this allows a greater range to the case code 228 MACRO 229 M_SWITCH $v, $s 230 ASSERT "$s"="":LOR:"$s"="L" 231 _SwLong SETL {FALSE} 232 IF "$s"="L" 233 _SwLong SETL {TRUE} 234 ENDIF 235 _SwNum SETA _SwNum+1 236 IF {CONFIG}=16 237 ;// Thumb 238 IF _SwLong 239 TBH [pc, $v, LSL#1] 240 ELSE 241 TBB [pc, $v] 242 ENDIF 243 _Switch$_SwNum 244 ELSE 245 ;// ARM 246 ADD pc, pc, $v, LSL #2 247 NOP 248 ENDIF 249 MEND 250 251 ;// Add a case to the switch statement 252 MACRO 253 M_CASE $label 254 IF {CONFIG}=16 255 ;// Thumb 256 IF _SwLong 257 DCW ($label - _Switch$_SwNum)/2 258 ELSE 259 DCB ($label - _Switch$_SwNum)/2 260 ENDIF 261 ELSE 262 ;// ARM 263 B $label 264 ENDIF 265 MEND 266 267 ;// End of switch statement 268 MACRO 269 M_ENDSWITCH 270 ALIGN 2 271 MEND 272 273 274 ;//////////////////////////////////////////////////////// 275 ;// Data area allocation 276 ;//////////////////////////////////////////////////////// 277 278 ;// Constant table allocator macro 279 ;// 280 ;// Creates a new section for each constant table 281 ;// $name is symbol through which the table can be accessed. 282 ;// $align is the optional alignment of the table, log2 of 283 ;// the byte alignment - $align=4 is 16 byte aligned 284 MACRO 285 M_TABLE $name, $align 286 ASSERT :LNOT:_InFunc 287 IF "$align"="" 288 AREA |.constdata|, READONLY, DATA 289 ELSE 290 ;// AREAs inherit the alignment of the first declaration. 291 ;// Therefore for each alignment size we must have an area 292 ;// of a different name. 293 AREA constdata_a$align, READONLY, DATA, ALIGN=$align 294 295 ;// We also force alignment incase we are tagging onto 296 ;// an already started area. 297 ALIGN (1<<$align) 298 ENDIF 299 $name 300 MEND 301 302 ;///////////////////////////////////////////////////// 303 ;// Macros to allocate space on the stack 304 ;// 305 ;// These all assume that the stack is 8-byte aligned 306 ;// at entry to the function, which means that the 307 ;// 32-byte alignment macro needs to work in a 308 ;// bit more of a special way... 309 ;///////////////////////////////////////////////////// 310 311 312 313 314 ;// Allocate 1-byte aligned area of name 315 ;// $name size $size bytes. 316 MACRO 317 M_ALLOC1 $name, $size 318 ASSERT :LNOT:_InFunc 319 $name$_F EQU _SBytes 320 _SBytes SETA _SBytes + ($size) 321 MEND 322 323 ;// Allocate 2-byte aligned area of name 324 ;// $name size $size bytes. 325 MACRO 326 M_ALLOC2 $name, $size 327 ASSERT :LNOT:_InFunc 328 IF (_SBytes:AND:1)!=0 329 _SBytes SETA _SBytes + (2 - (_SBytes:AND:1)) 330 ENDIF 331 $name$_F EQU _SBytes 332 _SBytes SETA _SBytes + ($size) 333 MEND 334 335 ;// Allocate 4-byte aligned area of name 336 ;// $name size $size bytes. 337 MACRO 338 M_ALLOC4 $name, $size 339 ASSERT :LNOT:_InFunc 340 IF (_SBytes:AND:3)!=0 341 _SBytes SETA _SBytes + (4 - (_SBytes:AND:3)) 342 ENDIF 343 $name$_F EQU _SBytes 344 _SBytes SETA _SBytes + ($size) 345 MEND 346 347 ;// Allocate 8-byte aligned area of name 348 ;// $name size $size bytes. 349 MACRO 350 M_ALLOC8 $name, $size 351 ASSERT :LNOT:_InFunc 352 IF (_SBytes:AND:7)!=0 353 _SBytes SETA _SBytes + (8 - (_SBytes:AND:7)) 354 ENDIF 355 $name$_F EQU _SBytes 356 _SBytes SETA _SBytes + ($size) 357 MEND 358 359 360 ;// Allocate 8-byte aligned area of name 361 ;// $name size ($size+16) bytes. 362 ;// The extra 16 bytes are later used to align the pointer to 16 bytes 363 364 MACRO 365 M_ALLOC16 $name, $size 366 ASSERT :LNOT:_InFunc 367 IF (_SBytes:AND:7)!=0 368 _SBytes SETA _SBytes + (8 - (_SBytes:AND:7)) 369 ENDIF 370 $name$_F$_16 EQU (_SBytes + 8) 371 _SBytes SETA _SBytes + ($size) + 8 372 MEND 373 374 ;// Allocate 8-byte aligned area of name 375 ;// $name size ($size+32) bytes. 376 ;// The extra 32 bytes are later used to align the pointer to 32 bytes 377 378 MACRO 379 M_ALLOC32 $name, $size 380 ASSERT :LNOT:_InFunc 381 IF (_SBytes:AND:7)!=0 382 _SBytes SETA _SBytes + (8 - (_SBytes:AND:7)) 383 ENDIF 384 $name$_F$_32 EQU (_SBytes + 24) 385 _SBytes SETA _SBytes + ($size) + 24 386 MEND 387 388 389 390 391 ;// Argument Declaration Macro 392 ;// 393 ;// Allocate an argument name $name 394 ;// size $size bytes 395 MACRO 396 M_ARG $name, $size 397 ASSERT _InFunc 398 $name$_F EQU _ABytes 399 _ABytes SETA _ABytes + ($size) 400 MEND 401 402 ;/////////////////////////////////////////////// 403 ;// Macros to access stacked variables 404 ;/////////////////////////////////////////////// 405 406 ;// Macro to perform a data processing operation 407 ;// with a constant second operand 408 MACRO 409 _M_OPC $op,$rd,$rn,$const 410 LCLA _sh 411 LCLA _cst 412 _sh SETA 0 413 _cst SETA $const 414 IF _cst=0 415 $op $rd, $rn, #_cst 416 MEXIT 417 ENDIF 418 WHILE (_cst:AND:3)=0 419 _cst SETA _cst>>2 420 _sh SETA _sh+2 421 WEND 422 $op $rd, $rn, #(_cst:AND:0x000000FF)<<_sh 423 IF _cst>=256 424 $op $rd, $rd, #(_cst:AND:0xFFFFFF00)<<_sh 425 ENDIF 426 MEND 427 428 ;// Macro to perform a data access operation 429 ;// Such as LDR or STR 430 ;// The addressing mode is modified such that 431 ;// 1. If no address is given then the name is taken 432 ;// as a stack offset 433 ;// 2. If the addressing mode is not available for the 434 ;// state being assembled for (eg Thumb) then a suitable 435 ;// addressing mode is substituted. 436 ;// 437 ;// On Entry: 438 ;// $i = Instruction to perform (eg "LDRB") 439 ;// $a = Required byte alignment 440 ;// $r = Register(s) to transfer (eg "r1") 441 ;// $a0,$a1,$a2. Addressing mode and condition. One of: 442 ;// label {,cc} 443 ;// [base] {,,,cc} 444 ;// [base, offset]{!} {,,cc} 445 ;// [base, offset, shift]{!} {,cc} 446 ;// [base], offset {,,cc} 447 ;// [base], offset, shift {,cc} 448 MACRO 449 _M_DATA $i,$a,$r,$a0,$a1,$a2,$a3 450 IF "$a0":LEFT:1="[" 451 IF "$a1"="" 452 $i$a3 $r, $a0 453 ELSE 454 IF "$a0":RIGHT:1="]" 455 IF "$a2"="" 456 _M_POSTIND $i$a3, "$r", $a0, $a1 457 ELSE 458 _M_POSTIND $i$a3, "$r", $a0, "$a1,$a2" 459 ENDIF 460 ELSE 461 IF "$a2"="" 462 _M_PREIND $i$a3, "$r", $a0, $a1 463 ELSE 464 _M_PREIND $i$a3, "$r", $a0, "$a1,$a2" 465 ENDIF 466 ENDIF 467 ENDIF 468 ELSE 469 LCLA _Offset 470 _Offset SETA _Workspace + $a0$_F 471 ASSERT (_Offset:AND:($a-1))=0 472 $i$a1 $r, [sp, #_Offset] 473 ENDIF 474 MEND 475 476 ;// Handle post indexed load/stores 477 ;// op reg, [base], offset 478 MACRO 479 _M_POSTIND $i,$r,$a0,$a1 480 LCLS _base 481 LCLS _offset 482 IF {CONFIG}=16 ;// Thumb 483 _base SETS ("$a0":LEFT:(:LEN:"$a0"-1)):RIGHT:(:LEN:"$a0"-2) ;// remove [] 484 _offset SETS "$a1" 485 IF _offset:LEFT:1="+" 486 _offset SETS _offset:RIGHT:(:LEN:_offset-1) 487 ENDIF 488 $i $r, $a0 489 IF _offset:LEFT:1="-" 490 _offset SETS _offset:RIGHT:(:LEN:_offset-1) 491 SUB $_base, $_base, $_offset 492 ELSE 493 ADD $_base, $_base, $_offset 494 ENDIF 495 ELSE ;// ARM 496 $i $r, $a0, $a1 497 ENDIF 498 MEND 499 500 ;// Handle pre indexed load/store 501 ;// op reg, [base, offset]{!} 502 MACRO 503 _M_PREIND $i,$r,$a0,$a1 504 LCLS _base 505 LCLS _offset 506 IF ({CONFIG}=16):LAND:(("$a1":RIGHT:2)="]!") 507 _base SETS "$a0":RIGHT:(:LEN:("$a0")-1) 508 _offset SETS "$a1":LEFT:(:LEN:("$a1")-2) 509 $i $r, [$_base, $_offset] 510 ADD $_base, $_base, $_offset 511 ELSE 512 $i $r, $a0, $a1 513 ENDIF 514 MEND 515 516 ;// Load unsigned byte from stack 517 MACRO 518 M_LDRB $r,$a0,$a1,$a2,$a3 519 _M_DATA "LDRB",1,$r,$a0,$a1,$a2,$a3 520 MEND 521 522 ;// Load signed byte from stack 523 MACRO 524 M_LDRSB $r,$a0,$a1,$a2,$a3 525 _M_DATA "LDRSB",1,$r,$a0,$a1,$a2,$a3 526 MEND 527 528 ;// Store byte to stack 529 MACRO 530 M_STRB $r,$a0,$a1,$a2,$a3 531 _M_DATA "STRB",1,$r,$a0,$a1,$a2,$a3 532 MEND 533 534 ;// Load unsigned half word from stack 535 MACRO 536 M_LDRH $r,$a0,$a1,$a2,$a3 537 _M_DATA "LDRH",2,$r,$a0,$a1,$a2,$a3 538 MEND 539 540 ;// Load signed half word from stack 541 MACRO 542 M_LDRSH $r,$a0,$a1,$a2,$a3 543 _M_DATA "LDRSH",2,$r,$a0,$a1,$a2,$a3 544 MEND 545 546 ;// Store half word to stack 547 MACRO 548 M_STRH $r,$a0,$a1,$a2,$a3 549 _M_DATA "STRH",2,$r,$a0,$a1,$a2,$a3 550 MEND 551 552 ;// Load word from stack 553 MACRO 554 M_LDR $r,$a0,$a1,$a2,$a3 555 _M_DATA "LDR",4,$r,$a0,$a1,$a2,$a3 556 MEND 557 558 ;// Store word to stack 559 MACRO 560 M_STR $r,$a0,$a1,$a2,$a3 561 _M_DATA "STR",4,$r,$a0,$a1,$a2,$a3 562 MEND 563 564 ;// Load double word from stack 565 MACRO 566 M_LDRD $r0,$r1,$a0,$a1,$a2,$a3 567 _M_DATA "LDRD",8,"$r0,$r1",$a0,$a1,$a2,$a3 568 MEND 569 570 ;// Store double word to stack 571 MACRO 572 M_STRD $r0,$r1,$a0,$a1,$a2,$a3 573 _M_DATA "STRD",8,"$r0,$r1",$a0,$a1,$a2,$a3 574 MEND 575 576 ;// Get absolute address of stack allocated location 577 MACRO 578 M_ADR $a, $b, $cc 579 _M_OPC ADD$cc, $a, sp, (_Workspace + $b$_F) 580 MEND 581 582 ;// Get absolute address of stack allocated location and align the address to 16 bytes 583 MACRO 584 M_ADR16 $a, $b, $cc 585 _M_OPC ADD$cc, $a, sp, (_Workspace + $b$_F$_16) 586 587 ;// Now align $a to 16 bytes 588 BIC$cc $a,$a,#0x0F 589 MEND 590 591 ;// Get absolute address of stack allocated location and align the address to 32 bytes 592 MACRO 593 M_ADR32 $a, $b, $cc 594 _M_OPC ADD$cc, $a, sp, (_Workspace + $b$_F$_32) 595 596 ;// Now align $a to 32 bytes 597 BIC$cc $a,$a,#0x1F 598 MEND 599 600 ;////////////////////////////////////////////////////////// 601 ;// Function header and footer macros 602 ;////////////////////////////////////////////////////////// 603 604 ;// Function Header Macro 605 ;// Generates the function prologue 606 ;// Note that functions should all be "stack-moves-once" 607 ;// The FNSTART and FNEND macros should be the only places 608 ;// where the stack moves. 609 ;// 610 ;// $name = function name 611 ;// $rreg = "" don't stack any registers 612 ;// "lr" stack "lr" only 613 ;// "rN" stack registers "r4-rN,lr" 614 ;// $dreg = "" don't stack any D registers 615 ;// "dN" stack registers "d8-dN" 616 ;// 617 ;// Note: ARM Archicture procedure call standard AAPCS 618 ;// states that r4-r11, sp, d8-d15 must be preserved by 619 ;// a compliant function. 620 MACRO 621 M_START $name, $rreg, $dreg 622 ASSERT :LNOT:_InFunc 623 ASSERT "$name"!="" 624 _InFunc SETL {TRUE} 625 _RBytes SETA 0 626 _Workspace SETA 0 627 628 ;// Create an area for the function 629 AREA |.text|, CODE 630 EXPORT $name 631 $name FUNCTION 632 633 ;// Save R registers 634 _M_GETRREGLIST $rreg 635 IF _RRegList<>"" 636 STMFD sp!, {$_RRegList, lr} 637 ENDIF 638 639 ;// Save D registers 640 _M_GETDREGLIST $dreg 641 IF _DRegList<>"" 642 VSTMFD sp!, {$_DRegList} 643 ENDIF 644 645 646 ;// Ensure size claimed on stack is 8-byte aligned 647 IF ((_SBytes:AND:7)!=0) 648 _SBytes SETA _SBytes + (8 - (_SBytes:AND:7)) 649 ENDIF 650 651 IF (_SBytes!=0) 652 _M_OPC SUB, sp, sp, _SBytes 653 ENDIF 654 655 656 _ABytes SETA _SBytes + _RBytes - _Workspace 657 658 659 ;// Print function name if debug enabled 660 M_PRINTF "$name\n", 661 MEND 662 663 ;// Work out a list of R saved registers 664 MACRO 665 _M_GETRREGLIST $rreg 666 IF "$rreg"="" 667 _RRegList SETS "" 668 MEXIT 669 ENDIF 670 IF "$rreg"="lr":LOR:"$rreg"="r4" 671 _RRegList SETS "r4" 672 _RBytes SETA _RBytes+8 673 MEXIT 674 ENDIF 675 IF "$rreg"="r5":LOR:"$rreg"="r6" 676 _RRegList SETS "r4-r6" 677 _RBytes SETA _RBytes+16 678 MEXIT 679 ENDIF 680 IF "$rreg"="r7":LOR:"$rreg"="r8" 681 _RRegList SETS "r4-r8" 682 _RBytes SETA _RBytes+24 683 MEXIT 684 ENDIF 685 IF "$rreg"="r9":LOR:"$rreg"="r10" 686 _RRegList SETS "r4-r10" 687 _RBytes SETA _RBytes+32 688 MEXIT 689 ENDIF 690 IF "$rreg"="r11":LOR:"$rreg"="r12" 691 _RRegList SETS "r4-r12" 692 _RBytes SETA _RBytes+40 693 MEXIT 694 ENDIF 695 INFO 1, "Unrecognized saved r register limit '$rreg'" 696 MEND 697 698 ;// Work out a list of D saved registers 699 MACRO 700 _M_GETDREGLIST $dreg 701 IF "$dreg"="" 702 _DRegList SETS "" 703 MEXIT 704 ENDIF 705 IF "$dreg"="d8" 706 _DRegList SETS "d8" 707 _RBytes SETA _RBytes+8 708 MEXIT 709 ENDIF 710 IF "$dreg"="d9" 711 _DRegList SETS "d8-d9" 712 _RBytes SETA _RBytes+16 713 MEXIT 714 ENDIF 715 IF "$dreg"="d10" 716 _DRegList SETS "d8-d10" 717 _RBytes SETA _RBytes+24 718 MEXIT 719 ENDIF 720 IF "$dreg"="d11" 721 _DRegList SETS "d8-d11" 722 _RBytes SETA _RBytes+32 723 MEXIT 724 ENDIF 725 IF "$dreg"="d12" 726 _DRegList SETS "d8-d12" 727 _RBytes SETA _RBytes+40 728 MEXIT 729 ENDIF 730 IF "$dreg"="d13" 731 _DRegList SETS "d8-d13" 732 _RBytes SETA _RBytes+48 733 MEXIT 734 ENDIF 735 IF "$dreg"="d14" 736 _DRegList SETS "d8-d14" 737 _RBytes SETA _RBytes+56 738 MEXIT 739 ENDIF 740 IF "$dreg"="d15" 741 _DRegList SETS "d8-d15" 742 _RBytes SETA _RBytes+64 743 MEXIT 744 ENDIF 745 INFO 1, "Unrecognized saved d register limit '$dreg'" 746 MEND 747 748 ;// Produce function return instructions 749 MACRO 750 _M_RET $cc 751 IF _DRegList<>"" 752 VPOP$cc {$_DRegList} 753 ENDIF 754 IF _RRegList="" 755 BX$cc lr 756 ELSE 757 LDM$cc.FD sp!, {$_RRegList, pc} 758 ENDIF 759 MEND 760 761 ;// Early Function Exit Macro 762 ;// $cc = condition to exit with 763 ;// (Example: M_EXIT EQ) 764 MACRO 765 M_EXIT $cc 766 ASSERT _InFunc 767 IF _SBytes!=0 768 ;// Restore stack frame and exit 769 B$cc _End$_F 770 ELSE 771 ;// Can return directly 772 _M_RET $cc 773 ENDIF 774 MEND 775 776 ;// Function Footer Macro 777 ;// Generates the function epilogue 778 MACRO 779 M_END 780 ASSERT _InFunc 781 _InFunc SETL {FALSE} 782 _End$_F 783 784 ;// Restore the stack pointer to its original value on function entry 785 IF _SBytes!=0 786 _M_OPC ADD, sp, sp, _SBytes 787 ENDIF 788 _M_RET 789 ENDFUNC 790 791 ;// Reset the global stack tracking variables back to their 792 ;// initial values, and increment the function count 793 _SBytes SETA 0 794 _F SETA _F+1 795 MEND 796 797 798 ;//========================================================================== 799 ;// Debug Macros 800 ;//========================================================================== 801 802 GBLL DEBUG_ON 803 DEBUG_ON SETL {FALSE} 804 GBLL DEBUG_STALLS_ON 805 DEBUG_STALLS_ON SETL {FALSE} 806 807 ;//========================================================================== 808 ;// Debug call to printf 809 ;// M_PRINTF $format, $val0, $val1, $val2 810 ;// 811 ;// Examples: 812 ;// M_PRINTF "x=%08x\n", r0 813 ;// 814 ;// This macro preserves the value of all registers including the 815 ;// flags. 816 ;//========================================================================== 817 818 MACRO 819 M_PRINTF $format, $val0, $val1, $val2 820 IF DEBUG_ON 821 822 IMPORT printf 823 LCLA nArgs 824 nArgs SETA 0 825 826 ;// save registers so we don't corrupt them 827 STMFD sp!, {r0-r12, lr} 828 829 ;// Drop stack to give us some workspace 830 SUB sp, sp, #16 831 832 ;// Save registers we need to print to the stack 833 IF "$val2" <> "" 834 ASSERT "$val1" <> "" 835 STR $val2, [sp, #8] 836 nArgs SETA nArgs+1 837 ENDIF 838 IF "$val1" <> "" 839 ASSERT "$val0" <> "" 840 STR $val1, [sp, #4] 841 nArgs SETA nArgs+1 842 ENDIF 843 IF "$val0"<>"" 844 STR $val0, [sp] 845 nArgs SETA nArgs+1 846 ENDIF 847 848 ;// Now we are safe to corrupt registers 849 ADR r0, %FT00 850 IF nArgs=1 851 LDR r1, [sp] 852 ENDIF 853 IF nArgs=2 854 LDMIA sp, {r1,r2} 855 ENDIF 856 IF nArgs=3 857 LDMIA sp, {r1,r2,r3} 858 ENDIF 859 860 ;// print the values 861 MRS r4, cpsr ;// preserve flags 862 BL printf 863 MSR cpsr_f, r4 ;// restore flags 864 B %FT01 865 00 ;// string to print 866 DCB "$format", 0 867 ALIGN 868 01 ;// Finished 869 ADD sp, sp, #16 870 ;// Restore registers 871 LDMFD sp!, {r0-r12,lr} 872 873 ENDIF ;// DEBUG_ON 874 MEND 875 876 877 ;// Stall Simulation Macro 878 ;// Inserts a given number of NOPs for the currently 879 ;// defined platform 880 MACRO 881 M_STALL $plat1stall, $plat2stall, $plat3stall, $plat4stall, $plat5stall, $plat6stall 882 IF DEBUG_STALLS_ON 883 _M_STALL_SUB $plat1stall 884 _M_STALL_SUB $plat2stall 885 _M_STALL_SUB $plat3stall 886 _M_STALL_SUB $plat4stall 887 _M_STALL_SUB $plat5stall 888 _M_STALL_SUB $plat6stall 889 ENDIF 890 MEND 891 892 MACRO 893 _M_STALL_SUB $platstall 894 IF "$platstall"!="" 895 LCLA _pllen 896 LCLS _pl 897 LCLL _pllog 898 _pllen SETA :LEN:"$platstall" 899 _pl SETS "$platstall":LEFT:(_pllen - 2) 900 IF :DEF:$_pl 901 IF $_pl 902 LCLS _st 903 LCLA _stnum 904 _st SETS "$platstall":RIGHT:1 905 _stnum SETA $_st 906 WHILE _stnum>0 907 MOV sp, sp 908 _stnum SETA _stnum - 1 909 WEND 910 ENDIF 911 ENDIF 912 ENDIF 913 MEND 914 915 916 917 ;//========================================================================== 918 ;// Endian Invarience Macros 919 ;// 920 ;// The idea behind these macros is that if an array is 921 ;// loaded as words then the SMUL00 macro will multiply 922 ;// array elements 0 regardless of the endianess of the 923 ;// system. For little endian SMUL00=SMULBB, for big 924 ;// endian SMUL00=SMULTT and similarly for other packed operations. 925 ;// 926 ;//========================================================================== 927 928 MACRO 929 LIBI4 $comli, $combi, $a, $b, $c, $d, $cc 930 IF {ENDIAN}="big" 931 $combi.$cc $a, $b, $c, $d 932 ELSE 933 $comli.$cc $a, $b, $c, $d 934 ENDIF 935 MEND 936 937 MACRO 938 LIBI3 $comli, $combi, $a, $b, $c, $cc 939 IF {ENDIAN}="big" 940 $combi.$cc $a, $b, $c 941 ELSE 942 $comli.$cc $a, $b, $c 943 ENDIF 944 MEND 945 946 ;// SMLAxy macros 947 948 MACRO 949 SMLA00 $a, $b, $c, $d, $cc 950 LIBI4 SMLABB, SMLATT, $a, $b, $c, $d, $cc 951 MEND 952 953 MACRO 954 SMLA01 $a, $b, $c, $d, $cc 955 LIBI4 SMLABT, SMLATB, $a, $b, $c, $d, $cc 956 MEND 957 958 MACRO 959 SMLA0B $a, $b, $c, $d, $cc 960 LIBI4 SMLABB, SMLATB, $a, $b, $c, $d, $cc 961 MEND 962 963 MACRO 964 SMLA0T $a, $b, $c, $d, $cc 965 LIBI4 SMLABT, SMLATT, $a, $b, $c, $d, $cc 966 MEND 967 968 MACRO 969 SMLA10 $a, $b, $c, $d, $cc 970 LIBI4 SMLATB, SMLABT, $a, $b, $c, $d, $cc 971 MEND 972 973 MACRO 974 SMLA11 $a, $b, $c, $d, $cc 975 LIBI4 SMLATT, SMLABB, $a, $b, $c, $d, $cc 976 MEND 977 978 MACRO 979 SMLA1B $a, $b, $c, $d, $cc 980 LIBI4 SMLATB, SMLABB, $a, $b, $c, $d, $cc 981 MEND 982 983 MACRO 984 SMLA1T $a, $b, $c, $d, $cc 985 LIBI4 SMLATT, SMLABT, $a, $b, $c, $d, $cc 986 MEND 987 988 MACRO 989 SMLAB0 $a, $b, $c, $d, $cc 990 LIBI4 SMLABB, SMLABT, $a, $b, $c, $d, $cc 991 MEND 992 993 MACRO 994 SMLAB1 $a, $b, $c, $d, $cc 995 LIBI4 SMLABT, SMLABB, $a, $b, $c, $d, $cc 996 MEND 997 998 MACRO 999 SMLAT0 $a, $b, $c, $d, $cc 1000 LIBI4 SMLATB, SMLATT, $a, $b, $c, $d, $cc 1001 MEND 1002 1003 MACRO 1004 SMLAT1 $a, $b, $c, $d, $cc 1005 LIBI4 SMLATT, SMLATB, $a, $b, $c, $d, $cc 1006 MEND 1007 1008 ;// SMULxy macros 1009 1010 MACRO 1011 SMUL00 $a, $b, $c, $cc 1012 LIBI3 SMULBB, SMULTT, $a, $b, $c, $cc 1013 MEND 1014 1015 MACRO 1016 SMUL01 $a, $b, $c, $cc 1017 LIBI3 SMULBT, SMULTB, $a, $b, $c, $cc 1018 MEND 1019 1020 MACRO 1021 SMUL0B $a, $b, $c, $cc 1022 LIBI3 SMULBB, SMULTB, $a, $b, $c, $cc 1023 MEND 1024 1025 MACRO 1026 SMUL0T $a, $b, $c, $cc 1027 LIBI3 SMULBT, SMULTT, $a, $b, $c, $cc 1028 MEND 1029 1030 MACRO 1031 SMUL10 $a, $b, $c, $cc 1032 LIBI3 SMULTB, SMULBT, $a, $b, $c, $cc 1033 MEND 1034 1035 MACRO 1036 SMUL11 $a, $b, $c, $cc 1037 LIBI3 SMULTT, SMULBB, $a, $b, $c, $cc 1038 MEND 1039 1040 MACRO 1041 SMUL1B $a, $b, $c, $cc 1042 LIBI3 SMULTB, SMULBB, $a, $b, $c, $cc 1043 MEND 1044 1045 MACRO 1046 SMUL1T $a, $b, $c, $cc 1047 LIBI3 SMULTT, SMULBT, $a, $b, $c, $cc 1048 MEND 1049 1050 MACRO 1051 SMULB0 $a, $b, $c, $cc 1052 LIBI3 SMULBB, SMULBT, $a, $b, $c, $cc 1053 MEND 1054 1055 MACRO 1056 SMULB1 $a, $b, $c, $cc 1057 LIBI3 SMULBT, SMULBB, $a, $b, $c, $cc 1058 MEND 1059 1060 MACRO 1061 SMULT0 $a, $b, $c, $cc 1062 LIBI3 SMULTB, SMULTT, $a, $b, $c, $cc 1063 MEND 1064 1065 MACRO 1066 SMULT1 $a, $b, $c, $cc 1067 LIBI3 SMULTT, SMULTB, $a, $b, $c, $cc 1068 MEND 1069 1070 ;// SMLAWx, SMULWx macros 1071 1072 MACRO 1073 SMLAW0 $a, $b, $c, $d, $cc 1074 LIBI4 SMLAWB, SMLAWT, $a, $b, $c, $d, $cc 1075 MEND 1076 1077 MACRO 1078 SMLAW1 $a, $b, $c, $d, $cc 1079 LIBI4 SMLAWT, SMLAWB, $a, $b, $c, $d, $cc 1080 MEND 1081 1082 MACRO 1083 SMULW0 $a, $b, $c, $cc 1084 LIBI3 SMULWB, SMULWT, $a, $b, $c, $cc 1085 MEND 1086 1087 MACRO 1088 SMULW1 $a, $b, $c, $cc 1089 LIBI3 SMULWT, SMULWB, $a, $b, $c, $cc 1090 MEND 1091 1092 ;// SMLALxy macros 1093 1094 1095 MACRO 1096 SMLAL00 $a, $b, $c, $d, $cc 1097 LIBI4 SMLALBB, SMLALTT, $a, $b, $c, $d, $cc 1098 MEND 1099 1100 MACRO 1101 SMLAL01 $a, $b, $c, $d, $cc 1102 LIBI4 SMLALBT, SMLALTB, $a, $b, $c, $d, $cc 1103 MEND 1104 1105 MACRO 1106 SMLAL0B $a, $b, $c, $d, $cc 1107 LIBI4 SMLALBB, SMLALTB, $a, $b, $c, $d, $cc 1108 MEND 1109 1110 MACRO 1111 SMLAL0T $a, $b, $c, $d, $cc 1112 LIBI4 SMLALBT, SMLALTT, $a, $b, $c, $d, $cc 1113 MEND 1114 1115 MACRO 1116 SMLAL10 $a, $b, $c, $d, $cc 1117 LIBI4 SMLALTB, SMLALBT, $a, $b, $c, $d, $cc 1118 MEND 1119 1120 MACRO 1121 SMLAL11 $a, $b, $c, $d, $cc 1122 LIBI4 SMLALTT, SMLALBB, $a, $b, $c, $d, $cc 1123 MEND 1124 1125 MACRO 1126 SMLAL1B $a, $b, $c, $d, $cc 1127 LIBI4 SMLALTB, SMLALBB, $a, $b, $c, $d, $cc 1128 MEND 1129 1130 MACRO 1131 SMLAL1T $a, $b, $c, $d, $cc 1132 LIBI4 SMLALTT, SMLALBT, $a, $b, $c, $d, $cc 1133 MEND 1134 1135 MACRO 1136 SMLALB0 $a, $b, $c, $d, $cc 1137 LIBI4 SMLALBB, SMLALBT, $a, $b, $c, $d, $cc 1138 MEND 1139 1140 MACRO 1141 SMLALB1 $a, $b, $c, $d, $cc 1142 LIBI4 SMLALBT, SMLALBB, $a, $b, $c, $d, $cc 1143 MEND 1144 1145 MACRO 1146 SMLALT0 $a, $b, $c, $d, $cc 1147 LIBI4 SMLALTB, SMLALTT, $a, $b, $c, $d, $cc 1148 MEND 1149 1150 MACRO 1151 SMLALT1 $a, $b, $c, $d, $cc 1152 LIBI4 SMLALTT, SMLALTB, $a, $b, $c, $d, $cc 1153 MEND 1154 1155 ENDIF ;// ARMCOMM_S_H 1156 1157 END 1158