multiply_and_divide.py revision 6458:d959f578ae42
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 muleh ah, flags=(OF,CF) 67}; 68 69def macroop MUL_B_M 70{ 71 ld t1, seg, sib, disp 72 mul1u rax, t1 73 mulel rax 74 muleh ah, flags=(OF,CF) 75}; 76 77def macroop MUL_B_P 78{ 79 rdip t7 80 ld t1, seg, riprel, disp 81 mul1u rax, t1 82 mulel rax 83 muleh ah, flags=(OF,CF) 84}; 85 86# 87# One operand unsigned multiply. 88# 89 90def macroop MUL_R 91{ 92 mul1u rax, reg 93 mulel rax 94 muleh rdx, flags=(OF,CF) 95}; 96 97def macroop MUL_M 98{ 99 ld t1, seg, sib, disp 100 mul1u rax, t1 101 mulel rax 102 muleh rdx, flags=(OF,CF) 103}; 104 105def macroop MUL_P 106{ 107 rdip t7 108 ld t1, seg, riprel, disp 109 mul1u rax, t1 110 mulel rax 111 muleh rdx, flags=(OF,CF) 112}; 113 114# 115# Byte version of one operand signed multiply. 116# 117 118def macroop IMUL_B_R 119{ 120 mul1s rax, reg 121 mulel rax 122 muleh ah, flags=(OF,CF) 123}; 124 125def macroop IMUL_B_M 126{ 127 ld t1, seg, sib, disp 128 mul1s rax, t1 129 mulel rax 130 muleh ah, flags=(OF,CF) 131}; 132 133def macroop IMUL_B_P 134{ 135 rdip t7 136 ld t1, seg, riprel, disp 137 mul1s rax, t1 138 mulel rax 139 muleh ah, flags=(OF,CF) 140}; 141 142# 143# One operand signed multiply. 144# 145 146def macroop IMUL_R 147{ 148 mul1s rax, reg 149 mulel rax 150 muleh rdx, flags=(OF,CF) 151}; 152 153def macroop IMUL_M 154{ 155 ld t1, seg, sib, disp 156 mul1s rax, t1 157 mulel rax 158 muleh rdx, flags=(OF,CF) 159}; 160 161def macroop IMUL_P 162{ 163 rdip t7 164 ld t1, seg, riprel, disp 165 mul1s rax, t1 166 mulel rax 167 muleh rdx, flags=(OF,CF) 168}; 169 170def macroop IMUL_R_R 171{ 172 mul1s reg, regm 173 mulel reg 174 muleh t0, flags=(CF,OF) 175}; 176 177def macroop IMUL_R_M 178{ 179 ld t1, seg, sib, disp 180 mul1s reg, t1 181 mulel reg 182 muleh t0, flags=(CF,OF) 183}; 184 185def macroop IMUL_R_P 186{ 187 rdip t7 188 ld t1, seg, riprel, disp 189 mul1s reg, t1 190 mulel reg 191 muleh t0, flags=(CF,OF) 192}; 193 194# 195# Three operand signed multiply. 196# 197 198def macroop IMUL_R_R_I 199{ 200 limm t1, imm 201 mul1s regm, t1 202 mulel reg 203 muleh t0, flags=(OF,CF) 204}; 205 206def macroop IMUL_R_M_I 207{ 208 limm t1, imm 209 ld t2, seg, sib, disp 210 mul1s t2, t1 211 mulel reg 212 muleh t0, flags=(OF,CF) 213}; 214 215def macroop IMUL_R_P_I 216{ 217 rdip t7 218 limm t1, imm 219 ld t2, seg, riprel 220 mul1s t2, t1 221 mulel reg 222 muleh t0, flags=(OF,CF) 223}; 224 225# 226# One byte version of unsigned division 227# 228 229def macroop DIV_B_R 230{ 231 # Do the initial part of the division 232 div1 rsi, reg, dataSize=1 233 234 #These are split out so we can initialize the number of bits in the 235 #second register 236 div2i t1, rax, 8, dataSize=1 237 div2 t1, rax, t1, dataSize=1 238 239 #Loop until we're out of bits to shift in 240divLoopTop: 241 div2 t1, rax, t1, dataSize=1 242 div2 t1, rax, t1, flags=(EZF,), dataSize=1 243 br label("divLoopTop"), flags=(nCEZF,) 244 245 #Unload the answer 246 divq rax, dataSize=1 247 divr rsi, dataSize=1 248}; 249 250def macroop DIV_B_M 251{ 252 ld t2, seg, sib, disp 253 254 # Do the initial part of the division 255 div1 rsi, t2, dataSize=1 256 257 #These are split out so we can initialize the number of bits in the 258 #second register 259 div2i t1, rax, 8, dataSize=1 260 div2 t1, rax, t1, dataSize=1 261 262 #Loop until we're out of bits to shift in 263divLoopTop: 264 div2 t1, rax, t1, dataSize=1 265 div2 t1, rax, t1, flags=(EZF,), dataSize=1 266 br label("divLoopTop"), flags=(nCEZF,) 267 268 #Unload the answer 269 divq rax, dataSize=1 270 divr rsi, dataSize=1 271}; 272 273def macroop DIV_B_P 274{ 275 rdip t7 276 ld t2, seg, riprel, disp 277 278 # Do the initial part of the division 279 div1 rsi, t2, dataSize=1 280 281 #These are split out so we can initialize the number of bits in the 282 #second register 283 div2i t1, rax, 8, dataSize=1 284 div2 t1, rax, t1, dataSize=1 285 286 #Loop until we're out of bits to shift in 287divLoopTop: 288 div2 t1, rax, t1, dataSize=1 289 div2 t1, rax, t1, flags=(EZF,), dataSize=1 290 br label("divLoopTop"), flags=(nCEZF,) 291 292 #Unload the answer 293 divq rax, dataSize=1 294 divr rsi, dataSize=1 295}; 296 297# 298# Unsigned division 299# 300 301def macroop DIV_R 302{ 303 # Do the initial part of the division 304 div1 rdx, reg 305 306 #These are split out so we can initialize the number of bits in the 307 #second register 308 div2i t1, rax, "env.dataSize * 8" 309 div2 t1, rax, t1 310 311 #Loop until we're out of bits to shift in 312 #The amount of unrolling here could stand some tuning 313divLoopTop: 314 div2 t1, rax, t1 315 div2 t1, rax, t1 316 div2 t1, rax, t1 317 div2 t1, rax, t1, flags=(EZF,) 318 br label("divLoopTop"), flags=(nCEZF,) 319 320 #Unload the answer 321 divq rax 322 divr rdx 323}; 324 325def macroop DIV_M 326{ 327 ld t2, seg, sib, disp 328 329 # Do the initial part of the division 330 div1 rdx, t2 331 332 #These are split out so we can initialize the number of bits in the 333 #second register 334 div2i t1, rax, "env.dataSize * 8" 335 div2 t1, rax, t1 336 337 #Loop until we're out of bits to shift in 338 #The amount of unrolling here could stand some tuning 339divLoopTop: 340 div2 t1, rax, t1 341 div2 t1, rax, t1 342 div2 t1, rax, t1 343 div2 t1, rax, t1, flags=(EZF,) 344 br label("divLoopTop"), flags=(nCEZF,) 345 346 #Unload the answer 347 divq rax 348 divr rdx 349}; 350 351def macroop DIV_P 352{ 353 rdip t7 354 ld t2, seg, riprel, disp 355 356 # Do the initial part of the division 357 div1 rdx, t2 358 359 #These are split out so we can initialize the number of bits in the 360 #second register 361 div2i t1, rax, "env.dataSize * 8" 362 div2 t1, rax, t1 363 364 #Loop until we're out of bits to shift in 365 #The amount of unrolling here could stand some tuning 366divLoopTop: 367 div2 t1, rax, t1 368 div2 t1, rax, t1 369 div2 t1, rax, t1 370 div2 t1, rax, t1, flags=(EZF,) 371 br label("divLoopTop"), flags=(nCEZF,) 372 373 #Unload the answer 374 divq rax 375 divr rdx 376}; 377 378# 379# One byte version of signed division 380# 381 382def macroop IDIV_B_R 383{ 384 # Negate dividend 385 sub t1, t0, rax, flags=(ECF,), dataSize=1 386 ruflag t4, 3 387 sub t2, t0, rsi, dataSize=1 388 sub t2, t2, t4 389 390 #Find the sign of the divisor 391 #FIXME!!! This depends on shifts setting the carry flag correctly. 392 slli t0, reg, 1, flags=(ECF,), dataSize=1 393 394 # Negate divisor 395 sub t3, t0, reg, dataSize=1 396 # Put the divisor's absolute value into t3 397 mov t3, t3, reg, flags=(nCECF,), dataSize=1 398 399 #Find the sign of the dividend 400 #FIXME!!! This depends on shifts setting the carry flag correctly. 401 slli t0, rsi, 1, flags=(ECF,), dataSize=1 402 403 # Put the dividend's absolute value into t1 and t2 404 mov t1, t1, rax, flags=(nCECF,), dataSize=1 405 mov t2, t2, rsi, flags=(nCECF,), dataSize=1 406 407 # Do the initial part of the division 408 div1 t2, t3, dataSize=1 409 410 #These are split out so we can initialize the number of bits in the 411 #second register 412 div2i t4, t1, 8, dataSize=1 413 div2 t4, t1, t4, dataSize=1 414 415 #Loop until we're out of bits to shift in 416divLoopTop: 417 div2 t4, t1, t4, dataSize=1 418 div2 t4, t1, t4, flags=(EZF,), dataSize=1 419 br label("divLoopTop"), flags=(nCEZF,) 420 421 #Unload the answer 422 divq t5, dataSize=1 423 divr t6, dataSize=1 424 425 # Fix up signs. The sign of the dividend is still lying around in ECF. 426 # The sign of the remainder, ah, is the same as the dividend. The sign 427 # of the quotient is negated if the signs of the divisor and dividend 428 # were different. 429 430 # Negate the remainder 431 sub t4, t0, t6, dataSize=1 432 # If the dividend was negitive, put the negated remainder in rsi. 433 mov rsi, rsi, t4, (CECF,), dataSize=1 434 # Otherwise put the regular remainder in rsi. 435 mov rsi, rsi, t6, (nCECF,), dataSize=1 436 437 # Negate the quotient. 438 sub t4, t0, t5, dataSize=1 439 # If the dividend was negative, start using the negated quotient 440 mov t5, t5, t4, (CECF,), dataSize=1 441 442 # Check the sign of the divisor 443 slli t0, t3, 1, flags=(ECF,), dataSize=1 444 445 # Negate the (possibly already negated) quotient 446 sub t4, t0, t5, dataSize=1 447 # If the divisor was negative, put the negated quotient in rax. 448 mov rax, rax, t4, (CECF,), dataSize=1 449 # Otherwise put the one that wasn't negated (at least here) in rax. 450 mov rax, rax, t5, (nCECF,), dataSize=1 451}; 452 453def macroop IDIV_B_M 454{ 455 # Negate dividend 456 sub t1, t0, rax, flags=(ECF,), dataSize=1 457 ruflag t4, 3 458 sub t2, t0, rsi, dataSize=1 459 sub t2, t2, t4 460 461 ld t3, seg, sib, disp 462 463 #Find the sign of the divisor 464 #FIXME!!! This depends on shifts setting the carry flag correctly. 465 slli t0, t3, 1, flags=(ECF,), dataSize=1 466 467 # Negate divisor 468 sub t4, t0, t3, dataSize=1 469 # Put the divisor's absolute value into t3 470 mov t3, t3, t4, flags=(CECF,), dataSize=1 471 472 #Find the sign of the dividend 473 #FIXME!!! This depends on shifts setting the carry flag correctly. 474 slli t0, rsi, 1, flags=(ECF,), dataSize=1 475 476 # Put the dividend's absolute value into t1 and t2 477 mov t1, t1, rax, flags=(nCECF,), dataSize=1 478 mov t2, t2, rsi, flags=(nCECF,), dataSize=1 479 480 # Do the initial part of the division 481 div1 t2, t3, dataSize=1 482 483 #These are split out so we can initialize the number of bits in the 484 #second register 485 div2i t4, t1, 8, dataSize=1 486 div2 t4, t1, t4, dataSize=1 487 488 #Loop until we're out of bits to shift in 489divLoopTop: 490 div2 t4, t1, t4, dataSize=1 491 div2 t4, t1, t4, flags=(EZF,), dataSize=1 492 br label("divLoopTop"), flags=(nCEZF,) 493 494 #Unload the answer 495 divq t5, dataSize=1 496 divr t6, dataSize=1 497 498 # Fix up signs. The sign of the dividend is still lying around in ECF. 499 # The sign of the remainder, ah, is the same as the dividend. The sign 500 # of the quotient is negated if the signs of the divisor and dividend 501 # were different. 502 503 # Negate the remainder 504 sub t4, t0, t6, dataSize=1 505 # If the dividend was negitive, put the negated remainder in rsi. 506 mov rsi, rsi, t4, (CECF,), dataSize=1 507 # Otherwise put the regular remainder in rsi. 508 mov rsi, rsi, t6, (nCECF,), dataSize=1 509 510 # Negate the quotient. 511 sub t4, t0, t5, dataSize=1 512 # If the dividend was negative, start using the negated quotient 513 mov t5, t5, t4, (CECF,), dataSize=1 514 515 # Check the sign of the divisor 516 slli t0, t3, 1, flags=(ECF,), dataSize=1 517 518 # Negate the (possibly already negated) quotient 519 sub t4, t0, t5, dataSize=1 520 # If the divisor was negative, put the negated quotient in rax. 521 mov rax, rax, t4, (CECF,), dataSize=1 522 # Otherwise put the one that wasn't negated (at least here) in rax. 523 mov rax, rax, t5, (nCECF,), dataSize=1 524}; 525 526def macroop IDIV_B_P 527{ 528 # Negate dividend 529 sub t1, t0, rax, flags=(ECF,), dataSize=1 530 ruflag t4, 3 531 sub t2, t0, rsi, dataSize=1 532 sub t2, t2, t4 533 534 rdip t7 535 ld t3, seg, riprel, disp 536 537 #Find the sign of the divisor 538 #FIXME!!! This depends on shifts setting the carry flag correctly. 539 slli t0, t3, 1, flags=(ECF,), dataSize=1 540 541 # Negate divisor 542 sub t4, t0, t3, dataSize=1 543 # Put the divisor's absolute value into t3 544 mov t3, t3, t4, flags=(CECF,), dataSize=1 545 546 #Find the sign of the dividend 547 #FIXME!!! This depends on shifts setting the carry flag correctly. 548 slli t0, rsi, 1, flags=(ECF,), dataSize=1 549 550 # Put the dividend's absolute value into t1 and t2 551 mov t1, t1, rax, flags=(nCECF,), dataSize=1 552 mov t2, t2, rsi, flags=(nCECF,), dataSize=1 553 554 # Do the initial part of the division 555 div1 t2, t3, dataSize=1 556 557 #These are split out so we can initialize the number of bits in the 558 #second register 559 div2i t4, t1, 8, dataSize=1 560 div2 t4, t1, t4, dataSize=1 561 562 #Loop until we're out of bits to shift in 563divLoopTop: 564 div2 t4, t1, t4, dataSize=1 565 div2 t4, t1, t4, flags=(EZF,), dataSize=1 566 br label("divLoopTop"), flags=(nCEZF,) 567 568 #Unload the answer 569 divq t5, dataSize=1 570 divr t6, dataSize=1 571 572 # Fix up signs. The sign of the dividend is still lying around in ECF. 573 # The sign of the remainder, ah, is the same as the dividend. The sign 574 # of the quotient is negated if the signs of the divisor and dividend 575 # were different. 576 577 # Negate the remainder 578 sub t4, t0, t6, dataSize=1 579 # If the dividend was negitive, put the negated remainder in rsi. 580 mov rsi, rsi, t4, (CECF,), dataSize=1 581 # Otherwise put the regular remainder in rsi. 582 mov rsi, rsi, t6, (nCECF,), dataSize=1 583 584 # Negate the quotient. 585 sub t4, t0, t5, dataSize=1 586 # If the dividend was negative, start using the negated quotient 587 mov t5, t5, t4, (CECF,), dataSize=1 588 589 # Check the sign of the divisor 590 slli t0, t3, 1, flags=(ECF,), dataSize=1 591 592 # Negate the (possibly already negated) quotient 593 sub t4, t0, t5, dataSize=1 594 # If the divisor was negative, put the negated quotient in rax. 595 mov rax, rax, t4, (CECF,), dataSize=1 596 # Otherwise put the one that wasn't negated (at least here) in rax. 597 mov rax, rax, t5, (nCECF,), dataSize=1 598}; 599 600# 601# Signed division 602# 603 604def macroop IDIV_R 605{ 606 # Negate dividend 607 sub t1, t0, rax, flags=(ECF,) 608 ruflag t4, 3 609 sub t2, t0, rdx 610 sub t2, t2, t4 611 612 #Find the sign of the divisor 613 #FIXME!!! This depends on shifts setting the carry flag correctly. 614 slli t0, reg, 1, flags=(ECF,) 615 616 # Negate divisor 617 sub t3, t0, reg 618 # Put the divisor's absolute value into t3 619 mov t3, t3, reg, flags=(nCECF,) 620 621 #Find the sign of the dividend 622 #FIXME!!! This depends on shifts setting the carry flag correctly. 623 slli t0, rdx, 1, flags=(ECF,) 624 625 # Put the dividend's absolute value into t1 and t2 626 mov t1, t1, rax, flags=(nCECF,) 627 mov t2, t2, rdx, flags=(nCECF,) 628 629 # Do the initial part of the division 630 div1 t2, t3 631 632 #These are split out so we can initialize the number of bits in the 633 #second register 634 div2i t4, t1, "env.dataSize * 8" 635 div2 t4, t1, t4 636 637 #Loop until we're out of bits to shift in 638divLoopTop: 639 div2 t4, t1, t4 640 div2 t4, t1, t4 641 div2 t4, t1, t4 642 div2 t4, t1, t4, flags=(EZF,) 643 br label("divLoopTop"), flags=(nCEZF,) 644 645 #Unload the answer 646 divq t5 647 divr t6 648 649 # Fix up signs. The sign of the dividend is still lying around in ECF. 650 # The sign of the remainder, ah, is the same as the dividend. The sign 651 # of the quotient is negated if the signs of the divisor and dividend 652 # were different. 653 654 # Negate the remainder 655 sub t4, t0, t6 656 # If the dividend was negitive, put the negated remainder in rdx. 657 mov rdx, rdx, t4, (CECF,) 658 # Otherwise put the regular remainder in rdx. 659 mov rdx, rdx, t6, (nCECF,) 660 661 # Negate the quotient. 662 sub t4, t0, t5 663 # If the dividend was negative, start using the negated quotient 664 mov t5, t5, t4, (CECF,) 665 666 # Check the sign of the divisor 667 slli t0, t3, 1, flags=(ECF,) 668 669 # Negate the (possibly already negated) quotient 670 sub t4, t0, t5 671 # If the divisor was negative, put the negated quotient in rax. 672 mov rax, rax, t4, (CECF,) 673 # Otherwise put the one that wasn't negated (at least here) in rax. 674 mov rax, rax, t5, (nCECF,) 675}; 676 677def macroop IDIV_M 678{ 679 # Negate dividend 680 sub t1, t0, rax, flags=(ECF,) 681 ruflag t4, 3 682 sub t2, t0, rdx 683 sub t2, t2, t4 684 685 ld t3, seg, sib, disp 686 687 #Find the sign of the divisor 688 #FIXME!!! This depends on shifts setting the carry flag correctly. 689 slli t0, t3, 1, flags=(ECF,) 690 691 # Negate divisor 692 sub t4, t0, t3 693 # Put the divisor's absolute value into t3 694 mov t3, t3, t4, flags=(CECF,) 695 696 #Find the sign of the dividend 697 #FIXME!!! This depends on shifts setting the carry flag correctly. 698 slli t0, rdx, 1, flags=(ECF,) 699 700 # Put the dividend's absolute value into t1 and t2 701 mov t1, t1, rax, flags=(nCECF,) 702 mov t2, t2, rdx, flags=(nCECF,) 703 704 # Do the initial part of the division 705 div1 t2, t3 706 707 #These are split out so we can initialize the number of bits in the 708 #second register 709 div2i t4, t1, "env.dataSize * 8" 710 div2 t4, t1, t4 711 712 #Loop until we're out of bits to shift in 713divLoopTop: 714 div2 t4, t1, t4 715 div2 t4, t1, t4 716 div2 t4, t1, t4 717 div2 t4, t1, t4, flags=(EZF,) 718 br label("divLoopTop"), flags=(nCEZF,) 719 720 #Unload the answer 721 divq t5 722 divr t6 723 724 # Fix up signs. The sign of the dividend is still lying around in ECF. 725 # The sign of the remainder, ah, is the same as the dividend. The sign 726 # of the quotient is negated if the signs of the divisor and dividend 727 # were different. 728 729 # Negate the remainder 730 sub t4, t0, t6 731 # If the dividend was negitive, put the negated remainder in rdx. 732 mov rdx, rdx, t4, (CECF,) 733 # Otherwise put the regular remainder in rdx. 734 mov rdx, rdx, t6, (nCECF,) 735 736 # Negate the quotient. 737 sub t4, t0, t5 738 # If the dividend was negative, start using the negated quotient 739 mov t5, t5, t4, (CECF,) 740 741 # Check the sign of the divisor 742 slli t0, t3, 1, flags=(ECF,) 743 744 # Negate the (possibly already negated) quotient 745 sub t4, t0, t5 746 # If the divisor was negative, put the negated quotient in rax. 747 mov rax, rax, t4, (CECF,) 748 # Otherwise put the one that wasn't negated (at least here) in rax. 749 mov rax, rax, t5, (nCECF,) 750}; 751 752def macroop IDIV_P 753{ 754 # Negate dividend 755 sub t1, t0, rax, flags=(ECF,) 756 ruflag t4, 3 757 sub t2, t0, rdx 758 sub t2, t2, t4 759 760 rdip t7 761 ld t3, seg, riprel, disp 762 763 #Find the sign of the divisor 764 #FIXME!!! This depends on shifts setting the carry flag correctly. 765 slli t0, t3, 1, flags=(ECF,) 766 767 # Negate divisor 768 sub t4, t0, t3 769 # Put the divisor's absolute value into t3 770 mov t3, t3, t4, flags=(CECF,) 771 772 #Find the sign of the dividend 773 #FIXME!!! This depends on shifts setting the carry flag correctly. 774 slli t0, rdx, 1, flags=(ECF,) 775 776 # Put the dividend's absolute value into t1 and t2 777 mov t1, t1, rax, flags=(nCECF,) 778 mov t2, t2, rdx, flags=(nCECF,) 779 780 # Do the initial part of the division 781 div1 t2, t3 782 783 #These are split out so we can initialize the number of bits in the 784 #second register 785 div2i t4, t1, "env.dataSize * 8" 786 div2 t4, t1, t4 787 788 #Loop until we're out of bits to shift in 789divLoopTop: 790 div2 t4, t1, t4 791 div2 t4, t1, t4 792 div2 t4, t1, t4 793 div2 t4, t1, t4, flags=(EZF,) 794 br label("divLoopTop"), flags=(nCEZF,) 795 796 #Unload the answer 797 divq t5 798 divr t6 799 800 # Fix up signs. The sign of the dividend is still lying around in ECF. 801 # The sign of the remainder, ah, is the same as the dividend. The sign 802 # of the quotient is negated if the signs of the divisor and dividend 803 # were different. 804 805 # Negate the remainder 806 sub t4, t0, t6 807 # If the dividend was negitive, put the negated remainder in rdx. 808 mov rdx, rdx, t4, (CECF,) 809 # Otherwise put the regular remainder in rdx. 810 mov rdx, rdx, t6, (nCECF,) 811 812 # Negate the quotient. 813 sub t4, t0, t5 814 # If the dividend was negative, start using the negated quotient 815 mov t5, t5, t4, (CECF,) 816 817 # Check the sign of the divisor 818 slli t0, t3, 1, flags=(ECF,) 819 820 # Negate the (possibly already negated) quotient 821 sub t4, t0, t5 822 # If the divisor was negative, put the negated quotient in rax. 823 mov rax, rax, t4, (CECF,) 824 # Otherwise put the one that wasn't negated (at least here) in rax. 825 mov rax, rax, t5, (nCECF,) 826}; 827''' 828