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

fp_decode.h (10284B)


      1/*
      2 * fp_decode.h
      3 *
      4 * Copyright Roman Zippel, 1997.  All rights reserved.
      5 *
      6 * Redistribution and use in source and binary forms, with or without
      7 * modification, are permitted provided that the following conditions
      8 * are met:
      9 * 1. Redistributions of source code must retain the above copyright
     10 *    notice, and the entire permission notice in its entirety,
     11 *    including the disclaimer of warranties.
     12 * 2. Redistributions in binary form must reproduce the above copyright
     13 *    notice, this list of conditions and the following disclaimer in the
     14 *    documentation and/or other materials provided with the distribution.
     15 * 3. The name of the author may not be used to endorse or promote
     16 *    products derived from this software without specific prior
     17 *    written permission.
     18 *
     19 * ALTERNATIVELY, this product may be distributed under the terms of
     20 * the GNU General Public License, in which case the provisions of the GPL are
     21 * required INSTEAD OF the above restrictions.  (This clause is
     22 * necessary due to a potential bad interaction between the GPL and
     23 * the restrictions contained in a BSD-style copyright.)
     24 *
     25 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
     26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     28 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     35 * OF THE POSSIBILITY OF SUCH DAMAGE.
     36 */
     37
     38#ifndef _FP_DECODE_H
     39#define _FP_DECODE_H
     40
     41/* These macros do the dirty work of the instr decoding, several variables
     42 * can be defined in the source file to modify the work of these macros,
     43 * currently the following variables are used:
     44 * ...
     45 * The register usage:
     46 * d0 - will contain source operand for data direct mode,
     47 *	otherwise scratch register
     48 * d1 - upper 16bit are reserved for caller
     49 *	lower 16bit may contain further arguments,
     50 *	is destroyed during decoding
     51 * d2 - contains first two instruction words,
     52 *	first word will be used for extension word
     53 * a0 - will point to source/dest operand for any indirect mode
     54 *	otherwise scratch register
     55 * a1 - scratch register
     56 * a2 - base addr to the task structure
     57 *
     58 * the current implementation doesn't check for every disallowed
     59 * addressing mode (e.g. pc relative modes as destination), as long
     60 * as it only means a new addressing mode, which should not appear
     61 * in a program and that doesn't crash the emulation, I think it's
     62 * not a problem to allow these modes.
     63 */
     64
     65do_fmovem=0
     66do_fmovem_cr=0
     67do_no_pc_mode=0
     68do_fscc=0
     69
     70| first decoding of the instr type
     71| this separates the conditional instr
     72.macro	fp_decode_cond_instr_type
     73	bfextu	%d2{#8,#2},%d0
     74	jmp	([0f:w,%pc,%d0*4])
     75
     76	.align	4
     770:
     78|	.long	"f<op>","fscc/fdbcc"
     79|	.long	"fbccw","fbccl"
     80.endm
     81
     82| second decoding of the instr type
     83| this separates most move instr
     84.macro	fp_decode_move_instr_type
     85	bfextu	%d2{#16,#3},%d0
     86	jmp	([0f:w,%pc,%d0*4])
     87
     88	.align	4
     890:
     90|	.long	"f<op> fpx,fpx","invalid instr"
     91|	.long	"f<op> <ea>,fpx","fmove fpx,<ea>"
     92|	.long	"fmovem <ea>,fpcr","fmovem <ea>,fpx"
     93|	.long	"fmovem fpcr,<ea>","fmovem fpx,<ea>"
     94.endm
     95
     96| extract the source specifier, specifies
     97| either source fp register or data format
     98.macro	fp_decode_sourcespec
     99	bfextu	%d2{#19,#3},%d0
    100.endm
    101
    102| decode destination format for fmove reg,ea
    103.macro	fp_decode_dest_format
    104	bfextu	%d2{#19,#3},%d0
    105.endm
    106
    107| decode source register for fmove reg,ea
    108.macro	fp_decode_src_reg
    109	bfextu	%d2{#22,#3},%d0
    110.endm
    111
    112| extract the addressing mode
    113| it depends on the instr which of the modes is valid
    114.macro	fp_decode_addr_mode
    115	bfextu	%d2{#10,#3},%d0
    116	jmp	([0f:w,%pc,%d0*4])
    117
    118	.align	4
    1190:
    120|	.long	"data register direct","addr register direct"
    121|	.long	"addr register indirect"
    122|	.long	"addr register indirect postincrement"
    123|	.long	"addr register indirect predecrement"
    124|	.long	"addr register + index16"
    125|	.long	"extension mode1","extension mode2"
    126.endm
    127
    128| extract the register for the addressing mode
    129.macro	fp_decode_addr_reg
    130	bfextu	%d2{#13,#3},%d0
    131.endm
    132
    133| decode the 8bit displacement from the brief extension word
    134.macro	fp_decode_disp8
    135	move.b	%d2,%d0
    136	ext.w	%d0
    137.endm
    138
    139| decode the index of the brief/full extension word
    140.macro	fp_decode_index
    141	bfextu	%d2{#17,#3},%d0		| get the register nr
    142	btst	#15,%d2			| test for data/addr register
    143	jne	1\@f
    144	printf	PDECODE,"d%d",1,%d0
    145	jsr	fp_get_data_reg
    146	jra	2\@f
    1471\@:	printf	PDECODE,"a%d",1,%d0
    148	jsr	fp_get_addr_reg
    149	move.l	%a0,%d0
    1502\@:
    151debug	lea	"'l'.w,%a0"
    152	btst	#11,%d2			| 16/32 bit size?
    153	jne	3\@f
    154debug	lea	"'w'.w,%a0"
    155	ext.l	%d0
    1563\@:	printf	PDECODE,":%c",1,%a0
    157	move.w	%d2,%d1			| scale factor
    158	rol.w	#7,%d1
    159	and.w	#3,%d1
    160debug	move.l	"%d1,-(%sp)"
    161debug	ext.l	"%d1"
    162	printf	PDECODE,":%d",1,%d1
    163debug	move.l	"(%sp)+,%d1"
    164	lsl.l	%d1,%d0
    165.endm
    166
    167| decode the base displacement size
    168.macro	fp_decode_basedisp
    169	bfextu	%d2{#26,#2},%d0
    170	jmp	([0f:w,%pc,%d0*4])
    171
    172	.align	4
    1730:
    174|	.long	"reserved","null displacement"
    175|	.long	"word displacement","long displacement"
    176.endm
    177
    178.macro	fp_decode_outerdisp
    179	bfextu	%d2{#30,#2},%d0
    180	jmp	([0f:w,%pc,%d0*4])
    181
    182	.align	4
    1830:
    184|	.long	"no memory indirect action/reserved","null outer displacement"
    185|	.long	"word outer displacement","long outer displacement"
    186.endm
    187
    188| get the extension word and test for brief or full extension type
    189.macro	fp_get_test_extword label
    190	fp_get_instr_word %d2,fp_err_ua1
    191	btst	#8,%d2
    192	jne	\label
    193.endm
    194
    195
    196| test if %pc is the base register for the indirect addr mode
    197.macro	fp_test_basereg_d16	label
    198	btst	#20,%d2
    199	jeq	\label
    200.endm
    201
    202| test if %pc is the base register for one of the extended modes
    203.macro	fp_test_basereg_ext	label
    204	btst	#19,%d2
    205	jeq	\label
    206.endm
    207
    208.macro	fp_test_suppr_index label
    209	btst	#6,%d2
    210	jne	\label
    211.endm
    212
    213
    214| addressing mode: data register direct
    215.macro	fp_mode_data_direct
    216	fp_decode_addr_reg
    217	printf	PDECODE,"d%d",1,%d0
    218.endm
    219
    220| addressing mode: address register indirect
    221.macro	fp_mode_addr_indirect
    222	fp_decode_addr_reg
    223	printf	PDECODE,"(a%d)",1,%d0
    224	jsr	fp_get_addr_reg
    225.endm
    226
    227| adjust stack for byte moves from/to stack
    228.macro	fp_test_sp_byte_move
    229	.if	!do_fmovem
    230	.if	do_fscc
    231	move.w	#6,%d1
    232	.endif
    233	cmp.w	#7,%d0
    234	jne	1\@f
    235	.if	!do_fscc
    236	cmp.w	#6,%d1
    237	jne	1\@f
    238	.endif
    239	move.w	#4,%d1
    2401\@:
    241	.endif
    242.endm
    243
    244| addressing mode: address register indirect with postincrement
    245.macro	fp_mode_addr_indirect_postinc
    246	fp_decode_addr_reg
    247	printf	PDECODE,"(a%d)+",1,%d0
    248	fp_test_sp_byte_move
    249	jsr	fp_get_addr_reg
    250	move.l	%a0,%a1			| save addr
    251	.if	do_fmovem
    252	lea	(%a0,%d1.w*4),%a0
    253	.if	!do_fmovem_cr
    254	lea	(%a0,%d1.w*8),%a0
    255	.endif
    256	.else
    257	add.w	(fp_datasize,%d1.w*2),%a0
    258	.endif
    259	jsr	fp_put_addr_reg
    260	move.l	%a1,%a0
    261.endm
    262
    263| addressing mode: address register indirect with predecrement
    264.macro	fp_mode_addr_indirect_predec
    265	fp_decode_addr_reg
    266	printf	PDECODE,"-(a%d)",1,%d0
    267	fp_test_sp_byte_move
    268	jsr	fp_get_addr_reg
    269	.if	do_fmovem
    270	.if	!do_fmovem_cr
    271	lea	(-12,%a0),%a1		| setup to addr of 1st reg to move
    272	neg.w	%d1
    273	lea	(%a0,%d1.w*4),%a0
    274	add.w	%d1,%d1
    275	lea	(%a0,%d1.w*4),%a0
    276	jsr	fp_put_addr_reg
    277	move.l	%a1,%a0
    278	.else
    279	neg.w	%d1
    280	lea	(%a0,%d1.w*4),%a0
    281	jsr	fp_put_addr_reg
    282	.endif
    283	.else
    284	sub.w	(fp_datasize,%d1.w*2),%a0
    285	jsr	fp_put_addr_reg
    286	.endif
    287.endm
    288
    289| addressing mode: address register/programm counter indirect
    290|		   with 16bit displacement
    291.macro	fp_mode_addr_indirect_disp16
    292	.if	!do_no_pc_mode
    293	fp_test_basereg_d16 1f
    294	printf	PDECODE,"pc"
    295	fp_get_pc %a0
    296	jra	2f
    297	.endif
    2981:	fp_decode_addr_reg
    299	printf	PDECODE,"a%d",1,%d0
    300	jsr	fp_get_addr_reg
    3012:	fp_get_instr_word %a1,fp_err_ua1
    302	printf	PDECODE,"@(%x)",1,%a1
    303	add.l	%a1,%a0
    304.endm
    305
    306| perform preindex (if I/IS == 0xx and xx != 00)
    307.macro	fp_do_preindex
    308	moveq	#3,%d0
    309	and.w	%d2,%d0
    310	jeq	1f
    311	btst	#2,%d2
    312	jne	1f
    313	printf	PDECODE,")@("
    314	getuser.l (%a1),%a1,fp_err_ua1,%a1
    315debug	jra	"2f"
    3161:	printf	PDECODE,","
    3172:
    318.endm
    319
    320| perform postindex (if I/IS == 1xx)
    321.macro	fp_do_postindex
    322	btst	#2,%d2
    323	jeq	1f
    324	printf	PDECODE,")@("
    325	getuser.l (%a1),%a1,fp_err_ua1,%a1
    326debug	jra	"2f"
    3271:	printf	PDECODE,","
    3282:
    329.endm
    330
    331| all other indirect addressing modes will finally end up here
    332.macro	fp_mode_addr_indirect_extmode0
    333	.if	!do_no_pc_mode
    334	fp_test_basereg_ext 1f
    335	printf	PDECODE,"pc"
    336	fp_get_pc %a0
    337	jra	2f
    338	.endif
    3391:	fp_decode_addr_reg
    340	printf	PDECODE,"a%d",1,%d0
    341	jsr	fp_get_addr_reg
    3422:	move.l	%a0,%a1
    343	swap	%d2
    344	fp_get_test_extword 3f
    345	| addressing mode: address register/programm counter indirect
    346	|		   with index and 8bit displacement
    347	fp_decode_disp8
    348debug	ext.l	"%d0"
    349	printf	PDECODE,"@(%x,",1,%d0
    350	add.w	%d0,%a1
    351	fp_decode_index
    352	add.l	%d0,%a1
    353	printf	PDECODE,")"
    354	jra	9f
    3553:	| addressing mode: address register/programm counter memory indirect
    356	|		   with base and/or outer displacement
    357	btst	#7,%d2			| base register suppressed?
    358	jeq	1f
    359	printf	PDECODE,"!"
    360	sub.l	%a1,%a1
    3611:	printf	PDECODE,"@("
    362	fp_decode_basedisp
    363
    364	.long	fp_ill,1f
    365	.long	2f,3f
    366
    367#ifdef FPU_EMU_DEBUG
    3681:	printf	PDECODE,"0"		| null base displacement
    369	jra	1f
    370#endif
    3712:	fp_get_instr_word %a0,fp_err_ua1 | 16bit base displacement
    372	printf	PDECODE,"%x:w",1,%a0
    373	jra	4f
    3743:	fp_get_instr_long %a0,fp_err_ua1 | 32bit base displacement
    375	printf	PDECODE,"%x:l",1,%a0
    3764:	add.l	%a0,%a1
    3771:
    378	fp_do_postindex
    379	fp_test_suppr_index 1f
    380	fp_decode_index
    381	add.l	%d0,%a1
    3821:	fp_do_preindex
    383
    384	fp_decode_outerdisp
    385
    386	.long	5f,1f
    387	.long	2f,3f
    388
    389#ifdef FPU_EMU_DEBUG
    3901:	printf	PDECODE,"0"		| null outer displacement
    391	jra	1f
    392#endif
    3932:	fp_get_instr_word %a0,fp_err_ua1 | 16bit outer displacement
    394	printf	PDECODE,"%x:w",1,%a0
    395	jra	4f
    3963:	fp_get_instr_long %a0,fp_err_ua1 | 32bit outer displacement
    397	printf	PDECODE,"%x:l",1,%a0
    3984:	add.l	%a0,%a1
    3991:
    4005:	printf	PDECODE,")"
    4019:	move.l	%a1,%a0
    402	swap	%d2
    403.endm
    404
    405| get the absolute short address from user space
    406.macro	fp_mode_abs_short
    407	fp_get_instr_word %a0,fp_err_ua1
    408	printf	PDECODE,"%x.w",1,%a0
    409.endm
    410
    411| get the absolute long address from user space
    412.macro	fp_mode_abs_long
    413	fp_get_instr_long %a0,fp_err_ua1
    414	printf	PDECODE,"%x.l",1,%a0
    415.endm
    416
    417#endif /* _FP_DECODE_H */