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, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  *      Copyright (c) 1988-1991 by Sun Microsystems, Inc.
  24  */
  25 
  26 #ident  "%Z%%M% %I%     %E% SMI"        /* From SunOS 4.1 1.6 */
  27 
  28 #if defined(lint)
  29 #include <sys/types.h>
  30 #include <sys/regset.h>
  31 #include <sys/privregs.h>
  32 #endif  /* lint */
  33 
  34 #include <sys/asm_linkage.h>
  35 #include <sys/trap.h>
  36 #include <sys/machtrap.h>
  37 #include <sys/simulate.h>
  38 
  39 /*
  40  * C run time subroutines.
  41  *
  42  *      Those beginning in `.' are not callable from C and hence do not
  43  *      get lint prototypes.
  44  */
  45 
  46 #if !defined(lint)
  47 
  48 /*
  49  * Structure return
  50  */
  51 #define UNIMP           0
  52 #define MASK            0x00000fff
  53 #define STRUCT_VAL_OFF  (16*4)
  54 
  55         RTENTRY(.stret4)
  56         RTENTRY(.stret8)
  57         !
  58         ! see if key matches: if not, structure value not expected,
  59         ! so just return
  60         !
  61         ld      [%i7 + 8], %o3
  62         and     %o1, MASK, %o4
  63         sethi   %hi(UNIMP), %o5
  64         or      %o4, %o5, %o5
  65         cmp     %o5, %o3
  66         be,a    0f
  67         ld      [%fp + STRUCT_VAL_OFF], %i0     ! set expected return value
  68         ret
  69         restore
  70 0:                                              ! copy the struct
  71         subcc   %o1, 4, %o1
  72         ld      [%o0 + %o1], %o4
  73         bg      0b
  74         st      %o4, [%i0 + %o1]                ! delay slot
  75         add     %i7, 0x4, %i7                   ! bump return address
  76         ret
  77         restore
  78         SET_SIZE(.stret4)
  79         SET_SIZE(.stret8)
  80 
  81         RTENTRY(.stret2)
  82         !
  83         ! see if key matches: if not, structure value not expected,
  84         ! so just return
  85         !
  86         ld      [%i7 + 8], %o3
  87         and     %o1, MASK, %o4
  88         sethi   %hi(UNIMP), %o5
  89         or      %o4, %o5, %o5
  90         cmp     %o5, %o3
  91         be,a    0f
  92         ld      [%fp + STRUCT_VAL_OFF], %i0     ! set expected return value
  93         ret
  94         restore
  95 0:                                              ! copy the struct
  96         subcc   %o1, 2, %o1
  97         lduh    [%o0 + %o1], %o4
  98         bg      0b
  99         sth     %o4, [%i0 + %o1]                ! delay slot
 100         add     %i7, 0x4, %i7                   ! bump return address
 101         ret
 102         restore
 103         SET_SIZE(.stret2)
 104 
 105 /*
 106  * Convert 32-bit arg pairs in %o0:o1 and %o2:%o3 to 64-bit args in %o1 and %o2
 107  */
 108 #define ARGS_TO_64                              \
 109         sllx    %o0, 32, %o0;                   \
 110         srl     %o1, 0, %o1;                    \
 111         sllx    %o2, 32, %o2;                   \
 112         srl     %o3, 0, %o3;                    \
 113         or      %o0, %o1, %o1;                  \
 114         or      %o2, %o3, %o2
 115 
 116         RTENTRY(__mul64)
 117         ALTENTRY(__umul64)
 118         ARGS_TO_64
 119         sub     %o1, %o2, %o0   ! %o0 = a - b
 120         movrlz  %o0, %g0, %o0   ! %o0 = (a < b) ? 0 : a - b
 121         sub     %o1, %o0, %o1   ! %o1 = (a < b) ? a : b = min(a, b)
 122         add     %o2, %o0, %o2   ! %o2 = (a < b) ? b : a = max(a, b)
 123         mulx    %o1, %o2, %o1   ! min(a, b) in "rs1" for early exit
 124         retl
 125         srax    %o1, 32, %o0
 126         SET_SIZE(__mul64)
 127         SET_SIZE(__umul64)
 128 
 129         RTENTRY(__div64)
 130         ARGS_TO_64
 131         sdivx   %o1, %o2, %o1
 132         retl
 133         srax    %o1, 32, %o0
 134         SET_SIZE(__div64)
 135 
 136         RTENTRY(__udiv64)
 137         ARGS_TO_64
 138         udivx   %o1, %o2, %o1
 139         retl
 140         srax    %o1, 32, %o0
 141         SET_SIZE(__udiv64)
 142 
 143         RTENTRY(__rem64)
 144         ARGS_TO_64
 145         sdivx   %o1, %o2, %o3
 146         mulx    %o2, %o3, %o3
 147         sub     %o1, %o3, %o1
 148         retl
 149         srax    %o1, 32, %o0
 150         SET_SIZE(__rem64)
 151 
 152         RTENTRY(__urem64)
 153         ARGS_TO_64
 154         udivx   %o1, %o2, %o3
 155         mulx    %o2, %o3, %o3
 156         sub     %o1, %o3, %o1
 157         retl
 158         srax    %o1, 32, %o0
 159         SET_SIZE(__urem64)
 160 
 161 #endif /* !lint */