1 /* SPDX-License-Identifier: GPL-2.0+ WITH GCC-exception-2.0 2 3 Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 4 2004, 2005, 2006 5 Free Software Foundation, Inc. 6 */ 7 8 !! libgcc routines for the Renesas / SuperH SH CPUs. 9 !! Contributed by Steve Chamberlain. 10 !! sac@cygnus.com 11 12 !! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines 13 !! recoded in assembly by Toshiyasu Morita 14 !! tm@netcom.com 15 16 /* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and 17 ELF local label prefixes by J"orn Rennecke 18 amylaar@cygnus.com */ 19 20 /* This code used shld, thus is not suitable for SH1 / SH2. */ 21 22 /* Signed / unsigned division without use of FPU, optimized for SH4. 23 Uses a lookup table for divisors in the range -128 .. +128, and 24 div1 with case distinction for larger divisors in three more ranges. 25 The code is lumped together with the table to allow the use of mova. */ 26 #ifdef CONFIG_CPU_LITTLE_ENDIAN 27 #define L_LSB 0 28 #define L_LSWMSB 1 29 #define L_MSWLSB 2 30 #else 31 #define L_LSB 3 32 #define L_LSWMSB 2 33 #define L_MSWLSB 1 34 #endif 35 36 .balign 4 37 .global __udivsi3_i4i 38 .global __udivsi3_i4 39 .set __udivsi3_i4, __udivsi3_i4i 40 .type __udivsi3_i4i, @function 41 __udivsi3_i4i: 42 mov.w c128_w, r1 43 div0u 44 mov r4,r0 45 shlr8 r0 46 cmp/hi r1,r5 47 extu.w r5,r1 48 bf udiv_le128 49 cmp/eq r5,r1 50 bf udiv_ge64k 51 shlr r0 52 mov r5,r1 53 shll16 r5 54 mov.l r4,@-r15 55 div1 r5,r0 56 mov.l r1,@-r15 57 div1 r5,r0 58 div1 r5,r0 59 bra udiv_25 60 div1 r5,r0 61 62 div_le128: 63 mova div_table_ix,r0 64 bra div_le128_2 65 mov.b @(r0,r5),r1 66 udiv_le128: 67 mov.l r4,@-r15 68 mova div_table_ix,r0 69 mov.b @(r0,r5),r1 70 mov.l r5,@-r15 71 div_le128_2: 72 mova div_table_inv,r0 73 mov.l @(r0,r1),r1 74 mov r5,r0 75 tst #0xfe,r0 76 mova div_table_clz,r0 77 dmulu.l r1,r4 78 mov.b @(r0,r5),r1 79 bt/s div_by_1 80 mov r4,r0 81 mov.l @r15+,r5 82 sts mach,r0 83 /* clrt */ 84 addc r4,r0 85 mov.l @r15+,r4 86 rotcr r0 87 rts 88 shld r1,r0 89 90 div_by_1_neg: 91 neg r4,r0 92 div_by_1: 93 mov.l @r15+,r5 94 rts 95 mov.l @r15+,r4 96 97 div_ge64k: 98 bt/s div_r8 99 div0u 100 shll8 r5 101 bra div_ge64k_2 102 div1 r5,r0 103 udiv_ge64k: 104 cmp/hi r0,r5 105 mov r5,r1 106 bt udiv_r8 107 shll8 r5 108 mov.l r4,@-r15 109 div1 r5,r0 110 mov.l r1,@-r15 111 div_ge64k_2: 112 div1 r5,r0 113 mov.l zero_l,r1 114 .rept 4 115 div1 r5,r0 116 .endr 117 mov.l r1,@-r15 118 div1 r5,r0 119 mov.w m256_w,r1 120 div1 r5,r0 121 mov.b r0,@(L_LSWMSB,r15) 122 xor r4,r0 123 and r1,r0 124 bra div_ge64k_end 125 xor r4,r0 126 127 div_r8: 128 shll16 r4 129 bra div_r8_2 130 shll8 r4 131 udiv_r8: 132 mov.l r4,@-r15 133 shll16 r4 134 clrt 135 shll8 r4 136 mov.l r5,@-r15 137 div_r8_2: 138 rotcl r4 139 mov r0,r1 140 div1 r5,r1 141 mov r4,r0 142 rotcl r0 143 mov r5,r4 144 div1 r5,r1 145 .rept 5 146 rotcl r0; div1 r5,r1 147 .endr 148 rotcl r0 149 mov.l @r15+,r5 150 div1 r4,r1 151 mov.l @r15+,r4 152 rts 153 rotcl r0 154 155 .global __sdivsi3_i4i 156 .global __sdivsi3_i4 157 .global __sdivsi3 158 .set __sdivsi3_i4, __sdivsi3_i4i 159 .set __sdivsi3, __sdivsi3_i4i 160 .type __sdivsi3_i4i, @function 161 /* This is link-compatible with a __sdivsi3 call, 162 but we effectively clobber only r1. */ 163 __sdivsi3_i4i: 164 mov.l r4,@-r15 165 cmp/pz r5 166 mov.w c128_w, r1 167 bt/s pos_divisor 168 cmp/pz r4 169 mov.l r5,@-r15 170 neg r5,r5 171 bt/s neg_result 172 cmp/hi r1,r5 173 neg r4,r4 174 pos_result: 175 extu.w r5,r0 176 bf div_le128 177 cmp/eq r5,r0 178 mov r4,r0 179 shlr8 r0 180 bf/s div_ge64k 181 cmp/hi r0,r5 182 div0u 183 shll16 r5 184 div1 r5,r0 185 div1 r5,r0 186 div1 r5,r0 187 udiv_25: 188 mov.l zero_l,r1 189 div1 r5,r0 190 div1 r5,r0 191 mov.l r1,@-r15 192 .rept 3 193 div1 r5,r0 194 .endr 195 mov.b r0,@(L_MSWLSB,r15) 196 xtrct r4,r0 197 swap.w r0,r0 198 .rept 8 199 div1 r5,r0 200 .endr 201 mov.b r0,@(L_LSWMSB,r15) 202 div_ge64k_end: 203 .rept 8 204 div1 r5,r0 205 .endr 206 mov.l @r15+,r4 ! zero-extension and swap using LS unit. 207 extu.b r0,r0 208 mov.l @r15+,r5 209 or r4,r0 210 mov.l @r15+,r4 211 rts 212 rotcl r0 213 214 div_le128_neg: 215 tst #0xfe,r0 216 mova div_table_ix,r0 217 mov.b @(r0,r5),r1 218 mova div_table_inv,r0 219 bt/s div_by_1_neg 220 mov.l @(r0,r1),r1 221 mova div_table_clz,r0 222 dmulu.l r1,r4 223 mov.b @(r0,r5),r1 224 mov.l @r15+,r5 225 sts mach,r0 226 /* clrt */ 227 addc r4,r0 228 mov.l @r15+,r4 229 rotcr r0 230 shld r1,r0 231 rts 232 neg r0,r0 233 234 pos_divisor: 235 mov.l r5,@-r15 236 bt/s pos_result 237 cmp/hi r1,r5 238 neg r4,r4 239 neg_result: 240 extu.w r5,r0 241 bf div_le128_neg 242 cmp/eq r5,r0 243 mov r4,r0 244 shlr8 r0 245 bf/s div_ge64k_neg 246 cmp/hi r0,r5 247 div0u 248 mov.l zero_l,r1 249 shll16 r5 250 div1 r5,r0 251 mov.l r1,@-r15 252 .rept 7 253 div1 r5,r0 254 .endr 255 mov.b r0,@(L_MSWLSB,r15) 256 xtrct r4,r0 257 swap.w r0,r0 258 .rept 8 259 div1 r5,r0 260 .endr 261 mov.b r0,@(L_LSWMSB,r15) 262 div_ge64k_neg_end: 263 .rept 8 264 div1 r5,r0 265 .endr 266 mov.l @r15+,r4 ! zero-extension and swap using LS unit. 267 extu.b r0,r1 268 mov.l @r15+,r5 269 or r4,r1 270 div_r8_neg_end: 271 mov.l @r15+,r4 272 rotcl r1 273 rts 274 neg r1,r0 275 276 div_ge64k_neg: 277 bt/s div_r8_neg 278 div0u 279 shll8 r5 280 mov.l zero_l,r1 281 .rept 6 282 div1 r5,r0 283 .endr 284 mov.l r1,@-r15 285 div1 r5,r0 286 mov.w m256_w,r1 287 div1 r5,r0 288 mov.b r0,@(L_LSWMSB,r15) 289 xor r4,r0 290 and r1,r0 291 bra div_ge64k_neg_end 292 xor r4,r0 293 294 c128_w: 295 .word 128 296 297 div_r8_neg: 298 clrt 299 shll16 r4 300 mov r4,r1 301 shll8 r1 302 mov r5,r4 303 .rept 7 304 rotcl r1; div1 r5,r0 305 .endr 306 mov.l @r15+,r5 307 rotcl r1 308 bra div_r8_neg_end 309 div1 r4,r0 310 311 m256_w: 312 .word 0xff00 313 /* This table has been generated by divtab-sh4.c. */ 314 .balign 4 315 div_table_clz: 316 .byte 0 317 .byte 1 318 .byte 0 319 .byte -1 320 .byte -1 321 .byte -2 322 .byte -2 323 .byte -2 324 .byte -2 325 .byte -3 326 .byte -3 327 .byte -3 328 .byte -3 329 .byte -3 330 .byte -3 331 .byte -3 332 .byte -3 333 .byte -4 334 .byte -4 335 .byte -4 336 .byte -4 337 .byte -4 338 .byte -4 339 .byte -4 340 .byte -4 341 .byte -4 342 .byte -4 343 .byte -4 344 .byte -4 345 .byte -4 346 .byte -4 347 .byte -4 348 .byte -4 349 .byte -5 350 .byte -5 351 .byte -5 352 .byte -5 353 .byte -5 354 .byte -5 355 .byte -5 356 .byte -5 357 .byte -5 358 .byte -5 359 .byte -5 360 .byte -5 361 .byte -5 362 .byte -5 363 .byte -5 364 .byte -5 365 .byte -5 366 .byte -5 367 .byte -5 368 .byte -5 369 .byte -5 370 .byte -5 371 .byte -5 372 .byte -5 373 .byte -5 374 .byte -5 375 .byte -5 376 .byte -5 377 .byte -5 378 .byte -5 379 .byte -5 380 .byte -5 381 .byte -6 382 .byte -6 383 .byte -6 384 .byte -6 385 .byte -6 386 .byte -6 387 .byte -6 388 .byte -6 389 .byte -6 390 .byte -6 391 .byte -6 392 .byte -6 393 .byte -6 394 .byte -6 395 .byte -6 396 .byte -6 397 .byte -6 398 .byte -6 399 .byte -6 400 .byte -6 401 .byte -6 402 .byte -6 403 .byte -6 404 .byte -6 405 .byte -6 406 .byte -6 407 .byte -6 408 .byte -6 409 .byte -6 410 .byte -6 411 .byte -6 412 .byte -6 413 .byte -6 414 .byte -6 415 .byte -6 416 .byte -6 417 .byte -6 418 .byte -6 419 .byte -6 420 .byte -6 421 .byte -6 422 .byte -6 423 .byte -6 424 .byte -6 425 .byte -6 426 .byte -6 427 .byte -6 428 .byte -6 429 .byte -6 430 .byte -6 431 .byte -6 432 .byte -6 433 .byte -6 434 .byte -6 435 .byte -6 436 .byte -6 437 .byte -6 438 .byte -6 439 .byte -6 440 .byte -6 441 .byte -6 442 .byte -6 443 .byte -6 444 /* Lookup table translating positive divisor to index into table of 445 normalized inverse. N.B. the '0' entry is also the last entry of the 446 previous table, and causes an unaligned access for division by zero. */ 447 div_table_ix: 448 .byte -6 449 .byte -128 450 .byte -128 451 .byte 0 452 .byte -128 453 .byte -64 454 .byte 0 455 .byte 64 456 .byte -128 457 .byte -96 458 .byte -64 459 .byte -32 460 .byte 0 461 .byte 32 462 .byte 64 463 .byte 96 464 .byte -128 465 .byte -112 466 .byte -96 467 .byte -80 468 .byte -64 469 .byte -48 470 .byte -32 471 .byte -16 472 .byte 0 473 .byte 16 474 .byte 32 475 .byte 48 476 .byte 64 477 .byte 80 478 .byte 96 479 .byte 112 480 .byte -128 481 .byte -120 482 .byte -112 483 .byte -104 484 .byte -96 485 .byte -88 486 .byte -80 487 .byte -72 488 .byte -64 489 .byte -56 490 .byte -48 491 .byte -40 492 .byte -32 493 .byte -24 494 .byte -16 495 .byte -8 496 .byte 0 497 .byte 8 498 .byte 16 499 .byte 24 500 .byte 32 501 .byte 40 502 .byte 48 503 .byte 56 504 .byte 64 505 .byte 72 506 .byte 80 507 .byte 88 508 .byte 96 509 .byte 104 510 .byte 112 511 .byte 120 512 .byte -128 513 .byte -124 514 .byte -120 515 .byte -116 516 .byte -112 517 .byte -108 518 .byte -104 519 .byte -100 520 .byte -96 521 .byte -92 522 .byte -88 523 .byte -84 524 .byte -80 525 .byte -76 526 .byte -72 527 .byte -68 528 .byte -64 529 .byte -60 530 .byte -56 531 .byte -52 532 .byte -48 533 .byte -44 534 .byte -40 535 .byte -36 536 .byte -32 537 .byte -28 538 .byte -24 539 .byte -20 540 .byte -16 541 .byte -12 542 .byte -8 543 .byte -4 544 .byte 0 545 .byte 4 546 .byte 8 547 .byte 12 548 .byte 16 549 .byte 20 550 .byte 24 551 .byte 28 552 .byte 32 553 .byte 36 554 .byte 40 555 .byte 44 556 .byte 48 557 .byte 52 558 .byte 56 559 .byte 60 560 .byte 64 561 .byte 68 562 .byte 72 563 .byte 76 564 .byte 80 565 .byte 84 566 .byte 88 567 .byte 92 568 .byte 96 569 .byte 100 570 .byte 104 571 .byte 108 572 .byte 112 573 .byte 116 574 .byte 120 575 .byte 124 576 .byte -128 577 /* 1/64 .. 1/127, normalized. There is an implicit leading 1 in bit 32. */ 578 .balign 4 579 zero_l: 580 .long 0x0 581 .long 0xF81F81F9 582 .long 0xF07C1F08 583 .long 0xE9131AC0 584 .long 0xE1E1E1E2 585 .long 0xDAE6076C 586 .long 0xD41D41D5 587 .long 0xCD856891 588 .long 0xC71C71C8 589 .long 0xC0E07039 590 .long 0xBACF914D 591 .long 0xB4E81B4F 592 .long 0xAF286BCB 593 .long 0xA98EF607 594 .long 0xA41A41A5 595 .long 0x9EC8E952 596 .long 0x9999999A 597 .long 0x948B0FCE 598 .long 0x8F9C18FA 599 .long 0x8ACB90F7 600 .long 0x86186187 601 .long 0x81818182 602 .long 0x7D05F418 603 .long 0x78A4C818 604 .long 0x745D1746 605 .long 0x702E05C1 606 .long 0x6C16C16D 607 .long 0x68168169 608 .long 0x642C8591 609 .long 0x60581606 610 .long 0x5C9882BA 611 .long 0x58ED2309 612 div_table_inv: 613 .long 0x55555556 614 .long 0x51D07EAF 615 .long 0x4E5E0A73 616 .long 0x4AFD6A06 617 .long 0x47AE147B 618 .long 0x446F8657 619 .long 0x41414142 620 .long 0x3E22CBCF 621 .long 0x3B13B13C 622 .long 0x38138139 623 .long 0x3521CFB3 624 .long 0x323E34A3 625 .long 0x2F684BDB 626 .long 0x2C9FB4D9 627 .long 0x29E4129F 628 .long 0x27350B89 629 .long 0x24924925 630 .long 0x21FB7813 631 .long 0x1F7047DD 632 .long 0x1CF06ADB 633 .long 0x1A7B9612 634 .long 0x18118119 635 .long 0x15B1E5F8 636 .long 0x135C8114 637 .long 0x11111112 638 .long 0xECF56BF 639 .long 0xC9714FC 640 .long 0xA6810A7 641 .long 0x8421085 642 .long 0x624DD30 643 .long 0x4104105 644 .long 0x2040811 645 /* maximum error: 0.987342 scaled: 0.921875*/
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.