fpu_test64.s revision 6491:448e02e63395
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29! Usage of %ncc 30! 31! When the branch instructions were modified from Bicc to BPcc format, 32! the pseudo-op %ncc was used. This will be converted by the assembler 33! to %icc or %xcc depending on whether the compilation is being done 34! for 32-bit or 64-bit platforms. 35 36 37#include<sys/asm_linkage.h> 38 39 40!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 41! Name: datap_add() 42! Function: This routine test the data path of the adder for single 43! precision. 44! Calling: i0 = value 45! Returns: 46! Convention: 47!-------------------------------------------------------------------------- 48! 49! f0 = value 50! f1 = 0 51! add = f2 = value 52! 53 .section ".data" 54 .align 4 55 56.Ldadd: 57 .skip 4 58.Ldadd1: 59 .skip 4 60 61ENTRY_NP(datap_add) 62 save %sp, -SA(MINFRAME), %sp ! save the stack frame 63 setn .Ldadd,%l6,%l0 ! get a memory address 64 setn .Ldadd1,%l6,%l1 ! .. one for the result 65 mov %g0,%l3 ! .. get a zero 66 st %l3, [%l1] ! .... and store it in memory 67 st %i0, [%l0] ! .... store the value passed 68 ld [%l0], %f0 ! .... put the passed value into f0 69 ld [%l1], %f1 ! .... put value 0 into reg f1 70 fadds %f0, %f1, %f2 ! ...... add zero and value into f2 71 fcmps %fcc0, %f0, %f2 ! .... check the value passed and added value 72 fbe,a %fcc0, datap_ok ! .. if they are equal 73 nop ! .... delay 74 75 st %f2, [%l1] ! return the result on error 76 77datap_ok: 78 ld [%l1], %i0 ! then return a zero 79 ret ! .... delay 80 restore 81SET_SIZE(datap_add) 82 83 84!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 85! Name: 86! Function: 87! Calling: 88! Returns: 89! Convention: 90!-------------------------------------------------------------------------- 91! 92! This routine test the data path of multiplier for single precision 93! f0 = value 94! f1 = 1 95! mult = f2 = f0 * f1 96! 97 .section ".data" 98 .align 4 99 100.Ldtmlt: 101 .skip 4 102.Ldtmlt1: 103 .skip 4 104 105ENTRY_NP(datap_mult) 106 save %sp, -SA(MINFRAME), %sp 107 setn .Ldtmlt,%l6,%l0 108 setn .Ldtmlt1,%l6,%l1 109 setn 0x3F800000,%l6,%l3 ! put value 1 into memory 110 st %l3, [%l1] 111 st %i0, [%l0] ! store the value passed into memory location 112 ld [%l0], %f0 ! put the passed value into f0 113 ld [%l1], %f1 ! put value 1 into reg f1 114 fmuls %f0, %f1, %f2 ! multiply value with 1 , it has to be same 115 fcmps %fcc0, %f0, %f2 116 117 fbne,a %fcc0, datap_mult_done 118 st %f2, [%l1] ! executed only when the conditional 119 ! branch is taken as annul bit is set. 120 ! This branch will be taken under 121 ! an error condition (%f0 != %f2). 122 ! Then we need to return the result. 123 124 mov %g0,%l3 125 st %l3, [%l1] 126 127datap_mult_done : 128 ld [%l1], %i0 129 ret 130 restore 131SET_SIZE(datap_mult) 132 133 134!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 135! Name: 136! Function: 137! Calling: 138! Returns: 139! Convention: 140!-------------------------------------------------------------------------- 141! 142! This routine tests the data path of the weitek multiplier for 143! double precision. Single-precision load and store are being 144! used as the input double-precision value is taken as two SP 145! arguments 146! 147! f0 = msw value 148! f1 = lsw value 149! f2 = 0 150! f3 = 0 151! add = f4 = f0 + f2 152! 153 .section ".data" 154 .align 8 155 156.Ldtadddp: 157 .skip 8 158.Ldtadddp1: 159 .skip 8 160.Ldtadddp2: 161 .skip 8 162.Lamsw: 163 .skip 8 164.Lalsw: 165 .skip 8 166 167ENTRY_NP(datap_add_dp) 168 save %sp, -SA(MINFRAME), %sp 169 setn .Ldtadddp,%l6,%l0 170 setn .Ldtadddp1,%l6,%l1 171 setn .Ldtadddp2,%l6,%l2 172 setn .Lamsw,%l6,%l4 173 setn .Lalsw,%l6,%l5 174 mov %g0,%l3 ! put value 0 into memory 175 st %l3, [%l1] 176 st %i0, [%l0] ! msw of value 177 st %i1, [%l2] ! lsw of value 178 ld [%l0], %f0 ! put the msw into f0 179 ld [%l2], %f1 ! put the lsw into f1 180 ld [%l1], %f2 ! put 0 into f2 181 ld [%l1], %f3 ! put 0 into f3 182 faddd %f0, %f2, %f4 ! add value + 0 into f4 183 fcmpd %fcc0, %f0, %f4 ! now compare the result 184 185 fbe,a %fcc0, datap_add_dp_ok ! good 186 nop 187 188 mov 0x1,%l3 189 st %l3, [%l1] 190 191datap_add_dp_ok : 192 ld [%l1], %i0 193 ret 194 restore 195 196SET_SIZE(datap_add_dp) 197 198!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 199! Name: 200! Function: 201! Calling: 202! Returns: 203! Convention: 204!-------------------------------------------------------------------------- 205! 206! This routine tests the data path of the weitek multiplier for 207! double precision. Single-precision load and store are being 208! used as the input double-precision value is taken as two SP 209! arguments. 210! 211! f0 = msw value 212! f1 = lsw value 213! f2 = 0 214! f3 = 0 215! mult = f4 = f0 * f2 216! 217 .section ".data" 218 .align 8 219 220.Ldtmdp: 221 .skip 8 222.Ldtmdp1: 223 .skip 8 224.Ldtmdp2: 225 .skip 8 226.Lmmsw: 227 .skip 8 228.Lmlsw: 229 .skip 8 230 231ENTRY_NP(datap_mult_dp) 232 save %sp, -SA(MINFRAME), %sp 233 setn .Ldtmdp,%l6,%l0 234 setn .Ldtmdp1,%l6,%l1 235 setn .Ldtmdp2,%l6,%l2 236 setn .Lmmsw,%l6,%l4 237 setn .Lmlsw,%l6,%l5 238 setn 0x3FF00000,%l6,%l3 ! put msw value of DP 1 into memory 239 st %l3, [%l1] 240 st %i0, [%l0] ! msw of value 241 st %i1, [%l2] ! lsw of value 242 ld [%l0], %f0 ! put the msw into f0 243 ld [%l2], %f1 ! put the lsw into f1 244 ld [%l1], %f2 ! put msw of DP 1 into f2 245 mov %g0,%l3 246 st %l3, [%l1] 247 ld [%l1], %f3 ! put 0 into f3, i.e f2|f3 = 0x3ff0000000000000 (dp 1) 248 fmuld %f0, %f2, %f4 ! mult value * 1 into f4 249 fcmpd %fcc0, %f0, %f4 ! now compare the result 250 251 fbe,a %fcc0, datap_mult_dp_ok ! good 252 nop 253 254 mov 0x1,%l3 255 st %l3, [%l1] 256 257datap_mult_dp_ok : 258 ld [%l1], %i0 259 ret 260 restore 261 262SET_SIZE(datap_mult_dp) 263 264! 265! for add routine all the f registers from 0 - 19 will be filled with numbers 266! and the result should be 10. 267! 268 269 .section ".data" 270 .align 4 271 272.Ltmasp: 273 .skip 4 274.Ltmasp1: 275 .skip 4 276.Ltmasp2: 277 .skip 4 278 279ENTRY_NP(timing_add_sp) 280 save %sp, -SA(MINFRAME), %sp ! save the registers, stacck 281 setn .Ltmasp,%l6,%l0 282 setn .Ltmasp1,%l6,%l1 283 setn .Ltmasp2,%l6,%l2 284 mov %g0,%l3 285 setn 0x3f800000,%l6,%l4 ! put value 1 286 setn 0x41200000,%l6,%l5 ! put value 10 into local 5 287 st %l5, [%l0] 288 st %l4, [%l1] 289 st %l3, [%l2] 290 ld [%l0], %f31 ! register 31 has 10 291 ld [%l1], %f30 ! register 30 has 1 292 293 ld [%l2], %f0 ! reg 0 has 0 294 fmovs %f31, %f1 ! reg1 has 10 295 fsubs %f31, %f30, %f18 ! reg 18 has 9 296 fmovs %f18, %f3 ! reg 3 has 9 297 fmovs %f30, %f2 ! reg 2 has 1 298 fmovs %f30, %f19 ! reg 19 has 1 299 fsubs %f18, %f19, %f16 ! reg 16 has 8 300 fmovs %f16, %f5 ! reg 5 has 8 301 fsubs %f31, %f16, %f17 ! reg 17 has 2 302 fmovs %f17, %f4 ! reg 4 has 2 303 fsubs %f16, %f30, %f14 ! reg 14 has 7 304 fmovs %f14, %f7 ! reg 7 has 7 305 fsubs %f31, %f14, %f15 ! reg 15 has 3 306 fmovs %f15, %f6 ! reg 6 has 3 307 fsubs %f14, %f30, %f12 ! reg 12 has 6 308 fmovs %f12, %f9 ! reg 9 has 6 309 fsubs %f31, %f12, %f13 ! reg 13 has 4 310 fmovs %f13, %f8 ! reg 8 has 4 311 fsubs %f12, %f30, %f10 ! reg 10 has 5 312 fmovs %f10, %f11 ! reg 11 has 5 313 314 fadds %f0, %f1, %f20 ! reg 0 + reg 1 = reg 20 = 10 315 fadds %f2, %f3, %f21 ! reg 2 + reg 3 = reg 21 = 10 316 fadds %f4, %f5, %f22 ! reg 4 + reg 5 = reg 22 = 10 317 fadds %f6, %f7, %f23 ! reg 6 + reg 7 = reg 23 = 10 318 fadds %f8, %f9, %f24 ! reg 8 + reg 9 = reg 24 = 10 319 fadds %f10, %f11, %f25 ! reg 10 + reg 11 = reg 25 = 10 320 fadds %f12, %f13, %f26 ! reg 12 + reg 13 = reg 26 = 10 321 fadds %f14, %f15, %f27 ! reg 14 + reg 15 = reg 27 = 10 322 fadds %f16, %f17, %f28 ! reg 16 + reg 17 = reg 28 = 10 323 fadds %f18, %f19, %f29 ! reg 18 + reg 19 = reg 29 = 10 324 325 ! Now additions are done check it out 326 fcmps %fcc0, %f31, %f20 327 fbne,a,pn %fcc0, done_t_add_sp ! If not equal, go to the end. 328 st %f20, [%l2] ! Executed only when the conditional 329 ! branch is taken as annul bit is set. 330 ! This branch will be taken under 331 ! an error condition. 332 333 ! No errors. Move on to the next register 334 335 fcmps %fcc0, %f31, %f21 336 fbne,a,pn %fcc0, done_t_add_sp 337 st %f21, [%l2] 338 339 340 fcmps %fcc0, %f31, %f22 341 fbne,a,pn %fcc0, done_t_add_sp 342 st %f22, [%l2] 343 344 345 fcmps %fcc0, %f31, %f23 346 fbne,a,pn %fcc0, done_t_add_sp 347 st %f23, [%l2] 348 349 350 fcmps %fcc0, %f31, %f24 351 fbne,a,pn %fcc0, done_t_add_sp 352 st %f24, [%l2] 353 354 355 fcmps %fcc0, %f31, %f25 356 fbne,a,pn %fcc0, done_t_add_sp 357 st %f25, [%l2] 358 359 360 fcmps %fcc0, %f31, %f26 361 fbne,a,pn %fcc0, done_t_add_sp 362 st %f26, [%l2] 363 364 365 fcmps %fcc0, %f31, %f27 366 fbne,a,pn %fcc0, done_t_add_sp 367 st %f27, [%l2] 368 369 370 fcmps %fcc0, %f31, %f28 371 fbne,a,pn %fcc0, done_t_add_sp 372 st %f28, [%l2] 373 374 375 ! Though this is the last set of compare instructions 376 ! we cannot fall through as the store needs to be done 377 ! only when the registers are not equal. That is why 378 ! we need the unconditional branch with the annul bit set. 379 fcmps %fcc0, %f31, %f29 380 fbne,a,pn %fcc0, done_t_add_sp 381 st %f29, [%l2] 382 383done_t_add_sp: 384 ld [%l2], %i0 385 ret 386 restore 387SET_SIZE(timing_add_sp) 388 389! 390! for mult routine all the f registers from 0 - 19 will be filled 391! with numbers and the result should be the number. 392! 393 .section ".data" 394 .align 4 395 396.Ltmmsp: 397 .skip 4 398.Ltmmsp1: 399 .skip 4 400.Ltmmsp2: 401 .skip 4 402 403ENTRY_NP(timing_mult_sp) 404 save %sp, -SA(MINFRAME), %sp ! save the registers, stacck 405 setn .Ltmmsp,%l6, %l0 406 setn .Ltmmsp1,%l6, %l1 407 setn .Ltmmsp2,%l6, %l2 408 mov %g0, %l3 409 setn 0x3f800000,%l6, %l4 ! put value 1 410 setn 0x41200000,%l6, %l5 ! put value 10 into local 5 411 st %l5, [%l0] 412 st %l4, [%l1] 413 st %l3, [%l2] 414 ld [%l0], %f31 ! register 31 has 10 415 ld [%l1], %f1 ! register 1 has 1 416 fmovs %f1, %f3 417 fmovs %f1, %f5 418 fmovs %f1, %f7 419 fmovs %f1, %f9 420 fmovs %f1, %f11 ! register 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 421 fmovs %f1, %f13 ! has a value of 1 422 fmovs %f1, %f15 423 fmovs %f1, %f17 424 fmovs %f1, %f19 ! 425 fmovs %f1, %f0 426 fmovs %f31, %f18 ! reg 18 has 10 427 fsubs %f31, %f0, %f16 ! reg 16 has 9 428 fsubs %f16, %f0, %f14 ! reg 14 has 8 429 fsubs %f14, %f0, %f12 ! reg 12 has 7 430 fsubs %f12, %f0, %f10 ! reg 10 has 6 431 fsubs %f10, %f0, %f8 ! reg 8 has 5 432 fsubs %f8, %f0, %f6 ! reg 6 has 4 433 fsubs %f6, %f0, %f4 ! reg 4 has 3 434 fsubs %f4, %f0, %f2 ! reg 2 has 2 435 436 fmuls %f0, %f1, %f20 ! reg 0 * reg 1 = reg 20 = 1 437 fmuls %f2, %f3, %f21 ! reg 2 * reg 3 = reg 21 = 2 438 fmuls %f4, %f5, %f22 ! reg 4 * reg 5 = reg 22 = 3 439 fmuls %f6, %f7, %f23 ! reg 6 * reg 7 = reg 23 = 4 440 fmuls %f8, %f9, %f24 ! reg 8 * reg 9 = reg 24 = 5 441 fmuls %f10, %f11, %f25 ! reg 10 * reg 11 = reg 25 = 6 442 fmuls %f12, %f13, %f26 ! reg 12 * reg 13 = reg 26 = 7 443 fmuls %f14, %f15, %f27 ! reg 14 * reg 15 = reg 27 = 8 444 fmuls %f16, %f17, %f28 ! reg 16 * reg 17 = reg 28 = 9 445 fmuls %f18, %f19, %f29 ! reg 18 * reg 19 = reg 29 = 10 446 447 fcmps %fcc0, %f0, %f20 448 fbne,a,pn %fcc0, done_t_mult_sp 449 st %f20, [%l2] ! Executed only when the conditional 450 ! branch is taken as annul bit is set. 451 ! This branch will be taken under 452 ! an error condition. 453 454 ! No errors. Move on to the next register 455 456 fcmps %fcc0, %f2, %f21 457 fbne,a,pn %fcc0, done_t_mult_sp 458 st %f21, [%l2] 459 460 461 fcmps %fcc0, %f4, %f22 462 fbne,a,pn %fcc0, done_t_mult_sp 463 st %f22, [%l2] 464 465 466 fcmps %fcc0, %f6, %f23 467 fbne,a,pn %fcc0, done_t_mult_sp 468 st %f23, [%l2] 469 470 471 fcmps %fcc0, %f8, %f24 472 fbne,a,pn %fcc0, done_t_mult_sp 473 st %f24, [%l2] 474 475 476 fcmps %fcc0, %f10, %f25 477 fbne,a,pn %fcc0, done_t_mult_sp 478 st %f25, [%l2] 479 480 481 fcmps %fcc0, %f12, %f26 482 fbne,a,pn %fcc0, done_t_mult_sp 483 st %f26, [%l2] 484 485 486 fcmps %fcc0, %f14, %f27 487 fbne,a,pn %fcc0, done_t_mult_sp 488 st %f27, [%l2] 489 490 491 fcmps %fcc0, %f16, %f28 492 fbne,a,pn %fcc0, done_t_mult_sp 493 st %f28, [%l2] 494 495 496 ! Though this is the last set of compare instructions 497 ! we cannot fall through as the store needs to be done 498 ! only when the registers are not equal. That is why 499 ! we need the unconditional branch with the annul bit set. 500 fcmps %fcc0, %f18, %f29 501 fbne,a,pn %fcc0, done_t_mult_sp 502 st %f29, [%l2] 503 504 505done_t_mult_sp: 506 ld [%l2], %i0 507 ret 508 restore 509SET_SIZE(timing_mult_sp) 510 511! 512! same thing for double precision 513! 514 .section ".data" 515 .align 8 516 517.Ltmadp: 518 .skip 8 519.Ltmadp1: 520 .skip 8 521.Ltmadp2: 522 .skip 8 523 524ENTRY_NP(timing_add_dp) 525 save %sp, -SA(MINFRAME), %sp ! save the registers, stacck 526 setn .Ltmadp,%l6, %l0 527 setn .Ltmadp1,%l6, %l1 528 setn .Ltmadp2,%l6, %l2 529 mov %g0, %l3 530 setn 0x3ff0000000000000,%l6, %l4 ! put value 1 531 setn 0x4024000000000000,%l6, %l5 ! put value 10 into local 5 532 stx %l5, [%l0] 533 stx %l4, [%l1] 534 stx %l3, [%l2] 535 ldd [%l0], %f30 ! register 30 has 10 536 fmovd %f30, %f2 ! reg 2 has 10 537 ldd [%l2], %f0 ! reg 0 has 0 538 ldd [%l1], %f4 ! reg 4 has 1 539 fsubd %f30, %f4, %f6 ! reg 6 has 9 540 fsubd %f6, %f4, %f10 ! reg 10 has 8 541 fsubd %f30, %f10, %f8 ! reg 8 has 2 542 fsubd %f10, %f4, %f14 ! reg 14 has 7 543 fsubd %f30, %f14, %f12 ! reg 12 has 3 544 fsubd %f14, %f4, %f18 ! reg 18 has 6 545 fsubd %f30, %f18, %f16 ! reg 16 has 4 546! 547 faddd %f0, %f2, %f20 ! reg 20 has 10 548 faddd %f4, %f6, %f22 ! reg 22 has 10 549 faddd %f8, %f10, %f24 ! reg 24 has 10 550 faddd %f12, %f14, %f26 ! reg 26 has 10 551 faddd %f16, %f18, %f28 ! reg 28 has 10 552! 553 fcmpd %fcc0, %f30, %f20 554 fbne,a,pn %fcc0, done_t_add_dp 555 std %f20, [%l2] 556 557 fcmpd %fcc0, %f30, %f22 558 fbne,a,pn %fcc0, done_t_add_dp 559 std %f22, [%l2] 560 561 fcmpd %fcc0, %f30, %f24 562 fbne,a,pn %fcc0, done_t_add_dp 563 std %f24, [%l2] 564 565 fcmpd %fcc0, %f30, %f26 566 fbne,a,pn %fcc0, done_t_add_dp 567 std %f26, [%l2] 568 569 ! Though this is the last set of compare instructions 570 ! we cannot fall through as the store needs to be done 571 ! only when the registers are not equal. That is why 572 ! we need the unconditional branch with the annul bit set. 573 fcmpd %fcc0, %f30, %f28 574 fbne,a %fcc0, done_t_add_dp 575 std %f28, [%l2] 576 577done_t_add_dp: 578 ldx [%l2], %i0 579 580 ret 581 restore 582SET_SIZE(timing_add_dp) 583 584 585! Now for mult 586! 587 .section ".data" 588 .align 8 589 590.Ltmmdp: 591 .skip 8 592.Ltmmdp1: 593 .skip 8 594.Ltmmdp2: 595 .skip 8 596 597ENTRY_NP(timing_mult_dp) 598 save %sp, -SA(MINFRAME), %sp ! save the registers, stacck 599 setn .Ltmmdp,%l6, %l0 600 setn .Ltmmdp1,%l6, %l1 601 setn .Ltmmdp2,%l6, %l2 602 mov %g0, %l3 603 setn 0x3ff0000000000000,%l6, %l4 ! put value 1 604 setn 0x4034000000000000,%l6, %l5 ! put value 20 into local 5 605 stx %l5, [%l0] 606 stx %l4, [%l1] 607 stx %l3, [%l2] 608 ldd [%l0], %f30 ! register 30 has 20 609 ldd [%l1], %f2 ! register 2 has 1 610 fmovd %f30, %f0 ! register 0 has 20 611 faddd %f2, %f2, %f10 ! register 10 has 2 612 fmovd %f10, %f16 ! register 16 has 2 613 faddd %f10, %f16, %f4 ! register 4 has 4 614 faddd %f4, %f2, %f6 ! register 6 has 5 615 fmovd %f6, %f12 ! reg. 12 has 5 616 fmovd %f4, %f14 ! reg 14 has 4 617 faddd %f12, %f6, %f18 ! reg 18 has 10 618 fmovd %f18, %f8 ! reg 8 has 10 619! 620! now everything is set 621! 622 fmuld %f0, %f2, %f20 ! reg 20 has 20 623 fmuld %f4, %f6, %f22 ! reg 22 has 20 624 fmuld %f8, %f10, %f24 ! reg 24 has 20 625 fmuld %f12, %f14, %f26 ! reg 26 has 20 626 fmuld %f16, %f18, %f28 ! reg 28 has 20 627! 628 fcmpd %fcc0, %f30, %f20 629 fbne,a,pn %fcc0, done_t_mult_dp 630 std %f20, [%l2] 631 632 fcmpd %fcc0, %f30, %f22 633 fbne,a,pn %fcc0, done_t_mult_dp 634 std %f22, [%l2] 635 636 fcmpd %fcc0, %f30, %f24 637 fbne,a,pn %fcc0, done_t_mult_dp 638 std %f24, [%l2] 639 640 fcmpd %fcc0, %f30, %f26 641 fbne,a,pn %fcc0, done_t_mult_dp 642 std %f26, [%l2] 643 644 ! Though this is the last set of compare instructions 645 ! we cannot fall through as the store needs to be done 646 ! only when the registers are not equal. That is why 647 ! we need the unconditional branch with the annul bit set. 648 fcmpd %fcc0, %f30, %f28 649 fbne,a %fcc0, done_t_mult_dp 650 std %f28, [%l2] 651 652done_t_mult_dp: 653 ldx [%l2], %i0 654 655 ret 656 restore 657SET_SIZE(timing_mult_dp) 658 659 660!-------------------------------------------------------------------------- 661! The following routines are for testing the IEEE754 exception fields 662! of the FSR (cexc, aexc) 663! The input is : i0 = amsw 664! i1 = bmsw or alsw (for double precision) 665! i2 = bmsw (for dp) 666! i3 = blsw (for dp) 667! 668! The output is i0 = value of FSR register 669! 670 671 .section ".data" 672 .align 8 673 674.Lwadds: 675 .word 0 676.Lwadds1: 677 .word 0 678.Lwadds2: 679 .xword 0 ! For the FSR contents 680 681 682ENTRY_NP(wadd_sp) 683 save %sp, -SA(MINFRAME), %sp 684 setn .Lwadds,%l6, %l0 685 setn .Lwadds1,%l6, %l1 686 setn .Lwadds2,%l6, %l2 687 688 st %i0, [%l0] ! get the first value 689 st %i1, [%l1] ! get the second value 690 ld [%l0], %f0 ! f0 has the first value 691 ld [%l1], %f2 ! f2 has the second value 692 693 fadds %f0, %f2, %f3 ! now do the instruction 694 stx %fsr, [%l2] ! get the fsr value 695 696 ldx [%l2], %i0 697 ret 698 restore 699SET_SIZE(wadd_sp) 700 701 702! 703! same thing for add double precision 704! 705 .section ".data" 706 .align 8 707 708.Ladddp: 709 .word 0 710.Ladddp1: 711 .word 0 712.Ladddp2: 713 .xword 0 ! For the FSR contents 714 715ENTRY_NP(wadd_dp) 716 save %sp, -SA(MINFRAME), %sp 717 setn .Ladddp,%l6, %l0 718 setn .Ladddp1,%l6, %l1 719 setn .Ladddp2,%l6, %l2 720 721 st %i0, [%l0] ! get the first value 722 st %i1, [%l1] ! get the lsw of first value 723 ld [%l0], %f0 724 ld [%l1], %f1 725 st %i2, [%l0] ! get the second value 726 st %i3, [%l1] ! get the lsw of second value 727 ld [%l0], %f2 728 ld [%l1], %f3 729 730 faddd %f0, %f2, %f4 ! now do the instruction 731 stx %fsr, [%l2] ! get the fsr value 732 733 ldx [%l2], %i0 734 ret 735 restore 736 737SET_SIZE(wadd_dp) 738 739 740! 741! 742! for divide single precision 743! 744 .section ".data" 745 .align 8 746 747.Ldvsp: 748 .word 0 749.Ldvsp1: 750 .word 0 751.Ldvsp2: 752 .xword 0 ! For the FSR contents 753 754ENTRY_NP(wdiv_sp) 755 save %sp, -SA(MINFRAME), %sp 756 setn .Ldvsp,%l6, %l0 757 setn .Ldvsp1,%l6, %l1 758 setn .Ldvsp2,%l6, %l2 759 760 st %i0, [%l0] ! get the first value 761 st %i1, [%l1] ! get the second value 762 ld [%l0], %f0 ! f0 has the first value 763 ld [%l1], %f2 ! f2 has the second value 764 765 fdivs %f0, %f2, %f3 ! now do the instruction 766 stx %fsr, [%l2] ! get the fsr value 767 768 ldx [%l2], %i0 769 ret 770 restore 771 772SET_SIZE(wdiv_sp) 773 774 775! 776! 777! for divide double precision 778! 779 .section ".data" 780 .align 8 781 782.Ldvdp: 783 .word 0 784.Ldvdp1: 785 .word 0 786.Ldvdp2: 787 .xword 0 ! For the FSR contents 788 789ENTRY_NP(wdiv_dp) 790 save %sp, -SA(MINFRAME), %sp 791 setn .Ldvdp,%l6, %l0 792 setn .Ldvdp1,%l6, %l1 793 setn .Ldvdp2,%l6, %l2 794 795 st %i0, [%l0] ! get the first value 796 st %i1, [%l1] ! get the lsw of first value 797 ld [%l0], %f0 798 ld [%l1], %f1 799 st %i2, [%l0] ! get the second value 800 st %i3, [%l1] ! get the lsw of second value 801 ld [%l0], %f2 802 ld [%l1], %f3 803 804 fdivd %f0, %f2, %f4 ! now do the instruction 805 stx %fsr, [%l2] ! get the fsr value 806 807 ldx [%l2], %i0 808 ret 809 restore 810 811SET_SIZE(wdiv_dp) 812 813 814! 815! 816! for multiply single precision 817! 818 .section ".data" 819 .align 8 820 821.Lmltsp: 822 .word 0 823.Lmltsp1: 824 .word 0 825.Lmltsp2: 826 .xword 0 ! For the FSR contents 827 828ENTRY_NP(wmult_sp) 829 save %sp, -SA(MINFRAME), %sp 830 setn .Lmltsp,%l6, %l0 831 setn .Lmltsp1,%l6, %l1 832 setn .Lmltsp2,%l6, %l2 833 834 st %i0, [%l0] ! get the first value 835 st %i1, [%l1] ! get the second value 836 ld [%l0], %f0 ! f0 has the first value 837 ld [%l1], %f2 ! f2 has the second value 838 839 fmuls %f0, %f2, %f3 ! now do the instruction 840 stx %fsr, [%l2] ! get the fsr value 841 842 ldx [%l2], %i0 843 ret 844 restore 845 846SET_SIZE(wmult_sp) 847 848 849! 850! 851! for multiply double precision 852! 853 .section ".data" 854 .align 8 855 856.Lmltdp: 857 .word 0 858.Lmltdp1: 859 .word 0 860.Lmltdp2: 861 .xword 0 ! For the FSR contents 862 863ENTRY_NP(wmult_dp) 864 save %sp, -SA(MINFRAME), %sp 865 setn .Lmltdp,%l6, %l0 866 setn .Lmltdp1,%l6, %l1 867 setn .Lmltdp2,%l6, %l2 868 869 st %i0, [%l0] ! get the first value 870 st %i1, [%l1] ! get the lsw of first value 871 ld [%l0], %f0 872 ld [%l1], %f1 873 st %i2, [%l0] ! get the second value 874 st %i3, [%l1] ! get the lsw of second value 875 ld [%l0], %f2 876 ld [%l1], %f3 877 878 fmuld %f0, %f2, %f4 ! now do the instruction 879 stx %fsr, [%l2] ! get the fsr value 880 881 ldx [%l2], %i0 882 ret 883 restore 884 885SET_SIZE(wmult_dp) 886 887 888! 889! 890! for square-root single precision 891! 892 .section ".data" 893 .align 4 894.Lsqsp_opr: 895 .word 0 896 897 .align 8 898.Lsqsp_fsr: 899 .xword 0 ! For the FSR contents 900 901ENTRY_NP(wsqrt_sp) 902 save %sp, -SA(MINFRAME), %sp ! save the registers, stack 903 setn .Lsqsp_opr,%l6,%l0 ! .. get the address of temp2 904 setn .Lsqsp_fsr,%l6,%l2 ! .. and temp 905 906 st %i0, [%l0] ! .. get the callers value 907 ld [%l0], %f0 ! .. into the float register 908 909 fsqrts %f0, %f2 ! .... have the fpu perform the operation 910 stx %fsr, [%l2] ! get the fsr value 911 912 ldx [%l2], %i0 913 ret 914 restore 915 916SET_SIZE(wsqrt_sp) 917 918 919! 920! 921! for square-root double precision 922! 923 .section ".data" 924 .align 8 925.Lsqdp_opr: 926 .xword 0 927.Lsqdp_fsr: 928 .xword 0 ! For the FSR contents 929 930ENTRY_NP(wsqrt_dp) 931 save %sp, -SA(MINFRAME), %sp ! save the registers, stack 932 setn .Lsqdp_opr,%l6,%l0 ! .. get the address of temp2 933 setn .Lsqdp_fsr,%l6,%l2 ! .. and temp 934 935 stx %i0, [%l0] ! .. get the callers value 936 ldd [%l0], %f0 ! .. into a float register 937 938 fsqrtd %f0, %f2 ! .... have the fpu perform the operation 939 stx %fsr, [%l2] ! get the fsr value 940 941 ldx [%l2], %i0 942 ret 943 restore 944 945SET_SIZE(wsqrt_dp) 946 947 948! 949! 950! Chaining test. 951! 952 .section ".data" 953 .align 8 954 955.Lchsp: 956 .word 0 957.Lchsp1: 958 .word 0 959 960ENTRY_NP(chain_sp) 961 save %sp, -SA(MINFRAME), %sp 962 setn .Lchsp,%l6, %l0 963 setn .Lchsp1,%l6, %l1 964 st %i0, [%l0] ! store the value 965 ld [%l0], %f0 966 fitos %f0, %f2 ! convert integer into single 967 fmovs %f2, %f0 ! f0 has the same value x 968 fadds %f0, %f2, %f4 ! f4 will have 2x 969 fsubs %f4, %f0, %f6 ! f6 will have x 970 fmuls %f6, %f4, %f8 ! f8 will have (2x * x) 971 fdivs %f8, %f4, %f10 ! f10 will have (2x * x) / 2x = x 972 fstoi %f10, %f12 973 974 st %f12, [%l1] 975 ld [%l1], %i0 976 977 ret 978 restore 979SET_SIZE(chain_sp) 980 981 982! 983! 984 .section ".data" 985 .align 8 986 987.Lchdp: 988 .word 0 989.Lchdp1: 990 .word 0 991 992ENTRY_NP(chain_dp) 993 save %sp, -SA(MINFRAME), %sp 994 setn .Lchdp,%l6, %l0 995 setn .Lchdp1,%l6, %l1 996 st %i0, [%l0] ! store the value 997 ld [%l0], %f0 998 fitod %f0, %f2 ! convert integer into double 999 fmovs %f2, %f0 ! f0 has the same value x 1000 faddd %f0, %f2, %f4 ! f4 will have 2x 1001 fsubd %f4, %f0, %f6 ! f6 will have x 1002 fmuld %f6, %f4, %f8 ! f8 will have (2x * x) 1003 fdivd %f8, %f4, %f10 ! f10 will have (2x * x) / 2x = x 1004 fdtoi %f10, %f12 1005 1006 st %f12, [%l1] 1007 ld [%l1], %i0 1008 1009 ret 1010 restore 1011SET_SIZE(chain_dp) 1012 1013 1014!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1015! Name: Initialize all SP Registers 1016! Function: Loads the callers value into all SP floating point registers. 1017! Calling: in0 = Value 1018! Returns: All float register = Value 1019! Convention: init_regs(val); 1020! Method: Copys the user value into each fp reg in sequence. 1021!-------------------------------------------------------------------------- 1022 .section ".data" 1023 .align 8 1024 1025.Lclrg: 1026 .skip 8 1027 1028ENTRY_NP(init_regs) 1029 save %sp, -SA(MINFRAME), %sp ! save the registers, stack 1030 setn .Lclrg,%l6,%l0 ! load the address of temp2 in local0 1031 st %i0, [%l0] ! load the value in temp2 via local0 1032 ld [%l0], %f0 ! .. load the value 1033 ld [%l0], %f1 ! .. load the value 1034 ld [%l0], %f2 ! .. load the value 1035 ld [%l0], %f3 ! .. load the value 1036 ld [%l0], %f4 ! .. load the value 1037 ld [%l0], %f5 ! .. load the value 1038 ld [%l0], %f6 ! .. load the value 1039 ld [%l0], %f7 ! .. load the value 1040 ld [%l0], %f8 ! .. load the value 1041 ld [%l0], %f9 ! .. load the value 1042 ld [%l0], %f10 ! .. load the value 1043 ld [%l0], %f11 ! .. load the value 1044 ld [%l0], %f12 ! .. load the value 1045 ld [%l0], %f13 ! .. load the value 1046 ld [%l0], %f14 ! .. load the value 1047 ld [%l0], %f15 ! .. load the value 1048 ld [%l0], %f16 ! .. load the value 1049 ld [%l0], %f17 ! .. load the value 1050 ld [%l0], %f18 ! .. load the value 1051 ld [%l0], %f19 ! .. load the value 1052 ld [%l0], %f20 ! .. load the value 1053 ld [%l0], %f21 ! .. load the value 1054 ld [%l0], %f22 ! .. load the value 1055 ld [%l0], %f23 ! .. load the value 1056 ld [%l0], %f24 ! .. load the value 1057 ld [%l0], %f25 ! .. load the value 1058 ld [%l0], %f26 ! .. load the value 1059 ld [%l0], %f27 ! .. load the value 1060 ld [%l0], %f28 ! .. load the value 1061 ld [%l0], %f29 ! .. load the value 1062 ld [%l0], %f30 ! .. load the value 1063 ld [%l0], %f31 ! .. load the value 1064 ret 1065 restore 1066SET_SIZE(init_regs) 1067 1068 1069 1070!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1071! Name: Initialize all double precision Registers 1072! Function: Loads the callers value into all floating point registers. 1073! Calling: in0 = Value 1074! Returns: All float register = Value 1075! Convention: init_regs_dp(val); 1076! Method: Copys the user value into each fp reg in sequence. 1077!-------------------------------------------------------------------------- 1078 .section ".data" 1079 .align 8 1080 1081.Lclrg_dp: 1082 .skip 16 1083 1084ENTRY_NP(init_regs_dp) 1085 save %sp, -SA(MINFRAME), %sp 1086 ! save the registers, stack 1087 setx .Lclrg_dp,%l6,%l0 ! load the address of temp2 in local0 1088 stx %i0, [%l0] ! load the value in temp2 via local0 1089 ldd [%l0], %f0 ! .. load the value 1090 ldd [%l0], %f2 ! .. load the value 1091 ldd [%l0], %f4 ! .. load the value 1092 ldd [%l0], %f6 ! .. load the value 1093 ldd [%l0], %f8 ! .. load the value 1094 ldd [%l0], %f10 ! .. load the value 1095 ldd [%l0], %f12 ! .. load the value 1096 ldd [%l0], %f14 ! .. load the value 1097 ldd [%l0], %f16 ! .. load the value 1098 ldd [%l0], %f18 ! .. load the value 1099 ldd [%l0], %f20 ! .. load the value 1100 ldd [%l0], %f22 ! .. load the value 1101 ldd [%l0], %f24 ! .. load the value 1102 ldd [%l0], %f26 ! .. load the value 1103 ldd [%l0], %f28 ! .. load the value 1104 ldd [%l0], %f30 ! .. load the value 1105 ldd [%l0], %f32 ! .. load the value 1106 ldd [%l0], %f34 ! .. load the value 1107 ldd [%l0], %f36 ! .. load the value 1108 ldd [%l0], %f38 ! .. load the value 1109 ldd [%l0], %f40 ! .. load the value 1110 ldd [%l0], %f42 ! .. load the value 1111 ldd [%l0], %f44 ! .. load the value 1112 ldd [%l0], %f46 ! .. load the value 1113 ldd [%l0], %f48 ! .. load the value 1114 ldd [%l0], %f50 ! .. load the value 1115 ldd [%l0], %f52 ! .. load the value 1116 ldd [%l0], %f54 ! .. load the value 1117 ldd [%l0], %f56 ! .. load the value 1118 ldd [%l0], %f58 ! .. load the value 1119 ldd [%l0], %f60 ! .. load the value 1120 ldd [%l0], %f62 ! .. load the value 1121 ret 1122 restore 1123SET_SIZE(init_regs_dp) 1124 1125 1126 1127!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1128! Name: 1129! Function: 1130! Calling: 1131! Returns: 1132! Convention: 1133!-------------------------------------------------------------------------- 1134 1135 .section ".data" 1136 .align 4 1137 1138.Lrgtst1: 1139 .skip 4 1140.Lrgtst2: 1141 .skip 4 1142 1143ENTRY_NP(register_test) 1144 save %sp, -SA(MINFRAME), %sp 1145 1146 setn .Lrgtst1,%l6,%l1 1147 setn .Lrgtst2,%l6,%l2 1148 1149 1150 setn regTable, %l6, %o0 1151 mulx %i0, 12, %o1 ! Table entries are 12 bytes each. 1152 1153 ! Jump to the appropriate set of instructions 1154 jmp %o0+%o1 1155 st %i1, [%l1] ! save the pattern to be written 1156 1157 1158! If the number of instructions in this macro are changed, 1159! please ensure that the second operand for the mulx above 1160! is also updated. We can calculate this during run-time but 1161! that will mean extra instructions and time. 1162#define TEST_REG(reg_num) \ 1163 ld [%l1], %f/**/reg_num; \ 1164 ba %ncc, reg_done; \ 1165 st %f/**/reg_num, [%l2] 1166 1167regTable : 1168 1169 TEST_REG(0) 1170 TEST_REG(1) 1171 TEST_REG(2) 1172 TEST_REG(3) 1173 TEST_REG(4) 1174 TEST_REG(5) 1175 TEST_REG(6) 1176 TEST_REG(7) 1177 TEST_REG(8) 1178 TEST_REG(9) 1179 TEST_REG(10) 1180 TEST_REG(11) 1181 TEST_REG(12) 1182 TEST_REG(13) 1183 TEST_REG(14) 1184 TEST_REG(15) 1185 TEST_REG(16) 1186 TEST_REG(17) 1187 TEST_REG(18) 1188 TEST_REG(19) 1189 TEST_REG(20) 1190 TEST_REG(21) 1191 TEST_REG(22) 1192 TEST_REG(23) 1193 TEST_REG(24) 1194 TEST_REG(25) 1195 TEST_REG(26) 1196 TEST_REG(27) 1197 TEST_REG(28) 1198 TEST_REG(29) 1199 TEST_REG(30) 1200 1201 ! No need for a branch here as this the last entry in 1202 ! the table and the label is will be reached by falling 1203 ! through. 1204 ld [%l1], %f31 1205 st %f31, [%l2] 1206 1207reg_done: 1208 ld [%l2], %i0 1209 1210 ret 1211 restore 1212SET_SIZE(register_test) 1213 1214 1215!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1216! Name: 1217! Function: 1218! Calling: 1219! Returns: 1220! Convention: 1221!-------------------------------------------------------------------------- 1222 .section ".data" 1223 .align 8 1224 1225.Lrgtst1_dp: 1226 .skip 8 1227.Lrgtst2_dp: 1228 .skip 8 1229 1230ENTRY_NP(register_test_dp) 1231 save %sp, -SA(MINFRAME), %sp 1232 1233 setx .Lrgtst1_dp,%l6,%l1 1234 setx .Lrgtst2_dp,%l6,%l2 1235 1236 setn regTable_dp, %l6, %o0 1237 mulx %i0, 6, %o1 ! Registers are 64-bit and hence the 1238 ! register numbers given will be even. 1239 ! Each table entry is 12 bytes. 1240 ! Multiplying the even register number 1241 ! by 6 will give the correct offset. 1242 1243 1244 ! Jump to the appropriate set of instructions 1245 jmp %o0+%o1 1246 stx %i1, [%l1] !save the pattern to be written 1247 1248! If the number of instructions in this macro are changed, 1249! please ensure that the second operand for the mulx above 1250! is also updated. We can calculate this during run-time but 1251! that will mean extra instructions and time. 1252#define TEST_REG_DP(reg_num) \ 1253 ldd [%l1], %f/**/reg_num; \ 1254 ba %ncc, reg_done_dp; \ 1255 std %f/**/reg_num, [%l2] 1256 1257regTable_dp : 1258 1259 TEST_REG_DP(0) 1260 TEST_REG_DP(2) 1261 TEST_REG_DP(4) 1262 TEST_REG_DP(6) 1263 TEST_REG_DP(8) 1264 TEST_REG_DP(10) 1265 TEST_REG_DP(12) 1266 TEST_REG_DP(14) 1267 TEST_REG_DP(16) 1268 TEST_REG_DP(18) 1269 TEST_REG_DP(20) 1270 TEST_REG_DP(22) 1271 TEST_REG_DP(24) 1272 TEST_REG_DP(26) 1273 TEST_REG_DP(28) 1274 TEST_REG_DP(30) 1275 TEST_REG_DP(32) 1276 TEST_REG_DP(34) 1277 TEST_REG_DP(36) 1278 TEST_REG_DP(38) 1279 TEST_REG_DP(40) 1280 TEST_REG_DP(42) 1281 TEST_REG_DP(44) 1282 TEST_REG_DP(46) 1283 TEST_REG_DP(48) 1284 TEST_REG_DP(50) 1285 TEST_REG_DP(52) 1286 TEST_REG_DP(54) 1287 TEST_REG_DP(56) 1288 TEST_REG_DP(58) 1289 TEST_REG_DP(60) 1290 1291 ! No need for a branch here as this the last entry in 1292 ! the table and the label is will be reached by falling 1293 ! through. 1294 ldd [%l1], %f62 1295 std %f62, [%l2] 1296 1297reg_done_dp: 1298 ldx [%l2], %i0 1299 1300 ret 1301 restore 1302SET_SIZE(register_test_dp) 1303 1304 1305 1306!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1307! Name: Move Registers 1308! Function: Move a value thru the float registers 1309! Calling: in0 = value 1310! Returns: in0 = result 1311! Convention: if (result != move_regs(value)) 1312! error(result-value); 1313!-------------------------------------------------------------------------- 1314 .section ".data" 1315 .align 4 1316 1317.Lmvrg: 1318 .skip 4 1319.Lmvrg1: 1320 .skip 4 1321 1322ENTRY_NP(move_regs) 1323 save %sp, -SA(MINFRAME), %sp ! save the registers, stack 1324 setn .Lmvrg1,%l6,%l0 ! get the address to temp2 1325 setn .Lmvrg,%l6,%l1 ! .. and temp 1326 st %i0, [%l0] ! get the callers value 1327 ld [%l0], %f0 ! .. into a float register 1328 fmovs %f0, %f1 ! copy from 1 register to the next 1329 fmovs %f1, %f2 ! .. to the next 1330 fmovs %f2, %f3 ! .. to the next 1331 fmovs %f3, %f4 ! .. to the next 1332 fmovs %f4, %f5 ! .. to the next 1333 fmovs %f5, %f6 ! .. to the next 1334 fmovs %f6, %f7 ! .. to the next 1335 fmovs %f7, %f8 ! .. to the next 1336 fmovs %f8, %f9 ! .. to the next 1337 fmovs %f9, %f10 ! .. to the next 1338 fmovs %f10, %f11 ! .. to the next 1339 fmovs %f11, %f12 ! .. to the next 1340 fmovs %f12, %f13 ! .. to the next 1341 fmovs %f13, %f14 ! .. to the next 1342 fmovs %f14, %f15 ! .. to the next 1343 fmovs %f15, %f16 ! .. to the next 1344 fmovs %f16, %f17 ! .. to the next 1345 fmovs %f17, %f18 ! .. to the next 1346 fmovs %f18, %f19 ! .. to the next 1347 fmovs %f19, %f20 ! .. to the next 1348 fmovs %f20, %f21 ! .. to the next 1349 fmovs %f21, %f22 ! .. to the next 1350 fmovs %f22, %f23 ! .. to the next 1351 fmovs %f23, %f24 ! .. to the next 1352 fmovs %f24, %f25 ! .. to the next 1353 fmovs %f25, %f26 ! .. to the next 1354 fmovs %f26, %f27 ! .. to the next 1355 fmovs %f27, %f28 ! .. to the next 1356 fmovs %f28, %f29 ! .. to the next 1357 fmovs %f29, %f30 ! .. to the next 1358 fmovs %f30, %f31 ! .. to the next 1359 st %f31, [%l1] ! .... save the result 1360 ld [%l1], %i0 ! .. and return it to the caller 1361 ret 1362 restore 1363SET_SIZE(move_regs) 1364 1365 1366 1367!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1368! Name: Move Registers Double Precision 1369! Function: Move a value thru the float registers 1370! Calling: in0 = value 1371! Returns: in0 = result 1372! Convention: if (result != move_regs_dp(value)) 1373! error(result-value); 1374!-------------------------------------------------------------------------- 1375 .section ".data" 1376 .align 8 1377 1378.Lmvrg_dp: 1379 .skip 8 1380.Lmvrg1_dp: 1381 .skip 8 1382 1383ENTRY_NP(move_regs_dp) 1384 save %sp, -SA(MINFRAME), %sp ! save the registers, stack 1385 setx .Lmvrg1_dp,%l6,%l0 ! get the address to temp2 1386 setx .Lmvrg_dp,%l6,%l1 ! .. and temp 1387 stx %i0, [%l0] ! get the callers value 1388 ldd [%l0], %f0 ! .. into a float register 1389 fmovd %f0, %f2 ! copy from 1 register to the next 1390 fmovd %f2, %f4 ! .. to the next 1391 fmovd %f4, %f6 ! .. to the next 1392 fmovd %f6, %f8 ! .. to the next 1393 fmovd %f8, %f10 ! .. to the next 1394 fmovd %f10, %f12 ! .. to the next 1395 fmovd %f12, %f14 ! .. to the next 1396 fmovd %f14, %f16 ! .. to the next 1397 fmovd %f16, %f18 ! .. to the next 1398 fmovd %f18, %f20 ! .. to the next 1399 fmovd %f20, %f22 ! .. to the next 1400 fmovd %f22, %f24 ! .. to the next 1401 fmovd %f24, %f26 ! .. to the next 1402 fmovd %f26, %f28 ! .. to the next 1403 fmovd %f28, %f30 ! .. to the next 1404 fmovd %f30, %f32 ! .. to the next 1405 fmovd %f32, %f34 ! .. to the next 1406 fmovd %f34, %f36 ! .. to the next 1407 fmovd %f36, %f38 ! .. to the next 1408 fmovd %f38, %f40 ! .. to the next 1409 fmovd %f40, %f42 ! .. to the next 1410 fmovd %f42, %f44 ! .. to the next 1411 fmovd %f44, %f46 ! .. to the next 1412 fmovd %f46, %f48 ! .. to the next 1413 fmovd %f48, %f50 ! .. to the next 1414 fmovd %f50, %f52 ! .. to the next 1415 fmovd %f52, %f54 ! .. to the next 1416 fmovd %f54, %f56 ! .. to the next 1417 fmovd %f56, %f58 ! .. to the next 1418 fmovd %f58, %f60 ! .. to the next 1419 fmovd %f60, %f62 ! .. to the next 1420 std %f62, [%l1] ! .... save the result 1421 ldx [%l1], %i0 ! .. and return it to the caller 1422 ret 1423 restore 1424SET_SIZE(move_regs_dp) 1425 1426 1427 1428!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1429! Name: 1430! Function: 1431! Calling: 1432! Returns: 1433! Convention: 1434!-------------------------------------------------------------------------- 1435! 1436! The following routine checks the branching is done accordingly 1437! to the ficc bits. 1438! input %i0 = 0 = branch unordered 1439! 1 = branch greater 1440! 2 = branch unordered or greater 1441! 3 = branch less 1442! 4 = branch unordered or less 1443! 5 = branch less or greater 1444! 6 = branch not equal 1445! 7 = branch equal 1446! 8 = branch unordered or equal 1447! . 9 = branch greater or equal 1448! 10 = branch branch unordered or greater or equal 1449! 11 = branch less or equal 1450! 12 = branch unordered or or less or equal 1451! 13 = branch ordered 1452! 14 = branch always 1453! 15 = branch never 1454! 1455! ouput : %i0 = 0 = good 1456! = 1 = error 1457! 1458 1459 .section ".data" 1460 .align 8 1461 1462.Lbr: 1463 .skip 8 1464.Lbr1: 1465 .skip 8 1466 1467ENTRY_NP(branches) 1468 save %sp, -SA(MINFRAME), %sp ! save the registers, stacck 1469 setn .Lbr1,%l6,%l1 1470 setn .Lbr,%l6,%l2 1471 st %i1, [%l1] 1472 st %i2, [%l2] 1473 ld [%l1], %f0 1474 ld [%l2], %f2 1475 1476 setn brn_0, %l6, %o0 1477 mulx %i0, 12, %o1 1478 1479 1480 jmp %o0+%o1 1481 fcmps %fcc0, %f0, %f2 ! compare the values to get ficc 1482! 1483! branch unordered 1484brn_0: 1485 fbu,a %fcc0, br_good 1486 nop 1487 ba,a %ncc, br_error 1488 1489! branch greater 1490brn_1: 1491 fbg,a %fcc0, br_good 1492 nop 1493 ba,a %ncc, br_error 1494 1495! branch unordered or greater 1496brn_2: 1497 fbug,a %fcc0, br_good 1498 nop 1499 ba,a %ncc, br_error 1500 1501! branch less 1502brn_3: 1503 fbl,a %fcc0, br_good 1504 nop 1505 ba,a %ncc, br_error 1506 1507! branch unorderd or less 1508brn_4: 1509 fbul,a %fcc0, br_good 1510 nop 1511 ba,a %ncc, br_error 1512 1513! branch less or greater 1514brn_5: 1515 fblg,a %fcc0, br_good 1516 nop 1517 ba,a %ncc, br_error 1518 1519! branch not equal 1520brn_6: 1521 fbne,a %fcc0, br_good 1522 nop 1523 ba,a %ncc, br_error 1524 1525! branch equal 1526brn_7: 1527 fbe,a %fcc0, br_good 1528 nop 1529 ba,a %ncc, br_error 1530 1531! branch unordered or equal 1532brn_8: 1533 fbue,a %fcc0, br_good 1534 nop 1535 ba,a %ncc, br_error 1536 1537! branch greater or equal 1538brn_9: 1539 fbge,a %fcc0, br_good 1540 nop 1541 ba,a %ncc, br_error 1542 1543! branch unordered or greater or equal 1544brn_10: 1545 fbuge,a %fcc0, br_good 1546 nop 1547 ba,a %ncc, br_error 1548 1549! branch less or equal 1550brn_11: 1551 fble,a %fcc0, br_good 1552 nop 1553 ba,a %ncc, br_error 1554 1555! branch unordered or less or equal 1556brn_12: 1557 fbule,a %fcc0, br_good 1558 nop 1559 ba,a %ncc, br_error 1560 1561! branch ordered 1562brn_13: 1563 fbo,a %fcc0, br_good 1564 nop 1565 ba,a %ncc, br_error 1566 1567! branch always 1568brn_14: 1569 fba,a %fcc0, br_good 1570 nop 1571 ba,a %ncc, br_error 1572 1573! branch never 1574brn_15: 1575 fbn,a %fcc0, br_error 1576 nop 1577 1578br_good: 1579 mov %g0, %i0 ! Branch worked as expected 1580 1581 ret 1582 restore 1583 1584br_error: 1585 mov 0xff, %i0 ! set the flag that it is error 1586 1587 ret 1588 restore 1589SET_SIZE(branches) 1590 1591 1592!void read_fpreg(pf, n) 1593! FPU_REGS_TYPE *pf; /* Old freg value. */ 1594! unsigned n; /* Want to read register n. */ 1595! 1596!{ 1597! *pf = %f[n]; 1598!} 1599 1600ENTRY_NP(read_fpreg) 1601 save %sp, -SA(MINFRAME), %sp 1602 mulx %i1, 12, %i1 ! Table entries are 12 bytes each. 1603 setn stable, %l1, %g1 ! g1 gets base of table. 1604 jmp %g1 + %i1 ! Jump into table 1605 nop ! Can't follow CTI by CTI. 1606 1607#define STOREFP(n) st %f/**/n, [%i0]; ret; restore 1608 1609stable: 1610 STOREFP(0) 1611 STOREFP(1) 1612 STOREFP(2) 1613 STOREFP(3) 1614 STOREFP(4) 1615 STOREFP(5) 1616 STOREFP(6) 1617 STOREFP(7) 1618 STOREFP(8) 1619 STOREFP(9) 1620 STOREFP(10) 1621 STOREFP(11) 1622 STOREFP(12) 1623 STOREFP(13) 1624 STOREFP(14) 1625 STOREFP(15) 1626 STOREFP(16) 1627 STOREFP(17) 1628 STOREFP(18) 1629 STOREFP(19) 1630 STOREFP(20) 1631 STOREFP(21) 1632 STOREFP(22) 1633 STOREFP(23) 1634 STOREFP(24) 1635 STOREFP(25) 1636 STOREFP(26) 1637 STOREFP(27) 1638 STOREFP(28) 1639 STOREFP(29) 1640 STOREFP(30) 1641 STOREFP(31) 1642SET_SIZE(read_fpreg) 1643 1644 1645ENTRY_NP(read_fpreg_dp) 1646 save %sp, -SA(MINFRAME), %sp 1647 mulx %i1, 6, %i1 ! Table entries are 12 bytes each. 1648 ! But o1 will have even numbered 1649 ! index 1650 setn stable_dp, %l0, %g1 ! g1 gets base of table. 1651 jmp %g1 + %i1 ! Jump into table 1652 nop ! Can't follow CTI by CTI. 1653 1654#define STOREFP_DP(n) std %f/**/n, [%i0]; ret; restore 1655 1656stable_dp: 1657 STOREFP_DP(0) 1658 STOREFP_DP(2) 1659 STOREFP_DP(4) 1660 STOREFP_DP(6) 1661 STOREFP_DP(8) 1662 STOREFP_DP(10) 1663 STOREFP_DP(12) 1664 STOREFP_DP(14) 1665 STOREFP_DP(16) 1666 STOREFP_DP(18) 1667 STOREFP_DP(20) 1668 STOREFP_DP(22) 1669 STOREFP_DP(24) 1670 STOREFP_DP(26) 1671 STOREFP_DP(28) 1672 STOREFP_DP(30) 1673 STOREFP_DP(32) 1674 STOREFP_DP(34) 1675 STOREFP_DP(36) 1676 STOREFP_DP(38) 1677 STOREFP_DP(40) 1678 STOREFP_DP(42) 1679 STOREFP_DP(44) 1680 STOREFP_DP(46) 1681 STOREFP_DP(48) 1682 STOREFP_DP(50) 1683 STOREFP_DP(52) 1684 STOREFP_DP(54) 1685 STOREFP_DP(56) 1686 STOREFP_DP(58) 1687 STOREFP_DP(60) 1688 STOREFP_DP(62) 1689 1690SET_SIZE(read_fpreg_dp) 1691 1692! 1693!void 1694!write_fpreg(pf, n) 1695! FPU_REGS_TYPE *pf; /* New freg value. */ 1696! unsigned n; /* Want to read register n. */ 1697! 1698!{ 1699! %f[n] = *pf; 1700!} 1701 1702ENTRY_NP(write_fpreg) 1703 sll %o1, 3, %o1 ! Table entries are 8 bytes each. 1704 setn ltable, %l0, %g1 ! g1 gets base of table. 1705 jmp %g1 + %o1 ! Jump into table 1706 nop ! Can't follow CTI by CTI. 1707 1708 1709#define LOADFP(n) jmp %o7+8 ; ld [%o0],%f/**/n 1710 1711ltable: 1712 LOADFP(0) 1713 LOADFP(1) 1714 LOADFP(2) 1715 LOADFP(3) 1716 LOADFP(4) 1717 LOADFP(5) 1718 LOADFP(6) 1719 LOADFP(7) 1720 LOADFP(8) 1721 LOADFP(9) 1722 LOADFP(10) 1723 LOADFP(11) 1724 LOADFP(12) 1725 LOADFP(13) 1726 LOADFP(14) 1727 LOADFP(15) 1728 LOADFP(16) 1729 LOADFP(17) 1730 LOADFP(18) 1731 LOADFP(19) 1732 LOADFP(20) 1733 LOADFP(21) 1734 LOADFP(22) 1735 LOADFP(23) 1736 LOADFP(24) 1737 LOADFP(25) 1738 LOADFP(26) 1739 LOADFP(27) 1740 LOADFP(28) 1741 LOADFP(29) 1742 LOADFP(30) 1743 LOADFP(31) 1744SET_SIZE(write_fpreg) 1745