xref: /titanic_41/usr/src/lib/libc/sparc/crt/hwmuldiv.s (revision 9a70fc3be3b1e966bf78825cdb8d509963a6f0a1)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*9a70fc3bSMark J. Nelson * Common Development and Distribution License (the "License").
6*9a70fc3bSMark J. Nelson * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate/*
224eb5116aSjwadams * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
234eb5116aSjwadams * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
26*9a70fc3bSMark J. Nelson	.file	"hwmuldiv.s"
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate/*
317c478bd9Sstevel@tonic-gate * Versions of .mul .umul .div .udiv .rem .urem written using
327c478bd9Sstevel@tonic-gate * appropriate SPARC V8 instructions.
337c478bd9Sstevel@tonic-gate */
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate	ENTRY(.mul)
367c478bd9Sstevel@tonic-gate	smul	%o0, %o1, %o0
377c478bd9Sstevel@tonic-gate	rd	%y, %o1
387c478bd9Sstevel@tonic-gate	sra	%o0, 31, %o2
397c478bd9Sstevel@tonic-gate	retl
407c478bd9Sstevel@tonic-gate	cmp	%o1, %o2	! return with Z set if %y == (%o0 >> 31)
417c478bd9Sstevel@tonic-gate	SET_SIZE(.mul)
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate	ENTRY(.umul)
447c478bd9Sstevel@tonic-gate	umul	%o0, %o1, %o0
457c478bd9Sstevel@tonic-gate	rd	%y, %o1
467c478bd9Sstevel@tonic-gate	retl
477c478bd9Sstevel@tonic-gate	tst	%o1		! return with Z set if high order bits are zero
487c478bd9Sstevel@tonic-gate	SET_SIZE(.umul)
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate	ENTRY(.div)
517c478bd9Sstevel@tonic-gate	sra	%o0, 31, %o2
527c478bd9Sstevel@tonic-gate	wr	%g0, %o2, %y
537c478bd9Sstevel@tonic-gate	nop
547c478bd9Sstevel@tonic-gate	nop
557c478bd9Sstevel@tonic-gate	nop
567c478bd9Sstevel@tonic-gate	sdivcc	%o0, %o1, %o0
577c478bd9Sstevel@tonic-gate	bvs,a	1f
587c478bd9Sstevel@tonic-gate	xnor	%o0, %g0, %o0	! Corbett Correction Factor
597c478bd9Sstevel@tonic-gate1:	retl
607c478bd9Sstevel@tonic-gate	nop
617c478bd9Sstevel@tonic-gate	SET_SIZE(.div)
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate	ENTRY(.udiv)
647c478bd9Sstevel@tonic-gate	wr	%g0, %g0, %y
657c478bd9Sstevel@tonic-gate	nop
667c478bd9Sstevel@tonic-gate	nop
677c478bd9Sstevel@tonic-gate	retl
687c478bd9Sstevel@tonic-gate	udiv	%o0, %o1, %o0
697c478bd9Sstevel@tonic-gate	SET_SIZE(.udiv)
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate	ENTRY(.rem)
727c478bd9Sstevel@tonic-gate	sra	%o0, 31, %o4
737c478bd9Sstevel@tonic-gate	wr	%o4, %g0, %y
747c478bd9Sstevel@tonic-gate	nop
757c478bd9Sstevel@tonic-gate	nop
767c478bd9Sstevel@tonic-gate	nop
777c478bd9Sstevel@tonic-gate	sdivcc	%o0, %o1, %o2
787c478bd9Sstevel@tonic-gate	bvs,a	1f
797c478bd9Sstevel@tonic-gate	xnor	%o2, %g0, %o2	! Corbett Correction Factor
807c478bd9Sstevel@tonic-gate1:	smul	%o2, %o1, %o2
817c478bd9Sstevel@tonic-gate	retl
827c478bd9Sstevel@tonic-gate	sub	%o0, %o2, %o0
837c478bd9Sstevel@tonic-gate	SET_SIZE(.rem)
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate	ENTRY(.urem)
867c478bd9Sstevel@tonic-gate	wr	%g0, %g0, %y
877c478bd9Sstevel@tonic-gate	nop
887c478bd9Sstevel@tonic-gate	nop
897c478bd9Sstevel@tonic-gate	nop
907c478bd9Sstevel@tonic-gate	udiv	%o0, %o1, %o2
917c478bd9Sstevel@tonic-gate	umul	%o2, %o1, %o2
927c478bd9Sstevel@tonic-gate	retl
937c478bd9Sstevel@tonic-gate	sub	%o0, %o2, %o0
947c478bd9Sstevel@tonic-gate	SET_SIZE(.urem)
954eb5116aSjwadams
964eb5116aSjwadams/*
974eb5116aSjwadams * v8plus versions of __{u,}{mul,div,rem}64 compiler support routines
984eb5116aSjwadams */
994eb5116aSjwadams
1004eb5116aSjwadams/*
1014eb5116aSjwadams * Convert 32-bit arg pairs in %o0:o1 and %o2:%o3 to 64-bit args in %o1 and %o2
1024eb5116aSjwadams */
1034eb5116aSjwadams#define	ARGS_TO_64				\
1044eb5116aSjwadams	sllx	%o0, 32, %o0;			\
1054eb5116aSjwadams	srl	%o1, 0, %o1;			\
1064eb5116aSjwadams	sllx	%o2, 32, %o2;			\
1074eb5116aSjwadams	srl	%o3, 0, %o3;			\
1084eb5116aSjwadams	or	%o0, %o1, %o1;			\
1094eb5116aSjwadams	or	%o2, %o3, %o2
1104eb5116aSjwadams
1114eb5116aSjwadams!
1124eb5116aSjwadams! division, signed
1134eb5116aSjwadams!
1144eb5116aSjwadams	ENTRY(__div64)
1154eb5116aSjwadams	ARGS_TO_64
1164eb5116aSjwadams	sdivx	%o1, %o2, %o1
1174eb5116aSjwadams	retl
1184eb5116aSjwadams	srax	%o1, 32, %o0
1194eb5116aSjwadams	SET_SIZE(__div64)
1204eb5116aSjwadams
1214eb5116aSjwadams!
1224eb5116aSjwadams! division, unsigned
1234eb5116aSjwadams!
1244eb5116aSjwadams	ENTRY(__udiv64)
1254eb5116aSjwadams	ARGS_TO_64
1264eb5116aSjwadams	udivx	%o1, %o2, %o1
1274eb5116aSjwadams	retl
1284eb5116aSjwadams	srax	%o1, 32, %o0
1294eb5116aSjwadams	SET_SIZE(__udiv64)
1304eb5116aSjwadams
1314eb5116aSjwadams!
1324eb5116aSjwadams! multiplication, signed and unsigned
1334eb5116aSjwadams!
1344eb5116aSjwadams	ENTRY(__mul64)
1354eb5116aSjwadams	ALTENTRY(__umul64)
1364eb5116aSjwadams	ARGS_TO_64
1374eb5116aSjwadams	sub	%o1, %o2, %o0	! %o0 = a - b
1384eb5116aSjwadams	movrlz	%o0, %g0, %o0	! %o0 = (a < b) ? 0 : a - b
1394eb5116aSjwadams	sub	%o1, %o0, %o1	! %o1 = (a < b) ? a : b = min(a, b)
1404eb5116aSjwadams	add	%o2, %o0, %o2	! %o2 = (a < b) ? b : a = max(a, b)
1414eb5116aSjwadams	mulx	%o1, %o2, %o1	! min(a, b) in "rs1" for early exit
1424eb5116aSjwadams	retl
1434eb5116aSjwadams	srax	%o1, 32, %o0
1444eb5116aSjwadams	SET_SIZE(__mul64)
1454eb5116aSjwadams	SET_SIZE(__umul64)
1464eb5116aSjwadams
1474eb5116aSjwadams!
1484eb5116aSjwadams! unsigned remainder
1494eb5116aSjwadams!
1504eb5116aSjwadams	ENTRY(__urem64)
1514eb5116aSjwadams	ARGS_TO_64
1524eb5116aSjwadams	udivx	%o1, %o2, %o3
1534eb5116aSjwadams	mulx	%o3, %o2, %o3
1544eb5116aSjwadams	sub	%o1, %o3, %o1
1554eb5116aSjwadams	retl
1564eb5116aSjwadams	srax	%o1, 32, %o0
1574eb5116aSjwadams	SET_SIZE(__urem64)
1584eb5116aSjwadams
1594eb5116aSjwadams!
1604eb5116aSjwadams! signed remainder
1614eb5116aSjwadams!
1624eb5116aSjwadams	ENTRY(__rem64)
1634eb5116aSjwadams	ARGS_TO_64
1644eb5116aSjwadams	sdivx	%o1, %o2, %o3
1654eb5116aSjwadams	mulx	%o2, %o3, %o3
1664eb5116aSjwadams	sub	%o1, %o3, %o1
1674eb5116aSjwadams	retl
1684eb5116aSjwadams	srax	%o1, 32, %o0
1694eb5116aSjwadams	SET_SIZE(__rem64)
170