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

x_store.S (6983B)


      1|
      2|	x_store.sa 3.2 1/24/91
      3|
      4|	store --- store operand to memory or register
      5|
      6|	Used by underflow and overflow handlers.
      7|
      8|	a6 = points to fp value to be stored.
      9|
     10
     11|		Copyright (C) Motorola, Inc. 1990
     12|			All Rights Reserved
     13|
     14|       For details on the license for this file, please see the
     15|       file, README, in this same directory.
     16
     17X_STORE:	|idnt    2,1 | Motorola 040 Floating Point Software Package
     18
     19	|section	8
     20
     21fpreg_mask:
     22	.byte	0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
     23
     24#include "fpsp.h"
     25
     26	|xref	mem_write
     27	|xref	get_fline
     28	|xref	g_opcls
     29	|xref	g_dfmtou
     30	|xref	reg_dest
     31
     32	.global	dest_ext
     33	.global	dest_dbl
     34	.global	dest_sgl
     35
     36	.global	store
     37store:
     38	btstb	#E3,E_BYTE(%a6)
     39	beqs	E1_sto
     40E3_sto:
     41	movel	CMDREG3B(%a6),%d0
     42	bfextu	%d0{#6:#3},%d0		|isolate dest. reg from cmdreg3b
     43sto_fp:
     44	lea	fpreg_mask,%a1
     45	moveb	(%a1,%d0.w),%d0		|convert reg# to dynamic register mask
     46	tstb	LOCAL_SGN(%a0)
     47	beqs	is_pos
     48	bsetb	#sign_bit,LOCAL_EX(%a0)
     49is_pos:
     50	fmovemx (%a0),%d0		|move to correct register
     51|
     52|	if fp0-fp3 is being modified, we must put a copy
     53|	in the USER_FPn variable on the stack because all exception
     54|	handlers restore fp0-fp3 from there.
     55|
     56	cmpb	#0x80,%d0
     57	bnes	not_fp0
     58	fmovemx %fp0-%fp0,USER_FP0(%a6)
     59	rts
     60not_fp0:
     61	cmpb	#0x40,%d0
     62	bnes	not_fp1
     63	fmovemx %fp1-%fp1,USER_FP1(%a6)
     64	rts
     65not_fp1:
     66	cmpb	#0x20,%d0
     67	bnes	not_fp2
     68	fmovemx %fp2-%fp2,USER_FP2(%a6)
     69	rts
     70not_fp2:
     71	cmpb	#0x10,%d0
     72	bnes	not_fp3
     73	fmovemx %fp3-%fp3,USER_FP3(%a6)
     74	rts
     75not_fp3:
     76	rts
     77
     78E1_sto:
     79	bsrl	g_opcls		|returns opclass in d0
     80	cmpib	#3,%d0
     81	beq	opc011		|branch if opclass 3
     82	movel	CMDREG1B(%a6),%d0
     83	bfextu	%d0{#6:#3},%d0	|extract destination register
     84	bras	sto_fp
     85
     86opc011:
     87	bsrl	g_dfmtou	|returns dest format in d0
     88|				;ext=00, sgl=01, dbl=10
     89	movel	%a0,%a1		|save source addr in a1
     90	movel	EXC_EA(%a6),%a0	|get the address
     91	cmpil	#0,%d0		|if dest format is extended
     92	beq	dest_ext	|then branch
     93	cmpil	#1,%d0		|if dest format is single
     94	beq	dest_sgl	|then branch
     95|
     96|	fall through to dest_dbl
     97|
     98
     99|
    100|	dest_dbl --- write double precision value to user space
    101|
    102|Input
    103|	a0 -> destination address
    104|	a1 -> source in extended precision
    105|Output
    106|	a0 -> destroyed
    107|	a1 -> destroyed
    108|	d0 -> 0
    109|
    110|Changes extended precision to double precision.
    111| Note: no attempt is made to round the extended value to double.
    112|	dbl_sign = ext_sign
    113|	dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)
    114|	get rid of ext integer bit
    115|	dbl_mant = ext_mant{62:12}
    116|
    117|		---------------   ---------------    ---------------
    118|  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
    119|		---------------   ---------------    ---------------
    120|		 95	    64    63 62	      32      31     11	  0
    121|				     |			     |
    122|				     |			     |
    123|				     |			     |
    124|			             v			     v
    125|			      ---------------   ---------------
    126|  double   ->		      |s|exp| mant  |   |  mant       |
    127|			      ---------------   ---------------
    128|			      63     51   32   31	       0
    129|
    130dest_dbl:
    131	clrl	%d0		|clear d0
    132	movew	LOCAL_EX(%a1),%d0	|get exponent
    133	subw	#0x3fff,%d0	|subtract extended precision bias
    134	cmpw	#0x4000,%d0	|check if inf
    135	beqs	inf		|if so, special case
    136	addw	#0x3ff,%d0	|add double precision bias
    137	swap	%d0		|d0 now in upper word
    138	lsll	#4,%d0		|d0 now in proper place for dbl prec exp
    139	tstb	LOCAL_SGN(%a1)
    140	beqs	get_mant	|if positive, go process mantissa
    141	bsetl	#31,%d0		|if negative, put in sign information
    142|				; before continuing
    143	bras	get_mant	|go process mantissa
    144inf:
    145	movel	#0x7ff00000,%d0	|load dbl inf exponent
    146	clrl	LOCAL_HI(%a1)	|clear msb
    147	tstb	LOCAL_SGN(%a1)
    148	beqs	dbl_inf		|if positive, go ahead and write it
    149	bsetl	#31,%d0		|if negative put in sign information
    150dbl_inf:
    151	movel	%d0,LOCAL_EX(%a1)	|put the new exp back on the stack
    152	bras	dbl_wrt
    153get_mant:
    154	movel	LOCAL_HI(%a1),%d1	|get ms mantissa
    155	bfextu	%d1{#1:#20},%d1	|get upper 20 bits of ms
    156	orl	%d1,%d0		|put these bits in ms word of double
    157	movel	%d0,LOCAL_EX(%a1)	|put the new exp back on the stack
    158	movel	LOCAL_HI(%a1),%d1	|get ms mantissa
    159	movel	#21,%d0		|load shift count
    160	lsll	%d0,%d1		|put lower 11 bits in upper bits
    161	movel	%d1,LOCAL_HI(%a1)	|build lower lword in memory
    162	movel	LOCAL_LO(%a1),%d1	|get ls mantissa
    163	bfextu	%d1{#0:#21},%d0	|get ls 21 bits of double
    164	orl	%d0,LOCAL_HI(%a1)	|put them in double result
    165dbl_wrt:
    166	movel	#0x8,%d0		|byte count for double precision number
    167	exg	%a0,%a1		|a0=supervisor source, a1=user dest
    168	bsrl	mem_write	|move the number to the user's memory
    169	rts
    170|
    171|	dest_sgl --- write single precision value to user space
    172|
    173|Input
    174|	a0 -> destination address
    175|	a1 -> source in extended precision
    176|
    177|Output
    178|	a0 -> destroyed
    179|	a1 -> destroyed
    180|	d0 -> 0
    181|
    182|Changes extended precision to single precision.
    183|	sgl_sign = ext_sign
    184|	sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)
    185|	get rid of ext integer bit
    186|	sgl_mant = ext_mant{62:12}
    187|
    188|		---------------   ---------------    ---------------
    189|  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
    190|		---------------   ---------------    ---------------
    191|		 95	    64    63 62	   40 32      31     12	  0
    192|				     |	   |
    193|				     |	   |
    194|				     |	   |
    195|			             v     v
    196|			      ---------------
    197|  single   ->		      |s|exp| mant  |
    198|			      ---------------
    199|			      31     22     0
    200|
    201dest_sgl:
    202	clrl	%d0
    203	movew	LOCAL_EX(%a1),%d0	|get exponent
    204	subw	#0x3fff,%d0	|subtract extended precision bias
    205	cmpw	#0x4000,%d0	|check if inf
    206	beqs	sinf		|if so, special case
    207	addw	#0x7f,%d0		|add single precision bias
    208	swap	%d0		|put exp in upper word of d0
    209	lsll	#7,%d0		|shift it into single exp bits
    210	tstb	LOCAL_SGN(%a1)
    211	beqs	get_sman	|if positive, continue
    212	bsetl	#31,%d0		|if negative, put in sign first
    213	bras	get_sman	|get mantissa
    214sinf:
    215	movel	#0x7f800000,%d0	|load single inf exp to d0
    216	tstb	LOCAL_SGN(%a1)
    217	beqs	sgl_wrt		|if positive, continue
    218	bsetl	#31,%d0		|if negative, put in sign info
    219	bras	sgl_wrt
    220
    221get_sman:
    222	movel	LOCAL_HI(%a1),%d1	|get ms mantissa
    223	bfextu	%d1{#1:#23},%d1	|get upper 23 bits of ms
    224	orl	%d1,%d0		|put these bits in ms word of single
    225
    226sgl_wrt:
    227	movel	%d0,L_SCR1(%a6)	|put the new exp back on the stack
    228	movel	#0x4,%d0		|byte count for single precision number
    229	tstl	%a0		|users destination address
    230	beqs	sgl_Dn		|destination is a data register
    231	exg	%a0,%a1		|a0=supervisor source, a1=user dest
    232	leal	L_SCR1(%a6),%a0	|point a0 to data
    233	bsrl	mem_write	|move the number to the user's memory
    234	rts
    235sgl_Dn:
    236	bsrl	get_fline	|returns fline word in d0
    237	andw	#0x7,%d0		|isolate register number
    238	movel	%d0,%d1		|d1 has size:reg formatted for reg_dest
    239	orl	#0x10,%d1		|reg_dest wants size added to reg#
    240	bral	reg_dest	|size is X, rts in reg_dest will
    241|				;return to caller of dest_sgl
    242
    243dest_ext:
    244	tstb	LOCAL_SGN(%a1)	|put back sign into exponent word
    245	beqs	dstx_cont
    246	bsetb	#sign_bit,LOCAL_EX(%a1)
    247dstx_cont:
    248	clrb	LOCAL_SGN(%a1)	|clear out the sign byte
    249
    250	movel	#0x0c,%d0		|byte count for extended number
    251	exg	%a0,%a1		|a0=supervisor source, a1=user dest
    252	bsrl	mem_write	|move the number to the user's memory
    253	rts
    254
    255	|end