#ifndef PARSER_H
#define PARSER_H
#include "operands.h"
#include "symbols.h"
#include "token.h"
enum special_token {
T_NULL,
#define res(token, string, type, value, bytval, flags, cpu, sflags) T_ ## token ,
#include "special.h"
#undef res
#define res(token, string, value, bytval, flags, cpu, sflags) T_ ## token ,
#include "directve.h"
#undef res
SPECIAL_LAST
};
enum instr_token {
INS_FIRST_1 = SPECIAL_LAST - 1,
#define ins(token, string, opcls, byte1_info,op_dir,rm_info,opcode,rm_byte,cpu,prefix ) T_ ## token ,
#define insx(token, string, opcls, byte1_info,op_dir,rm_info,opcode,rm_byte,cpu,prefix,flgs ) T_ ## token ,
#define insn(tok, suffix, opcls, byte1_info,op_dir,rm_info,opcode,rm_byte,cpu,prefix)
#define insm(tok, suffix, opcls, byte1_info,op_dir,rm_info,opcode,rm_byte,cpu,prefix)
#include "instruct.h"
#undef insm
#undef insn
#undef insx
#undef ins
#if AVXSUPP
#define VEX_START T_VBROADCASTSS
#define avxins(token, string, cpu, flgs ) T_V ## token ,
#include "instravx.h"
#undef avxins
#endif
};
struct symbol_queue {
struct dsym *head;
struct dsym *tail;
};
enum queue_type {
TAB_UNDEF = 0,
TAB_EXT,
TAB_SEG,
TAB_GRP,
TAB_PROC,
TAB_ALIAS,
TAB_LAST,
};
extern struct symbol_queue SymTables[];
enum rm_info {
no_RM = 0x1,
no_WDS = 0x2,
R_in_OP = 0x3,
};
enum allowed_prefix {
AP_LOCK = 0x01,
AP_REP = 0x02,
AP_REPxx = 0x03,
AP_FWAIT = 0x04,
AP_NO_FWAIT = 0x05,
AP_BND = 0x06
};
enum special_type {
RWT_REG = 2,
RWT_DIRECTIVE,
RWT_UNARY_OP,
RWT_BINARY_OP,
RWT_STYPE,
RWT_RES_ID
};
enum op1_flags {
SFR_SIZMSK = 0x1F,
SFR_IREG = 0x20,
SFR_SSBASED = 0x40,
SFR_YMMMASK = 0x3F,
SFR_ZMMMASK = 0x7F,
};
#define EVEX_P0RMASK 0x80
#define EVEX_P0XMASK 0x40
#define EVEX_P0BMASK 0x20
#define EVEX_P0R1MASK 0x10
#define EVEX_P0MMMASK 0x03
#define EVEX_P1WMASK 0x80
#define EVEX_P1VVVV 0x78
#define EVEX_P1PPMASK 0x03
#define EVEX_P2ZMASK 0x80
#define EVEX_P2L1MASK 0x40
#define EVEX_P2LMASK 0x20
#define EVEX_P2BMASK 0x10
#define EVEX_P2VMASK 0x08
#define EVEX_P2AAAMASK 0x07
#define EVEX_P2LLMASK 0x60
#define W1 0x8000
#if AMD64_SUPPORT
enum rex_bits {
REX_B = 1,
REX_X = 2,
REX_R = 4,
REX_W = 8
};
#endif
struct opnd_class {
enum operand_type opnd_type[2];
unsigned char opnd_type_3rd;
};
struct instr_item {
unsigned short opclsidx;
unsigned char byte1_info;
unsigned short allowed_prefix;
unsigned char first;
unsigned char rm_info;
unsigned char opnd_dir;
unsigned short prefix;
unsigned short cpu;
unsigned char opcode;
unsigned char rm_byte;
};
struct special_item {
unsigned value;
unsigned sflags;
#ifdef __WATCOMC__
enum cpu_info cpu;
#else
uint_16 cpu;
#endif
uint_8 bytval;
#ifdef __WATCOMC__
enum special_type type;
#else
uint_8 type;
#endif
};
#define GetRegNo( x ) SpecialTable[x].bytval
#define GetSflagsSp( x ) SpecialTable[x].sflags
#define GetValueSp( x ) SpecialTable[x].value
#define GetMemtypeSp( x ) SpecialTable[x].bytval
#define GetCpuSp( x ) SpecialTable[x].cpu
enum directive_flags {
DF_CEXPR = 0x01,
DF_STRPARM = 0x02,
DF_NOEXPAND = 0x04,
DF_LABEL = 0x08,
DF_NOSTRUC = 0x10,
DF_NOCONCAT = 0x20,
DF_PROC = 0x40,
DF_STORE = 0x80,
DF_CGEN = 0x100
};
#define res(token, function) DRT_ ## token ,
enum directive_type {
#include "dirtype.h"
};
#undef res
#define MAX_OPND 4
struct opnd_item {
enum operand_type type;
union {
struct {
int_32 data32l;
int_32 data32h;
};
uint_64 data64;
};
struct fixup *InsFixup;
const char *tokenPtr;
};
enum ttypes {
FV = 1,
HV = 2,
FVM = 3,
T1S8 = 4,
T1S16 = 5,
T1S = 6,
T1F32 = 7,
T1F64 = 10,
T2 = 11,
T4 = 12,
T8 = 13,
HVM = 14,
QVM = 15,
OVM = 16,
T128 = 17,
DUP = 20
};
enum mtypes {
BSIZE = 0x00, WSIZE = 0x20, DSIZE = 0x40, QSIZE = 0x60, XSIZE = 0x80, YSIZE = 0xA0, ZSIZE = 0xC0 };
enum indextypes {
IXSZ = 0x0000,
IYSZ = 0x0100,
IZSZ = 0x0200,
};
struct code_info {
struct {
enum instr_token ins;
enum assume_segreg RegOverride;
#if AMD64_SUPPORT
unsigned char rex;
#endif
unsigned char adrsiz:1;
unsigned char opsiz:1;
} prefix;
const struct instr_item *pinstr;
enum instr_token token;
enum memtype mem_type;
struct opnd_item opnd[MAX_OPND];
unsigned char rm_byte;
unsigned char sib;
unsigned char Ofssize;
unsigned char opc_or;
unsigned char first_byte;
#if AVXSUPP
unsigned char basetype;
unsigned char reg1;
unsigned char reg2;
unsigned char reg3;
unsigned char indexreg;
unsigned char basereg;
unsigned int r1type;
unsigned int r2type;
int_32 vexconst;
unsigned char vexregop;
unsigned int indextype;
unsigned char evex_flag;
unsigned char evex_p0;
unsigned char evex_p1;
unsigned char evex_p2;
unsigned char zreg;
bool tuple;
bool isptr;
unsigned char evex_sae;
#endif
union {
unsigned char flags;
struct {
unsigned char iswide:1;
unsigned char isdirect:1;
unsigned char isfar:1;
unsigned char const_size_fixed:1;
#if AMD64_SUPPORT
unsigned char x86hi_used:1;
unsigned char x64lo_used:1;
#endif
unsigned char undef_sym:1;
};
};
};
#define OPND1 0
#define OPND2 1
#define OPND3 2
#define OPND4 3
#define IS_CALL( inst ) ( inst == T_CALL )
#define IS_JMPCALL( inst ) ( inst == T_CALL || inst == T_JMP )
#define IS_JMP( inst ) ( inst >= T_JMP && inst < T_LOOP )
#define IS_JCC( inst ) ( inst > T_JMP && inst < T_JCXZ )
#define IS_BRANCH( inst ) ( inst >= T_CALL && inst < T_LOOP )
#define IS_ANY_BRANCH( inst ) ( inst >= T_CALL && inst <= T_LOOPNZW )
#define IS_XCX_BRANCH( inst ) ( inst >= T_JCXZ && inst <= T_LOOPNZW )
#define IS_OPER_32( s ) ( s->Ofssize ? ( s->prefix.opsiz == FALSE ) : ( s->prefix.opsiz == TRUE ))
extern const struct instr_item InstrTable[];
extern const struct special_item SpecialTable[];
extern uint_16 optable_idx[];
#define IndexFromToken( tok ) optable_idx[ ( tok ) - SPECIAL_LAST ]
extern int SizeFromMemtype( enum memtype, int, struct asym * );
extern ret_code MemtypeFromSize( int, enum memtype * );
extern int SizeFromRegister( int );
extern ret_code GetLangType( int *, struct asm_tok[], enum lang_type * );
extern void sym_add_table( struct symbol_queue *, struct dsym * );
extern void sym_remove_table( struct symbol_queue *, struct dsym * );
extern void sym_ext2int( struct asym * );
extern int OperandSize( enum operand_type, const struct code_info * );
extern void set_frame( const struct asym *sym );
extern void set_frame2( const struct asym *sym );
extern ret_code ParseLine( struct asm_tok[] );
extern void ProcessFile( struct asm_tok[] );
extern void WritePreprocessedLine( const char * );
#endif