multiply_and_divide.py revision 6463:fe6165923529
15661Sgblack@eecs.umich.edu# Copyright (c) 2007 The Hewlett-Packard Development Company 25661Sgblack@eecs.umich.edu# All rights reserved. 35661Sgblack@eecs.umich.edu# 45661Sgblack@eecs.umich.edu# Redistribution and use of this software in source and binary forms, 55661Sgblack@eecs.umich.edu# with or without modification, are permitted provided that the 65661Sgblack@eecs.umich.edu# following conditions are met: 75661Sgblack@eecs.umich.edu# 85661Sgblack@eecs.umich.edu# The software must be used only for Non-Commercial Use which means any 95661Sgblack@eecs.umich.edu# use which is NOT directed to receiving any direct monetary 105661Sgblack@eecs.umich.edu# compensation for, or commercial advantage from such use. Illustrative 115661Sgblack@eecs.umich.edu# examples of non-commercial use are academic research, personal study, 125661Sgblack@eecs.umich.edu# teaching, education and corporate research & development. 135661Sgblack@eecs.umich.edu# Illustrative examples of commercial use are distributing products for 145661Sgblack@eecs.umich.edu# commercial advantage and providing services using the software for 155661Sgblack@eecs.umich.edu# commercial advantage. 165661Sgblack@eecs.umich.edu# 175661Sgblack@eecs.umich.edu# If you wish to use this software or functionality therein that may be 185661Sgblack@eecs.umich.edu# covered by patents for commercial use, please contact: 195661Sgblack@eecs.umich.edu# Director of Intellectual Property Licensing 205661Sgblack@eecs.umich.edu# Office of Strategy and Technology 215661Sgblack@eecs.umich.edu# Hewlett-Packard Company 225661Sgblack@eecs.umich.edu# 1501 Page Mill Road 235661Sgblack@eecs.umich.edu# Palo Alto, California 94304 245661Sgblack@eecs.umich.edu# 255661Sgblack@eecs.umich.edu# Redistributions of source code must retain the above copyright notice, 265661Sgblack@eecs.umich.edu# this list of conditions and the following disclaimer. Redistributions 275661Sgblack@eecs.umich.edu# in binary form must reproduce the above copyright notice, this list of 285661Sgblack@eecs.umich.edu# conditions and the following disclaimer in the documentation and/or 295661Sgblack@eecs.umich.edu# other materials provided with the distribution. Neither the name of 305661Sgblack@eecs.umich.edu# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 315661Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from 325661Sgblack@eecs.umich.edu# this software without specific prior written permission. No right of 335661Sgblack@eecs.umich.edu# sublicense is granted herewith. Derivatives of the software and 345661Sgblack@eecs.umich.edu# output created using the software may be prepared, but only for 355661Sgblack@eecs.umich.edu# Non-Commercial Uses. Derivatives of the software may be shared with 365661Sgblack@eecs.umich.edu# others provided: (i) the others agree to abide by the list of 375661Sgblack@eecs.umich.edu# conditions herein which includes the Non-Commercial Use restrictions; 385661Sgblack@eecs.umich.edu# and (ii) such Derivatives of the software include the above copyright 395661Sgblack@eecs.umich.edu# notice to acknowledge the contribution from this software where 405661Sgblack@eecs.umich.edu# applicable, this list of conditions and the disclaimer below. 415661Sgblack@eecs.umich.edu# 425661Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 435661Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 445661Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 455661Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 465661Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 475661Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 485661Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 495661Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 505661Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 515661Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 525661Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 535661Sgblack@eecs.umich.edu# 545661Sgblack@eecs.umich.edu# Authors: Gabe Black 555661Sgblack@eecs.umich.edu 565661Sgblack@eecs.umich.edumicrocode = ''' 575661Sgblack@eecs.umich.edu 585661Sgblack@eecs.umich.edu# 595661Sgblack@eecs.umich.edu# Byte version of one operand unsigned multiply. 605661Sgblack@eecs.umich.edu# 615661Sgblack@eecs.umich.edu 625661Sgblack@eecs.umich.edudef macroop MUL_B_R 635661Sgblack@eecs.umich.edu{ 645661Sgblack@eecs.umich.edu mul1u rax, reg, flags=(OF,CF) 655661Sgblack@eecs.umich.edu mulel rax 665661Sgblack@eecs.umich.edu muleh ah 675661Sgblack@eecs.umich.edu}; 685661Sgblack@eecs.umich.edu 695661Sgblack@eecs.umich.edudef macroop MUL_B_M 705661Sgblack@eecs.umich.edu{ 715661Sgblack@eecs.umich.edu ld t1, seg, sib, disp 725661Sgblack@eecs.umich.edu mul1u rax, t1, flags=(OF,CF) 735661Sgblack@eecs.umich.edu mulel rax 745661Sgblack@eecs.umich.edu muleh ah 755661Sgblack@eecs.umich.edu}; 765661Sgblack@eecs.umich.edu 775661Sgblack@eecs.umich.edudef macroop MUL_B_P 785661Sgblack@eecs.umich.edu{ 795661Sgblack@eecs.umich.edu rdip t7 805661Sgblack@eecs.umich.edu ld t1, seg, riprel, disp 815661Sgblack@eecs.umich.edu mul1u rax, t1, flags=(OF,CF) 825661Sgblack@eecs.umich.edu mulel rax 835661Sgblack@eecs.umich.edu muleh ah 845661Sgblack@eecs.umich.edu}; 855661Sgblack@eecs.umich.edu 865661Sgblack@eecs.umich.edu# 875661Sgblack@eecs.umich.edu# One operand unsigned multiply. 885661Sgblack@eecs.umich.edu# 895661Sgblack@eecs.umich.edu 905661Sgblack@eecs.umich.edudef macroop MUL_R 915661Sgblack@eecs.umich.edu{ 925661Sgblack@eecs.umich.edu mul1u rax, reg, flags=(OF,CF) 935661Sgblack@eecs.umich.edu mulel rax 945661Sgblack@eecs.umich.edu muleh rdx 955661Sgblack@eecs.umich.edu}; 965661Sgblack@eecs.umich.edu 975661Sgblack@eecs.umich.edudef macroop MUL_M 985661Sgblack@eecs.umich.edu{ 995661Sgblack@eecs.umich.edu ld t1, seg, sib, disp 1005661Sgblack@eecs.umich.edu mul1u rax, t1, flags=(OF,CF) 1015661Sgblack@eecs.umich.edu mulel rax 1025661Sgblack@eecs.umich.edu muleh rdx 1035661Sgblack@eecs.umich.edu}; 1045661Sgblack@eecs.umich.edu 1055661Sgblack@eecs.umich.edudef macroop MUL_P 1065661Sgblack@eecs.umich.edu{ 1075661Sgblack@eecs.umich.edu rdip t7 1085661Sgblack@eecs.umich.edu ld t1, seg, riprel, disp 1095661Sgblack@eecs.umich.edu mul1u rax, t1, flags=(OF,CF) 1105661Sgblack@eecs.umich.edu mulel rax 1115661Sgblack@eecs.umich.edu muleh rdx 1125661Sgblack@eecs.umich.edu}; 1135661Sgblack@eecs.umich.edu 1145661Sgblack@eecs.umich.edu# 1155661Sgblack@eecs.umich.edu# Byte version of one operand signed multiply. 1165661Sgblack@eecs.umich.edu# 1175661Sgblack@eecs.umich.edu 1185661Sgblack@eecs.umich.edudef macroop IMUL_B_R 1195661Sgblack@eecs.umich.edu{ 1205661Sgblack@eecs.umich.edu mul1s rax, reg, flags=(OF,CF) 1215661Sgblack@eecs.umich.edu mulel rax 1225661Sgblack@eecs.umich.edu muleh ah 1235661Sgblack@eecs.umich.edu}; 1245661Sgblack@eecs.umich.edu 1255661Sgblack@eecs.umich.edudef macroop IMUL_B_M 1265661Sgblack@eecs.umich.edu{ 1275661Sgblack@eecs.umich.edu ld t1, seg, sib, disp 1285661Sgblack@eecs.umich.edu mul1s rax, t1, flags=(OF,CF) 1295661Sgblack@eecs.umich.edu mulel rax 1305661Sgblack@eecs.umich.edu muleh ah 1315661Sgblack@eecs.umich.edu}; 1325661Sgblack@eecs.umich.edu 1335661Sgblack@eecs.umich.edudef macroop IMUL_B_P 1345661Sgblack@eecs.umich.edu{ 1355661Sgblack@eecs.umich.edu rdip t7 1365661Sgblack@eecs.umich.edu ld t1, seg, riprel, disp 1375661Sgblack@eecs.umich.edu mul1s rax, t1, flags=(OF,CF) 1385661Sgblack@eecs.umich.edu mulel rax 1395661Sgblack@eecs.umich.edu muleh ah 1405661Sgblack@eecs.umich.edu}; 1415661Sgblack@eecs.umich.edu 1425661Sgblack@eecs.umich.edu# 1435661Sgblack@eecs.umich.edu# One operand signed multiply. 1445661Sgblack@eecs.umich.edu# 1455661Sgblack@eecs.umich.edu 1465661Sgblack@eecs.umich.edudef macroop IMUL_R 1475661Sgblack@eecs.umich.edu{ 1485661Sgblack@eecs.umich.edu mul1s rax, reg, flags=(OF,CF) 1495661Sgblack@eecs.umich.edu mulel rax 1505661Sgblack@eecs.umich.edu muleh rdx 1515661Sgblack@eecs.umich.edu}; 1525661Sgblack@eecs.umich.edu 1535661Sgblack@eecs.umich.edudef macroop IMUL_M 1545661Sgblack@eecs.umich.edu{ 1555661Sgblack@eecs.umich.edu ld t1, seg, sib, disp 1565661Sgblack@eecs.umich.edu mul1s rax, t1, flags=(OF,CF) 1575661Sgblack@eecs.umich.edu mulel rax 1585661Sgblack@eecs.umich.edu muleh rdx 1595661Sgblack@eecs.umich.edu}; 1605661Sgblack@eecs.umich.edu 1615661Sgblack@eecs.umich.edudef macroop IMUL_P 1625661Sgblack@eecs.umich.edu{ 1635661Sgblack@eecs.umich.edu rdip t7 1645661Sgblack@eecs.umich.edu ld t1, seg, riprel, disp 1655661Sgblack@eecs.umich.edu mul1s rax, t1, flags=(OF,CF) 1665661Sgblack@eecs.umich.edu mulel rax 1675661Sgblack@eecs.umich.edu muleh rdx 1685661Sgblack@eecs.umich.edu}; 1695661Sgblack@eecs.umich.edu 1705661Sgblack@eecs.umich.edudef macroop IMUL_R_R 1715661Sgblack@eecs.umich.edu{ 1725662Sgblack@eecs.umich.edu mul1s reg, regm, flags=(OF,CF) 1735661Sgblack@eecs.umich.edu mulel reg 1745661Sgblack@eecs.umich.edu muleh t0 1755661Sgblack@eecs.umich.edu}; 1765661Sgblack@eecs.umich.edu 1775661Sgblack@eecs.umich.edudef macroop IMUL_R_M 1785661Sgblack@eecs.umich.edu{ 1795661Sgblack@eecs.umich.edu ld t1, seg, sib, disp 1805661Sgblack@eecs.umich.edu mul1s reg, t1, flags=(CF,OF) 1815661Sgblack@eecs.umich.edu mulel reg 1825661Sgblack@eecs.umich.edu muleh t0 1835661Sgblack@eecs.umich.edu}; 1845661Sgblack@eecs.umich.edu 1855661Sgblack@eecs.umich.edudef macroop IMUL_R_P 1865661Sgblack@eecs.umich.edu{ 1875661Sgblack@eecs.umich.edu rdip t7 1885661Sgblack@eecs.umich.edu ld t1, seg, riprel, disp 1895661Sgblack@eecs.umich.edu mul1s reg, t1, flags=(CF,OF) 1905661Sgblack@eecs.umich.edu mulel reg 1915661Sgblack@eecs.umich.edu muleh t0 1925662Sgblack@eecs.umich.edu}; 1935662Sgblack@eecs.umich.edu 1945662Sgblack@eecs.umich.edu# 1955662Sgblack@eecs.umich.edu# Three operand signed multiply. 1965662Sgblack@eecs.umich.edu# 1975662Sgblack@eecs.umich.edu 1985662Sgblack@eecs.umich.edudef macroop IMUL_R_R_I 1995662Sgblack@eecs.umich.edu{ 2005662Sgblack@eecs.umich.edu limm t1, imm 2015663Sgblack@eecs.umich.edu mul1s regm, t1, flags=(OF,CF) 2025663Sgblack@eecs.umich.edu mulel reg 2035663Sgblack@eecs.umich.edu muleh t0 2045663Sgblack@eecs.umich.edu}; 2055663Sgblack@eecs.umich.edu 2065663Sgblack@eecs.umich.edudef macroop IMUL_R_M_I 2075663Sgblack@eecs.umich.edu{ 2085663Sgblack@eecs.umich.edu limm t1, imm 2095663Sgblack@eecs.umich.edu ld t2, seg, sib, disp 2105663Sgblack@eecs.umich.edu mul1s t2, t1, flags=(OF,CF) 2115663Sgblack@eecs.umich.edu mulel reg 2125663Sgblack@eecs.umich.edu muleh t0 2135663Sgblack@eecs.umich.edu}; 2145663Sgblack@eecs.umich.edu 2155663Sgblack@eecs.umich.edudef macroop IMUL_R_P_I 2165663Sgblack@eecs.umich.edu{ 2175663Sgblack@eecs.umich.edu rdip t7 2185663Sgblack@eecs.umich.edu limm t1, imm 2195663Sgblack@eecs.umich.edu ld t2, seg, riprel 2205661Sgblack@eecs.umich.edu mul1s t2, t1, flags=(OF,CF) 2215661Sgblack@eecs.umich.edu mulel reg 2225661Sgblack@eecs.umich.edu muleh t0 2235661Sgblack@eecs.umich.edu}; 2245661Sgblack@eecs.umich.edu 2255661Sgblack@eecs.umich.edu# 2265661Sgblack@eecs.umich.edu# One byte version of unsigned division 2275661Sgblack@eecs.umich.edu# 2285661Sgblack@eecs.umich.edu 2295661Sgblack@eecs.umich.edudef macroop DIV_B_R 2305661Sgblack@eecs.umich.edu{ 2315661Sgblack@eecs.umich.edu # Do the initial part of the division 2325661Sgblack@eecs.umich.edu div1 ah, reg, dataSize=1 2335661Sgblack@eecs.umich.edu 2345661Sgblack@eecs.umich.edu #These are split out so we can initialize the number of bits in the 2355663Sgblack@eecs.umich.edu #second register 2365663Sgblack@eecs.umich.edu div2i t1, rax, 8, dataSize=1 2375663Sgblack@eecs.umich.edu div2 t1, rax, t1, dataSize=1 2385663Sgblack@eecs.umich.edu 2395663Sgblack@eecs.umich.edu #Loop until we're out of bits to shift in 2405663Sgblack@eecs.umich.edudivLoopTop: 2415663Sgblack@eecs.umich.edu div2 t1, rax, t1, dataSize=1 2425663Sgblack@eecs.umich.edu div2 t1, rax, t1, flags=(EZF,), dataSize=1 2435663Sgblack@eecs.umich.edu br label("divLoopTop"), flags=(nCEZF,) 2445663Sgblack@eecs.umich.edu 2455663Sgblack@eecs.umich.edu #Unload the answer 2465663Sgblack@eecs.umich.edu divq rax, dataSize=1 2475663Sgblack@eecs.umich.edu divr ah, dataSize=1 2485663Sgblack@eecs.umich.edu}; 2495661Sgblack@eecs.umich.edu 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 #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, ah, 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, ah, 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 ah. 433 mov ah, ah, t4, (CECF,), dataSize=1 434 # Otherwise put the regular remainder in ah. 435 mov ah, ah, 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, ah, 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, ah, 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, ah, 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 ah. 506 mov ah, ah, t4, (CECF,), dataSize=1 507 # Otherwise put the regular remainder in ah. 508 mov ah, ah, 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, ah, 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, ah, 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, ah, 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 ah. 580 mov ah, ah, t4, (CECF,), dataSize=1 581 # Otherwise put the regular remainder in ah. 582 mov ah, ah, 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