Home | History | Annotate | Download | only in i386
      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 2004 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 /*
     30  * This file contains bignum implementation code that
     31  * is specific to x86, but which is still more appropriate
     32  * to write in C, rather than assembly language.
     33  * bignum_i386_asm.s does all the assembly language code
     34  * for x86 specific bignum support.  The assembly language
     35  * source file has pure code, no data.  Let the C compiler
     36  * generate what is needed to handle the variations in
     37  * data representation and addressing, for example,
     38  * statically linked vs PIC.
     39  */
     40 
     41 #include "bignum.h"
     42 
     43 #if defined(_KERNEL)
     44 #include <sys/cpuvar.h>
     45 #include <sys/disp.h>
     46 #endif
     47 
     48 extern uint32_t big_mul_set_vec_sse2(uint32_t *, uint32_t *, int, uint32_t);
     49 extern uint32_t big_mul_add_vec_sse2(uint32_t *, uint32_t *, int, uint32_t);
     50 extern void big_mul_vec_sse2(uint32_t *, uint32_t *, int, uint32_t *, int);
     51 extern void big_sqr_vec_sse2(uint32_t *, uint32_t *, int);
     52 
     53 #if defined(MMX_MANAGE)
     54 
     55 extern uint32_t big_mul_set_vec_sse2_nsv(uint32_t *, uint32_t *, int, uint32_t);
     56 extern uint32_t big_mul_add_vec_sse2_nsv(uint32_t *, uint32_t *, int, uint32_t);
     57 extern void big_mul_vec_sse2_nsv(uint32_t *, uint32_t *, int, uint32_t *, int);
     58 extern void big_sqr_vec_sse2_nsv(uint32_t *, uint32_t *, int);
     59 
     60 #endif
     61 
     62 extern uint32_t big_mul_set_vec_umul(uint32_t *, uint32_t *, int, uint32_t);
     63 extern uint32_t big_mul_add_vec_umul(uint32_t *, uint32_t *, int, uint32_t);
     64 extern void big_mul_vec_umul(uint32_t *, uint32_t *, int, uint32_t *, int);
     65 extern void big_sqr_vec_umul(uint32_t *, uint32_t *, int);
     66 
     67 extern uint32_t bignum_use_sse2();
     68 
     69 static void bignum_i386_init();
     70 
     71 static uint32_t big_mul_set_vec_init(uint32_t *, uint32_t *, int, uint32_t);
     72 static uint32_t big_mul_add_vec_init(uint32_t *, uint32_t *, int, uint32_t);
     73 static void big_mul_vec_init(uint32_t *, uint32_t *, int, uint32_t *, int);
     74 static void big_sqr_vec_init(uint32_t *, uint32_t *, int);
     75 
     76 uint32_t
     77 (*big_mul_set_vec_impl)(uint32_t *r, uint32_t *a, int len, uint32_t digit)
     78 	= &big_mul_set_vec_init;
     79 
     80 uint32_t
     81 (*big_mul_add_vec_impl)(uint32_t *r, uint32_t *a, int len, uint32_t digit)
     82 	= &big_mul_add_vec_init;
     83 
     84 void
     85 (*big_mul_vec_impl)(uint32_t *r, uint32_t *a, int alen, uint32_t *b, int blen)
     86 	= &big_mul_vec_init;
     87 void
     88 (*big_sqr_vec_impl)(uint32_t *r, uint32_t *a, int alen)
     89 	= &big_sqr_vec_init;
     90 
     91 static uint32_t
     92 big_mul_set_vec_init(uint32_t *r, uint32_t *a, int len, uint32_t digit)
     93 {
     94 	bignum_i386_init();
     95 	return ((*big_mul_set_vec_impl)(r, a, len, digit));
     96 }
     97 
     98 static uint32_t
     99 big_mul_add_vec_init(uint32_t *r, uint32_t *a, int len, uint32_t digit)
    100 {
    101 	bignum_i386_init();
    102 	return ((*big_mul_add_vec_impl)(r, a, len, digit));
    103 }
    104 
    105 static void
    106 big_mul_vec_init(uint32_t *r, uint32_t *a, int alen, uint32_t *b, int blen)
    107 {
    108 	bignum_i386_init();
    109 	(*big_mul_vec_impl)(r, a, alen, b, blen);
    110 }
    111 
    112 static void
    113 big_sqr_vec_init(uint32_t *r, uint32_t *a, int alen)
    114 {
    115 	bignum_i386_init();
    116 	(*big_sqr_vec_impl)(r, a, alen);
    117 }
    118 
    119 static void
    120 bignum_i386_init()
    121 {
    122 	if (bignum_use_sse2() != 0) {
    123 		big_mul_set_vec_impl = &big_mul_set_vec_sse2;
    124 		big_mul_add_vec_impl = &big_mul_add_vec_sse2;
    125 		big_mul_vec_impl = &big_mul_vec_sse2;
    126 		big_sqr_vec_impl = &big_sqr_vec_sse2;
    127 	} else {
    128 		big_mul_set_vec_impl = &big_mul_set_vec_umul;
    129 		big_mul_add_vec_impl = &big_mul_add_vec_umul;
    130 		big_mul_vec_impl = &big_mul_vec_umul;
    131 		big_sqr_vec_impl = &big_sqr_vec_umul;
    132 	}
    133 }
    134 
    135 void
    136 big_mul_vec_umul(uint32_t *r, uint32_t *a, int alen, uint32_t *b, int blen)
    137 {
    138 	int i;
    139 
    140 	r[alen] = big_mul_set_vec_umul(r, a, alen, b[0]);
    141 	for (i = 1; i < blen; ++i)
    142 		r[alen + i] = big_mul_add_vec_umul(r+i, a, alen, b[i]);
    143 }
    144 
    145 void
    146 big_sqr_vec_umul(uint32_t *r, uint32_t *a, int alen)
    147 {
    148 	int i;
    149 
    150 	r[alen] = big_mul_set_vec_umul(r, a, alen, a[0]);
    151 	for (i = 1; i < alen; ++i)
    152 		r[alen + i] = big_mul_add_vec_umul(r+i, a, alen, a[i]);
    153 }
    154 
    155 #if defined(_KERNEL)
    156 
    157 void
    158 kpr_disable()
    159 {
    160 	kpreempt_disable();
    161 }
    162 
    163 void
    164 kpr_enable()
    165 {
    166 	kpreempt_enable();
    167 }
    168 
    169 #endif
    170