15081Sgblack@eecs.umich.edu# Copyright (c) 2007 The Hewlett-Packard Development Company
25081Sgblack@eecs.umich.edu# All rights reserved.
35081Sgblack@eecs.umich.edu#
47087Snate@binkert.org# The license below extends only to copyright in the software and shall
57087Snate@binkert.org# not be construed as granting a license to any other intellectual
67087Snate@binkert.org# property including but not limited to intellectual property relating
77087Snate@binkert.org# to a hardware implementation of the functionality of the software
87087Snate@binkert.org# licensed hereunder.  You may use the software subject to the license
97087Snate@binkert.org# terms below provided that you ensure that this notice is replicated
107087Snate@binkert.org# unmodified and in its entirety in all distributions of the software,
117087Snate@binkert.org# modified or unmodified, in source code or in binary form.
125081Sgblack@eecs.umich.edu#
137087Snate@binkert.org# Redistribution and use in source and binary forms, with or without
147087Snate@binkert.org# modification, are permitted provided that the following conditions are
157087Snate@binkert.org# met: redistributions of source code must retain the above copyright
167087Snate@binkert.org# notice, this list of conditions and the following disclaimer;
177087Snate@binkert.org# redistributions in binary form must reproduce the above copyright
187087Snate@binkert.org# notice, this list of conditions and the following disclaimer in the
197087Snate@binkert.org# documentation and/or other materials provided with the distribution;
207087Snate@binkert.org# neither the name of the copyright holders nor the names of its
215081Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from
227087Snate@binkert.org# this software without specific prior written permission.
235081Sgblack@eecs.umich.edu#
245081Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
255081Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
265081Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
275081Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
285081Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
295081Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
305081Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
315081Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
325081Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
335081Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
345081Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
355081Sgblack@eecs.umich.edu#
365081Sgblack@eecs.umich.edu# Authors: Gabe Black
375081Sgblack@eecs.umich.edu
385081Sgblack@eecs.umich.edumicrocode = '''
395081Sgblack@eecs.umich.edu
405081Sgblack@eecs.umich.edu#
415081Sgblack@eecs.umich.edu# Byte version of one operand unsigned multiply.
425081Sgblack@eecs.umich.edu#
435081Sgblack@eecs.umich.edu
445081Sgblack@eecs.umich.edudef macroop MUL_B_R
455081Sgblack@eecs.umich.edu{
466463Sgblack@eecs.umich.edu    mul1u rax, reg, flags=(OF,CF)
475081Sgblack@eecs.umich.edu    mulel rax
486463Sgblack@eecs.umich.edu    muleh ah
495081Sgblack@eecs.umich.edu};
505081Sgblack@eecs.umich.edu
515081Sgblack@eecs.umich.edudef macroop MUL_B_M
525081Sgblack@eecs.umich.edu{
535081Sgblack@eecs.umich.edu    ld t1, seg, sib, disp
546463Sgblack@eecs.umich.edu    mul1u rax, t1, flags=(OF,CF)
555081Sgblack@eecs.umich.edu    mulel rax
566463Sgblack@eecs.umich.edu    muleh ah
575081Sgblack@eecs.umich.edu};
585081Sgblack@eecs.umich.edu
595081Sgblack@eecs.umich.edudef macroop MUL_B_P
605081Sgblack@eecs.umich.edu{
615081Sgblack@eecs.umich.edu    rdip t7
625081Sgblack@eecs.umich.edu    ld t1, seg, riprel, disp
636463Sgblack@eecs.umich.edu    mul1u rax, t1, flags=(OF,CF)
645081Sgblack@eecs.umich.edu    mulel rax
656463Sgblack@eecs.umich.edu    muleh ah
665081Sgblack@eecs.umich.edu};
675081Sgblack@eecs.umich.edu
685081Sgblack@eecs.umich.edu#
695081Sgblack@eecs.umich.edu# One operand unsigned multiply.
705081Sgblack@eecs.umich.edu#
715081Sgblack@eecs.umich.edu
725081Sgblack@eecs.umich.edudef macroop MUL_R
735081Sgblack@eecs.umich.edu{
746463Sgblack@eecs.umich.edu    mul1u rax, reg, flags=(OF,CF)
755081Sgblack@eecs.umich.edu    mulel rax
766463Sgblack@eecs.umich.edu    muleh rdx
775081Sgblack@eecs.umich.edu};
785081Sgblack@eecs.umich.edu
795081Sgblack@eecs.umich.edudef macroop MUL_M
805081Sgblack@eecs.umich.edu{
815081Sgblack@eecs.umich.edu    ld t1, seg, sib, disp
826463Sgblack@eecs.umich.edu    mul1u rax, t1, flags=(OF,CF)
835081Sgblack@eecs.umich.edu    mulel rax
846463Sgblack@eecs.umich.edu    muleh rdx
855081Sgblack@eecs.umich.edu};
865081Sgblack@eecs.umich.edu
875081Sgblack@eecs.umich.edudef macroop MUL_P
885081Sgblack@eecs.umich.edu{
895081Sgblack@eecs.umich.edu    rdip t7
905081Sgblack@eecs.umich.edu    ld t1, seg, riprel, disp
916463Sgblack@eecs.umich.edu    mul1u rax, t1, flags=(OF,CF)
925081Sgblack@eecs.umich.edu    mulel rax
936463Sgblack@eecs.umich.edu    muleh rdx
945081Sgblack@eecs.umich.edu};
955081Sgblack@eecs.umich.edu
965081Sgblack@eecs.umich.edu#
975081Sgblack@eecs.umich.edu# Byte version of one operand signed multiply.
985081Sgblack@eecs.umich.edu#
995081Sgblack@eecs.umich.edu
1005081Sgblack@eecs.umich.edudef macroop IMUL_B_R
1015081Sgblack@eecs.umich.edu{
1026463Sgblack@eecs.umich.edu    mul1s rax, reg, flags=(OF,CF)
1035081Sgblack@eecs.umich.edu    mulel rax
1046463Sgblack@eecs.umich.edu    muleh ah
1055081Sgblack@eecs.umich.edu};
1065081Sgblack@eecs.umich.edu
1075081Sgblack@eecs.umich.edudef macroop IMUL_B_M
1085081Sgblack@eecs.umich.edu{
1095081Sgblack@eecs.umich.edu    ld t1, seg, sib, disp
1106463Sgblack@eecs.umich.edu    mul1s rax, t1, flags=(OF,CF)
1115081Sgblack@eecs.umich.edu    mulel rax
1126463Sgblack@eecs.umich.edu    muleh ah
1135081Sgblack@eecs.umich.edu};
1145081Sgblack@eecs.umich.edu
1155081Sgblack@eecs.umich.edudef macroop IMUL_B_P
1165081Sgblack@eecs.umich.edu{
1175081Sgblack@eecs.umich.edu    rdip t7
1185081Sgblack@eecs.umich.edu    ld t1, seg, riprel, disp
1196463Sgblack@eecs.umich.edu    mul1s rax, t1, flags=(OF,CF)
1205081Sgblack@eecs.umich.edu    mulel rax
1216463Sgblack@eecs.umich.edu    muleh ah
1225081Sgblack@eecs.umich.edu};
1235081Sgblack@eecs.umich.edu
1245081Sgblack@eecs.umich.edu#
1255081Sgblack@eecs.umich.edu# One operand signed multiply.
1265081Sgblack@eecs.umich.edu#
1275081Sgblack@eecs.umich.edu
1285081Sgblack@eecs.umich.edudef macroop IMUL_R
1295081Sgblack@eecs.umich.edu{
1306463Sgblack@eecs.umich.edu    mul1s rax, reg, flags=(OF,CF)
1315081Sgblack@eecs.umich.edu    mulel rax
1326463Sgblack@eecs.umich.edu    muleh rdx
1335081Sgblack@eecs.umich.edu};
1345081Sgblack@eecs.umich.edu
1355081Sgblack@eecs.umich.edudef macroop IMUL_M
1365081Sgblack@eecs.umich.edu{
1375081Sgblack@eecs.umich.edu    ld t1, seg, sib, disp
1386463Sgblack@eecs.umich.edu    mul1s rax, t1, flags=(OF,CF)
1395081Sgblack@eecs.umich.edu    mulel rax
1406463Sgblack@eecs.umich.edu    muleh rdx
1415081Sgblack@eecs.umich.edu};
1425081Sgblack@eecs.umich.edu
1435081Sgblack@eecs.umich.edudef macroop IMUL_P
1445081Sgblack@eecs.umich.edu{
1455081Sgblack@eecs.umich.edu    rdip t7
1465081Sgblack@eecs.umich.edu    ld t1, seg, riprel, disp
1476463Sgblack@eecs.umich.edu    mul1s rax, t1, flags=(OF,CF)
1485081Sgblack@eecs.umich.edu    mulel rax
1496463Sgblack@eecs.umich.edu    muleh rdx
1505081Sgblack@eecs.umich.edu};
1515081Sgblack@eecs.umich.edu
1525081Sgblack@eecs.umich.edudef macroop IMUL_R_R
1535081Sgblack@eecs.umich.edu{
1546463Sgblack@eecs.umich.edu    mul1s reg, regm, flags=(OF,CF)
1555081Sgblack@eecs.umich.edu    mulel reg
1566463Sgblack@eecs.umich.edu    muleh t0
1575081Sgblack@eecs.umich.edu};
1585081Sgblack@eecs.umich.edu
1595081Sgblack@eecs.umich.edudef macroop IMUL_R_M
1605081Sgblack@eecs.umich.edu{
1615081Sgblack@eecs.umich.edu    ld t1, seg, sib, disp
1626463Sgblack@eecs.umich.edu    mul1s reg, t1, flags=(CF,OF)
1635081Sgblack@eecs.umich.edu    mulel reg
1646463Sgblack@eecs.umich.edu    muleh t0
1655081Sgblack@eecs.umich.edu};
1665081Sgblack@eecs.umich.edu
1675081Sgblack@eecs.umich.edudef macroop IMUL_R_P
1685081Sgblack@eecs.umich.edu{
1695081Sgblack@eecs.umich.edu    rdip t7
1705081Sgblack@eecs.umich.edu    ld t1, seg, riprel, disp
1716463Sgblack@eecs.umich.edu    mul1s reg, t1, flags=(CF,OF)
1725081Sgblack@eecs.umich.edu    mulel reg
1736463Sgblack@eecs.umich.edu    muleh t0
1745081Sgblack@eecs.umich.edu};
1755081Sgblack@eecs.umich.edu
1765081Sgblack@eecs.umich.edu#
1775081Sgblack@eecs.umich.edu# Three operand signed multiply.
1785081Sgblack@eecs.umich.edu#
1795081Sgblack@eecs.umich.edu
1805081Sgblack@eecs.umich.edudef macroop IMUL_R_R_I
1815081Sgblack@eecs.umich.edu{
1825081Sgblack@eecs.umich.edu    limm t1, imm
1836463Sgblack@eecs.umich.edu    mul1s regm, t1, flags=(OF,CF)
1845081Sgblack@eecs.umich.edu    mulel reg
1856463Sgblack@eecs.umich.edu    muleh t0
1865081Sgblack@eecs.umich.edu};
1875081Sgblack@eecs.umich.edu
1885081Sgblack@eecs.umich.edudef macroop IMUL_R_M_I
1895081Sgblack@eecs.umich.edu{
1905081Sgblack@eecs.umich.edu    limm t1, imm
1915081Sgblack@eecs.umich.edu    ld t2, seg, sib, disp
1926463Sgblack@eecs.umich.edu    mul1s t2, t1, flags=(OF,CF)
1935081Sgblack@eecs.umich.edu    mulel reg
1946463Sgblack@eecs.umich.edu    muleh t0
1955081Sgblack@eecs.umich.edu};
1965081Sgblack@eecs.umich.edu
1975081Sgblack@eecs.umich.edudef macroop IMUL_R_P_I
1985081Sgblack@eecs.umich.edu{
1995081Sgblack@eecs.umich.edu    rdip t7
2005081Sgblack@eecs.umich.edu    limm t1, imm
2018973Sgblack@eecs.umich.edu    ld t2, seg, riprel, disp
2026463Sgblack@eecs.umich.edu    mul1s t2, t1, flags=(OF,CF)
2035081Sgblack@eecs.umich.edu    mulel reg
2046463Sgblack@eecs.umich.edu    muleh t0
2055081Sgblack@eecs.umich.edu};
2066514Sgblack@eecs.umich.edu'''
2076514Sgblack@eecs.umich.edu
2086514Sgblack@eecs.umich.edupcRel = '''
2096514Sgblack@eecs.umich.edu    rdip t7
2106514Sgblack@eecs.umich.edu    ld %s, seg, riprel, disp
2116514Sgblack@eecs.umich.edu'''
2126514Sgblack@eecs.umich.edusibRel = '''
2136514Sgblack@eecs.umich.edu    ld %s, seg, sib, disp
2146514Sgblack@eecs.umich.edu'''
2155081Sgblack@eecs.umich.edu
2165081Sgblack@eecs.umich.edu#
2175081Sgblack@eecs.umich.edu# One byte version of unsigned division
2185081Sgblack@eecs.umich.edu#
2195081Sgblack@eecs.umich.edu
2206514Sgblack@eecs.umich.edudivcode = '''
2216514Sgblack@eecs.umich.edudef macroop DIV_B_%(suffix)s
2225081Sgblack@eecs.umich.edu{
2236514Sgblack@eecs.umich.edu    %(readOp1)s
2245081Sgblack@eecs.umich.edu    # Do the initial part of the division
2256514Sgblack@eecs.umich.edu    div1 ah, %(op1)s, dataSize=1
2265081Sgblack@eecs.umich.edu
2275081Sgblack@eecs.umich.edu    #These are split out so we can initialize the number of bits in the
2285081Sgblack@eecs.umich.edu    #second register
2295081Sgblack@eecs.umich.edu    div2i t1, rax, 8, dataSize=1
2305081Sgblack@eecs.umich.edu    div2 t1, rax, t1, dataSize=1
2315081Sgblack@eecs.umich.edu
2325081Sgblack@eecs.umich.edu    #Loop until we're out of bits to shift in
2335081Sgblack@eecs.umich.edudivLoopTop:
2345081Sgblack@eecs.umich.edu    div2 t1, rax, t1, dataSize=1
2355081Sgblack@eecs.umich.edu    div2 t1, rax, t1, flags=(EZF,), dataSize=1
2365661Sgblack@eecs.umich.edu    br label("divLoopTop"), flags=(nCEZF,)
2375081Sgblack@eecs.umich.edu
2385081Sgblack@eecs.umich.edu    #Unload the answer
2395081Sgblack@eecs.umich.edu    divq rax, dataSize=1
2406459Sgblack@eecs.umich.edu    divr ah, dataSize=1
2415081Sgblack@eecs.umich.edu};
2426514Sgblack@eecs.umich.edu'''
2435081Sgblack@eecs.umich.edu
2445081Sgblack@eecs.umich.edu#
2455081Sgblack@eecs.umich.edu# Unsigned division
2465081Sgblack@eecs.umich.edu#
2475081Sgblack@eecs.umich.edu
2486514Sgblack@eecs.umich.edudivcode += '''
2496514Sgblack@eecs.umich.edudef macroop DIV_%(suffix)s
2505081Sgblack@eecs.umich.edu{
2516514Sgblack@eecs.umich.edu    %(readOp1)s
2525081Sgblack@eecs.umich.edu    # Do the initial part of the division
2536514Sgblack@eecs.umich.edu    div1 rdx, %(op1)s
2545081Sgblack@eecs.umich.edu
2555081Sgblack@eecs.umich.edu    #These are split out so we can initialize the number of bits in the
2565081Sgblack@eecs.umich.edu    #second register
2575081Sgblack@eecs.umich.edu    div2i t1, rax, "env.dataSize * 8"
2585081Sgblack@eecs.umich.edu    div2 t1, rax, t1
2595081Sgblack@eecs.umich.edu
2605081Sgblack@eecs.umich.edu    #Loop until we're out of bits to shift in
2615081Sgblack@eecs.umich.edu    #The amount of unrolling here could stand some tuning
2625081Sgblack@eecs.umich.edudivLoopTop:
2635081Sgblack@eecs.umich.edu    div2 t1, rax, t1
2645081Sgblack@eecs.umich.edu    div2 t1, rax, t1
2655081Sgblack@eecs.umich.edu    div2 t1, rax, t1
2665081Sgblack@eecs.umich.edu    div2 t1, rax, t1, flags=(EZF,)
2675661Sgblack@eecs.umich.edu    br label("divLoopTop"), flags=(nCEZF,)
2685081Sgblack@eecs.umich.edu
2695081Sgblack@eecs.umich.edu    #Unload the answer
2705081Sgblack@eecs.umich.edu    divq rax
2715081Sgblack@eecs.umich.edu    divr rdx
2725081Sgblack@eecs.umich.edu};
2736514Sgblack@eecs.umich.edu'''
2745081Sgblack@eecs.umich.edu
2755081Sgblack@eecs.umich.edu#
2765081Sgblack@eecs.umich.edu# One byte version of signed division
2775081Sgblack@eecs.umich.edu#
2785081Sgblack@eecs.umich.edu
2796514Sgblack@eecs.umich.edudivcode += '''
2806514Sgblack@eecs.umich.edudef macroop IDIV_B_%(suffix)s
2815081Sgblack@eecs.umich.edu{
2825081Sgblack@eecs.umich.edu    # Negate dividend
2835081Sgblack@eecs.umich.edu    sub t1, t0, rax, flags=(ECF,), dataSize=1
2845081Sgblack@eecs.umich.edu    ruflag t4, 3
2856459Sgblack@eecs.umich.edu    sub t2, t0, ah, dataSize=1
2865081Sgblack@eecs.umich.edu    sub t2, t2, t4
2875081Sgblack@eecs.umich.edu
2886514Sgblack@eecs.umich.edu    %(readOp1)s
2896514Sgblack@eecs.umich.edu
2905081Sgblack@eecs.umich.edu    #Find the sign of the divisor
2916514Sgblack@eecs.umich.edu    slli t0, %(op1)s, 1, flags=(ECF,), dataSize=1
2925081Sgblack@eecs.umich.edu
2935081Sgblack@eecs.umich.edu    # Negate divisor
2946514Sgblack@eecs.umich.edu    sub t3, t0, %(op1)s, dataSize=1
2955081Sgblack@eecs.umich.edu    # Put the divisor's absolute value into t3
2966514Sgblack@eecs.umich.edu    mov t3, t3, %(op1)s, flags=(nCECF,), dataSize=1
2975081Sgblack@eecs.umich.edu
2985081Sgblack@eecs.umich.edu    #Find the sign of the dividend
2996459Sgblack@eecs.umich.edu    slli t0, ah, 1, flags=(ECF,), dataSize=1
3005081Sgblack@eecs.umich.edu
3015081Sgblack@eecs.umich.edu    # Put the dividend's absolute value into t1 and t2
3025081Sgblack@eecs.umich.edu    mov t1, t1, rax, flags=(nCECF,), dataSize=1
3036459Sgblack@eecs.umich.edu    mov t2, t2, ah, flags=(nCECF,), dataSize=1
3045081Sgblack@eecs.umich.edu
3055081Sgblack@eecs.umich.edu    # Do the initial part of the division
3065081Sgblack@eecs.umich.edu    div1 t2, t3, dataSize=1
3075081Sgblack@eecs.umich.edu
3085081Sgblack@eecs.umich.edu    #These are split out so we can initialize the number of bits in the
3095081Sgblack@eecs.umich.edu    #second register
3105081Sgblack@eecs.umich.edu    div2i t4, t1, 8, dataSize=1
3115081Sgblack@eecs.umich.edu    div2 t4, t1, t4, dataSize=1
3125081Sgblack@eecs.umich.edu
3135081Sgblack@eecs.umich.edu    #Loop until we're out of bits to shift in
3145081Sgblack@eecs.umich.edudivLoopTop:
3155081Sgblack@eecs.umich.edu    div2 t4, t1, t4, dataSize=1
3165081Sgblack@eecs.umich.edu    div2 t4, t1, t4, flags=(EZF,), dataSize=1
3175661Sgblack@eecs.umich.edu    br label("divLoopTop"), flags=(nCEZF,)
3185081Sgblack@eecs.umich.edu
3195081Sgblack@eecs.umich.edu    #Unload the answer
3205081Sgblack@eecs.umich.edu    divq t5, dataSize=1
3215081Sgblack@eecs.umich.edu    divr t6, dataSize=1
3225081Sgblack@eecs.umich.edu
3235081Sgblack@eecs.umich.edu    # Fix up signs. The sign of the dividend is still lying around in ECF.
3245081Sgblack@eecs.umich.edu    # The sign of the remainder, ah, is the same as the dividend. The sign
3255081Sgblack@eecs.umich.edu    # of the quotient is negated if the signs of the divisor and dividend
3265081Sgblack@eecs.umich.edu    # were different.
3275081Sgblack@eecs.umich.edu
3285081Sgblack@eecs.umich.edu    # Negate the remainder
3295081Sgblack@eecs.umich.edu    sub t4, t0, t6, dataSize=1
3306459Sgblack@eecs.umich.edu    # If the dividend was negitive, put the negated remainder in ah.
3316459Sgblack@eecs.umich.edu    mov ah, ah, t4, (CECF,), dataSize=1
3326459Sgblack@eecs.umich.edu    # Otherwise put the regular remainder in ah.
3336459Sgblack@eecs.umich.edu    mov ah, ah, t6, (nCECF,), dataSize=1
3345081Sgblack@eecs.umich.edu
3355081Sgblack@eecs.umich.edu    # Negate the quotient.
3365081Sgblack@eecs.umich.edu    sub t4, t0, t5, dataSize=1
3375081Sgblack@eecs.umich.edu    # If the dividend was negative, start using the negated quotient
3385081Sgblack@eecs.umich.edu    mov t5, t5, t4, (CECF,), dataSize=1
3395081Sgblack@eecs.umich.edu
3405081Sgblack@eecs.umich.edu    # Check the sign of the divisor
3416514Sgblack@eecs.umich.edu    slli t0, %(op1)s, 1, flags=(ECF,), dataSize=1
3425081Sgblack@eecs.umich.edu
3435081Sgblack@eecs.umich.edu    # Negate the (possibly already negated) quotient
3445081Sgblack@eecs.umich.edu    sub t4, t0, t5, dataSize=1
3455081Sgblack@eecs.umich.edu    # If the divisor was negative, put the negated quotient in rax.
3465081Sgblack@eecs.umich.edu    mov rax, rax, t4, (CECF,), dataSize=1
3475081Sgblack@eecs.umich.edu    # Otherwise put the one that wasn't negated (at least here) in rax.
3485081Sgblack@eecs.umich.edu    mov rax, rax, t5, (nCECF,), dataSize=1
3495081Sgblack@eecs.umich.edu};
3506514Sgblack@eecs.umich.edu'''
3515081Sgblack@eecs.umich.edu
3525081Sgblack@eecs.umich.edu#
3535081Sgblack@eecs.umich.edu# Signed division
3545081Sgblack@eecs.umich.edu#
3555081Sgblack@eecs.umich.edu
3566514Sgblack@eecs.umich.edudivcode += '''
3576514Sgblack@eecs.umich.edudef macroop IDIV_%(suffix)s
3585081Sgblack@eecs.umich.edu{
3595081Sgblack@eecs.umich.edu    # Negate dividend
3605081Sgblack@eecs.umich.edu    sub t1, t0, rax, flags=(ECF,)
3615081Sgblack@eecs.umich.edu    ruflag t4, 3
3625081Sgblack@eecs.umich.edu    sub t2, t0, rdx
3635081Sgblack@eecs.umich.edu    sub t2, t2, t4
3645081Sgblack@eecs.umich.edu
3656514Sgblack@eecs.umich.edu    %(readOp1)s
3666514Sgblack@eecs.umich.edu
3675081Sgblack@eecs.umich.edu    #Find the sign of the divisor
3686514Sgblack@eecs.umich.edu    slli t0, %(op1)s, 1, flags=(ECF,)
3695081Sgblack@eecs.umich.edu
3705081Sgblack@eecs.umich.edu    # Negate divisor
3716514Sgblack@eecs.umich.edu    sub t3, t0, %(op1)s
3725081Sgblack@eecs.umich.edu    # Put the divisor's absolute value into t3
3736514Sgblack@eecs.umich.edu    mov t3, t3, %(op1)s, flags=(nCECF,)
3745081Sgblack@eecs.umich.edu
3755081Sgblack@eecs.umich.edu    #Find the sign of the dividend
3765081Sgblack@eecs.umich.edu    slli t0, rdx, 1, flags=(ECF,)
3775081Sgblack@eecs.umich.edu
3785081Sgblack@eecs.umich.edu    # Put the dividend's absolute value into t1 and t2
3795081Sgblack@eecs.umich.edu    mov t1, t1, rax, flags=(nCECF,)
3805081Sgblack@eecs.umich.edu    mov t2, t2, rdx, flags=(nCECF,)
3815081Sgblack@eecs.umich.edu
3825081Sgblack@eecs.umich.edu    # Do the initial part of the division
3835081Sgblack@eecs.umich.edu    div1 t2, t3
3845081Sgblack@eecs.umich.edu
3855081Sgblack@eecs.umich.edu    #These are split out so we can initialize the number of bits in the
3865081Sgblack@eecs.umich.edu    #second register
3875081Sgblack@eecs.umich.edu    div2i t4, t1, "env.dataSize * 8"
3885081Sgblack@eecs.umich.edu    div2 t4, t1, t4
3895081Sgblack@eecs.umich.edu
3905081Sgblack@eecs.umich.edu    #Loop until we're out of bits to shift in
3915081Sgblack@eecs.umich.edudivLoopTop:
3925081Sgblack@eecs.umich.edu    div2 t4, t1, t4
3935081Sgblack@eecs.umich.edu    div2 t4, t1, t4
3945081Sgblack@eecs.umich.edu    div2 t4, t1, t4
3955081Sgblack@eecs.umich.edu    div2 t4, t1, t4, flags=(EZF,)
3965661Sgblack@eecs.umich.edu    br label("divLoopTop"), flags=(nCEZF,)
3975081Sgblack@eecs.umich.edu
3985081Sgblack@eecs.umich.edu    #Unload the answer
3995081Sgblack@eecs.umich.edu    divq t5
4005081Sgblack@eecs.umich.edu    divr t6
4015081Sgblack@eecs.umich.edu
4025081Sgblack@eecs.umich.edu    # Fix up signs. The sign of the dividend is still lying around in ECF.
4035081Sgblack@eecs.umich.edu    # The sign of the remainder, ah, is the same as the dividend. The sign
4045081Sgblack@eecs.umich.edu    # of the quotient is negated if the signs of the divisor and dividend
4055081Sgblack@eecs.umich.edu    # were different.
4065081Sgblack@eecs.umich.edu
4075081Sgblack@eecs.umich.edu    # Negate the remainder
4085081Sgblack@eecs.umich.edu    sub t4, t0, t6
4095081Sgblack@eecs.umich.edu    # If the dividend was negitive, put the negated remainder in rdx.
4105081Sgblack@eecs.umich.edu    mov rdx, rdx, t4, (CECF,)
4115081Sgblack@eecs.umich.edu    # Otherwise put the regular remainder in rdx.
4125081Sgblack@eecs.umich.edu    mov rdx, rdx, t6, (nCECF,)
4135081Sgblack@eecs.umich.edu
4145081Sgblack@eecs.umich.edu    # Negate the quotient.
4155081Sgblack@eecs.umich.edu    sub t4, t0, t5
4165081Sgblack@eecs.umich.edu    # If the dividend was negative, start using the negated quotient
4175081Sgblack@eecs.umich.edu    mov t5, t5, t4, (CECF,)
4185081Sgblack@eecs.umich.edu
4195081Sgblack@eecs.umich.edu    # Check the sign of the divisor
4206514Sgblack@eecs.umich.edu    slli t0, %(op1)s, 1, flags=(ECF,)
4215081Sgblack@eecs.umich.edu
4225081Sgblack@eecs.umich.edu    # Negate the (possibly already negated) quotient
4235081Sgblack@eecs.umich.edu    sub t4, t0, t5
4245081Sgblack@eecs.umich.edu    # If the divisor was negative, put the negated quotient in rax.
4255081Sgblack@eecs.umich.edu    mov rax, rax, t4, (CECF,)
4265081Sgblack@eecs.umich.edu    # Otherwise put the one that wasn't negated (at least here) in rax.
4275081Sgblack@eecs.umich.edu    mov rax, rax, t5, (nCECF,)
4285081Sgblack@eecs.umich.edu};
4295081Sgblack@eecs.umich.edu'''
4306514Sgblack@eecs.umich.edu
4316514Sgblack@eecs.umich.edumicrocode += divcode % {"suffix": "R",
4326514Sgblack@eecs.umich.edu                        "readOp1": "", "op1": "reg"}
4336514Sgblack@eecs.umich.edumicrocode += divcode % {"suffix": "M",
4346514Sgblack@eecs.umich.edu                        "readOp1": sibRel % "t2", "op1": "t2"}
4356514Sgblack@eecs.umich.edumicrocode += divcode % {"suffix": "P",
4366514Sgblack@eecs.umich.edu                        "readOp1": pcRel % "t2", "op1": "t2"}
437