/* Buffer to hold a cache of instruction bytes...we have to make sure
 * that there are AT LEAST 15 unread bytes in the buffer at all times,
 * as this is the maximum number of bytest that can belong to a single
 * instruction.
 *
 * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
 */

typedef struct instr_buf_s {
	kaddr_t 	addr;
	int		size;
	unsigned char  *ptr;	
	unsigned char	buf[256];
} instr_buf_t;

typedef struct opcode_rec_s {
	char    *name;
	int     Op1;
	int     opdata1;
	int     Op2;
	int     opdata2;
	int     Op3;
	int     opdata3;
} opcode_rec_t;

typedef struct op_s {
	int             op_type;
	int		op_seg;
	int		op_reg;
	int		op_disp;
	int		op_base;
	int		op_index;
	int		op_scale;
	kaddr_t         op_addr;
} op_t; 

typedef struct instr_rec_s {
	struct instr_rec_s	*next;
	struct instr_rec_s	*prev;
	kaddr_t			 addr;	    /* start address of instruction */ 
	opcode_rec_t    	*opcodep;
	int		 	 size;
	int		 	 aflag; 
	int		 	 dflag;
	unsigned int     	 prefixes;
	unsigned int     	 opcode;
	unsigned char    	 modrm;
	unsigned char    	 sib;
	int		 	 have_sib; /* needed because sib can be zero */
	op_t             	 operand[3];
} instr_rec_t;

/* Addressing methods
 */
#define M_NONE    	 0
#define M_A       	 1
#define M_C       	 2
#define M_D	  	 3
#define M_E	  	 4
#define M_indirE  	 5
#define M_F	  	 6
#define M_G	  	 7
#define M_I	  	 8
#define M_sI	  	 9
#define M_J	 	10
#define M_M	 	11
#define M_O	 	12
#define M_P	 	13
#define M_Q	 	14
#define M_R	 	15
#define M_S	 	16
#define M_T	 	17
#define M_V	 	18
#define M_W	 	19
#define M_X	 	20
#define M_Y	 	21
#define M_MMX    	22
#define M_EM     	23
#define M_MS     	24
#define M_GRP    	25
#define M_REG    	26
#define M_indirREG    	27
#define M_FLOAT		28
#define M_FGRP		29
#define M_BAD    	30  /* Must be last on list */

/* Operand data types
 */
#define T_NONE    	 0
#define T_a	  	 1
#define T_b	  	 2
#define T_c    	  	 3
#define T_d       	 4
#define T_dq      	 5
#define T_p       	 6
#define T_pi      	 7
#define T_ps      	 8
#define T_q       	 9
#define T_s      	10
#define T_ss     	11
#define T_si     	12
#define T_v      	13
#define T_w      	14
#define T_BAD    	15	/* Must be last in list */

/* Register operand types
 */
#define R_eAX 	  	 0
#define R_eCX 	  	 1
#define R_eDX 	  	 2
#define R_eBX 	  	 3
#define R_eSP 	  	 4
#define R_eBP 	  	 5
#define R_eSI 	  	 6
#define R_eDI 	  	 7
#define R_AX 	  	 8
#define R_CX 	  	 9
#define R_DX 	 	10
#define R_BX 	 	11
#define R_SP 	 	12
#define R_BP 	 	13
#define R_SI 	 	14
#define R_DI 	 	15
#define R_AL 	 	16
#define R_CL 	 	17
#define R_DL 	 	18
#define R_BL 	 	19
#define R_AH 	 	20
#define R_CH 	 	21
#define R_DH 	 	22
#define R_BH 	 	23
#define R_ES 	 	24
#define R_CS 	 	25
#define R_SS 	 	26
#define R_DS 	 	27
#define R_FS 	 	28
#define R_GS 	 	29
#define R_BX_SI		30
#define R_BX_DI		31
#define R_BP_SI		32
#define R_BP_DI		33
#define R_BAD 	 	34	/* Must be last on list */

/* Operand codes
 */
#define BAD 	M_BAD, T_BAD
#define NONE 	M_NONE, T_NONE
#define Ap 	M_A, T_p
#define Av 	M_A, T_v
#define Cd 	M_C, T_d
#define Dd	M_D, T_d
#define Dx 	M_D, T_x
#define Td 	M_T, T_d
#define Eb 	M_E, T_b
#define indirEb M_indirE, T_b
#define Ev 	M_E, T_v
#define indirEv M_indirE, T_v
#define Ew	M_E, T_w
#define Gb 	M_G, T_b
#define Gv 	M_G, T_v
#define Gw 	M_G, T_w
#define Ib 	M_I, T_b
#define sIb 	M_sI, T_b
#define Iv 	M_I, T_v
#define sIv 	M_sI, T_v
#define Iw 	M_I, T_w
#define sIw 	M_sI, T_w
#define Jb 	M_J, T_b
#define Jp 	M_J, T_p
#define Jv 	M_J, T_v
#define M  	M_M, T_NONE
#define Ma 	M_M, T_a
#define Mp 	M_M, T_p
#define Ob 	M_O, T_b
#define Ov 	M_O, T_v
#define Pq 	M_P, T_q
#define Qq 	M_Q, T_q
#define Qd 	M_Q, T_d
#define Rw 	M_R, T_w
#define Rd 	M_R, T_d
#define Sw 	M_S, T_w
#define Vq 	M_V, T_q
#define Vss 	M_V, T_ss
#define Wq 	M_W, T_q
#define Wss 	M_W, T_ss
#define Xb 	M_X, T_b
#define Xv 	M_X, T_v
#define Yb 	M_Y, T_b
#define Yv 	M_Y, T_v

