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 #include <sys/asm_linkage.h>
  29 #include <sys/trap.h>
  30 #include <sys/machtrap.h>
  31 #include <sys/simulate.h>
  32 
  33 /*
  34  * C run time subroutines.
  35  *
  36  *      Those beginning in `.' are not callable from C and hence do not
  37  *      get lint prototypes.
  38  */
  39 
  40 /*
  41  * Structure return
  42  */
  43 #define UNIMP           0
  44 #define MASK            0x00000fff
  45 #define STRUCT_VAL_OFF  (16*4)
  46 
  47         RTENTRY(.stret4)
  48         RTENTRY(.stret8)
  49         !
  50         ! see if key matches: if not, structure value not expected,
  51         ! so just return
  52         !
  53         ld      [%i7 + 8], %o3
  54         and     %o1, MASK, %o4
  55         sethi   %hi(UNIMP), %o5
  56         or      %o4, %o5, %o5
  57         cmp     %o5, %o3
  58         be,a    0f
  59         ld      [%fp + STRUCT_VAL_OFF], %i0     ! set expected return value
  60         ret
  61         restore
  62 0:                                              ! copy the struct
  63         subcc   %o1, 4, %o1
  64         ld      [%o0 + %o1], %o4
  65         bg      0b
  66         st      %o4, [%i0 + %o1]                ! delay slot
  67         add     %i7, 0x4, %i7                   ! bump return address
  68         ret
  69         restore
  70         SET_SIZE(.stret4)
  71         SET_SIZE(.stret8)
  72 
  73         RTENTRY(.stret2)
  74         !
  75         ! see if key matches: if not, structure value not expected,
  76         ! so just return
  77         !
  78         ld      [%i7 + 8], %o3
  79         and     %o1, MASK, %o4
  80         sethi   %hi(UNIMP), %o5
  81         or      %o4, %o5, %o5
  82         cmp     %o5, %o3
  83         be,a    0f
  84         ld      [%fp + STRUCT_VAL_OFF], %i0     ! set expected return value
  85         ret
  86         restore
  87 0:                                              ! copy the struct
  88         subcc   %o1, 2, %o1
  89         lduh    [%o0 + %o1], %o4
  90         bg      0b
  91         sth     %o4, [%i0 + %o1]                ! delay slot
  92         add     %i7, 0x4, %i7                   ! bump return address
  93         ret
  94         restore
  95         SET_SIZE(.stret2)
  96 
  97 /*
  98  * Convert 32-bit arg pairs in %o0:o1 and %o2:%o3 to 64-bit args in %o1 and %o2
  99  */
 100 #define ARGS_TO_64                              \
 101         sllx    %o0, 32, %o0;                   \
 102         srl     %o1, 0, %o1;                    \
 103         sllx    %o2, 32, %o2;                   \
 104         srl     %o3, 0, %o3;                    \
 105         or      %o0, %o1, %o1;                  \
 106         or      %o2, %o3, %o2
 107 
 108         RTENTRY(__mul64)
 109         ALTENTRY(__umul64)
 110         ARGS_TO_64
 111         sub     %o1, %o2, %o0   ! %o0 = a - b
 112         movrlz  %o0, %g0, %o0   ! %o0 = (a < b) ? 0 : a - b
 113         sub     %o1, %o0, %o1   ! %o1 = (a < b) ? a : b = min(a, b)
 114         add     %o2, %o0, %o2   ! %o2 = (a < b) ? b : a = max(a, b)
 115         mulx    %o1, %o2, %o1   ! min(a, b) in "rs1" for early exit
 116         retl
 117         srax    %o1, 32, %o0
 118         SET_SIZE(__mul64)
 119         SET_SIZE(__umul64)
 120 
 121         RTENTRY(__div64)
 122         ARGS_TO_64
 123         sdivx   %o1, %o2, %o1
 124         retl
 125         srax    %o1, 32, %o0
 126         SET_SIZE(__div64)
 127 
 128         RTENTRY(__udiv64)
 129         ARGS_TO_64
 130         udivx   %o1, %o2, %o1
 131         retl
 132         srax    %o1, 32, %o0
 133         SET_SIZE(__udiv64)
 134 
 135         RTENTRY(__rem64)
 136         ARGS_TO_64
 137         sdivx   %o1, %o2, %o3
 138         mulx    %o2, %o3, %o3
 139         sub     %o1, %o3, %o1
 140         retl
 141         srax    %o1, 32, %o0
 142         SET_SIZE(__rem64)
 143 
 144         RTENTRY(__urem64)
 145         ARGS_TO_64
 146         udivx   %o1, %o2, %o3
 147         mulx    %o2, %o3, %o3
 148         sub     %o1, %o3, %o1
 149         retl
 150         srax    %o1, 32, %o0
 151         SET_SIZE(__urem64)
 152