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