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