1*5d9d9091SRichard Lowe/* 2*5d9d9091SRichard Lowe * CDDL HEADER START 3*5d9d9091SRichard Lowe * 4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the 5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License"). 6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License. 7*5d9d9091SRichard Lowe * 8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing. 10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions 11*5d9d9091SRichard Lowe * and limitations under the License. 12*5d9d9091SRichard Lowe * 13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 18*5d9d9091SRichard Lowe * 19*5d9d9091SRichard Lowe * CDDL HEADER END 20*5d9d9091SRichard Lowe */ 21*5d9d9091SRichard Lowe/* 22*5d9d9091SRichard Lowe * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 23*5d9d9091SRichard Lowe * Use is subject to license terms. 24*5d9d9091SRichard Lowe */ 25*5d9d9091SRichard Lowe 26*5d9d9091SRichard Lowe .file "hwmuldiv.s" 27*5d9d9091SRichard Lowe 28*5d9d9091SRichard Lowe#include <sys/asm_linkage.h> 29*5d9d9091SRichard Lowe 30*5d9d9091SRichard Lowe/* 31*5d9d9091SRichard Lowe * Versions of .mul .umul .div .udiv .rem .urem written using 32*5d9d9091SRichard Lowe * appropriate SPARC V8 instructions. 33*5d9d9091SRichard Lowe */ 34*5d9d9091SRichard Lowe 35*5d9d9091SRichard Lowe ENTRY(.mul) 36*5d9d9091SRichard Lowe smul %o0, %o1, %o0 37*5d9d9091SRichard Lowe rd %y, %o1 38*5d9d9091SRichard Lowe sra %o0, 31, %o2 39*5d9d9091SRichard Lowe retl 40*5d9d9091SRichard Lowe cmp %o1, %o2 ! return with Z set if %y == (%o0 >> 31) 41*5d9d9091SRichard Lowe SET_SIZE(.mul) 42*5d9d9091SRichard Lowe 43*5d9d9091SRichard Lowe ENTRY(.umul) 44*5d9d9091SRichard Lowe umul %o0, %o1, %o0 45*5d9d9091SRichard Lowe rd %y, %o1 46*5d9d9091SRichard Lowe retl 47*5d9d9091SRichard Lowe tst %o1 ! return with Z set if high order bits are zero 48*5d9d9091SRichard Lowe SET_SIZE(.umul) 49*5d9d9091SRichard Lowe 50*5d9d9091SRichard Lowe ENTRY(.div) 51*5d9d9091SRichard Lowe sra %o0, 31, %o2 52*5d9d9091SRichard Lowe wr %g0, %o2, %y 53*5d9d9091SRichard Lowe nop 54*5d9d9091SRichard Lowe nop 55*5d9d9091SRichard Lowe nop 56*5d9d9091SRichard Lowe sdivcc %o0, %o1, %o0 57*5d9d9091SRichard Lowe bvs,a 1f 58*5d9d9091SRichard Lowe xnor %o0, %g0, %o0 ! Corbett Correction Factor 59*5d9d9091SRichard Lowe1: retl 60*5d9d9091SRichard Lowe nop 61*5d9d9091SRichard Lowe SET_SIZE(.div) 62*5d9d9091SRichard Lowe 63*5d9d9091SRichard Lowe ENTRY(.udiv) 64*5d9d9091SRichard Lowe wr %g0, %g0, %y 65*5d9d9091SRichard Lowe nop 66*5d9d9091SRichard Lowe nop 67*5d9d9091SRichard Lowe retl 68*5d9d9091SRichard Lowe udiv %o0, %o1, %o0 69*5d9d9091SRichard Lowe SET_SIZE(.udiv) 70*5d9d9091SRichard Lowe 71*5d9d9091SRichard Lowe ENTRY(.rem) 72*5d9d9091SRichard Lowe sra %o0, 31, %o4 73*5d9d9091SRichard Lowe wr %o4, %g0, %y 74*5d9d9091SRichard Lowe nop 75*5d9d9091SRichard Lowe nop 76*5d9d9091SRichard Lowe nop 77*5d9d9091SRichard Lowe sdivcc %o0, %o1, %o2 78*5d9d9091SRichard Lowe bvs,a 1f 79*5d9d9091SRichard Lowe xnor %o2, %g0, %o2 ! Corbett Correction Factor 80*5d9d9091SRichard Lowe1: smul %o2, %o1, %o2 81*5d9d9091SRichard Lowe retl 82*5d9d9091SRichard Lowe sub %o0, %o2, %o0 83*5d9d9091SRichard Lowe SET_SIZE(.rem) 84*5d9d9091SRichard Lowe 85*5d9d9091SRichard Lowe ENTRY(.urem) 86*5d9d9091SRichard Lowe wr %g0, %g0, %y 87*5d9d9091SRichard Lowe nop 88*5d9d9091SRichard Lowe nop 89*5d9d9091SRichard Lowe nop 90*5d9d9091SRichard Lowe udiv %o0, %o1, %o2 91*5d9d9091SRichard Lowe umul %o2, %o1, %o2 92*5d9d9091SRichard Lowe retl 93*5d9d9091SRichard Lowe sub %o0, %o2, %o0 94*5d9d9091SRichard Lowe SET_SIZE(.urem) 95*5d9d9091SRichard Lowe 96*5d9d9091SRichard Lowe/* 97*5d9d9091SRichard Lowe * v8plus versions of __{u,}{mul,div,rem}64 compiler support routines 98*5d9d9091SRichard Lowe */ 99*5d9d9091SRichard Lowe 100*5d9d9091SRichard Lowe/* 101*5d9d9091SRichard Lowe * Convert 32-bit arg pairs in %o0:o1 and %o2:%o3 to 64-bit args in %o1 and %o2 102*5d9d9091SRichard Lowe */ 103*5d9d9091SRichard Lowe#define ARGS_TO_64 \ 104*5d9d9091SRichard Lowe sllx %o0, 32, %o0; \ 105*5d9d9091SRichard Lowe srl %o1, 0, %o1; \ 106*5d9d9091SRichard Lowe sllx %o2, 32, %o2; \ 107*5d9d9091SRichard Lowe srl %o3, 0, %o3; \ 108*5d9d9091SRichard Lowe or %o0, %o1, %o1; \ 109*5d9d9091SRichard Lowe or %o2, %o3, %o2 110*5d9d9091SRichard Lowe 111*5d9d9091SRichard Lowe! 112*5d9d9091SRichard Lowe! division, signed 113*5d9d9091SRichard Lowe! 114*5d9d9091SRichard Lowe ENTRY(__div64) 115*5d9d9091SRichard Lowe ARGS_TO_64 116*5d9d9091SRichard Lowe sdivx %o1, %o2, %o1 117*5d9d9091SRichard Lowe retl 118*5d9d9091SRichard Lowe srax %o1, 32, %o0 119*5d9d9091SRichard Lowe SET_SIZE(__div64) 120*5d9d9091SRichard Lowe 121*5d9d9091SRichard Lowe! 122*5d9d9091SRichard Lowe! division, unsigned 123*5d9d9091SRichard Lowe! 124*5d9d9091SRichard Lowe ENTRY(__udiv64) 125*5d9d9091SRichard Lowe ARGS_TO_64 126*5d9d9091SRichard Lowe udivx %o1, %o2, %o1 127*5d9d9091SRichard Lowe retl 128*5d9d9091SRichard Lowe srax %o1, 32, %o0 129*5d9d9091SRichard Lowe SET_SIZE(__udiv64) 130*5d9d9091SRichard Lowe 131*5d9d9091SRichard Lowe! 132*5d9d9091SRichard Lowe! multiplication, signed and unsigned 133*5d9d9091SRichard Lowe! 134*5d9d9091SRichard Lowe ENTRY(__mul64) 135*5d9d9091SRichard Lowe ALTENTRY(__umul64) 136*5d9d9091SRichard Lowe ARGS_TO_64 137*5d9d9091SRichard Lowe sub %o1, %o2, %o0 ! %o0 = a - b 138*5d9d9091SRichard Lowe movrlz %o0, %g0, %o0 ! %o0 = (a < b) ? 0 : a - b 139*5d9d9091SRichard Lowe sub %o1, %o0, %o1 ! %o1 = (a < b) ? a : b = min(a, b) 140*5d9d9091SRichard Lowe add %o2, %o0, %o2 ! %o2 = (a < b) ? b : a = max(a, b) 141*5d9d9091SRichard Lowe mulx %o1, %o2, %o1 ! min(a, b) in "rs1" for early exit 142*5d9d9091SRichard Lowe retl 143*5d9d9091SRichard Lowe srax %o1, 32, %o0 144*5d9d9091SRichard Lowe SET_SIZE(__mul64) 145*5d9d9091SRichard Lowe SET_SIZE(__umul64) 146*5d9d9091SRichard Lowe 147*5d9d9091SRichard Lowe! 148*5d9d9091SRichard Lowe! unsigned remainder 149*5d9d9091SRichard Lowe! 150*5d9d9091SRichard Lowe ENTRY(__urem64) 151*5d9d9091SRichard Lowe ARGS_TO_64 152*5d9d9091SRichard Lowe udivx %o1, %o2, %o3 153*5d9d9091SRichard Lowe mulx %o3, %o2, %o3 154*5d9d9091SRichard Lowe sub %o1, %o3, %o1 155*5d9d9091SRichard Lowe retl 156*5d9d9091SRichard Lowe srax %o1, 32, %o0 157*5d9d9091SRichard Lowe SET_SIZE(__urem64) 158*5d9d9091SRichard Lowe 159*5d9d9091SRichard Lowe! 160*5d9d9091SRichard Lowe! signed remainder 161*5d9d9091SRichard Lowe! 162*5d9d9091SRichard Lowe ENTRY(__rem64) 163*5d9d9091SRichard Lowe ARGS_TO_64 164*5d9d9091SRichard Lowe sdivx %o1, %o2, %o3 165*5d9d9091SRichard Lowe mulx %o2, %o3, %o3 166*5d9d9091SRichard Lowe sub %o1, %o3, %o1 167*5d9d9091SRichard Lowe retl 168*5d9d9091SRichard Lowe srax %o1, 32, %o0 169*5d9d9091SRichard Lowe SET_SIZE(__rem64) 170