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