cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

reg_u_mul.S (3715B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2	.file	"reg_u_mul.S"
      3/*---------------------------------------------------------------------------+
      4 |  reg_u_mul.S                                                              |
      5 |                                                                           |
      6 | Core multiplication routine                                               |
      7 |                                                                           |
      8 | Copyright (C) 1992,1993,1995,1997                                         |
      9 |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
     10 |                  E-mail   billm@suburbia.net                              |
     11 |                                                                           |
     12 |                                                                           |
     13 +---------------------------------------------------------------------------*/
     14
     15/*---------------------------------------------------------------------------+
     16 |   Basic multiplication routine.                                           |
     17 |   Does not check the resulting exponent for overflow/underflow            |
     18 |                                                                           |
     19 |   FPU_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw);         |
     20 |                                                                           |
     21 |   Internal working is at approx 128 bits.                                 |
     22 |   Result is rounded to nearest 53 or 64 bits, using "nearest or even".    |
     23 +---------------------------------------------------------------------------*/
     24
     25#include "exception.h"
     26#include "fpu_emu.h"
     27#include "control_w.h"
     28
     29
     30
     31#ifndef NON_REENTRANT_FPU
     32/*  Local storage on the stack: */
     33#define FPU_accum_0	-4(%ebp)	/* ms word */
     34#define FPU_accum_1	-8(%ebp)
     35
     36#else
     37/*  Local storage in a static area: */
     38.data
     39	.align 4,0
     40FPU_accum_0:
     41	.long	0
     42FPU_accum_1:
     43	.long	0
     44#endif /* NON_REENTRANT_FPU */
     45
     46
     47.text
     48SYM_FUNC_START(FPU_u_mul)
     49	pushl	%ebp
     50	movl	%esp,%ebp
     51#ifndef NON_REENTRANT_FPU
     52	subl	$8,%esp
     53#endif /* NON_REENTRANT_FPU */ 
     54
     55	pushl	%esi
     56	pushl	%edi
     57	pushl	%ebx
     58
     59	movl	PARAM1,%esi
     60	movl	PARAM2,%edi
     61
     62#ifdef PARANOID
     63	testl	$0x80000000,SIGH(%esi)
     64	jz	L_bugged
     65	testl	$0x80000000,SIGH(%edi)
     66	jz	L_bugged
     67#endif /* PARANOID */
     68
     69	xorl	%ecx,%ecx
     70	xorl	%ebx,%ebx
     71
     72	movl	SIGL(%esi),%eax
     73	mull	SIGL(%edi)
     74	movl	%eax,FPU_accum_0
     75	movl	%edx,FPU_accum_1
     76
     77	movl	SIGL(%esi),%eax
     78	mull	SIGH(%edi)
     79	addl	%eax,FPU_accum_1
     80	adcl	%edx,%ebx
     81/*	adcl	$0,%ecx		// overflow here is not possible */
     82
     83	movl	SIGH(%esi),%eax
     84	mull	SIGL(%edi)
     85	addl	%eax,FPU_accum_1
     86	adcl	%edx,%ebx
     87	adcl	$0,%ecx
     88
     89	movl	SIGH(%esi),%eax
     90	mull	SIGH(%edi)
     91	addl	%eax,%ebx
     92	adcl	%edx,%ecx
     93
     94	/* Get the sum of the exponents. */
     95	movl	PARAM6,%eax
     96	subl	EXP_BIAS-1,%eax
     97
     98	/* Two denormals can cause an exponent underflow */
     99	cmpl	EXP_WAY_UNDER,%eax
    100	jg	Exp_not_underflow
    101
    102	/* Set to a really low value allow correct handling */
    103	movl	EXP_WAY_UNDER,%eax
    104
    105Exp_not_underflow:
    106
    107/*  Have now finished with the sources */
    108	movl	PARAM3,%edi	/* Point to the destination */
    109	movw	%ax,EXP(%edi)
    110
    111/*  Now make sure that the result is normalized */
    112	testl	$0x80000000,%ecx
    113	jnz	LResult_Normalised
    114
    115	/* Normalize by shifting left one bit */
    116	shll	$1,FPU_accum_0
    117	rcll	$1,FPU_accum_1
    118	rcll	$1,%ebx
    119	rcll	$1,%ecx
    120	decw	EXP(%edi)
    121
    122LResult_Normalised:
    123	movl	FPU_accum_0,%eax
    124	movl	FPU_accum_1,%edx
    125	orl	%eax,%eax
    126	jz	L_extent_zero
    127
    128	orl	$1,%edx
    129
    130L_extent_zero:
    131	movl	%ecx,%eax
    132	jmp	fpu_reg_round
    133
    134
    135#ifdef PARANOID
    136L_bugged:
    137	pushl	EX_INTERNAL|0x205
    138	call	EXCEPTION
    139	pop	%ebx
    140	jmp	L_exit
    141
    142L_exit:
    143	popl	%ebx
    144	popl	%edi
    145	popl	%esi
    146	leave
    147	RET
    148#endif /* PARANOID */ 
    149
    150SYM_FUNC_END(FPU_u_mul)