summaryrefslogtreecommitdiff
path: root/codex86.h
blob: 50d9e7f1140bea93a8dfc32460b78ca70f6a4ddf (plain)
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