multiply_and_divide.py revision 5661:443e6f925027
1# Copyright (c) 2007 The Hewlett-Packard Development Company 2# All rights reserved. 3# 4# Redistribution and use of this software in source and binary forms, 5# with or without modification, are permitted provided that the 6# following conditions are met: 7# 8# The software must be used only for Non-Commercial Use which means any 9# use which is NOT directed to receiving any direct monetary 10# compensation for, or commercial advantage from such use. Illustrative 11# examples of non-commercial use are academic research, personal study, 12# teaching, education and corporate research & development. 13# Illustrative examples of commercial use are distributing products for 14# commercial advantage and providing services using the software for 15# commercial advantage. 16# 17# If you wish to use this software or functionality therein that may be 18# covered by patents for commercial use, please contact: 19# Director of Intellectual Property Licensing 20# Office of Strategy and Technology 21# Hewlett-Packard Company 22# 1501 Page Mill Road 23# Palo Alto, California 94304 24# 25# Redistributions of source code must retain the above copyright notice, 26# this list of conditions and the following disclaimer. Redistributions 27# in binary form must reproduce the above copyright notice, this list of 28# conditions and the following disclaimer in the documentation and/or 29# other materials provided with the distribution. Neither the name of 30# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 31# contributors may be used to endorse or promote products derived from 32# this software without specific prior written permission. No right of 33# sublicense is granted herewith. Derivatives of the software and 34# output created using the software may be prepared, but only for 35# Non-Commercial Uses. Derivatives of the software may be shared with 36# others provided: (i) the others agree to abide by the list of 37# conditions herein which includes the Non-Commercial Use restrictions; 38# and (ii) such Derivatives of the software include the above copyright 39# notice to acknowledge the contribution from this software where 40# applicable, this list of conditions and the disclaimer below. 41# 42# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53# 54# Authors: Gabe Black 55 56microcode = ''' 57 58# 59# Byte version of one operand unsigned multiply. 60# 61 62def macroop MUL_B_R 63{ 64 mul1u rax, reg 65 mulel rax 66 # Really ah 67 muleh rsi, flags=(OF,CF) 68}; 69 70def macroop MUL_B_M 71{ 72 ld t1, seg, sib, disp 73 mul1u rax, t1 74 mulel rax 75 # Really ah 76 muleh rsi, flags=(OF,CF) 77}; 78 79def macroop MUL_B_P 80{ 81 rdip t7 82 ld t1, seg, riprel, disp 83 mul1u rax, t1 84 mulel rax 85 # Really ah 86 muleh rsi, flags=(OF,CF) 87}; 88 89# 90# One operand unsigned multiply. 91# 92 93def macroop MUL_R 94{ 95 mul1u rax, reg 96 mulel rax 97 muleh rdx, flags=(OF,CF) 98}; 99 100def macroop MUL_M 101{ 102 ld t1, seg, sib, disp 103 mul1u rax, t1 104 mulel rax 105 muleh rdx, flags=(OF,CF) 106}; 107 108def macroop MUL_P 109{ 110 rdip t7 111 ld t1, seg, riprel, disp 112 mul1u rax, t1 113 mulel rax 114 muleh rdx, flags=(OF,CF) 115}; 116 117# 118# Byte version of one operand signed multiply. 119# 120 121def macroop IMUL_B_R 122{ 123 mul1s rax, reg 124 mulel rax 125 # Really ah 126 muleh rsi, flags=(OF,CF) 127}; 128 129def macroop IMUL_B_M 130{ 131 ld t1, seg, sib, disp 132 mul1s rax, t1 133 mulel rax 134 # Really ah 135 muleh rsi, flags=(OF,CF) 136}; 137 138def macroop IMUL_B_P 139{ 140 rdip t7 141 ld t1, seg, riprel, disp 142 mul1s rax, t1 143 mulel rax 144 # Really ah 145 muleh rsi, flags=(OF,CF) 146}; 147 148# 149# One operand signed multiply. 150# 151 152def macroop IMUL_R 153{ 154 mul1s rax, reg 155 mulel rax 156 muleh rdx, flags=(OF,CF) 157}; 158 159def macroop IMUL_M 160{ 161 ld t1, seg, sib, disp 162 mul1s rax, t1 163 mulel rax 164 muleh rdx, flags=(OF,CF) 165}; 166 167def macroop IMUL_P 168{ 169 rdip t7 170 ld t1, seg, riprel, disp 171 mul1s rax, t1 172 mulel rax 173 muleh rdx, flags=(OF,CF) 174}; 175 176def macroop IMUL_R_R 177{ 178 mul1s reg, regm 179 mulel reg 180 muleh t0, flags=(CF,OF) 181}; 182 183def macroop IMUL_R_M 184{ 185 ld t1, seg, sib, disp 186 mul1s reg, t1 187 mulel reg 188 muleh t0, flags=(CF,OF) 189}; 190 191def macroop IMUL_R_P 192{ 193 rdip t7 194 ld t1, seg, riprel, disp 195 mul1s reg, t1 196 mulel reg 197 muleh t0, flags=(CF,OF) 198}; 199 200# 201# Three operand signed multiply. 202# 203 204def macroop IMUL_R_R_I 205{ 206 limm t1, imm 207 mul1s regm, t1 208 mulel reg 209 muleh t0, flags=(OF,CF) 210}; 211 212def macroop IMUL_R_M_I 213{ 214 limm t1, imm 215 ld t2, seg, sib, disp 216 mul1s t2, t1 217 mulel reg 218 muleh t0, flags=(OF,CF) 219}; 220 221def macroop IMUL_R_P_I 222{ 223 rdip t7 224 limm t1, imm 225 ld t2, seg, riprel 226 mul1s t2, t1 227 mulel reg 228 muleh t0, flags=(OF,CF) 229}; 230 231# 232# One byte version of unsigned division 233# 234 235def macroop DIV_B_R 236{ 237 # Do the initial part of the division 238 div1 rsi, reg, dataSize=1 239 240 #These are split out so we can initialize the number of bits in the 241 #second register 242 div2i t1, rax, 8, dataSize=1 243 div2 t1, rax, t1, dataSize=1 244 245 #Loop until we're out of bits to shift in 246divLoopTop: 247 div2 t1, rax, t1, dataSize=1 248 div2 t1, rax, t1, flags=(EZF,), dataSize=1 249 br label("divLoopTop"), flags=(nCEZF,) 250 251 #Unload the answer 252 divq rax, dataSize=1 253 divr rsi, dataSize=1 254}; 255 256def macroop DIV_B_M 257{ 258 ld t2, seg, sib, disp 259 260 # Do the initial part of the division 261 div1 rsi, t2, dataSize=1 262 263 #These are split out so we can initialize the number of bits in the 264 #second register 265 div2i t1, rax, 8, dataSize=1 266 div2 t1, rax, t1, dataSize=1 267 268 #Loop until we're out of bits to shift in 269divLoopTop: 270 div2 t1, rax, t1, dataSize=1 271 div2 t1, rax, t1, flags=(EZF,), dataSize=1 272 br label("divLoopTop"), flags=(nCEZF,) 273 274 #Unload the answer 275 divq rax, dataSize=1 276 divr rsi, dataSize=1 277}; 278 279def macroop DIV_B_P 280{ 281 rdip t7 282 ld t2, seg, riprel, disp 283 284 # Do the initial part of the division 285 div1 rsi, t2, dataSize=1 286 287 #These are split out so we can initialize the number of bits in the 288 #second register 289 div2i t1, rax, 8, dataSize=1 290 div2 t1, rax, t1, dataSize=1 291 292 #Loop until we're out of bits to shift in 293divLoopTop: 294 div2 t1, rax, t1, dataSize=1 295 div2 t1, rax, t1, flags=(EZF,), dataSize=1 296 br label("divLoopTop"), flags=(nCEZF,) 297 298 #Unload the answer 299 divq rax, dataSize=1 300 divr rsi, dataSize=1 301}; 302 303# 304# Unsigned division 305# 306 307def macroop DIV_R 308{ 309 # Do the initial part of the division 310 div1 rdx, reg 311 312 #These are split out so we can initialize the number of bits in the 313 #second register 314 div2i t1, rax, "env.dataSize * 8" 315 div2 t1, rax, t1 316 317 #Loop until we're out of bits to shift in 318 #The amount of unrolling here could stand some tuning 319divLoopTop: 320 div2 t1, rax, t1 321 div2 t1, rax, t1 322 div2 t1, rax, t1 323 div2 t1, rax, t1, flags=(EZF,) 324 br label("divLoopTop"), flags=(nCEZF,) 325 326 #Unload the answer 327 divq rax 328 divr rdx 329}; 330 331def macroop DIV_M 332{ 333 ld t2, seg, sib, disp 334 335 # Do the initial part of the division 336 div1 rdx, t2 337 338 #These are split out so we can initialize the number of bits in the 339 #second register 340 div2i t1, rax, "env.dataSize * 8" 341 div2 t1, rax, t1 342 343 #Loop until we're out of bits to shift in 344 #The amount of unrolling here could stand some tuning 345divLoopTop: 346 div2 t1, rax, t1 347 div2 t1, rax, t1 348 div2 t1, rax, t1 349 div2 t1, rax, t1, flags=(EZF,) 350 br label("divLoopTop"), flags=(nCEZF,) 351 352 #Unload the answer 353 divq rax 354 divr rdx 355}; 356 357def macroop DIV_P 358{ 359 rdip t7 360 ld t2, seg, riprel, disp 361 362 # Do the initial part of the division 363 div1 rdx, t2 364 365 #These are split out so we can initialize the number of bits in the 366 #second register 367 div2i t1, rax, "env.dataSize * 8" 368 div2 t1, rax, t1 369 370 #Loop until we're out of bits to shift in 371 #The amount of unrolling here could stand some tuning 372divLoopTop: 373 div2 t1, rax, t1 374 div2 t1, rax, t1 375 div2 t1, rax, t1 376 div2 t1, rax, t1, flags=(EZF,) 377 br label("divLoopTop"), flags=(nCEZF,) 378 379 #Unload the answer 380 divq rax 381 divr rdx 382}; 383 384# 385# One byte version of signed division 386# 387 388def macroop IDIV_B_R 389{ 390 # Negate dividend 391 sub t1, t0, rax, flags=(ECF,), dataSize=1 392 ruflag t4, 3 393 sub t2, t0, rsi, dataSize=1 394 sub t2, t2, t4 395 396 #Find the sign of the divisor 397 #FIXME!!! This depends on shifts setting the carry flag correctly. 398 slli t0, reg, 1, flags=(ECF,), dataSize=1 399 400 # Negate divisor 401 sub t3, t0, reg, dataSize=1 402 # Put the divisor's absolute value into t3 403 mov t3, t3, reg, flags=(nCECF,), dataSize=1 404 405 #Find the sign of the dividend 406 #FIXME!!! This depends on shifts setting the carry flag correctly. 407 slli t0, rsi, 1, flags=(ECF,), dataSize=1 408 409 # Put the dividend's absolute value into t1 and t2 410 mov t1, t1, rax, flags=(nCECF,), dataSize=1 411 mov t2, t2, rsi, flags=(nCECF,), dataSize=1 412 413 # Do the initial part of the division 414 div1 t2, t3, dataSize=1 415 416 #These are split out so we can initialize the number of bits in the 417 #second register 418 div2i t4, t1, 8, dataSize=1 419 div2 t4, t1, t4, dataSize=1 420 421 #Loop until we're out of bits to shift in 422divLoopTop: 423 div2 t4, t1, t4, dataSize=1 424 div2 t4, t1, t4, flags=(EZF,), dataSize=1 425 br label("divLoopTop"), flags=(nCEZF,) 426 427 #Unload the answer 428 divq t5, dataSize=1 429 divr t6, dataSize=1 430 431 # Fix up signs. The sign of the dividend is still lying around in ECF. 432 # The sign of the remainder, ah, is the same as the dividend. The sign 433 # of the quotient is negated if the signs of the divisor and dividend 434 # were different. 435 436 # Negate the remainder 437 sub t4, t0, t6, dataSize=1 438 # If the dividend was negitive, put the negated remainder in rsi. 439 mov rsi, rsi, t4, (CECF,), dataSize=1 440 # Otherwise put the regular remainder in rsi. 441 mov rsi, rsi, t6, (nCECF,), dataSize=1 442 443 # Negate the quotient. 444 sub t4, t0, t5, dataSize=1 445 # If the dividend was negative, start using the negated quotient 446 mov t5, t5, t4, (CECF,), dataSize=1 447 448 # Check the sign of the divisor 449 slli t0, t3, 1, flags=(ECF,), dataSize=1 450 451 # Negate the (possibly already negated) quotient 452 sub t4, t0, t5, dataSize=1 453 # If the divisor was negative, put the negated quotient in rax. 454 mov rax, rax, t4, (CECF,), dataSize=1 455 # Otherwise put the one that wasn't negated (at least here) in rax. 456 mov rax, rax, t5, (nCECF,), dataSize=1 457}; 458 459def macroop IDIV_B_M 460{ 461 # Negate dividend 462 sub t1, t0, rax, flags=(ECF,), dataSize=1 463 ruflag t4, 3 464 sub t2, t0, rsi, dataSize=1 465 sub t2, t2, t4 466 467 ld t3, seg, sib, disp 468 469 #Find the sign of the divisor 470 #FIXME!!! This depends on shifts setting the carry flag correctly. 471 slli t0, t3, 1, flags=(ECF,), dataSize=1 472 473 # Negate divisor 474 sub t4, t0, t3, dataSize=1 475 # Put the divisor's absolute value into t3 476 mov t3, t3, t4, flags=(CECF,), dataSize=1 477 478 #Find the sign of the dividend 479 #FIXME!!! This depends on shifts setting the carry flag correctly. 480 slli t0, rsi, 1, flags=(ECF,), dataSize=1 481 482 # Put the dividend's absolute value into t1 and t2 483 mov t1, t1, rax, flags=(nCECF,), dataSize=1 484 mov t2, t2, rsi, flags=(nCECF,), dataSize=1 485 486 # Do the initial part of the division 487 div1 t2, t3, dataSize=1 488 489 #These are split out so we can initialize the number of bits in the 490 #second register 491 div2i t4, t1, 8, dataSize=1 492 div2 t4, t1, t4, dataSize=1 493 494 #Loop until we're out of bits to shift in 495divLoopTop: 496 div2 t4, t1, t4, dataSize=1 497 div2 t4, t1, t4, flags=(EZF,), dataSize=1 498 br label("divLoopTop"), flags=(nCEZF,) 499 500 #Unload the answer 501 divq t5, dataSize=1 502 divr t6, dataSize=1 503 504 # Fix up signs. The sign of the dividend is still lying around in ECF. 505 # The sign of the remainder, ah, is the same as the dividend. The sign 506 # of the quotient is negated if the signs of the divisor and dividend 507 # were different. 508 509 # Negate the remainder 510 sub t4, t0, t6, dataSize=1 511 # If the dividend was negitive, put the negated remainder in rsi. 512 mov rsi, rsi, t4, (CECF,), dataSize=1 513 # Otherwise put the regular remainder in rsi. 514 mov rsi, rsi, t6, (nCECF,), dataSize=1 515 516 # Negate the quotient. 517 sub t4, t0, t5, dataSize=1 518 # If the dividend was negative, start using the negated quotient 519 mov t5, t5, t4, (CECF,), dataSize=1 520 521 # Check the sign of the divisor 522 slli t0, t3, 1, flags=(ECF,), dataSize=1 523 524 # Negate the (possibly already negated) quotient 525 sub t4, t0, t5, dataSize=1 526 # If the divisor was negative, put the negated quotient in rax. 527 mov rax, rax, t4, (CECF,), dataSize=1 528 # Otherwise put the one that wasn't negated (at least here) in rax. 529 mov rax, rax, t5, (nCECF,), dataSize=1 530}; 531 532def macroop IDIV_B_P 533{ 534 # Negate dividend 535 sub t1, t0, rax, flags=(ECF,), dataSize=1 536 ruflag t4, 3 537 sub t2, t0, rsi, dataSize=1 538 sub t2, t2, t4 539 540 rdip t7 541 ld t3, seg, riprel, disp 542 543 #Find the sign of the divisor 544 #FIXME!!! This depends on shifts setting the carry flag correctly. 545 slli t0, t3, 1, flags=(ECF,), dataSize=1 546 547 # Negate divisor 548 sub t4, t0, t3, dataSize=1 549 # Put the divisor's absolute value into t3 550 mov t3, t3, t4, flags=(CECF,), dataSize=1 551 552 #Find the sign of the dividend 553 #FIXME!!! This depends on shifts setting the carry flag correctly. 554 slli t0, rsi, 1, flags=(ECF,), dataSize=1 555 556 # Put the dividend's absolute value into t1 and t2 557 mov t1, t1, rax, flags=(nCECF,), dataSize=1 558 mov t2, t2, rsi, flags=(nCECF,), dataSize=1 559 560 # Do the initial part of the division 561 div1 t2, t3, dataSize=1 562 563 #These are split out so we can initialize the number of bits in the 564 #second register 565 div2i t4, t1, 8, dataSize=1 566 div2 t4, t1, t4, dataSize=1 567 568 #Loop until we're out of bits to shift in 569divLoopTop: 570 div2 t4, t1, t4, dataSize=1 571 div2 t4, t1, t4, flags=(EZF,), dataSize=1 572 br label("divLoopTop"), flags=(nCEZF,) 573 574 #Unload the answer 575 divq t5, dataSize=1 576 divr t6, dataSize=1 577 578 # Fix up signs. The sign of the dividend is still lying around in ECF. 579 # The sign of the remainder, ah, is the same as the dividend. The sign 580 # of the quotient is negated if the signs of the divisor and dividend 581 # were different. 582 583 # Negate the remainder 584 sub t4, t0, t6, dataSize=1 585 # If the dividend was negitive, put the negated remainder in rsi. 586 mov rsi, rsi, t4, (CECF,), dataSize=1 587 # Otherwise put the regular remainder in rsi. 588 mov rsi, rsi, t6, (nCECF,), dataSize=1 589 590 # Negate the quotient. 591 sub t4, t0, t5, dataSize=1 592 # If the dividend was negative, start using the negated quotient 593 mov t5, t5, t4, (CECF,), dataSize=1 594 595 # Check the sign of the divisor 596 slli t0, t3, 1, flags=(ECF,), dataSize=1 597 598 # Negate the (possibly already negated) quotient 599 sub t4, t0, t5, dataSize=1 600 # If the divisor was negative, put the negated quotient in rax. 601 mov rax, rax, t4, (CECF,), dataSize=1 602 # Otherwise put the one that wasn't negated (at least here) in rax. 603 mov rax, rax, t5, (nCECF,), dataSize=1 604}; 605 606# 607# Signed division 608# 609 610def macroop IDIV_R 611{ 612 # Negate dividend 613 sub t1, t0, rax, flags=(ECF,) 614 ruflag t4, 3 615 sub t2, t0, rdx 616 sub t2, t2, t4 617 618 #Find the sign of the divisor 619 #FIXME!!! This depends on shifts setting the carry flag correctly. 620 slli t0, reg, 1, flags=(ECF,) 621 622 # Negate divisor 623 sub t3, t0, reg 624 # Put the divisor's absolute value into t3 625 mov t3, t3, reg, flags=(nCECF,) 626 627 #Find the sign of the dividend 628 #FIXME!!! This depends on shifts setting the carry flag correctly. 629 slli t0, rdx, 1, flags=(ECF,) 630 631 # Put the dividend's absolute value into t1 and t2 632 mov t1, t1, rax, flags=(nCECF,) 633 mov t2, t2, rdx, flags=(nCECF,) 634 635 # Do the initial part of the division 636 div1 t2, t3 637 638 #These are split out so we can initialize the number of bits in the 639 #second register 640 div2i t4, t1, "env.dataSize * 8" 641 div2 t4, t1, t4 642 643 #Loop until we're out of bits to shift in 644divLoopTop: 645 div2 t4, t1, t4 646 div2 t4, t1, t4 647 div2 t4, t1, t4 648 div2 t4, t1, t4, flags=(EZF,) 649 br label("divLoopTop"), flags=(nCEZF,) 650 651 #Unload the answer 652 divq t5 653 divr t6 654 655 # Fix up signs. The sign of the dividend is still lying around in ECF. 656 # The sign of the remainder, ah, is the same as the dividend. The sign 657 # of the quotient is negated if the signs of the divisor and dividend 658 # were different. 659 660 # Negate the remainder 661 sub t4, t0, t6 662 # If the dividend was negitive, put the negated remainder in rdx. 663 mov rdx, rdx, t4, (CECF,) 664 # Otherwise put the regular remainder in rdx. 665 mov rdx, rdx, t6, (nCECF,) 666 667 # Negate the quotient. 668 sub t4, t0, t5 669 # If the dividend was negative, start using the negated quotient 670 mov t5, t5, t4, (CECF,) 671 672 # Check the sign of the divisor 673 slli t0, t3, 1, flags=(ECF,) 674 675 # Negate the (possibly already negated) quotient 676 sub t4, t0, t5 677 # If the divisor was negative, put the negated quotient in rax. 678 mov rax, rax, t4, (CECF,) 679 # Otherwise put the one that wasn't negated (at least here) in rax. 680 mov rax, rax, t5, (nCECF,) 681}; 682 683def macroop IDIV_M 684{ 685 # Negate dividend 686 sub t1, t0, rax, flags=(ECF,) 687 ruflag t4, 3 688 sub t2, t0, rdx 689 sub t2, t2, t4 690 691 ld t3, seg, sib, disp 692 693 #Find the sign of the divisor 694 #FIXME!!! This depends on shifts setting the carry flag correctly. 695 slli t0, t3, 1, flags=(ECF,) 696 697 # Negate divisor 698 sub t4, t0, t3 699 # Put the divisor's absolute value into t3 700 mov t3, t3, t4, flags=(CECF,) 701 702 #Find the sign of the dividend 703 #FIXME!!! This depends on shifts setting the carry flag correctly. 704 slli t0, rdx, 1, flags=(ECF,) 705 706 # Put the dividend's absolute value into t1 and t2 707 mov t1, t1, rax, flags=(nCECF,) 708 mov t2, t2, rdx, flags=(nCECF,) 709 710 # Do the initial part of the division 711 div1 t2, t3 712 713 #These are split out so we can initialize the number of bits in the 714 #second register 715 div2i t4, t1, "env.dataSize * 8" 716 div2 t4, t1, t4 717 718 #Loop until we're out of bits to shift in 719divLoopTop: 720 div2 t4, t1, t4 721 div2 t4, t1, t4 722 div2 t4, t1, t4 723 div2 t4, t1, t4, flags=(EZF,) 724 br label("divLoopTop"), flags=(nCEZF,) 725 726 #Unload the answer 727 divq t5 728 divr t6 729 730 # Fix up signs. The sign of the dividend is still lying around in ECF. 731 # The sign of the remainder, ah, is the same as the dividend. The sign 732 # of the quotient is negated if the signs of the divisor and dividend 733 # were different. 734 735 # Negate the remainder 736 sub t4, t0, t6 737 # If the dividend was negitive, put the negated remainder in rdx. 738 mov rdx, rdx, t4, (CECF,) 739 # Otherwise put the regular remainder in rdx. 740 mov rdx, rdx, t6, (nCECF,) 741 742 # Negate the quotient. 743 sub t4, t0, t5 744 # If the dividend was negative, start using the negated quotient 745 mov t5, t5, t4, (CECF,) 746 747 # Check the sign of the divisor 748 slli t0, t3, 1, flags=(ECF,) 749 750 # Negate the (possibly already negated) quotient 751 sub t4, t0, t5 752 # If the divisor was negative, put the negated quotient in rax. 753 mov rax, rax, t4, (CECF,) 754 # Otherwise put the one that wasn't negated (at least here) in rax. 755 mov rax, rax, t5, (nCECF,) 756}; 757 758def macroop IDIV_P 759{ 760 # Negate dividend 761 sub t1, t0, rax, flags=(ECF,) 762 ruflag t4, 3 763 sub t2, t0, rdx 764 sub t2, t2, t4 765 766 rdip t7 767 ld t3, seg, riprel, disp 768 769 #Find the sign of the divisor 770 #FIXME!!! This depends on shifts setting the carry flag correctly. 771 slli t0, t3, 1, flags=(ECF,) 772 773 # Negate divisor 774 sub t4, t0, t3 775 # Put the divisor's absolute value into t3 776 mov t3, t3, t4, flags=(CECF,) 777 778 #Find the sign of the dividend 779 #FIXME!!! This depends on shifts setting the carry flag correctly. 780 slli t0, rdx, 1, flags=(ECF,) 781 782 # Put the dividend's absolute value into t1 and t2 783 mov t1, t1, rax, flags=(nCECF,) 784 mov t2, t2, rdx, flags=(nCECF,) 785 786 # Do the initial part of the division 787 div1 t2, t3 788 789 #These are split out so we can initialize the number of bits in the 790 #second register 791 div2i t4, t1, "env.dataSize * 8" 792 div2 t4, t1, t4 793 794 #Loop until we're out of bits to shift in 795divLoopTop: 796 div2 t4, t1, t4 797 div2 t4, t1, t4 798 div2 t4, t1, t4 799 div2 t4, t1, t4, flags=(EZF,) 800 br label("divLoopTop"), flags=(nCEZF,) 801 802 #Unload the answer 803 divq t5 804 divr t6 805 806 # Fix up signs. The sign of the dividend is still lying around in ECF. 807 # The sign of the remainder, ah, is the same as the dividend. The sign 808 # of the quotient is negated if the signs of the divisor and dividend 809 # were different. 810 811 # Negate the remainder 812 sub t4, t0, t6 813 # If the dividend was negitive, put the negated remainder in rdx. 814 mov rdx, rdx, t4, (CECF,) 815 # Otherwise put the regular remainder in rdx. 816 mov rdx, rdx, t6, (nCECF,) 817 818 # Negate the quotient. 819 sub t4, t0, t5 820 # If the dividend was negative, start using the negated quotient 821 mov t5, t5, t4, (CECF,) 822 823 # Check the sign of the divisor 824 slli t0, t3, 1, flags=(ECF,) 825 826 # Negate the (possibly already negated) quotient 827 sub t4, t0, t5 828 # If the divisor was negative, put the negated quotient in rax. 829 mov rax, rax, t4, (CECF,) 830 # Otherwise put the one that wasn't negated (at least here) in rax. 831 mov rax, rax, t5, (nCECF,) 832}; 833''' 834