multiply_and_divide.py revision 6514
15081Sgblack@eecs.umich.edu# Copyright (c) 2007 The Hewlett-Packard Development Company
25081Sgblack@eecs.umich.edu# All rights reserved.
35081Sgblack@eecs.umich.edu#
45081Sgblack@eecs.umich.edu# Redistribution and use of this software in source and binary forms,
55081Sgblack@eecs.umich.edu# with or without modification, are permitted provided that the
65081Sgblack@eecs.umich.edu# following conditions are met:
75081Sgblack@eecs.umich.edu#
85081Sgblack@eecs.umich.edu# The software must be used only for Non-Commercial Use which means any
95081Sgblack@eecs.umich.edu# use which is NOT directed to receiving any direct monetary
105081Sgblack@eecs.umich.edu# compensation for, or commercial advantage from such use.  Illustrative
115081Sgblack@eecs.umich.edu# examples of non-commercial use are academic research, personal study,
125081Sgblack@eecs.umich.edu# teaching, education and corporate research & development.
135081Sgblack@eecs.umich.edu# Illustrative examples of commercial use are distributing products for
145081Sgblack@eecs.umich.edu# commercial advantage and providing services using the software for
155081Sgblack@eecs.umich.edu# commercial advantage.
165081Sgblack@eecs.umich.edu#
175081Sgblack@eecs.umich.edu# If you wish to use this software or functionality therein that may be
185081Sgblack@eecs.umich.edu# covered by patents for commercial use, please contact:
195081Sgblack@eecs.umich.edu#     Director of Intellectual Property Licensing
205081Sgblack@eecs.umich.edu#     Office of Strategy and Technology
215081Sgblack@eecs.umich.edu#     Hewlett-Packard Company
225081Sgblack@eecs.umich.edu#     1501 Page Mill Road
235081Sgblack@eecs.umich.edu#     Palo Alto, California  94304
245081Sgblack@eecs.umich.edu#
255081Sgblack@eecs.umich.edu# Redistributions of source code must retain the above copyright notice,
265081Sgblack@eecs.umich.edu# this list of conditions and the following disclaimer.  Redistributions
275081Sgblack@eecs.umich.edu# in binary form must reproduce the above copyright notice, this list of
285081Sgblack@eecs.umich.edu# conditions and the following disclaimer in the documentation and/or
295081Sgblack@eecs.umich.edu# other materials provided with the distribution.  Neither the name of
305081Sgblack@eecs.umich.edu# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
315081Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from
325081Sgblack@eecs.umich.edu# this software without specific prior written permission.  No right of
335081Sgblack@eecs.umich.edu# sublicense is granted herewith.  Derivatives of the software and
345081Sgblack@eecs.umich.edu# output created using the software may be prepared, but only for
355081Sgblack@eecs.umich.edu# Non-Commercial Uses.  Derivatives of the software may be shared with
365081Sgblack@eecs.umich.edu# others provided: (i) the others agree to abide by the list of
375081Sgblack@eecs.umich.edu# conditions herein which includes the Non-Commercial Use restrictions;
385081Sgblack@eecs.umich.edu# and (ii) such Derivatives of the software include the above copyright
395081Sgblack@eecs.umich.edu# notice to acknowledge the contribution from this software where
405081Sgblack@eecs.umich.edu# applicable, this list of conditions and the disclaimer below.
415081Sgblack@eecs.umich.edu#
425081Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
435081Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
445081Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
455081Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
465081Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
475081Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
485081Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
495081Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
505081Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
515081Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
525081Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
535081Sgblack@eecs.umich.edu#
545081Sgblack@eecs.umich.edu# Authors: Gabe Black
555081Sgblack@eecs.umich.edu
565081Sgblack@eecs.umich.edumicrocode = '''
575081Sgblack@eecs.umich.edu
585081Sgblack@eecs.umich.edu#
595081Sgblack@eecs.umich.edu# Byte version of one operand unsigned multiply.
605081Sgblack@eecs.umich.edu#
615081Sgblack@eecs.umich.edu
625081Sgblack@eecs.umich.edudef macroop MUL_B_R
635081Sgblack@eecs.umich.edu{
646463Sgblack@eecs.umich.edu    mul1u rax, reg, flags=(OF,CF)
655081Sgblack@eecs.umich.edu    mulel rax
666463Sgblack@eecs.umich.edu    muleh ah
675081Sgblack@eecs.umich.edu};
685081Sgblack@eecs.umich.edu
695081Sgblack@eecs.umich.edudef macroop MUL_B_M
705081Sgblack@eecs.umich.edu{
715081Sgblack@eecs.umich.edu    ld t1, seg, sib, disp
726463Sgblack@eecs.umich.edu    mul1u rax, t1, flags=(OF,CF)
735081Sgblack@eecs.umich.edu    mulel rax
746463Sgblack@eecs.umich.edu    muleh ah
755081Sgblack@eecs.umich.edu};
765081Sgblack@eecs.umich.edu
775081Sgblack@eecs.umich.edudef macroop MUL_B_P
785081Sgblack@eecs.umich.edu{
795081Sgblack@eecs.umich.edu    rdip t7
805081Sgblack@eecs.umich.edu    ld t1, seg, riprel, disp
816463Sgblack@eecs.umich.edu    mul1u rax, t1, flags=(OF,CF)
825081Sgblack@eecs.umich.edu    mulel rax
836463Sgblack@eecs.umich.edu    muleh ah
845081Sgblack@eecs.umich.edu};
855081Sgblack@eecs.umich.edu
865081Sgblack@eecs.umich.edu#
875081Sgblack@eecs.umich.edu# One operand unsigned multiply.
885081Sgblack@eecs.umich.edu#
895081Sgblack@eecs.umich.edu
905081Sgblack@eecs.umich.edudef macroop MUL_R
915081Sgblack@eecs.umich.edu{
926463Sgblack@eecs.umich.edu    mul1u rax, reg, flags=(OF,CF)
935081Sgblack@eecs.umich.edu    mulel rax
946463Sgblack@eecs.umich.edu    muleh rdx
955081Sgblack@eecs.umich.edu};
965081Sgblack@eecs.umich.edu
975081Sgblack@eecs.umich.edudef macroop MUL_M
985081Sgblack@eecs.umich.edu{
995081Sgblack@eecs.umich.edu    ld t1, seg, sib, disp
1006463Sgblack@eecs.umich.edu    mul1u rax, t1, flags=(OF,CF)
1015081Sgblack@eecs.umich.edu    mulel rax
1026463Sgblack@eecs.umich.edu    muleh rdx
1035081Sgblack@eecs.umich.edu};
1045081Sgblack@eecs.umich.edu
1055081Sgblack@eecs.umich.edudef macroop MUL_P
1065081Sgblack@eecs.umich.edu{
1075081Sgblack@eecs.umich.edu    rdip t7
1085081Sgblack@eecs.umich.edu    ld t1, seg, riprel, disp
1096463Sgblack@eecs.umich.edu    mul1u rax, t1, flags=(OF,CF)
1105081Sgblack@eecs.umich.edu    mulel rax
1116463Sgblack@eecs.umich.edu    muleh rdx
1125081Sgblack@eecs.umich.edu};
1135081Sgblack@eecs.umich.edu
1145081Sgblack@eecs.umich.edu#
1155081Sgblack@eecs.umich.edu# Byte version of one operand signed multiply.
1165081Sgblack@eecs.umich.edu#
1175081Sgblack@eecs.umich.edu
1185081Sgblack@eecs.umich.edudef macroop IMUL_B_R
1195081Sgblack@eecs.umich.edu{
1206463Sgblack@eecs.umich.edu    mul1s rax, reg, flags=(OF,CF)
1215081Sgblack@eecs.umich.edu    mulel rax
1226463Sgblack@eecs.umich.edu    muleh ah
1235081Sgblack@eecs.umich.edu};
1245081Sgblack@eecs.umich.edu
1255081Sgblack@eecs.umich.edudef macroop IMUL_B_M
1265081Sgblack@eecs.umich.edu{
1275081Sgblack@eecs.umich.edu    ld t1, seg, sib, disp
1286463Sgblack@eecs.umich.edu    mul1s rax, t1, flags=(OF,CF)
1295081Sgblack@eecs.umich.edu    mulel rax
1306463Sgblack@eecs.umich.edu    muleh ah
1315081Sgblack@eecs.umich.edu};
1325081Sgblack@eecs.umich.edu
1335081Sgblack@eecs.umich.edudef macroop IMUL_B_P
1345081Sgblack@eecs.umich.edu{
1355081Sgblack@eecs.umich.edu    rdip t7
1365081Sgblack@eecs.umich.edu    ld t1, seg, riprel, disp
1376463Sgblack@eecs.umich.edu    mul1s rax, t1, flags=(OF,CF)
1385081Sgblack@eecs.umich.edu    mulel rax
1396463Sgblack@eecs.umich.edu    muleh ah
1405081Sgblack@eecs.umich.edu};
1415081Sgblack@eecs.umich.edu
1425081Sgblack@eecs.umich.edu#
1435081Sgblack@eecs.umich.edu# One operand signed multiply.
1445081Sgblack@eecs.umich.edu#
1455081Sgblack@eecs.umich.edu
1465081Sgblack@eecs.umich.edudef macroop IMUL_R
1475081Sgblack@eecs.umich.edu{
1486463Sgblack@eecs.umich.edu    mul1s rax, reg, flags=(OF,CF)
1495081Sgblack@eecs.umich.edu    mulel rax
1506463Sgblack@eecs.umich.edu    muleh rdx
1515081Sgblack@eecs.umich.edu};
1525081Sgblack@eecs.umich.edu
1535081Sgblack@eecs.umich.edudef macroop IMUL_M
1545081Sgblack@eecs.umich.edu{
1555081Sgblack@eecs.umich.edu    ld t1, seg, sib, disp
1566463Sgblack@eecs.umich.edu    mul1s rax, t1, flags=(OF,CF)
1575081Sgblack@eecs.umich.edu    mulel rax
1586463Sgblack@eecs.umich.edu    muleh rdx
1595081Sgblack@eecs.umich.edu};
1605081Sgblack@eecs.umich.edu
1615081Sgblack@eecs.umich.edudef macroop IMUL_P
1625081Sgblack@eecs.umich.edu{
1635081Sgblack@eecs.umich.edu    rdip t7
1645081Sgblack@eecs.umich.edu    ld t1, seg, riprel, disp
1656463Sgblack@eecs.umich.edu    mul1s rax, t1, flags=(OF,CF)
1665081Sgblack@eecs.umich.edu    mulel rax
1676463Sgblack@eecs.umich.edu    muleh rdx
1685081Sgblack@eecs.umich.edu};
1695081Sgblack@eecs.umich.edu
1705081Sgblack@eecs.umich.edudef macroop IMUL_R_R
1715081Sgblack@eecs.umich.edu{
1726463Sgblack@eecs.umich.edu    mul1s reg, regm, flags=(OF,CF)
1735081Sgblack@eecs.umich.edu    mulel reg
1746463Sgblack@eecs.umich.edu    muleh t0
1755081Sgblack@eecs.umich.edu};
1765081Sgblack@eecs.umich.edu
1775081Sgblack@eecs.umich.edudef macroop IMUL_R_M
1785081Sgblack@eecs.umich.edu{
1795081Sgblack@eecs.umich.edu    ld t1, seg, sib, disp
1806463Sgblack@eecs.umich.edu    mul1s reg, t1, flags=(CF,OF)
1815081Sgblack@eecs.umich.edu    mulel reg
1826463Sgblack@eecs.umich.edu    muleh t0
1835081Sgblack@eecs.umich.edu};
1845081Sgblack@eecs.umich.edu
1855081Sgblack@eecs.umich.edudef macroop IMUL_R_P
1865081Sgblack@eecs.umich.edu{
1875081Sgblack@eecs.umich.edu    rdip t7
1885081Sgblack@eecs.umich.edu    ld t1, seg, riprel, disp
1896463Sgblack@eecs.umich.edu    mul1s reg, t1, flags=(CF,OF)
1905081Sgblack@eecs.umich.edu    mulel reg
1916463Sgblack@eecs.umich.edu    muleh t0
1925081Sgblack@eecs.umich.edu};
1935081Sgblack@eecs.umich.edu
1945081Sgblack@eecs.umich.edu#
1955081Sgblack@eecs.umich.edu# Three operand signed multiply.
1965081Sgblack@eecs.umich.edu#
1975081Sgblack@eecs.umich.edu
1985081Sgblack@eecs.umich.edudef macroop IMUL_R_R_I
1995081Sgblack@eecs.umich.edu{
2005081Sgblack@eecs.umich.edu    limm t1, imm
2016463Sgblack@eecs.umich.edu    mul1s regm, t1, flags=(OF,CF)
2025081Sgblack@eecs.umich.edu    mulel reg
2036463Sgblack@eecs.umich.edu    muleh t0
2045081Sgblack@eecs.umich.edu};
2055081Sgblack@eecs.umich.edu
2065081Sgblack@eecs.umich.edudef macroop IMUL_R_M_I
2075081Sgblack@eecs.umich.edu{
2085081Sgblack@eecs.umich.edu    limm t1, imm
2095081Sgblack@eecs.umich.edu    ld t2, seg, sib, disp
2106463Sgblack@eecs.umich.edu    mul1s t2, t1, flags=(OF,CF)
2115081Sgblack@eecs.umich.edu    mulel reg
2126463Sgblack@eecs.umich.edu    muleh t0
2135081Sgblack@eecs.umich.edu};
2145081Sgblack@eecs.umich.edu
2155081Sgblack@eecs.umich.edudef macroop IMUL_R_P_I
2165081Sgblack@eecs.umich.edu{
2175081Sgblack@eecs.umich.edu    rdip t7
2185081Sgblack@eecs.umich.edu    limm t1, imm
2195081Sgblack@eecs.umich.edu    ld t2, seg, riprel
2206463Sgblack@eecs.umich.edu    mul1s t2, t1, flags=(OF,CF)
2215081Sgblack@eecs.umich.edu    mulel reg
2226463Sgblack@eecs.umich.edu    muleh t0
2235081Sgblack@eecs.umich.edu};
2246514Sgblack@eecs.umich.edu'''
2256514Sgblack@eecs.umich.edu
2266514Sgblack@eecs.umich.edupcRel = '''
2276514Sgblack@eecs.umich.edu    rdip t7
2286514Sgblack@eecs.umich.edu    ld %s, seg, riprel, disp
2296514Sgblack@eecs.umich.edu'''
2306514Sgblack@eecs.umich.edusibRel = '''
2316514Sgblack@eecs.umich.edu    ld %s, seg, sib, disp
2326514Sgblack@eecs.umich.edu'''
2335081Sgblack@eecs.umich.edu
2345081Sgblack@eecs.umich.edu#
2355081Sgblack@eecs.umich.edu# One byte version of unsigned division
2365081Sgblack@eecs.umich.edu#
2375081Sgblack@eecs.umich.edu
2386514Sgblack@eecs.umich.edudivcode = '''
2396514Sgblack@eecs.umich.edudef macroop DIV_B_%(suffix)s
2405081Sgblack@eecs.umich.edu{
2416514Sgblack@eecs.umich.edu    %(readOp1)s
2425081Sgblack@eecs.umich.edu    # Do the initial part of the division
2436514Sgblack@eecs.umich.edu    div1 ah, %(op1)s, dataSize=1
2445081Sgblack@eecs.umich.edu
2455081Sgblack@eecs.umich.edu    #These are split out so we can initialize the number of bits in the
2465081Sgblack@eecs.umich.edu    #second register
2475081Sgblack@eecs.umich.edu    div2i t1, rax, 8, dataSize=1
2485081Sgblack@eecs.umich.edu    div2 t1, rax, t1, dataSize=1
2495081Sgblack@eecs.umich.edu
2505081Sgblack@eecs.umich.edu    #Loop until we're out of bits to shift in
2515081Sgblack@eecs.umich.edudivLoopTop:
2525081Sgblack@eecs.umich.edu    div2 t1, rax, t1, dataSize=1
2535081Sgblack@eecs.umich.edu    div2 t1, rax, t1, flags=(EZF,), dataSize=1
2545661Sgblack@eecs.umich.edu    br label("divLoopTop"), flags=(nCEZF,)
2555081Sgblack@eecs.umich.edu
2565081Sgblack@eecs.umich.edu    #Unload the answer
2575081Sgblack@eecs.umich.edu    divq rax, dataSize=1
2586459Sgblack@eecs.umich.edu    divr ah, dataSize=1
2595081Sgblack@eecs.umich.edu};
2606514Sgblack@eecs.umich.edu'''
2615081Sgblack@eecs.umich.edu
2625081Sgblack@eecs.umich.edu#
2635081Sgblack@eecs.umich.edu# Unsigned division
2645081Sgblack@eecs.umich.edu#
2655081Sgblack@eecs.umich.edu
2666514Sgblack@eecs.umich.edudivcode += '''
2676514Sgblack@eecs.umich.edudef macroop DIV_%(suffix)s
2685081Sgblack@eecs.umich.edu{
2696514Sgblack@eecs.umich.edu    %(readOp1)s
2705081Sgblack@eecs.umich.edu    # Do the initial part of the division
2716514Sgblack@eecs.umich.edu    div1 rdx, %(op1)s
2725081Sgblack@eecs.umich.edu
2735081Sgblack@eecs.umich.edu    #These are split out so we can initialize the number of bits in the
2745081Sgblack@eecs.umich.edu    #second register
2755081Sgblack@eecs.umich.edu    div2i t1, rax, "env.dataSize * 8"
2765081Sgblack@eecs.umich.edu    div2 t1, rax, t1
2775081Sgblack@eecs.umich.edu
2785081Sgblack@eecs.umich.edu    #Loop until we're out of bits to shift in
2795081Sgblack@eecs.umich.edu    #The amount of unrolling here could stand some tuning
2805081Sgblack@eecs.umich.edudivLoopTop:
2815081Sgblack@eecs.umich.edu    div2 t1, rax, t1
2825081Sgblack@eecs.umich.edu    div2 t1, rax, t1
2835081Sgblack@eecs.umich.edu    div2 t1, rax, t1
2845081Sgblack@eecs.umich.edu    div2 t1, rax, t1, flags=(EZF,)
2855661Sgblack@eecs.umich.edu    br label("divLoopTop"), flags=(nCEZF,)
2865081Sgblack@eecs.umich.edu
2875081Sgblack@eecs.umich.edu    #Unload the answer
2885081Sgblack@eecs.umich.edu    divq rax
2895081Sgblack@eecs.umich.edu    divr rdx
2905081Sgblack@eecs.umich.edu};
2916514Sgblack@eecs.umich.edu'''
2925081Sgblack@eecs.umich.edu
2935081Sgblack@eecs.umich.edu#
2945081Sgblack@eecs.umich.edu# One byte version of signed division
2955081Sgblack@eecs.umich.edu#
2965081Sgblack@eecs.umich.edu
2976514Sgblack@eecs.umich.edudivcode += '''
2986514Sgblack@eecs.umich.edudef macroop IDIV_B_%(suffix)s
2995081Sgblack@eecs.umich.edu{
3005081Sgblack@eecs.umich.edu    # Negate dividend
3015081Sgblack@eecs.umich.edu    sub t1, t0, rax, flags=(ECF,), dataSize=1
3025081Sgblack@eecs.umich.edu    ruflag t4, 3
3036459Sgblack@eecs.umich.edu    sub t2, t0, ah, dataSize=1
3045081Sgblack@eecs.umich.edu    sub t2, t2, t4
3055081Sgblack@eecs.umich.edu
3066514Sgblack@eecs.umich.edu    %(readOp1)s
3076514Sgblack@eecs.umich.edu
3085081Sgblack@eecs.umich.edu    #Find the sign of the divisor
3096514Sgblack@eecs.umich.edu    slli t0, %(op1)s, 1, flags=(ECF,), dataSize=1
3105081Sgblack@eecs.umich.edu
3115081Sgblack@eecs.umich.edu    # Negate divisor
3126514Sgblack@eecs.umich.edu    sub t3, t0, %(op1)s, dataSize=1
3135081Sgblack@eecs.umich.edu    # Put the divisor's absolute value into t3
3146514Sgblack@eecs.umich.edu    mov t3, t3, %(op1)s, flags=(nCECF,), dataSize=1
3155081Sgblack@eecs.umich.edu
3165081Sgblack@eecs.umich.edu    #Find the sign of the dividend
3176459Sgblack@eecs.umich.edu    slli t0, ah, 1, flags=(ECF,), dataSize=1
3185081Sgblack@eecs.umich.edu
3195081Sgblack@eecs.umich.edu    # Put the dividend's absolute value into t1 and t2
3205081Sgblack@eecs.umich.edu    mov t1, t1, rax, flags=(nCECF,), dataSize=1
3216459Sgblack@eecs.umich.edu    mov t2, t2, ah, flags=(nCECF,), dataSize=1
3225081Sgblack@eecs.umich.edu
3235081Sgblack@eecs.umich.edu    # Do the initial part of the division
3245081Sgblack@eecs.umich.edu    div1 t2, t3, dataSize=1
3255081Sgblack@eecs.umich.edu
3265081Sgblack@eecs.umich.edu    #These are split out so we can initialize the number of bits in the
3275081Sgblack@eecs.umich.edu    #second register
3285081Sgblack@eecs.umich.edu    div2i t4, t1, 8, dataSize=1
3295081Sgblack@eecs.umich.edu    div2 t4, t1, t4, dataSize=1
3305081Sgblack@eecs.umich.edu
3315081Sgblack@eecs.umich.edu    #Loop until we're out of bits to shift in
3325081Sgblack@eecs.umich.edudivLoopTop:
3335081Sgblack@eecs.umich.edu    div2 t4, t1, t4, dataSize=1
3345081Sgblack@eecs.umich.edu    div2 t4, t1, t4, flags=(EZF,), dataSize=1
3355661Sgblack@eecs.umich.edu    br label("divLoopTop"), flags=(nCEZF,)
3365081Sgblack@eecs.umich.edu
3375081Sgblack@eecs.umich.edu    #Unload the answer
3385081Sgblack@eecs.umich.edu    divq t5, dataSize=1
3395081Sgblack@eecs.umich.edu    divr t6, dataSize=1
3405081Sgblack@eecs.umich.edu
3415081Sgblack@eecs.umich.edu    # Fix up signs. The sign of the dividend is still lying around in ECF.
3425081Sgblack@eecs.umich.edu    # The sign of the remainder, ah, is the same as the dividend. The sign
3435081Sgblack@eecs.umich.edu    # of the quotient is negated if the signs of the divisor and dividend
3445081Sgblack@eecs.umich.edu    # were different.
3455081Sgblack@eecs.umich.edu
3465081Sgblack@eecs.umich.edu    # Negate the remainder
3475081Sgblack@eecs.umich.edu    sub t4, t0, t6, dataSize=1
3486459Sgblack@eecs.umich.edu    # If the dividend was negitive, put the negated remainder in ah.
3496459Sgblack@eecs.umich.edu    mov ah, ah, t4, (CECF,), dataSize=1
3506459Sgblack@eecs.umich.edu    # Otherwise put the regular remainder in ah.
3516459Sgblack@eecs.umich.edu    mov ah, ah, t6, (nCECF,), dataSize=1
3525081Sgblack@eecs.umich.edu
3535081Sgblack@eecs.umich.edu    # Negate the quotient.
3545081Sgblack@eecs.umich.edu    sub t4, t0, t5, dataSize=1
3555081Sgblack@eecs.umich.edu    # If the dividend was negative, start using the negated quotient
3565081Sgblack@eecs.umich.edu    mov t5, t5, t4, (CECF,), dataSize=1
3575081Sgblack@eecs.umich.edu
3585081Sgblack@eecs.umich.edu    # Check the sign of the divisor
3596514Sgblack@eecs.umich.edu    slli t0, %(op1)s, 1, flags=(ECF,), dataSize=1
3605081Sgblack@eecs.umich.edu
3615081Sgblack@eecs.umich.edu    # Negate the (possibly already negated) quotient
3625081Sgblack@eecs.umich.edu    sub t4, t0, t5, dataSize=1
3635081Sgblack@eecs.umich.edu    # If the divisor was negative, put the negated quotient in rax.
3645081Sgblack@eecs.umich.edu    mov rax, rax, t4, (CECF,), dataSize=1
3655081Sgblack@eecs.umich.edu    # Otherwise put the one that wasn't negated (at least here) in rax.
3665081Sgblack@eecs.umich.edu    mov rax, rax, t5, (nCECF,), dataSize=1
3675081Sgblack@eecs.umich.edu};
3686514Sgblack@eecs.umich.edu'''
3695081Sgblack@eecs.umich.edu
3705081Sgblack@eecs.umich.edu#
3715081Sgblack@eecs.umich.edu# Signed division
3725081Sgblack@eecs.umich.edu#
3735081Sgblack@eecs.umich.edu
3746514Sgblack@eecs.umich.edudivcode += '''
3756514Sgblack@eecs.umich.edudef macroop IDIV_%(suffix)s
3765081Sgblack@eecs.umich.edu{
3775081Sgblack@eecs.umich.edu    # Negate dividend
3785081Sgblack@eecs.umich.edu    sub t1, t0, rax, flags=(ECF,)
3795081Sgblack@eecs.umich.edu    ruflag t4, 3
3805081Sgblack@eecs.umich.edu    sub t2, t0, rdx
3815081Sgblack@eecs.umich.edu    sub t2, t2, t4
3825081Sgblack@eecs.umich.edu
3836514Sgblack@eecs.umich.edu    %(readOp1)s
3846514Sgblack@eecs.umich.edu
3855081Sgblack@eecs.umich.edu    #Find the sign of the divisor
3866514Sgblack@eecs.umich.edu    slli t0, %(op1)s, 1, flags=(ECF,)
3875081Sgblack@eecs.umich.edu
3885081Sgblack@eecs.umich.edu    # Negate divisor
3896514Sgblack@eecs.umich.edu    sub t3, t0, %(op1)s
3905081Sgblack@eecs.umich.edu    # Put the divisor's absolute value into t3
3916514Sgblack@eecs.umich.edu    mov t3, t3, %(op1)s, flags=(nCECF,)
3925081Sgblack@eecs.umich.edu
3935081Sgblack@eecs.umich.edu    #Find the sign of the dividend
3945081Sgblack@eecs.umich.edu    slli t0, rdx, 1, flags=(ECF,)
3955081Sgblack@eecs.umich.edu
3965081Sgblack@eecs.umich.edu    # Put the dividend's absolute value into t1 and t2
3975081Sgblack@eecs.umich.edu    mov t1, t1, rax, flags=(nCECF,)
3985081Sgblack@eecs.umich.edu    mov t2, t2, rdx, flags=(nCECF,)
3995081Sgblack@eecs.umich.edu
4005081Sgblack@eecs.umich.edu    # Do the initial part of the division
4015081Sgblack@eecs.umich.edu    div1 t2, t3
4025081Sgblack@eecs.umich.edu
4035081Sgblack@eecs.umich.edu    #These are split out so we can initialize the number of bits in the
4045081Sgblack@eecs.umich.edu    #second register
4055081Sgblack@eecs.umich.edu    div2i t4, t1, "env.dataSize * 8"
4065081Sgblack@eecs.umich.edu    div2 t4, t1, t4
4075081Sgblack@eecs.umich.edu
4085081Sgblack@eecs.umich.edu    #Loop until we're out of bits to shift in
4095081Sgblack@eecs.umich.edudivLoopTop:
4105081Sgblack@eecs.umich.edu    div2 t4, t1, t4
4115081Sgblack@eecs.umich.edu    div2 t4, t1, t4
4125081Sgblack@eecs.umich.edu    div2 t4, t1, t4
4135081Sgblack@eecs.umich.edu    div2 t4, t1, t4, flags=(EZF,)
4145661Sgblack@eecs.umich.edu    br label("divLoopTop"), flags=(nCEZF,)
4155081Sgblack@eecs.umich.edu
4165081Sgblack@eecs.umich.edu    #Unload the answer
4175081Sgblack@eecs.umich.edu    divq t5
4185081Sgblack@eecs.umich.edu    divr t6
4195081Sgblack@eecs.umich.edu
4205081Sgblack@eecs.umich.edu    # Fix up signs. The sign of the dividend is still lying around in ECF.
4215081Sgblack@eecs.umich.edu    # The sign of the remainder, ah, is the same as the dividend. The sign
4225081Sgblack@eecs.umich.edu    # of the quotient is negated if the signs of the divisor and dividend
4235081Sgblack@eecs.umich.edu    # were different.
4245081Sgblack@eecs.umich.edu
4255081Sgblack@eecs.umich.edu    # Negate the remainder
4265081Sgblack@eecs.umich.edu    sub t4, t0, t6
4275081Sgblack@eecs.umich.edu    # If the dividend was negitive, put the negated remainder in rdx.
4285081Sgblack@eecs.umich.edu    mov rdx, rdx, t4, (CECF,)
4295081Sgblack@eecs.umich.edu    # Otherwise put the regular remainder in rdx.
4305081Sgblack@eecs.umich.edu    mov rdx, rdx, t6, (nCECF,)
4315081Sgblack@eecs.umich.edu
4325081Sgblack@eecs.umich.edu    # Negate the quotient.
4335081Sgblack@eecs.umich.edu    sub t4, t0, t5
4345081Sgblack@eecs.umich.edu    # If the dividend was negative, start using the negated quotient
4355081Sgblack@eecs.umich.edu    mov t5, t5, t4, (CECF,)
4365081Sgblack@eecs.umich.edu
4375081Sgblack@eecs.umich.edu    # Check the sign of the divisor
4386514Sgblack@eecs.umich.edu    slli t0, %(op1)s, 1, flags=(ECF,)
4395081Sgblack@eecs.umich.edu
4405081Sgblack@eecs.umich.edu    # Negate the (possibly already negated) quotient
4415081Sgblack@eecs.umich.edu    sub t4, t0, t5
4425081Sgblack@eecs.umich.edu    # If the divisor was negative, put the negated quotient in rax.
4435081Sgblack@eecs.umich.edu    mov rax, rax, t4, (CECF,)
4445081Sgblack@eecs.umich.edu    # Otherwise put the one that wasn't negated (at least here) in rax.
4455081Sgblack@eecs.umich.edu    mov rax, rax, t5, (nCECF,)
4465081Sgblack@eecs.umich.edu};
4475081Sgblack@eecs.umich.edu'''
4486514Sgblack@eecs.umich.edu
4496514Sgblack@eecs.umich.edumicrocode += divcode % {"suffix": "R",
4506514Sgblack@eecs.umich.edu                        "readOp1": "", "op1": "reg"}
4516514Sgblack@eecs.umich.edumicrocode += divcode % {"suffix": "M",
4526514Sgblack@eecs.umich.edu                        "readOp1": sibRel % "t2", "op1": "t2"}
4536514Sgblack@eecs.umich.edumicrocode += divcode % {"suffix": "P",
4546514Sgblack@eecs.umich.edu                        "readOp1": pcRel % "t2", "op1": "t2"}
455