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