1# gr28-gr31, fr31, icc3, fcc3 are used as tmps. 2# consider them call clobbered by these macros. 3 4 .macro start 5 .data 6failmsg: 7 .ascii "fail\n" 8passmsg: 9 .ascii "pass\n" 10 .text 11 .global _start 12_start: 13 ; enable data and insn caches in copy-back mode 14 ; Also enable all registers 15 or_spr_immed 0xc80003c0,hsr0 16 and_spr_immed 0xfffff3ff,hsr0 17 18 ; turn on psr.nem, psr.cm, psr.ef, psr.em, psr.esr, 19 ; disable external interrupts 20 or_spr_immed 0x69f8,psr 21 22 ; If fsr exists, enable all fp_exceptions except inexact 23 movsg psr,gr28 24 srli gr28,28,gr28 25 subicc gr28,0x2,gr0,icc3 ; is fr400? 26 beq icc3,0,nofsr0 27 or_spr_immed 0x3d000000,fsr0 28nofsr0: 29 30 ; Set the stack pointer 31 sethi.p 0x7,sp 32 setlo 0xfffc,sp ; TODO -- what's a good value for this? 33 34 ; Set the TBR address 35 sethi.p 0xf,gr28 36 setlo 0xf000,gr28 37 movgs gr28,tbr ; TODO -- what's a good value for this? 38 39 ; Go to user mode -- causes too many problems 40 ;and_spr_immed 0xfffffffb,psr 41 .endm 42 43; Set GR with another GR 44 .macro set_gr_gr src targ 45 addi \src,0,\targ 46 .endm 47 48; Set GR with immediate value 49 .macro set_gr_immed val reg 50 .if (\val >= -32768) && (\val <= 23767) 51 setlos \val,\reg 52 .else 53 setlo.p %lo(\val),\reg 54 sethi %hi(\val),\reg 55 .endif 56 .endm 57 58 .macro set_gr_limmed valh vall reg 59 sethi.p \valh,\reg 60 setlo \vall,\reg 61 .endm 62 63; Set GR with address value 64 .macro set_gr_addr addr reg 65 sethi.p %hi(\addr),\reg 66 setlo %lo(\addr),\reg 67 .endm 68 69; Set GR with SPR 70 .macro set_gr_spr src targ 71 movsg \src,\targ 72 .endm 73 74; Set GR with a value from memory 75 .macro set_gr_mem addr reg 76 set_gr_addr \addr,gr28 77 ldi @(gr28,0),\reg 78 .endm 79 80; Increment GR with immediate value 81 .macro inc_gr_immed val reg 82 .if (\val >= -2048) && (\val <= 2047) 83 addi \reg,\val,\reg 84 .else 85 set_gr_immed \val,gr28 86 add \reg,gr28,\reg 87 .endif 88 .endm 89 90; AND GR with immediate value 91 .macro and_gr_immed val reg 92 .if (\val >= -2048) && (\val <= 2047) 93 andi \reg,\val,\reg 94 .else 95 set_gr_immed \val,gr28 96 and \reg,gr28,\reg 97 .endif 98 .endm 99 100; OR GR with immediate value 101 .macro or_gr_immed val reg 102 .if (\val >= -2048) && (\val <= 2047) 103 ori \reg,\val,\reg 104 .else 105 set_gr_immed \val,gr28 106 or \reg,gr28,\reg 107 .endif 108 .endm 109 110; Set FR with another FR 111 .macro set_fr_fr src targ 112 fmovs \src,\targ 113 .endm 114 115; Set FR with integer immediate value 116 .macro set_fr_iimmed valh vall reg 117 set_gr_limmed \valh,\vall,gr28 118 movgf gr28,\reg 119 .endm 120 121; Set FR with integer immediate value 122 .macro set_fr_immed val reg 123 set_gr_immed \val,gr28 124 movgf gr28,\reg 125 .endm 126 127; Set FR with a value from memory 128 .macro set_fr_mem addr reg 129 set_gr_addr \addr,gr28 130 ldfi @(gr28,0),\reg 131 .endm 132 133; Set double FR with another double FR 134 .macro set_dfr_dfr src targ 135 fmovd \src,\targ 136 .endm 137 138; Set double FR with a value from memory 139 .macro set_dfr_mem addr reg 140 set_gr_addr \addr,gr28 141 lddfi @(gr28,0),\reg 142 .endm 143 144; Set CPR with immediate value 145 .macro set_cpr_immed val reg 146 addi sp,-4,gr28 147 set_gr_immed \val,gr29 148 st gr29,@(gr28,gr0) 149 ldc @(gr28,gr0),\reg 150 .endm 151 152 .macro set_cpr_limmed valh vall reg 153 addi sp,-4,gr28 154 set_gr_limmed \valh,\vall,gr29 155 st gr29,@(gr28,gr0) 156 ldc @(gr28,gr0),\reg 157 .endm 158 159; Set SPR with immediate value 160 .macro set_spr_immed val reg 161 set_gr_immed \val,gr28 162 movgs gr28,\reg 163 .endm 164 165 .macro set_spr_limmed valh vall reg 166 set_gr_limmed \valh,\vall,gr28 167 movgs gr28,\reg 168 .endm 169 170 .macro set_spr_addr addr reg 171 set_gr_addr \addr,gr28 172 movgs gr28,\reg 173 .endm 174 175; increment SPR with immediate value 176 .macro inc_spr_immed val reg 177 movsg \reg,gr28 178 inc_gr_immed \val,gr28 179 movgs gr28,\reg 180 .endm 181 182; OR spr with immediate value 183 .macro or_spr_immed val reg 184 movsg \reg,gr28 185 set_gr_immed \val,gr29 186 or gr28,gr29,gr28 187 movgs gr28,\reg 188 .endm 189 190; AND spr with immediate value 191 .macro and_spr_immed val reg 192 movsg \reg,gr28 193 set_gr_immed \val,gr29 194 and gr28,gr29,gr28 195 movgs gr28,\reg 196 .endm 197 198; Set accumulator with immediate value 199 .macro set_acc_immed val reg 200 set_fr_immed \val,fr31 201 mwtacc fr31,\reg 202 .endm 203 204; Set accumulator guard with immediate value 205 .macro set_accg_immed val reg 206 set_fr_immed \val,fr31 207 mwtaccg fr31,\reg 208 .endm 209 210; Set memory with immediate value 211 .macro set_mem_immed val base 212 set_gr_immed \val,gr28 213 sti gr28,@(\base,0) 214 .endm 215 216 .macro set_mem_limmed valh vall base 217 set_gr_limmed \valh,\vall,gr28 218 sti gr28,@(\base,0) 219 .endm 220 221; Set memory with GR value 222 .macro set_mem_gr reg addr 223 set_gr_addr \addr,gr28 224 sti \reg,@(gr28,0) 225 .endm 226 227; Test the value of a general register against another general register 228 .macro test_gr_gr reg1 reg2 229 subcc \reg1,\reg2,gr0,icc3 230 beq icc3,0,test_gr\@ 231 fail 232test_gr\@: 233 .endm 234 235; Test the value of an immediate against a general register 236 .macro test_gr_immed val reg 237 .if (\val >= -512) && (\val <= 511) 238 subicc \reg,\val,gr0,icc3 239 .else 240 set_gr_immed \val,gr28 241 subcc \reg,gr28,gr0,icc3 242 .endif 243 beq icc3,0,test_gr\@ 244 fail 245test_gr\@: 246 .endm 247 248 .macro test_gr_limmed valh vall reg 249 set_gr_limmed \valh,\vall,gr28 250 subcc \reg,gr28,gr0,icc3 251 beq icc3,0,test_gr\@ 252 fail 253test_gr\@: 254 .endm 255 256; Test the value of an floating register against an integer immediate 257 .macro test_fr_limmed valh vall reg 258 movfg \reg,gr29 259 set_gr_limmed \valh,\vall,gr28 260 subcc gr29,gr28,gr0,icc3 261 beq icc3,0,test_gr\@ 262 fail 263test_gr\@: 264 .endm 265 266 .macro test_fr_iimmed val reg 267 movfg \reg,gr29 268 set_gr_immed \val,gr28 269 subcc gr29,gr28,gr0,icc3 270 beq icc3,0,test_gr\@ 271 fail 272test_gr\@: 273 .endm 274 275; Test the value of a floating register against another floating point register 276 .macro test_fr_fr reg1 reg2 277 fcmps \reg1,\reg2,fcc3 278 fbeq fcc3,0,test_gr\@ 279 fail 280test_gr\@: 281 .endm 282 283; Test the value of a double floating register against another 284; double floating point register 285 .macro test_dfr_dfr reg1 reg2 286 fcmpd \reg1,\reg2,fcc3 287 fbeq fcc3,0,test_gr\@ 288 fail 289test_gr\@: 290 .endm 291 292; Test the value of a special purpose register against an integer immediate 293 .macro test_spr_immed val reg 294 movsg \reg,gr29 295 set_gr_immed \val,gr28 296 subcc gr29,gr28,gr0,icc3 297 beq icc3,0,test_gr\@ 298 fail 299test_gr\@: 300 .endm 301 302 .macro test_spr_limmed valh vall reg 303 movsg \reg,gr29 304 set_gr_limmed \valh,\vall,gr28 305 subcc gr29,gr28,gr0,icc3 306 beq icc3,0,test_gr\@ 307 fail 308test_gr\@: 309 .endm 310 311 .macro test_spr_gr spr gr 312 movsg \spr,gr28 313 test_gr_gr \gr,gr28 314 .endm 315 316 .macro test_spr_addr addr reg 317 movsg \reg,gr29 318 set_gr_addr \addr,gr28 319 test_gr_gr gr28,gr29 320 .endm 321 322; Test spr bits masked and shifted against the given value 323 .macro test_spr_bits mask,shift,val,reg 324 movsg \reg,gr28 325 set_gr_immed \mask,gr29 326 and gr28,gr29,gr28 327 srli gr28,\shift,gr29 328 test_gr_immed \val,gr29 329 .endm 330 331 332; Test the value of an accumulator against an integer immediate 333 .macro test_acc_immed val reg 334 mrdacc \reg,fr31 335 test_fr_iimmed \val,fr31 336 .endm 337 338; Test the value of an accumulator against an integer immediate 339 .macro test_acc_limmed valh vall reg 340 mrdacc \reg,fr31 341 test_fr_limmed \valh,\vall,fr31 342 .endm 343 344; Test the value of an accumulator guard against an integer immediate 345 .macro test_accg_immed val reg 346 mrdaccg \reg,fr31 347 test_fr_iimmed \val,fr31 348 .endm 349 350; Test CPR agains an immediate value 351 .macro test_cpr_limmed valh vall reg 352 addi sp,-4,gr31 353 stc \reg,@(gr31,gr0) 354 test_mem_limmed \valh,\vall,gr31 355 .endm 356 357; Test the value of an immediate against memory 358 .macro test_mem_immed val base 359 ldi @(\base,0),gr29 360 .if (\val >= -512) && (\val <= 511) 361 subicc gr29,\val,gr0,icc3 362 .else 363 set_gr_immed \val,gr28 364 subcc gr29,gr28,gr0,icc3 365 .endif 366 beq icc3,0,test_gr\@ 367 fail 368test_gr\@: 369 .endm 370 371 .macro test_mem_limmed valh vall base 372 ldi @(\base,0),gr29 373 set_gr_limmed \valh,\vall,gr28 374 subcc gr29,gr28,gr0,icc3 375 beq icc3,0,test_gr\@ 376 fail 377test_gr\@: 378 .endm 379 380; Set an integer condition code 381 .macro set_icc mask iccno 382 set_gr_immed 4,gr29 383 smuli gr29,\iccno,gr30 384 addi gr31,16,gr31 385 set_gr_immed 0xf,gr28 386 sll gr28,gr31,gr28 387 not gr28,gr28 388 movsg ccr,gr29 389 and gr28,gr29,gr29 390 set_gr_immed \mask,gr28 391 sll gr28,gr31,gr28 392 or gr28,gr29,gr29 393 movgs gr29,ccr 394 .endm 395; started here 396; Test the condition codes 397 .macro test_icc N Z V C iccno 398 .if (\N == 1) 399 bp \iccno,0,fail\@ 400 .else 401 bn \iccno,0,fail\@ 402 .endif 403 .if (\Z == 1) 404 bne \iccno,0,fail\@ 405 .else 406 beq \iccno,0,fail\@ 407 .endif 408 .if (\V == 1) 409 bnv \iccno,0,fail\@ 410 .else 411 bv \iccno,0,fail\@ 412 .endif 413 .if (\C == 1) 414 bnc \iccno,0,fail\@ 415 .else 416 bc \iccno,0,fail\@ 417 .endif 418 bra test_cc\@ 419fail\@: 420 fail 421test_cc\@: 422 .endm 423 424; Set an floating point condition code 425 .macro set_fcc mask fccno 426 set_gr_immed 4,gr29 427 smuli gr29,\fccno,gr30 428 set_gr_immed 0xf,gr28 429 sll gr28,gr31,gr28 430 not gr28,gr28 431 movsg ccr,gr29 432 and gr28,gr29,gr29 433 set_gr_immed \mask,gr28 434 sll gr28,gr31,gr28 435 or gr28,gr29,gr29 436 movgs gr29,ccr 437 .endm 438 439; Test the condition codes 440 .macro test_fcc val fccno 441 set_gr_immed 4,gr29 442 smuli gr29,\fccno,gr30 443 movsg ccr,gr29 444 srl gr29,gr31,gr29 445 andi gr29,0xf,gr29 446 test_gr_immed \val,gr29 447 .endm 448 449; Set PSR.ET 450 .macro set_psr_et val 451 movsg psr,gr28 452 .if (\val == 1) 453 ori gr28,1,gr28 ; Turn on SPR.ET 454 .else 455 andi gr28,0xfffffffe,gr28 ; Turn off SPR.ET 456 .endif 457 movgs gr28,psr 458 .endm 459 460; Floating point constants 461 .macro float_constants 462f0: .float 0.0 463f1: .float 1.0 464f2: .float 2.0 465f3: .float 3.0 466f6: .float 6.0 467f9: .float 9.0 468fn0: .float -0.0 469fn1: .float -1.0 470finf: .long 0x7f800000 471fninf: .long 0xff800000 472fmax: .long 0x7f7fffff 473fmin: .long 0xff7fffff 474feps: .long 0x00400000 475fneps: .long 0x80400000 476fnan1: .long 0x7fc00000 477fnan2: .long 0x7f800001 478 .endm 479 480 .macro double_constants 481d0: .double 0.0 482d1: .double 1.0 483d2: .double 2.0 484d3: .double 3.0 485d6: .double 6.0 486d9: .double 9.0 487dn0: .double -0.0 488dn1: .double -1.0 489dinf: .long 0x7ff00000 490 .long 0x00000000 491dninf: .long 0xfff00000 492 .long 0x00000000 493dmax: .long 0x7fefffff 494 .long 0xffffffff 495dmin: .long 0xffefffff 496 .long 0xffffffff 497deps: .long 0x00080000 498 .long 0x00000000 499dneps: .long 0x80080000 500 .long 0x00000000 501dnan1: .long 0x7ff80000 502 .long 0x00000000 503dnan2: .long 0x7ff00000 504 .long 0x00000001 505 .endm 506 507; Load floating point constants 508 .macro load_float_constants 509 set_fr_mem fninf,fr0 510 set_fr_mem fmin,fr4 511 set_fr_mem fn1,fr8 512 set_fr_mem fneps,fr12 513 set_fr_mem fn0,fr16 514 set_fr_mem f0,fr20 515 set_fr_mem feps,fr24 516 set_fr_mem f1,fr28 517 set_fr_mem f2,fr32 518 set_fr_mem f3,fr36 519 set_fr_mem f6,fr40 520 set_fr_mem f9,fr44 521 set_fr_mem fmax,fr48 522 set_fr_mem finf,fr52 523 set_fr_mem fnan1,fr56 524 set_fr_mem fnan2,fr60 525 .endm 526 527 .macro load_float_constants1 528 set_fr_mem fninf,fr1 529 set_fr_mem fmin,fr5 530 set_fr_mem fn1,fr9 531 set_fr_mem fneps,fr13 532 set_fr_mem fn0,fr17 533 set_fr_mem f0,fr21 534 set_fr_mem feps,fr25 535 set_fr_mem f1,fr29 536 set_fr_mem f2,fr33 537 set_fr_mem f3,fr37 538 set_fr_mem f6,fr41 539 set_fr_mem f9,fr45 540 set_fr_mem fmax,fr49 541 set_fr_mem finf,fr53 542 set_fr_mem fnan1,fr57 543 set_fr_mem fnan2,fr61 544 .endm 545 546 .macro load_float_constants2 547 set_fr_mem fninf,fr2 548 set_fr_mem fmin,fr6 549 set_fr_mem fn1,fr10 550 set_fr_mem fneps,fr14 551 set_fr_mem fn0,fr18 552 set_fr_mem f0,fr22 553 set_fr_mem feps,fr26 554 set_fr_mem f1,fr30 555 set_fr_mem f2,fr34 556 set_fr_mem f3,fr38 557 set_fr_mem f6,fr42 558 set_fr_mem f9,fr46 559 set_fr_mem fmax,fr50 560 set_fr_mem finf,fr54 561 set_fr_mem fnan1,fr58 562 set_fr_mem fnan2,fr62 563 .endm 564 565 .macro load_float_constants3 566 set_fr_mem fninf,fr3 567 set_fr_mem fmin,fr7 568 set_fr_mem fn1,fr11 569 set_fr_mem fneps,fr15 570 set_fr_mem fn0,fr19 571 set_fr_mem f0,fr23 572 set_fr_mem feps,fr27 573 set_fr_mem f1,fr31 574 set_fr_mem f2,fr35 575 set_fr_mem f3,fr39 576 set_fr_mem f6,fr43 577 set_fr_mem f9,fr47 578 set_fr_mem fmax,fr51 579 set_fr_mem finf,fr55 580 set_fr_mem fnan1,fr59 581 set_fr_mem fnan2,fr63 582 .endm 583 584 .macro load_double_constants 585 set_dfr_mem dninf,fr0 586 set_dfr_mem dmin,fr4 587 set_dfr_mem dn1,fr8 588 set_dfr_mem dneps,fr12 589 set_dfr_mem dn0,fr16 590 set_dfr_mem d0,fr20 591 set_dfr_mem deps,fr24 592 set_dfr_mem d1,fr28 593 set_dfr_mem d2,fr32 594 set_dfr_mem d3,fr36 595 set_dfr_mem d6,fr40 596 set_dfr_mem d9,fr44 597 set_dfr_mem dmax,fr48 598 set_dfr_mem dinf,fr52 599 set_dfr_mem dnan1,fr56 600 set_dfr_mem dnan2,fr60 601 .endm 602 603; Lock the insn cache at the given address 604 .macro lock_insn_cache address 605 icpl \address,gr0,1 606 .endm 607 608; Lock the data cache at the given address 609 .macro lock_data_cache address 610 dcpl \address,gr0,1 611 .endm 612 613; Invalidate the data cache at the given address 614 .macro invalidate_data_cache address 615 dci @(\address,gr0) 616 .endm 617 618; Flush the data cache at the given address 619 .macro flush_data_cache address 620 dcf @(\address,gr0) 621 .endm 622 623; Write a bctrlr 0,0 insn at the address contained in the given register 624 .macro set_bctrlr_0_0 address 625 set_mem_immed 0x80382000,\address ; bctrlr 0,0 626 flush_data_cache \address 627 .endm 628 629; Exit with return code 630 .macro exit rc 631 setlos #1,gr7 632 set_gr_immed \rc,gr8 633 tira gr0,#0 634 .endm 635 636; Pass the test case 637 .macro pass 638pass\@: 639 setlos.p #5,gr10 640 setlos #1,gr8 641 setlos #5,gr7 642 set_gr_addr passmsg,gr9 643 tira gr0,#0 644 exit #0 645 .endm 646 647; Fail the testcase 648 .macro fail 649fail\@: 650 setlos.p #5,gr10 651 setlos #1,gr8 652 setlos #5,gr7 653 set_gr_addr failmsg,gr9 654 tira gr0,#0 655 exit #1 656 .endm 657