Lua: Fix type confusion between signed and unsigned
[lsnes.git] / include / library / assembler-intrinsics-i386.hpp
bloba29e227f0304f5aecbd32aa57ebfc1a840292c61
1 #ifndef _library__assembler_intrinsics_i386__hpp__included__
2 #define _library__assembler_intrinsics_i386__hpp__included__
4 #include "assembler.hpp"
5 #include <cstdint>
6 #include <cstdlib>
8 namespace assembler_intrinsics
10 struct I386
12 struct ref;
13 struct sib_scale_off_intermediate;
14 struct sib_scale_intermediate;
15 struct reg
17 explicit reg(uint8_t _val);
18 ref operator[](int32_t off) const;
19 sib_scale_intermediate operator*(uint8_t scale) const;
20 ref operator[](const reg r) const;
21 ref operator[](sib_scale_intermediate r) const;
22 ref operator[](sib_scale_off_intermediate r) const;
23 sib_scale_off_intermediate operator+(int32_t off) const;
24 bool hbit();
25 uint8_t lbits();
26 uint8_t num();
27 bool valid(bool amd64);
28 bool is_none();
29 private:
30 friend class ref;
31 friend class sib_scale_intermediate;
32 friend class sib_scale_off_intermediate;
33 uint8_t val;
35 const static reg reg_none;
36 const static reg reg_ax;
37 const static reg reg_bx;
38 const static reg reg_cx;
39 const static reg reg_dx;
40 const static reg reg_bp; //Don't use in 8-bit mode.
41 const static reg reg_sp; //Don't use in 8-bit mode.
42 const static reg reg_si; //Don't use in 8-bit mode.
43 const static reg reg_di; //Don't use in 8-bit mode.
44 const static reg reg_r8;
45 const static reg reg_r9;
46 const static reg reg_r10;
47 const static reg reg_r11;
48 const static reg reg_r12;
49 const static reg reg_r13;
50 const static reg reg_r14;
51 const static reg reg_r15;
52 const static reg reg_rip;
54 struct sib_scale_off_intermediate
56 sib_scale_off_intermediate(reg idx, uint8_t scale, int32_t offset);
57 private:
58 friend class reg;
59 friend class ref;
60 reg index;
61 uint8_t scale;
62 int32_t offset;
64 struct sib_scale_intermediate
66 sib_scale_intermediate(reg idx, uint8_t scale);
67 sib_scale_off_intermediate operator+(int32_t off) const;
68 private:
69 friend class reg;
70 friend class ref;
71 reg index;
72 uint8_t scale;
74 struct low
76 low(bool _need_amd64, uint8_t _rex_prefix, std::vector<uint8_t> _ref);
77 bool need_amd64();
78 bool has_rex();
79 uint8_t rex_prefix();
80 std::vector<uint8_t> bytes();
81 void emit_rex(assembler::assembler& a);
82 void emit_bytes(assembler::assembler& a);
83 private:
84 bool needs_amd64;
85 uint8_t rex;
86 std::vector<uint8_t> mref;
88 struct ref
90 ref();
91 ref(reg r);
92 ref(sib_scale_intermediate r);
93 ref(sib_scale_off_intermediate r);
94 low operator()(reg r, bool set_size_flag, bool amd64);
95 void emit(assembler::assembler& a, bool set_size_flag, bool amd64, reg r, uint8_t op1);
96 void emit(assembler::assembler& a, bool set_size_flag, bool amd64, reg r, uint8_t op1,
97 uint8_t op2);
98 private:
99 friend class sib_scale_intermediate;
100 friend class sib_scale_off_intermediate;
101 friend class reg;
102 static ref reg_off(reg r, int32_t off = 0);
103 static ref rip_off(int32_t off = 0);
104 static ref sib(reg base, reg index, uint8_t scale = 1, int32_t off = 0);
105 bool needs_amd64;
106 uint8_t rex;
107 std::vector<uint8_t> mref;
109 I386(assembler::assembler& _a, bool _amd64);
110 //Is amd64?
111 bool is_amd64();
112 //Is i386?
113 bool is_i386();
114 //Get word size.
115 uint8_t wordsize();
116 //Label:
117 void label(assembler::label& l);
118 //PUSH NWORD <reg>
119 void push_reg(reg r);
120 //POP NWORD <reg>
121 void pop_reg(reg r);
122 //MOV NWORD <reg>,<regmem>
123 void mov_reg_regmem(reg r, ref mem);
124 //LEA <reg>,<mem>
125 void lea_reg_mem(reg r, ref mem);
126 //XOR NWORD <reg>,<regmem>
127 void xor_reg_regmem(reg r, ref mem);
128 //MOV BYTE <regmem>, imm
129 void mov_regmem_imm8(ref mem, uint8_t imm);
130 //ADD BYTE <regmem>, imm
131 void add_regmem_imm8(ref mem, uint8_t imm);
132 //MOV DWORD <regmem>, imm
133 void mov_regmem_imm32(ref mem, uint32_t imm);
134 //MOV WORD <regmem>, <reg>
135 void mov_regmem_reg16(ref mem, reg r);
136 //MOV WORD <reg>, <regmem>
137 void mov_reg_regmem16(reg r, ref mem);
138 //MOV BYTE <reg>, <regmem>
139 void mov_reg_regmem8(reg r, ref mem);
140 //MOV BYTE <regmem>, <reg>
141 void mov_regmem_reg8(ref mem, reg r);
142 //OR BYTE <regmem>, imm
143 void or_regmem_imm8(ref mem, uint8_t imm);
144 //AND BYTE <regmem>, imm
145 void and_regmem_imm8(ref mem, uint8_t imm);
146 //TEST BYTE <regmem>, imm
147 void test_regmem_imm8(ref mem, uint8_t imm);
148 //CMP BYTE <regmem>, imm
149 void cmp_regmem_imm8(ref mem, uint8_t imm);
150 //CMP NWORD <regmem>, imm
151 void cmp_regmem_imm(ref mem, int32_t imm);
152 //SHL NWORD <regmem>, imm
153 void shl_regmem_imm(ref mem, uint8_t imm);
154 //SHL BYTE <regmem>, imm
155 void shl_regmem_imm8(ref mem, uint8_t imm);
156 //AND NWORD <regmem>, imm
157 void and_regmem_imm(ref mem, int32_t imm);
158 //ADD NWORD <regmem>, imm
159 void add_regmem_imm(ref mem, int32_t imm);
160 //ADD NWORD <reg>,<regmem>
161 void add_reg_regmem(reg r, ref mem);
162 //INC NWORD <regmem>
163 void inc_regmem(ref mem);
164 //MOV NWORD <reg>, <addr>.
165 void mov_reg_addr(reg r, assembler::label& l);
166 //MOV NWORD <reg>, imm.
167 void mov_reg_imm(reg r, size_t imm);
168 //NEG BYTE <regmem>
169 void neg_regmem8(ref mem);
170 //OR BYTE <regmem>, <reg>
171 void or_regmem_reg8(ref mem, reg r);
172 //CALL <addr>
173 void call_addr(assembler::label& l);
174 //CALL <regmem>
175 void call_regmem(ref mem);
176 //SETNZ <regmem>
177 void setnz_regmem(ref mem);
178 //JMP <regmem>
179 void jmp_regmem(ref mem);
180 //JNZ SHORT <label>
181 void jnz_short(assembler::label& l);
182 //JZ SHORT <label>
183 void jz_short(assembler::label& l);
184 //JZ SHORT <label>
185 void jz_long(assembler::label& l);
186 //JMP SHORT <label>
187 void jmp_short(assembler::label& l);
188 //JMP LONG <label>
189 void jmp_long(assembler::label& l);
190 //JAE SHORT <label>
191 void jae_short(assembler::label& l);
192 //JAE LONG <label>
193 void jae_long(assembler::label& l);
194 //RET
195 void ret();
196 //Write address constant.
197 void address(assembler::label& l);
198 private:
199 assembler::assembler& a;
200 bool amd64;
204 #endif