1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
/*
* Standard integers
*/
#ifndef CODE_X86_H
#define CODE_X86_H
#if defined (__SVR4) && defined (__sun)
# include <sys/int_types.h>
# include <stdint.h>
#elif defined (__OpenBSD__)
# include <inttypes.h>
#elif defined (_MSC_VER)
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
# include <stdint.h>
#endif
typedef union op op_t;
typedef struct imm_op imm_op_t;
typedef struct reg_op reg_op_t;
typedef struct mem_op mem_op_t;
typedef struct regno_op regno_op_t;
typedef struct alloc_op alloc_op_t;
typedef enum
{
FIRST = 16, /* Make sure these are never valid regno's */
EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI,
MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
NO_REG = -1
} reg_t;
typedef enum
{
IMM,
REG,
MEM,
REGNO, /* Used internally */
ALLOC /* Used internally, by the register allocator */
} op_type_t;
typedef enum
{
REG_TYPE_GP,
REG_TYPE_MMX,
REG_TYPE_SSE,
} reg_type_t;
struct imm_op
{
op_type_t type;
uint32_t value;
};
struct reg_op
{
op_type_t type;
reg_t reg;
};
struct regno_op
{
op_type_t type;
int regno;
};
struct mem_op
{
op_type_t type;
reg_t base_reg;
reg_t index_reg;
int shift;
int32_t disp;
};
struct alloc_op
{
op_type_t type;
void * info; /* Maintained by the register allocator */
};
union op
{
op_type_t type;
imm_op_t immediate;
reg_op_t reg;
mem_op_t mem;
regno_op_t regno;
alloc_op_t alloc;
};
typedef struct Asm Asm;
op_t x86_imm (uint32_t imm); /* imm */
op_t x86_address (void *address); /* (immediate) */
op_t x86_regp (op_t reg); /* (%edx) */
op_t x86_membase (op_t base, int32_t disp); /* 8(%edx) */
op_t x86_memindex (op_t base, int32_t disp,
op_t index, uint32_t shift); /* 8(%edx, ecx, 4) */
Asm *asm_new (void);
uint8_t *asm_emit (Asm *a);
void asm_label (Asm *a, const char *label);
void asm_free_code (uint8_t *code);
void asm_function_preamble (Asm *a);
void asm_function_postamble (Asm *a);
void x86_lea (Asm *a, op_t op, op_t dest);
void x86_mov (Asm *a, op_t from, op_t to);
void x86_movd (Asm *a, op_t from, op_t to);
void x86_movzwx (Asm *a, op_t from, op_t to);
void x86_movq (Asm *a, op_t from, op_t to);
void x86_movdqa (Asm *a, op_t from, op_t to);
void x86_movdqu (Asm *a, op_t from, op_t to);
void x86_neg (Asm *a, op_t dest);
void x86_push (Asm *a, op_t what);
void x86_pop (Asm *a, op_t what);
void x86_pusha (Asm *a);
void x86_popa (Asm *a);
void x86_pushf (Asm *a);
void x86_popf (Asm *a);
void x86_ret (Asm *a);
void x86_shr (Asm *a, op_t what, op_t imm);
void x86_sub (Asm *a, op_t op, op_t dest);
void x86_cmp (Asm *a, op_t op, op_t dest);
void x86_add (Asm *a, op_t op, op_t dest);
void x86_xor (Asm *a, op_t op, op_t dest);
void x86_test (Asm *a, op_t op, op_t dest);
void x86_paddusb (Asm *a, op_t op, op_t dest);
void x86_pcmpeqw (Asm *a, op_t op, op_t dest);
void x86_pmullw (Asm *a, op_t op, op_t dest);
void x86_packuswb (Asm *a, op_t op, op_t dest);
void x86_punpcklbw (Asm *a, op_t op, op_t dest);
void x86_punpckhbw (Asm *a, op_t op, op_t dest);
void x86_pshuflw (Asm *a, op_t op, op_t dest, op_t imm);
void x86_pshufhw (Asm *a, op_t op, op_t dest, op_t imm);
void x86_pshufd (Asm *a, op_t op, op_t dest, op_t imm);
void x86_pshufb (Asm *a, op_t op, op_t dest); /* SSE3 */
void x86_psrlw (Asm *a, op_t dest, op_t amount);
void x86_psllw (Asm *a, op_t dest, op_t amount);
void x86_paddusw (Asm *a, op_t op, op_t dest);
void x86_pxor (Asm *a, op_t op, op_t dest);
void x86_cpuid (Asm *a);
void x86_call (Asm *a, op_t op);
void x86_call_label (Asm *a, const char *label);
void x86_emms (Asm *a);
void x86_jmp (Asm *a, const char *label);
void x86_jnz (Asm *a, const char *label);
void x86_je (Asm *a, const char *label);
void x86_jz (Asm *a, const char *label);
void x86_jne (Asm *a, const char *label);
void x86_jge (Asm *a, const char *label);
void x86_jg_s (Asm *a, const char *label);
void x86_jle_s (Asm *a, const char *label);
op_t x86_ebp (void);
op_t x86_eax (void);
op_t x86_ebx (void);
op_t x86_ecx (void);
op_t x86_edx (void);
op_t x86_esp (void);
op_t x86_ebp (void);
op_t x86_esi (void);
op_t x86_edi (void);
op_t x86_mm0 (void);
op_t x86_mm1 (void);
op_t x86_mm2 (void);
op_t x86_mm3 (void);
op_t x86_mm4 (void);
op_t x86_mm5 (void);
op_t x86_mm6 (void);
op_t x86_mm7 (void);
op_t x86_xmm0 (void);
op_t x86_xmm1 (void);
op_t x86_xmm2 (void);
op_t x86_xmm3 (void);
op_t x86_xmm4 (void);
op_t x86_xmm5 (void);
op_t x86_xmm6 (void);
op_t x86_xmm7 (void);
#endif
|