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