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