multiply_and_divide.py revision 6513:e2ffac65a76a
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, flags=(OF,CF) 65 mulel rax 66 muleh ah 67}; 68 69def macroop MUL_B_M 70{ 71 ld t1, seg, sib, disp 72 mul1u rax, t1, flags=(OF,CF) 73 mulel rax 74 muleh ah 75}; 76 77def macroop MUL_B_P 78{ 79 rdip t7 80 ld t1, seg, riprel, disp 81 mul1u rax, t1, flags=(OF,CF) 82 mulel rax 83 muleh ah 84}; 85 86# 87# One operand unsigned multiply. 88# 89 90def macroop MUL_R 91{ 92 mul1u rax, reg, flags=(OF,CF) 93 mulel rax 94 muleh rdx 95}; 96 97def macroop MUL_M 98{ 99 ld t1, seg, sib, disp 100 mul1u rax, t1, flags=(OF,CF) 101 mulel rax 102 muleh rdx 103}; 104 105def macroop MUL_P 106{ 107 rdip t7 108 ld t1, seg, riprel, disp 109 mul1u rax, t1, flags=(OF,CF) 110 mulel rax 111 muleh rdx 112}; 113 114# 115# Byte version of one operand signed multiply. 116# 117 118def macroop IMUL_B_R 119{ 120 mul1s rax, reg, flags=(OF,CF) 121 mulel rax 122 muleh ah 123}; 124 125def macroop IMUL_B_M 126{ 127 ld t1, seg, sib, disp 128 mul1s rax, t1, flags=(OF,CF) 129 mulel rax 130 muleh ah 131}; 132 133def macroop IMUL_B_P 134{ 135 rdip t7 136 ld t1, seg, riprel, disp 137 mul1s rax, t1, flags=(OF,CF) 138 mulel rax 139 muleh ah 140}; 141 142# 143# One operand signed multiply. 144# 145 146def macroop IMUL_R 147{ 148 mul1s rax, reg, flags=(OF,CF) 149 mulel rax 150 muleh rdx 151}; 152 153def macroop IMUL_M 154{ 155 ld t1, seg, sib, disp 156 mul1s rax, t1, flags=(OF,CF) 157 mulel rax 158 muleh rdx 159}; 160 161def macroop IMUL_P 162{ 163 rdip t7 164 ld t1, seg, riprel, disp 165 mul1s rax, t1, flags=(OF,CF) 166 mulel rax 167 muleh rdx 168}; 169 170def macroop IMUL_R_R 171{ 172 mul1s reg, regm, flags=(OF,CF) 173 mulel reg 174 muleh t0 175}; 176 177def macroop IMUL_R_M 178{ 179 ld t1, seg, sib, disp 180 mul1s reg, t1, flags=(CF,OF) 181 mulel reg 182 muleh t0 183}; 184 185def macroop IMUL_R_P 186{ 187 rdip t7 188 ld t1, seg, riprel, disp 189 mul1s reg, t1, flags=(CF,OF) 190 mulel reg 191 muleh t0 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, flags=(OF,CF) 202 mulel reg 203 muleh t0 204}; 205 206def macroop IMUL_R_M_I 207{ 208 limm t1, imm 209 ld t2, seg, sib, disp 210 mul1s t2, t1, flags=(OF,CF) 211 mulel reg 212 muleh t0 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, flags=(OF,CF) 221 mulel reg 222 muleh t0 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 ah, 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 ah, 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 ah, 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 ah, 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 ah, 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 ah, 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, ah, dataSize=1 388 sub t2, t2, t4 389 390 #Find the sign of the divisor 391 slli t0, reg, 1, flags=(ECF,), dataSize=1 392 393 # Negate divisor 394 sub t3, t0, reg, dataSize=1 395 # Put the divisor's absolute value into t3 396 mov t3, t3, reg, flags=(nCECF,), dataSize=1 397 398 #Find the sign of the dividend 399 slli t0, ah, 1, flags=(ECF,), dataSize=1 400 401 # Put the dividend's absolute value into t1 and t2 402 mov t1, t1, rax, flags=(nCECF,), dataSize=1 403 mov t2, t2, ah, flags=(nCECF,), dataSize=1 404 405 # Do the initial part of the division 406 div1 t2, t3, dataSize=1 407 408 #These are split out so we can initialize the number of bits in the 409 #second register 410 div2i t4, t1, 8, dataSize=1 411 div2 t4, t1, t4, dataSize=1 412 413 #Loop until we're out of bits to shift in 414divLoopTop: 415 div2 t4, t1, t4, dataSize=1 416 div2 t4, t1, t4, flags=(EZF,), dataSize=1 417 br label("divLoopTop"), flags=(nCEZF,) 418 419 #Unload the answer 420 divq t5, dataSize=1 421 divr t6, dataSize=1 422 423 # Fix up signs. The sign of the dividend is still lying around in ECF. 424 # The sign of the remainder, ah, is the same as the dividend. The sign 425 # of the quotient is negated if the signs of the divisor and dividend 426 # were different. 427 428 # Negate the remainder 429 sub t4, t0, t6, dataSize=1 430 # If the dividend was negitive, put the negated remainder in ah. 431 mov ah, ah, t4, (CECF,), dataSize=1 432 # Otherwise put the regular remainder in ah. 433 mov ah, ah, t6, (nCECF,), dataSize=1 434 435 # Negate the quotient. 436 sub t4, t0, t5, dataSize=1 437 # If the dividend was negative, start using the negated quotient 438 mov t5, t5, t4, (CECF,), dataSize=1 439 440 # Check the sign of the divisor 441 slli t0, reg, 1, flags=(ECF,), dataSize=1 442 443 # Negate the (possibly already negated) quotient 444 sub t4, t0, t5, dataSize=1 445 # If the divisor was negative, put the negated quotient in rax. 446 mov rax, rax, t4, (CECF,), dataSize=1 447 # Otherwise put the one that wasn't negated (at least here) in rax. 448 mov rax, rax, t5, (nCECF,), dataSize=1 449}; 450 451def macroop IDIV_B_M 452{ 453 # Negate dividend 454 sub t1, t0, rax, flags=(ECF,), dataSize=1 455 ruflag t4, 3 456 sub t2, t0, ah, dataSize=1 457 sub t2, t2, t4 458 459 ld t8, seg, sib, disp 460 461 #Find the sign of the divisor 462 slli t0, t8, 1, flags=(ECF,), dataSize=1 463 464 # Negate divisor 465 sub t3, t0, t8, dataSize=1 466 # Put the divisor's absolute value into t3 467 mov t3, t3, t8, flags=(nCECF,), dataSize=1 468 469 #Find the sign of the dividend 470 slli t0, ah, 1, flags=(ECF,), dataSize=1 471 472 # Put the dividend's absolute value into t1 and t2 473 mov t1, t1, rax, flags=(nCECF,), dataSize=1 474 mov t2, t2, ah, flags=(nCECF,), dataSize=1 475 476 # Do the initial part of the division 477 div1 t2, t3, dataSize=1 478 479 #These are split out so we can initialize the number of bits in the 480 #second register 481 div2i t4, t1, 8, dataSize=1 482 div2 t4, t1, t4, dataSize=1 483 484 #Loop until we're out of bits to shift in 485divLoopTop: 486 div2 t4, t1, t4, dataSize=1 487 div2 t4, t1, t4, flags=(EZF,), dataSize=1 488 br label("divLoopTop"), flags=(nCEZF,) 489 490 #Unload the answer 491 divq t5, dataSize=1 492 divr t6, dataSize=1 493 494 # Fix up signs. The sign of the dividend is still lying around in ECF. 495 # The sign of the remainder, ah, is the same as the dividend. The sign 496 # of the quotient is negated if the signs of the divisor and dividend 497 # were different. 498 499 # Negate the remainder 500 sub t4, t0, t6, dataSize=1 501 # If the dividend was negitive, put the negated remainder in ah. 502 mov ah, ah, t4, (CECF,), dataSize=1 503 # Otherwise put the regular remainder in ah. 504 mov ah, ah, t6, (nCECF,), dataSize=1 505 506 # Negate the quotient. 507 sub t4, t0, t5, dataSize=1 508 # If the dividend was negative, start using the negated quotient 509 mov t5, t5, t4, (CECF,), dataSize=1 510 511 # Check the sign of the divisor 512 slli t0, t8, 1, flags=(ECF,), dataSize=1 513 514 # Negate the (possibly already negated) quotient 515 sub t4, t0, t5, dataSize=1 516 # If the divisor was negative, put the negated quotient in rax. 517 mov rax, rax, t4, (CECF,), dataSize=1 518 # Otherwise put the one that wasn't negated (at least here) in rax. 519 mov rax, rax, t5, (nCECF,), dataSize=1 520}; 521 522def macroop IDIV_B_P 523{ 524 # Negate dividend 525 sub t1, t0, rax, flags=(ECF,), dataSize=1 526 ruflag t4, 3 527 sub t2, t0, ah, dataSize=1 528 sub t2, t2, t4 529 530 rdip t7 531 ld t8, seg, riprel, disp 532 533 #Find the sign of the divisor 534 slli t0, t8, 1, flags=(ECF,), dataSize=1 535 536 # Negate divisor 537 sub t3, t0, t8, dataSize=1 538 # Put the divisor's absolute value into t3 539 mov t3, t3, t8, flags=(nCECF,), dataSize=1 540 541 #Find the sign of the dividend 542 slli t0, ah, 1, flags=(ECF,), dataSize=1 543 544 # Put the dividend's absolute value into t1 and t2 545 mov t1, t1, rax, flags=(nCECF,), dataSize=1 546 mov t2, t2, ah, flags=(nCECF,), dataSize=1 547 548 # Do the initial part of the division 549 div1 t2, t3, dataSize=1 550 551 #These are split out so we can initialize the number of bits in the 552 #second register 553 div2i t4, t1, 8, dataSize=1 554 div2 t4, t1, t4, dataSize=1 555 556 #Loop until we're out of bits to shift in 557divLoopTop: 558 div2 t4, t1, t4, dataSize=1 559 div2 t4, t1, t4, flags=(EZF,), dataSize=1 560 br label("divLoopTop"), flags=(nCEZF,) 561 562 #Unload the answer 563 divq t5, dataSize=1 564 divr t6, dataSize=1 565 566 # Fix up signs. The sign of the dividend is still lying around in ECF. 567 # The sign of the remainder, ah, is the same as the dividend. The sign 568 # of the quotient is negated if the signs of the divisor and dividend 569 # were different. 570 571 # Negate the remainder 572 sub t4, t0, t6, dataSize=1 573 # If the dividend was negitive, put the negated remainder in ah. 574 mov ah, ah, t4, (CECF,), dataSize=1 575 # Otherwise put the regular remainder in ah. 576 mov ah, ah, t6, (nCECF,), dataSize=1 577 578 # Negate the quotient. 579 sub t4, t0, t5, dataSize=1 580 # If the dividend was negative, start using the negated quotient 581 mov t5, t5, t4, (CECF,), dataSize=1 582 583 # Check the sign of the divisor 584 slli t0, t8, 1, flags=(ECF,), dataSize=1 585 586 # Negate the (possibly already negated) quotient 587 sub t4, t0, t5, dataSize=1 588 # If the divisor was negative, put the negated quotient in rax. 589 mov rax, rax, t4, (CECF,), dataSize=1 590 # Otherwise put the one that wasn't negated (at least here) in rax. 591 mov rax, rax, t5, (nCECF,), dataSize=1 592}; 593 594# 595# Signed division 596# 597 598def macroop IDIV_R 599{ 600 # Negate dividend 601 sub t1, t0, rax, flags=(ECF,) 602 ruflag t4, 3 603 sub t2, t0, rdx 604 sub t2, t2, t4 605 606 #Find the sign of the divisor 607 slli t0, reg, 1, flags=(ECF,) 608 609 # Negate divisor 610 sub t3, t0, reg 611 # Put the divisor's absolute value into t3 612 mov t3, t3, reg, flags=(nCECF,) 613 614 #Find the sign of the dividend 615 slli t0, rdx, 1, flags=(ECF,) 616 617 # Put the dividend's absolute value into t1 and t2 618 mov t1, t1, rax, flags=(nCECF,) 619 mov t2, t2, rdx, flags=(nCECF,) 620 621 # Do the initial part of the division 622 div1 t2, t3 623 624 #These are split out so we can initialize the number of bits in the 625 #second register 626 div2i t4, t1, "env.dataSize * 8" 627 div2 t4, t1, t4 628 629 #Loop until we're out of bits to shift in 630divLoopTop: 631 div2 t4, t1, t4 632 div2 t4, t1, t4 633 div2 t4, t1, t4 634 div2 t4, t1, t4, flags=(EZF,) 635 br label("divLoopTop"), flags=(nCEZF,) 636 637 #Unload the answer 638 divq t5 639 divr t6 640 641 # Fix up signs. The sign of the dividend is still lying around in ECF. 642 # The sign of the remainder, ah, is the same as the dividend. The sign 643 # of the quotient is negated if the signs of the divisor and dividend 644 # were different. 645 646 # Negate the remainder 647 sub t4, t0, t6 648 # If the dividend was negitive, put the negated remainder in rdx. 649 mov rdx, rdx, t4, (CECF,) 650 # Otherwise put the regular remainder in rdx. 651 mov rdx, rdx, t6, (nCECF,) 652 653 # Negate the quotient. 654 sub t4, t0, t5 655 # If the dividend was negative, start using the negated quotient 656 mov t5, t5, t4, (CECF,) 657 658 # Check the sign of the divisor 659 slli t0, reg, 1, flags=(ECF,) 660 661 # Negate the (possibly already negated) quotient 662 sub t4, t0, t5 663 # If the divisor was negative, put the negated quotient in rax. 664 mov rax, rax, t4, (CECF,) 665 # Otherwise put the one that wasn't negated (at least here) in rax. 666 mov rax, rax, t5, (nCECF,) 667}; 668 669def macroop IDIV_M 670{ 671 # Negate dividend 672 sub t1, t0, rax, flags=(ECF,) 673 ruflag t4, 3 674 sub t2, t0, rdx 675 sub t2, t2, t4 676 677 ld t8, seg, sib, disp 678 679 #Find the sign of the divisor 680 slli t0, t8, 1, flags=(ECF,) 681 682 # Negate divisor 683 sub t3, t0, t8 684 # Put the divisor's absolute value into t3 685 mov t3, t3, t8, flags=(nCECF,) 686 687 #Find the sign of the dividend 688 slli t0, rdx, 1, flags=(ECF,) 689 690 # Put the dividend's absolute value into t1 and t2 691 mov t1, t1, rax, flags=(nCECF,) 692 mov t2, t2, rdx, flags=(nCECF,) 693 694 # Do the initial part of the division 695 div1 t2, t3 696 697 #These are split out so we can initialize the number of bits in the 698 #second register 699 div2i t4, t1, "env.dataSize * 8" 700 div2 t4, t1, t4 701 702 #Loop until we're out of bits to shift in 703divLoopTop: 704 div2 t4, t1, t4 705 div2 t4, t1, t4 706 div2 t4, t1, t4 707 div2 t4, t1, t4, flags=(EZF,) 708 br label("divLoopTop"), flags=(nCEZF,) 709 710 #Unload the answer 711 divq t5 712 divr t6 713 714 # Fix up signs. The sign of the dividend is still lying around in ECF. 715 # The sign of the remainder, ah, is the same as the dividend. The sign 716 # of the quotient is negated if the signs of the divisor and dividend 717 # were different. 718 719 # Negate the remainder 720 sub t4, t0, t6 721 # If the dividend was negitive, put the negated remainder in rdx. 722 mov rdx, rdx, t4, (CECF,) 723 # Otherwise put the regular remainder in rdx. 724 mov rdx, rdx, t6, (nCECF,) 725 726 # Negate the quotient. 727 sub t4, t0, t5 728 # If the dividend was negative, start using the negated quotient 729 mov t5, t5, t4, (CECF,) 730 731 # Check the sign of the divisor 732 slli t0, t8, 1, flags=(ECF,) 733 734 # Negate the (possibly already negated) quotient 735 sub t4, t0, t5 736 # If the divisor was negative, put the negated quotient in rax. 737 mov rax, rax, t4, (CECF,) 738 # Otherwise put the one that wasn't negated (at least here) in rax. 739 mov rax, rax, t5, (nCECF,) 740}; 741 742def macroop IDIV_P 743{ 744 # Negate dividend 745 sub t1, t0, rax, flags=(ECF,) 746 ruflag t4, 3 747 sub t2, t0, rdx 748 sub t2, t2, t4 749 750 rdip t7 751 ld t8, seg, riprel, disp 752 753 #Find the sign of the divisor 754 slli t0, t8, 1, flags=(ECF,) 755 756 # Negate divisor 757 sub t3, t0, t8 758 # Put the divisor's absolute value into t3 759 mov t3, t3, t4, flags=(nCECF,) 760 761 #Find the sign of the dividend 762 slli t0, rdx, 1, flags=(ECF,) 763 764 # Put the dividend's absolute value into t1 and t2 765 mov t1, t1, rax, flags=(nCECF,) 766 mov t2, t2, rdx, flags=(nCECF,) 767 768 # Do the initial part of the division 769 div1 t2, t3 770 771 #These are split out so we can initialize the number of bits in the 772 #second register 773 div2i t4, t1, "env.dataSize * 8" 774 div2 t4, t1, t4 775 776 #Loop until we're out of bits to shift in 777divLoopTop: 778 div2 t4, t1, t4 779 div2 t4, t1, t4 780 div2 t4, t1, t4 781 div2 t4, t1, t4, flags=(EZF,) 782 br label("divLoopTop"), flags=(nCEZF,) 783 784 #Unload the answer 785 divq t5 786 divr t6 787 788 # Fix up signs. The sign of the dividend is still lying around in ECF. 789 # The sign of the remainder, ah, is the same as the dividend. The sign 790 # of the quotient is negated if the signs of the divisor and dividend 791 # were different. 792 793 # Negate the remainder 794 sub t4, t0, t6 795 # If the dividend was negitive, put the negated remainder in rdx. 796 mov rdx, rdx, t4, (CECF,) 797 # Otherwise put the regular remainder in rdx. 798 mov rdx, rdx, t6, (nCECF,) 799 800 # Negate the quotient. 801 sub t4, t0, t5 802 # If the dividend was negative, start using the negated quotient 803 mov t5, t5, t4, (CECF,) 804 805 # Check the sign of the divisor 806 slli t0, t8, 1, flags=(ECF,) 807 808 # Negate the (possibly already negated) quotient 809 sub t4, t0, t5 810 # If the divisor was negative, put the negated quotient in rax. 811 mov rax, rax, t4, (CECF,) 812 # Otherwise put the one that wasn't negated (at least here) in rax. 813 mov rax, rax, t5, (nCECF,) 814}; 815''' 816