/* 32-bit */
#define eAX 	M_REG, R_eAX
#define eBX 	M_REG, R_eBX
#define eCX 	M_REG, R_eCX
#define eDX 	M_REG, R_eDX
#define eSP 	M_REG, R_eSP
#define eBP 	M_REG, R_eBP
#define eSI 	M_REG, R_eSI
#define eDI 	M_REG, R_eDI

/* 16-bit */
#define AX 	M_REG, R_AX
#define BX 	M_REG, R_BX
#define CX 	M_REG, R_CX
#define DX 	M_REG, R_DX
#define indirDX	M_indirREG, R_DX
#define DX 	M_REG, R_DX
#define BP 	M_REG, R_BP
#define SI 	M_REG, R_SI
#define DI 	M_REG, R_DI
#define SP 	M_REG, R_SP

/* 8-bit */
#define AH 	M_REG, R_AH
#define AL 	M_REG, R_AL
#define BH 	M_REG, R_BH
#define BL 	M_REG, R_BL
#define CH 	M_REG, R_CH
#define CL 	M_REG, R_CL
#define DH 	M_REG, R_DH
#define DL 	M_REG, R_DL

/* Segment Registers */
#define cs 	M_REG, R_CS
#define ds 	M_REG, R_DS
#define ss 	M_REG, R_SS
#define es 	M_REG, R_ES
#define fs 	M_REG, R_FS
#define gs 	M_REG, R_GS

#define MX 	M_MMX, T_NONE
#define EM 	M_EM, T_NONE
#define MS 	M_MS, T_NONE

#define GRP1b "GRP1b", M_GRP, 0
#define GRP1S "GRP1S", M_GRP, 1
#define GRP1Ss "GRP1Ss", M_GRP, 2
#define GRP2b "GRP2b", M_GRP, 3
#define GRP2S "GRP2S", M_GRP, 4
#define GRP2b_one "GRP2b_one", M_GRP, 5
#define GRP2S_one "GRP2S_one", M_GRP, 6
#define GRP2b_cl "GRP2b_cl", M_GRP, 7
#define GRP2S_cl "GRP2S_cl", M_GRP, 8
#define GRP3b "GRP3b", M_GRP, 9
#define GRP3S "GRP3S", M_GRP, 10
#define GRP4  "GRP4", M_GRP, 11
#define GRP5  "GRP5", M_GRP, 12
#define GRP6  "GRP6", M_GRP, 13
#define GRP7 "GRP7",  M_GRP, 14
#define GRP8 "GRP8", M_GRP, 15
#define GRP9 "GRP9", M_GRP, 16
#define GRP10 "GRP10", M_GRP, 17
#define GRP11 "GRP11", M_GRP, 18
#define GRP12 "GRP12", M_GRP, 19

#define FLOAT 	"FLOAT", M_FLOAT, T_NONE

#define ST 	M_FLOAT, T_NONE
#define STi 	M_FLOAT, T_NONE

#define FGRPd9_2 "FGRPd9_2", M_FGRP, 0
#define FGRPd9_4 "FGRPd9_4", M_FGRP, 1
#define FGRPd9_5 "FGRPd9_5", M_FGRP, 2
#define FGRPd9_6 "FGRPd9_6", M_FGRP, 3
#define FGRPd9_7 "FGRPd9_7", M_FGRP, 4
#define FGRPda_5 "FGRPda_5", M_FGRP, 5
#define FGRPdb_4 "FGRPdb_4", M_FGRP, 6
#define FGRPde_3 "FGRPde_3", M_FGRP, 7
#define FGRPdf_4 "FGRPdf_4", M_FGRP, 8

#define PREFIX_REPZ 	0x0001
#define PREFIX_REPNZ 	0x0002
#define PREFIX_LOCK 	0x0004
#define PREFIX_CS 	0x0008
#define PREFIX_SS       0x0010
#define PREFIX_DS 	0x0020
#define PREFIX_ES 	0x0040
#define PREFIX_FS 	0x0080
#define PREFIX_GS 	0x0100
#define PREFIX_DATA 	0x0200
#define PREFIX_ADR 	0x0400
#define PREFIX_FWAIT 	0x0800

/* Operand types
 */
#define O_REG	  	0x0001
#define O_IMMEDIATE  	0x0002
#define O_ADDR  	0x0004
#define O_OFF  		0x0008
#define O_DISP   	0x0010
#define O_BASE   	0x0020
#define O_INDEX   	0x0040
#define O_SCALE         0x0080
#define O_INDIR         0x0100
#define O_SEG           0x0200
#define O_CR            0x0400
#define O_DB            0x0800
#define O_LPTR          0x1000

/* Function prototypes
 */
int get_instr_info(	
	kaddr_t 	/* pc */, 
	instr_rec_t * 	/* pointer to instr_rec_s struct */);

instr_rec_t *get_instr_stream(
	kaddr_t 	/* program counter */, 
	int 		/* before count */, 
	int 		/* after count */);

void free_instr_stream(
	instr_rec_t *);
