multiply_and_divide.py (6513:e2ffac65a76a) multiply_and_divide.py (6514:1802d70f4092)
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

--- 207 unchanged lines hidden (view full) ---

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};
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

--- 207 unchanged lines hidden (view full) ---

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'''
224
225
226pcRel = '''
227 rdip t7
228 ld %s, seg, riprel, disp
229'''
230sibRel = '''
231 ld %s, seg, sib, disp
232'''
233
225#
226# One byte version of unsigned division
227#
228
234#
235# One byte version of unsigned division
236#
237
229def macroop DIV_B_R
238divcode = '''
239def macroop DIV_B_%(suffix)s
230{
240{
241 %(readOp1)s
231 # Do the initial part of the division
242 # Do the initial part of the division
232 div1 ah, reg, dataSize=1
243 div1 ah, %(op1)s, 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};
244
245 #These are split out so we can initialize the number of bits in the
246 #second register
247 div2i t1, rax, 8, dataSize=1
248 div2 t1, rax, t1, dataSize=1
249
250 #Loop until we're out of bits to shift in
251divLoopTop:
252 div2 t1, rax, t1, dataSize=1
253 div2 t1, rax, t1, flags=(EZF,), dataSize=1
254 br label("divLoopTop"), flags=(nCEZF,)
255
256 #Unload the answer
257 divq rax, dataSize=1
258 divr ah, dataSize=1
259};
260'''
249
261
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
262#
263# Unsigned division
264#
265
301def macroop DIV_R
266divcode += '''
267def macroop DIV_%(suffix)s
302{
268{
269 %(readOp1)s
303 # Do the initial part of the division
270 # Do the initial part of the division
304 div1 rdx, reg
271 div1 rdx, %(op1)s
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};
272
273 #These are split out so we can initialize the number of bits in the
274 #second register
275 div2i t1, rax, "env.dataSize * 8"
276 div2 t1, rax, t1
277
278 #Loop until we're out of bits to shift in
279 #The amount of unrolling here could stand some tuning
280divLoopTop:
281 div2 t1, rax, t1
282 div2 t1, rax, t1
283 div2 t1, rax, t1
284 div2 t1, rax, t1, flags=(EZF,)
285 br label("divLoopTop"), flags=(nCEZF,)
286
287 #Unload the answer
288 divq rax
289 divr rdx
290};
291'''
324
292
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
293#
294# One byte version of signed division
295#
296
382def macroop IDIV_B_R
297divcode += '''
298def macroop IDIV_B_%(suffix)s
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
299{
300 # Negate dividend
301 sub t1, t0, rax, flags=(ECF,), dataSize=1
302 ruflag t4, 3
303 sub t2, t0, ah, dataSize=1
304 sub t2, t2, t4
305
390 #Find the sign of the divisor
391 slli t0, reg, 1, flags=(ECF,), dataSize=1
306 %(readOp1)s
392
307
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
308 #Find the sign of the divisor
462 slli t0, t8, 1, flags=(ECF,), dataSize=1
309 slli t0, %(op1)s, 1, flags=(ECF,), dataSize=1
463
464 # Negate divisor
310
311 # Negate divisor
465 sub t3, t0, t8, dataSize=1
312 sub t3, t0, %(op1)s, dataSize=1
466 # Put the divisor's absolute value into t3
313 # Put the divisor's absolute value into t3
467 mov t3, t3, t8, flags=(nCECF,), dataSize=1
314 mov t3, t3, %(op1)s, 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

--- 28 unchanged lines hidden (view full) ---

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
315
316 #Find the sign of the dividend
317 slli t0, ah, 1, flags=(ECF,), dataSize=1
318
319 # Put the dividend's absolute value into t1 and t2
320 mov t1, t1, rax, flags=(nCECF,), dataSize=1
321 mov t2, t2, ah, flags=(nCECF,), dataSize=1
322

--- 28 unchanged lines hidden (view full) ---

351 mov ah, ah, t6, (nCECF,), dataSize=1
352
353 # Negate the quotient.
354 sub t4, t0, t5, dataSize=1
355 # If the dividend was negative, start using the negated quotient
356 mov t5, t5, t4, (CECF,), dataSize=1
357
358 # Check the sign of the divisor
512 slli t0, t8, 1, flags=(ECF,), dataSize=1
359 slli t0, %(op1)s, 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};
360
361 # Negate the (possibly already negated) quotient
362 sub t4, t0, t5, dataSize=1
363 # If the divisor was negative, put the negated quotient in rax.
364 mov rax, rax, t4, (CECF,), dataSize=1
365 # Otherwise put the one that wasn't negated (at least here) in rax.
366 mov rax, rax, t5, (nCECF,), dataSize=1
367};
368'''
521
369
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
370#
371# Signed division
372#
373
598def macroop IDIV_R
374divcode += '''
375def macroop IDIV_%(suffix)s
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
376{
377 # Negate dividend
378 sub t1, t0, rax, flags=(ECF,)
379 ruflag t4, 3
380 sub t2, t0, rdx
381 sub t2, t2, t4
382
606 #Find the sign of the divisor
607 slli t0, reg, 1, flags=(ECF,)
383 %(readOp1)s
608
384
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
385 #Find the sign of the divisor
680 slli t0, t8, 1, flags=(ECF,)
386 slli t0, %(op1)s, 1, flags=(ECF,)
681
682 # Negate divisor
387
388 # Negate divisor
683 sub t3, t0, t8
389 sub t3, t0, %(op1)s
684 # Put the divisor's absolute value into t3
390 # Put the divisor's absolute value into t3
685 mov t3, t3, t8, flags=(nCECF,)
391 mov t3, t3, %(op1)s, 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

--- 30 unchanged lines hidden (view full) ---

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
392
393 #Find the sign of the dividend
394 slli t0, rdx, 1, flags=(ECF,)
395
396 # Put the dividend's absolute value into t1 and t2
397 mov t1, t1, rax, flags=(nCECF,)
398 mov t2, t2, rdx, flags=(nCECF,)
399

--- 30 unchanged lines hidden (view full) ---

430 mov rdx, rdx, t6, (nCECF,)
431
432 # Negate the quotient.
433 sub t4, t0, t5
434 # If the dividend was negative, start using the negated quotient
435 mov t5, t5, t4, (CECF,)
436
437 # Check the sign of the divisor
732 slli t0, t8, 1, flags=(ECF,)
438 slli t0, %(op1)s, 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};
439
440 # Negate the (possibly already negated) quotient
441 sub t4, t0, t5
442 # If the divisor was negative, put the negated quotient in rax.
443 mov rax, rax, t4, (CECF,)
444 # Otherwise put the one that wasn't negated (at least here) in rax.
445 mov rax, rax, t5, (nCECF,)
446};
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'''
447'''
448
449microcode += divcode % {"suffix": "R",
450 "readOp1": "", "op1": "reg"}
451microcode += divcode % {"suffix": "M",
452 "readOp1": sibRel % "t2", "op1": "t2"}
453microcode += divcode % {"suffix": "P",
454 "readOp1": pcRel % "t2", "op1": "t2"}