1 /* asm86.h - 80X86 assembly intermediate Author: Kees J. Bot
5 typedef enum opcode
{ /* 80486 opcodes, from the i486 reference manual.
6 * Synonyms left out, some new words invented.
10 DOT_ASSERT
, /* Pseudo's invented */
16 DOT_DEFINE
, DOT_EXTERN
,
23 DOT_TEXT
, DOT_ROM
, DOT_DATA
, DOT_BSS
, DOT_END
,
41 CALL
, CALLF
, /* CALLF added */
59 FADD
, FADDD
, FADDS
, FADDP
, FIADDL
, FIADDS
,
64 FCOMD
, FCOMS
, FCOMPD
, FCOMPS
, FCOMPP
,
67 FDIVD
, FDIVS
, FDIVP
, FIDIVL
, FIDIVS
,
68 FDIVRD
, FDIVRS
, FDIVRP
, FIDIVRL
, FIDIVRS
,
76 FLD1
, FLDL2T
, FLDL2E
, FLDPI
, FLDLG2
, FLDLN2
, FLDZ
,
79 FMULD
, FMULS
, FMULP
, FIMULL
, FIMULS
,
92 FSTD
, FSTS
, FSTP
, FSTPX
, FSTPD
, FSTPS
,
96 FSUBD
, FSUBS
, FSUBP
, FISUBL
, FISUBS
,
97 FSUBRD
, FSUBRS
, FSUBPR
, FISUBRL
, FISUBRS
,
99 FUCOM
, FUCOMP
, FUCOMPP
,
115 JA
, JAE
, JB
, JBE
, JCXZ
, JE
, JG
, JGE
, JL
,
116 JLE
, JNE
, JNO
, JNP
, JNS
, JO
, JP
, JS
,
117 JMP
, JMPF
, /* JMPF added */
123 LGS
, LSS
, LDS
, LES
, LFS
,
151 RET
, RETF
, /* RETF added */
156 SETA
, SETAE
, SETB
, SETBE
, SETE
, SETG
, SETGE
, SETL
,
157 SETLE
, SETNE
, SETNO
, SETNP
, SETNS
, SETO
, SETP
, SETS
,
179 #define is_pseudo(o) ((o) <= DOT_USE32)
180 #define N_OPCODES ((int) XOR + 1)
182 #define OPZ 0x01 /* Operand size prefix. */
183 #define ADZ 0x02 /* Address size prefix. */
185 typedef enum optype
{
186 PSEUDO
, JUMP
, BYTE
, WORD
, OWORD
/* Ordered list! */
189 typedef enum repeat
{
190 ONCE
, REP
, REPE
, REPNE
193 typedef enum segment
{
194 DEFSEG
, CSEG
, DSEG
, ESEG
, FSEG
, GSEG
, SSEG
197 typedef struct expression
{
199 struct expression
*left
, *middle
, *right
;
205 typedef struct asm86
{
206 opcode_t opcode
; /* DOT_TEXT, MOV, ... */
207 char *file
; /* Name of the file it is found in. */
208 long line
; /* Line number. */
209 optype_t optype
; /* Type of operands: byte, word... */
210 int oaz
; /* Operand/address size prefix? */
211 repeat_t rep
; /* Repeat prefix used on this instr. */
212 segment_t seg
; /* Segment override. */
213 expression_t
*args
; /* Arguments in ACK order. */
217 expression_t
*new_expr(void);
218 void del_expr(expression_t
*a
);
219 asm86_t
*new_asm86(void);
220 void del_asm86(asm86_t
*a
);
221 int isregister(const char *name
);
224 * Format of the arguments of the asm86_t structure:
227 * ACK assembly operands expression_t cell:
228 * or part of operand: {operator, left, middle, right, name, len}
230 * [expr] {'[', nil, expr, nil}
231 * word {'W', nil, nil, nil, word}
232 * "string" {'S', nil, nil, nil, "string", strlen("string")}
233 * label = expr {'=', nil, expr, nil, label}
234 * expr * expr {'*', expr, nil, expr}
235 * - expr {'-', nil, expr, nil}
236 * (memory) {'(', nil, memory, nil}
237 * offset(base)(index*n) {'O', offset, base, index*n}
238 * base {'B', nil, nil, nil, base}
239 * index*4 {'4', nil, nil, nil, index}
240 * operand, oplist {',', operand, nil, oplist}
241 * label : {':', nil, nil, nil, label}
243 * The precedence of operators is ignored. The expression is simply copied
244 * as is, including parentheses. Problems like missing operators in the
245 * target language will have to be handled by rewriting the source language.
246 * 16-bit or 32-bit registers must be used where they are required by the
247 * target assembler even though ACK makes no difference between 'ax' and
248 * 'eax'. Asmconv is smart enough to transform compiler output. Human made
249 * assembly can be fixed up to be transformable.