1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * This file contains bignum implementation code that 31*7c478bd9Sstevel@tonic-gate * is specific to x86, but which is still more appropriate 32*7c478bd9Sstevel@tonic-gate * to write in C, rather than assembly language. 33*7c478bd9Sstevel@tonic-gate * bignum_i386_asm.s does all the assembly language code 34*7c478bd9Sstevel@tonic-gate * for x86 specific bignum support. The assembly language 35*7c478bd9Sstevel@tonic-gate * source file has pure code, no data. Let the C compiler 36*7c478bd9Sstevel@tonic-gate * generate what is needed to handle the variations in 37*7c478bd9Sstevel@tonic-gate * data representation and addressing, for example, 38*7c478bd9Sstevel@tonic-gate * statically linked vs PIC. 39*7c478bd9Sstevel@tonic-gate */ 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include "bignum.h" 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate #if defined(_KERNEL) 44*7c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/disp.h> 46*7c478bd9Sstevel@tonic-gate #endif 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate extern uint32_t big_mul_set_vec_sse2(uint32_t *, uint32_t *, int, uint32_t); 49*7c478bd9Sstevel@tonic-gate extern uint32_t big_mul_add_vec_sse2(uint32_t *, uint32_t *, int, uint32_t); 50*7c478bd9Sstevel@tonic-gate extern void big_mul_vec_sse2(uint32_t *, uint32_t *, int, uint32_t *, int); 51*7c478bd9Sstevel@tonic-gate extern void big_sqr_vec_sse2(uint32_t *, uint32_t *, int); 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #if defined(MMX_MANAGE) 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate extern uint32_t big_mul_set_vec_sse2_nsv(uint32_t *, uint32_t *, int, uint32_t); 56*7c478bd9Sstevel@tonic-gate extern uint32_t big_mul_add_vec_sse2_nsv(uint32_t *, uint32_t *, int, uint32_t); 57*7c478bd9Sstevel@tonic-gate extern void big_mul_vec_sse2_nsv(uint32_t *, uint32_t *, int, uint32_t *, int); 58*7c478bd9Sstevel@tonic-gate extern void big_sqr_vec_sse2_nsv(uint32_t *, uint32_t *, int); 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate #endif 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate extern uint32_t big_mul_set_vec_umul(uint32_t *, uint32_t *, int, uint32_t); 63*7c478bd9Sstevel@tonic-gate extern uint32_t big_mul_add_vec_umul(uint32_t *, uint32_t *, int, uint32_t); 64*7c478bd9Sstevel@tonic-gate extern void big_mul_vec_umul(uint32_t *, uint32_t *, int, uint32_t *, int); 65*7c478bd9Sstevel@tonic-gate extern void big_sqr_vec_umul(uint32_t *, uint32_t *, int); 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate extern uint32_t bignum_use_sse2(); 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate static void bignum_i386_init(); 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate static uint32_t big_mul_set_vec_init(uint32_t *, uint32_t *, int, uint32_t); 72*7c478bd9Sstevel@tonic-gate static uint32_t big_mul_add_vec_init(uint32_t *, uint32_t *, int, uint32_t); 73*7c478bd9Sstevel@tonic-gate static void big_mul_vec_init(uint32_t *, uint32_t *, int, uint32_t *, int); 74*7c478bd9Sstevel@tonic-gate static void big_sqr_vec_init(uint32_t *, uint32_t *, int); 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate uint32_t 77*7c478bd9Sstevel@tonic-gate (*big_mul_set_vec_impl)(uint32_t *r, uint32_t *a, int len, uint32_t digit) 78*7c478bd9Sstevel@tonic-gate = &big_mul_set_vec_init; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate uint32_t 81*7c478bd9Sstevel@tonic-gate (*big_mul_add_vec_impl)(uint32_t *r, uint32_t *a, int len, uint32_t digit) 82*7c478bd9Sstevel@tonic-gate = &big_mul_add_vec_init; 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate void 85*7c478bd9Sstevel@tonic-gate (*big_mul_vec_impl)(uint32_t *r, uint32_t *a, int alen, uint32_t *b, int blen) 86*7c478bd9Sstevel@tonic-gate = &big_mul_vec_init; 87*7c478bd9Sstevel@tonic-gate void 88*7c478bd9Sstevel@tonic-gate (*big_sqr_vec_impl)(uint32_t *r, uint32_t *a, int alen) 89*7c478bd9Sstevel@tonic-gate = &big_sqr_vec_init; 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate static uint32_t 92*7c478bd9Sstevel@tonic-gate big_mul_set_vec_init(uint32_t *r, uint32_t *a, int len, uint32_t digit) 93*7c478bd9Sstevel@tonic-gate { 94*7c478bd9Sstevel@tonic-gate bignum_i386_init(); 95*7c478bd9Sstevel@tonic-gate return ((*big_mul_set_vec_impl)(r, a, len, digit)); 96*7c478bd9Sstevel@tonic-gate } 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate static uint32_t 99*7c478bd9Sstevel@tonic-gate big_mul_add_vec_init(uint32_t *r, uint32_t *a, int len, uint32_t digit) 100*7c478bd9Sstevel@tonic-gate { 101*7c478bd9Sstevel@tonic-gate bignum_i386_init(); 102*7c478bd9Sstevel@tonic-gate return ((*big_mul_add_vec_impl)(r, a, len, digit)); 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate static void 106*7c478bd9Sstevel@tonic-gate big_mul_vec_init(uint32_t *r, uint32_t *a, int alen, uint32_t *b, int blen) 107*7c478bd9Sstevel@tonic-gate { 108*7c478bd9Sstevel@tonic-gate bignum_i386_init(); 109*7c478bd9Sstevel@tonic-gate (*big_mul_vec_impl)(r, a, alen, b, blen); 110*7c478bd9Sstevel@tonic-gate } 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate static void 113*7c478bd9Sstevel@tonic-gate big_sqr_vec_init(uint32_t *r, uint32_t *a, int alen) 114*7c478bd9Sstevel@tonic-gate { 115*7c478bd9Sstevel@tonic-gate bignum_i386_init(); 116*7c478bd9Sstevel@tonic-gate (*big_sqr_vec_impl)(r, a, alen); 117*7c478bd9Sstevel@tonic-gate } 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate static void 120*7c478bd9Sstevel@tonic-gate bignum_i386_init() 121*7c478bd9Sstevel@tonic-gate { 122*7c478bd9Sstevel@tonic-gate if (bignum_use_sse2() != 0) { 123*7c478bd9Sstevel@tonic-gate big_mul_set_vec_impl = &big_mul_set_vec_sse2; 124*7c478bd9Sstevel@tonic-gate big_mul_add_vec_impl = &big_mul_add_vec_sse2; 125*7c478bd9Sstevel@tonic-gate big_mul_vec_impl = &big_mul_vec_sse2; 126*7c478bd9Sstevel@tonic-gate big_sqr_vec_impl = &big_sqr_vec_sse2; 127*7c478bd9Sstevel@tonic-gate } else { 128*7c478bd9Sstevel@tonic-gate big_mul_set_vec_impl = &big_mul_set_vec_umul; 129*7c478bd9Sstevel@tonic-gate big_mul_add_vec_impl = &big_mul_add_vec_umul; 130*7c478bd9Sstevel@tonic-gate big_mul_vec_impl = &big_mul_vec_umul; 131*7c478bd9Sstevel@tonic-gate big_sqr_vec_impl = &big_sqr_vec_umul; 132*7c478bd9Sstevel@tonic-gate } 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate void 136*7c478bd9Sstevel@tonic-gate big_mul_vec_umul(uint32_t *r, uint32_t *a, int alen, uint32_t *b, int blen) 137*7c478bd9Sstevel@tonic-gate { 138*7c478bd9Sstevel@tonic-gate int i; 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate r[alen] = big_mul_set_vec_umul(r, a, alen, b[0]); 141*7c478bd9Sstevel@tonic-gate for (i = 1; i < blen; ++i) 142*7c478bd9Sstevel@tonic-gate r[alen + i] = big_mul_add_vec_umul(r+i, a, alen, b[i]); 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate void 146*7c478bd9Sstevel@tonic-gate big_sqr_vec_umul(uint32_t *r, uint32_t *a, int alen) 147*7c478bd9Sstevel@tonic-gate { 148*7c478bd9Sstevel@tonic-gate int i; 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate r[alen] = big_mul_set_vec_umul(r, a, alen, a[0]); 151*7c478bd9Sstevel@tonic-gate for (i = 1; i < alen; ++i) 152*7c478bd9Sstevel@tonic-gate r[alen + i] = big_mul_add_vec_umul(r+i, a, alen, a[i]); 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate #if defined(_KERNEL) 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate void 158*7c478bd9Sstevel@tonic-gate kpr_disable() 159*7c478bd9Sstevel@tonic-gate { 160*7c478bd9Sstevel@tonic-gate kpreempt_disable(); 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate void 164*7c478bd9Sstevel@tonic-gate kpr_enable() 165*7c478bd9Sstevel@tonic-gate { 166*7c478bd9Sstevel@tonic-gate kpreempt_enable(); 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate #endif 170