infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
emit_math.c
Go to the documentation of this file.
1
13#include "emit/emit_math.h"
14#include "emit/emit.h"
15#include "emit_internals.h"
16#include <stdio.h>
17#include <string.h>
18
19#define EMIT_CHECK(x) \
20 do { \
21 infix_status _s = (x); \
22 if (_s != INFIX_SUCCESS) \
23 return _s; \
24 } while (0)
25
26#define EMIT_REG_NEEDS_REX(reg) ((reg) >= 8)
27
28static infix_status emit_x86_rex(emit_context_t * ctx, bool w, bool r, bool x, bool b) {
29 if (ctx->arch == EMIT_ARCH_X86_64 && (w || r || x || b)) {
30 uint8_t rex = 0x40 | (w << 3) | (r << 2) | (x << 1) | b;
31 return emit_emit_u8(ctx, rex);
32 }
33 return INFIX_SUCCESS;
34}
35
38 if (!ctx)
40 if (ctx->arch == EMIT_ARCH_X86_64) {
41 EMIT_CHECK(emit_x86_rex(ctx, true, false, false, EMIT_REG_NEEDS_REX(dest)));
42 EMIT_CHECK(emit_emit_u8(ctx, 0xB8 | (dest & 0x07)));
43 EMIT_CHECK(emit_emit_u64(ctx, imm));
44 }
45 return INFIX_SUCCESS;
46}
48 if (ctx->arch == EMIT_ARCH_X86_64) {
49 /* MOVQ r64, xmm -> 66 REX.W 0F 7E /r */
50 EMIT_CHECK(emit_emit_u8(ctx, 0x66));
51 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(xmm_src), false, EMIT_REG_NEEDS_REX(gpr_dest)));
52 EMIT_CHECK(emit_emit_u8(ctx, 0x0F));
53 EMIT_CHECK(emit_emit_u8(ctx, 0x7E));
54 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((xmm_src & 0x07) << 3) | (gpr_dest & 0x07)));
55 }
56 return INFIX_SUCCESS;
57}
60 if (!ctx)
62 if (ctx->arch == EMIT_ARCH_X86_64) {
63 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(src), false, EMIT_REG_NEEDS_REX(dest)));
64 EMIT_CHECK(emit_emit_u8(ctx, 0x89));
65 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((src & 0x07) << 3) | (dest & 0x07)));
66 }
67 return INFIX_SUCCESS;
68}
69
72 if (!ctx)
74 if (ctx->arch == EMIT_ARCH_X86_64) {
75 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(src), false, EMIT_REG_NEEDS_REX(dest)));
76 EMIT_CHECK(emit_emit_u8(ctx, 0x01));
77 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((src & 0x07) << 3) | (dest & 0x07)));
78 }
79 return INFIX_SUCCESS;
80}
81
84 if (!ctx)
86 if (ctx->arch == EMIT_ARCH_X86_64) {
87 EMIT_CHECK(emit_x86_rex(ctx, true, false, false, EMIT_REG_NEEDS_REX(dest)));
88 EMIT_CHECK(emit_emit_u8(ctx, 0x81));
89 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | (dest & 0x07)));
90 EMIT_CHECK(emit_emit_u32(ctx, (uint32_t)imm));
91 }
92 return INFIX_SUCCESS;
93}
94
97 if (!ctx)
99 if (ctx->arch == EMIT_ARCH_X86_64) {
100 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(src), false, EMIT_REG_NEEDS_REX(dest)));
101 EMIT_CHECK(emit_emit_u8(ctx, 0x29));
102 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((src & 0x07) << 3) | (dest & 0x07)));
103 }
104 return INFIX_SUCCESS;
105}
106
109 if (!ctx)
111 if (ctx->arch == EMIT_ARCH_X86_64) {
112 EMIT_CHECK(emit_x86_rex(ctx, true, false, false, EMIT_REG_NEEDS_REX(dest)));
113 EMIT_CHECK(emit_emit_u8(ctx, 0x81));
114 EMIT_CHECK(emit_emit_u8(ctx, 0xE8 | (dest & 0x07)));
115 EMIT_CHECK(emit_emit_u32(ctx, (uint32_t)imm));
116 }
117 return INFIX_SUCCESS;
118}
119
122 if (!ctx)
124 if (ctx->arch == EMIT_ARCH_X86_64) {
125 EMIT_CHECK(emit_x86_rex(ctx, true, false, false, EMIT_REG_NEEDS_REX(src)));
126 EMIT_CHECK(emit_emit_u8(ctx, 0xF7));
127 EMIT_CHECK(emit_emit_u8(ctx, 0xE0 | (src & 0x07)));
128 }
129 return INFIX_SUCCESS;
130}
131
134 if (!ctx)
136 if (ctx->arch == EMIT_ARCH_X86_64) {
137 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(dest), false, EMIT_REG_NEEDS_REX(dest)));
138 if (imm >= -128 && imm <= 127) {
139 EMIT_CHECK(emit_emit_u8(ctx, 0x6B));
140 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((dest & 0x07) << 3) | (dest & 0x07)));
141 EMIT_CHECK(emit_emit_u8(ctx, (uint8_t)imm));
142 }
143 else {
144 EMIT_CHECK(emit_emit_u8(ctx, 0x69));
145 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((dest & 0x07) << 3) | (dest & 0x07)));
146 EMIT_CHECK(emit_emit_u32(ctx, (uint32_t)imm));
147 }
148 }
149 return INFIX_SUCCESS;
150}
151
154 if (!ctx)
156 if (ctx->arch == EMIT_ARCH_X86_64) {
157 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(src), false, EMIT_REG_NEEDS_REX(dest)));
158 EMIT_CHECK(emit_emit_u8(ctx, 0x21));
159 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((src & 0x07) << 3) | (dest & 0x07)));
160 }
161 return INFIX_SUCCESS;
162}
163
166 if (!ctx)
168 if (ctx->arch == EMIT_ARCH_X86_64) {
169 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(src), false, EMIT_REG_NEEDS_REX(dest)));
170 EMIT_CHECK(emit_emit_u8(ctx, 0x09));
171 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((src & 0x07) << 3) | (dest & 0x07)));
172 }
173 return INFIX_SUCCESS;
174}
175
178 if (!ctx)
180 if (ctx->arch == EMIT_ARCH_X86_64) {
181 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(src), false, EMIT_REG_NEEDS_REX(dest)));
182 EMIT_CHECK(emit_emit_u8(ctx, 0x31));
183 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((src & 0x07) << 3) | (dest & 0x07)));
184 }
185 return INFIX_SUCCESS;
186}
187
190 if (!ctx)
192 if (ctx->arch == EMIT_ARCH_X86_64) {
193 EMIT_CHECK(emit_x86_rex(ctx, true, false, false, EMIT_REG_NEEDS_REX(reg)));
194 EMIT_CHECK(emit_emit_u8(ctx, 0xF7));
195 EMIT_CHECK(emit_emit_u8(ctx, 0xD0 | (reg & 0x07)));
196 }
197 return INFIX_SUCCESS;
198}
199
202 if (!ctx)
204 if (ctx->arch == EMIT_ARCH_X86_64) {
205 EMIT_CHECK(emit_x86_rex(ctx, true, false, false, EMIT_REG_NEEDS_REX(reg)));
206 EMIT_CHECK(emit_emit_u8(ctx, 0xF7));
207 EMIT_CHECK(emit_emit_u8(ctx, 0xD8 | (reg & 0x07)));
208 }
209 return INFIX_SUCCESS;
210}
211
214 if (!ctx)
216 if (ctx->arch == EMIT_ARCH_X86_64) {
217 if (src != EMIT_REG_RCX)
219 EMIT_CHECK(emit_x86_rex(ctx, true, false, false, EMIT_REG_NEEDS_REX(dest)));
220 EMIT_CHECK(emit_emit_u8(ctx, 0xD3));
221 EMIT_CHECK(emit_emit_u8(ctx, 0xE0 | (dest & 0x07)));
222 }
223 return INFIX_SUCCESS;
224}
225
228 if (!ctx)
230 if (ctx->arch == EMIT_ARCH_X86_64) {
231 if (src != EMIT_REG_RCX)
233 EMIT_CHECK(emit_x86_rex(ctx, true, false, false, EMIT_REG_NEEDS_REX(dest)));
234 EMIT_CHECK(emit_emit_u8(ctx, 0xD3));
235 EMIT_CHECK(emit_emit_u8(ctx, 0xE8 | (dest & 0x07)));
236 }
237 return INFIX_SUCCESS;
238}
239
242 if (!ctx)
244 if (ctx->arch == EMIT_ARCH_X86_64) {
246 EMIT_CHECK(emit_emit_u8(ctx, 0x39));
247 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((b & 0x07) << 3) | (a & 0x07)));
248 }
249 return INFIX_SUCCESS;
250}
251
254 if (!ctx)
256 if (ctx->arch == EMIT_ARCH_X86_64) {
257 EMIT_CHECK(emit_x86_rex(ctx, true, false, false, EMIT_REG_NEEDS_REX(reg)));
258 EMIT_CHECK(emit_emit_u8(ctx, 0x81));
259 EMIT_CHECK(emit_emit_u8(ctx, 0xF8 | (reg & 0x07)));
260 EMIT_CHECK(emit_emit_u32(ctx, (uint32_t)imm));
261 }
262 return INFIX_SUCCESS;
263}
264
267 if (!ctx)
269 if (ctx->arch == EMIT_ARCH_X86_64) {
271 EMIT_CHECK(emit_emit_u8(ctx, 0x85));
272 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((b & 0x07) << 3) | (a & 0x07)));
273 }
274 return INFIX_SUCCESS;
275}
276
277static const uint8_t x86_jcc_opcodes[16] = {
278 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F};
279
282 if (!ctx)
284 if (ctx->arch == EMIT_ARCH_X86_64) {
285 uint64_t jump_offset = ctx->current_section->size;
286 EMIT_CHECK(emit_emit_u8(ctx, 0xE9));
287 EMIT_CHECK(emit_emit_u32(ctx, 0));
288 EMIT_CHECK(emit_add_relocation(ctx, label, jump_offset + 1, 4, 5));
289 }
290 return INFIX_SUCCESS;
291}
292
295 if (!ctx)
297 if (ctx->arch == EMIT_ARCH_X86_64) {
298 uint64_t jump_offset = ctx->current_section->size;
299 EMIT_CHECK(emit_emit_u8(ctx, 0x0F));
301 EMIT_CHECK(emit_emit_u32(ctx, 0));
302 EMIT_CHECK(emit_add_relocation(ctx, label, jump_offset + 2, 4, 6));
303 }
304 return INFIX_SUCCESS;
305}
306
309 if (!ctx)
311 if (ctx->arch == EMIT_ARCH_X86_64) {
312 uint64_t call_offset = ctx->current_section->size;
313 EMIT_CHECK(emit_emit_u8(ctx, 0xE8));
314 EMIT_CHECK(emit_emit_u32(ctx, 0));
315 EMIT_CHECK(emit_add_relocation(ctx, name, call_offset + 1, 4, 5));
316 }
317 return INFIX_SUCCESS;
318}
319
321 if (ctx->arch == EMIT_ARCH_X86_64) {
322 EMIT_CHECK(emit_emit_u8(ctx, 0x55));
323 EMIT_CHECK(emit_emit_u8(ctx, 0x48));
324 EMIT_CHECK(emit_emit_u8(ctx, 0x8B));
325 EMIT_CHECK(emit_emit_u8(ctx, 0xEC));
326 }
327 return INFIX_SUCCESS;
328}
329
331 if (ctx->arch == EMIT_ARCH_X86_64) {
332 EMIT_CHECK(emit_emit_u8(ctx, 0xC9));
333 EMIT_CHECK(emit_emit_u8(ctx, 0xC3));
334 }
335 return INFIX_SUCCESS;
336}
337
343
345 if (ctx->arch == EMIT_ARCH_X86_64) {
346 EMIT_CHECK(emit_x86_rex(ctx, false, false, false, EMIT_REG_NEEDS_REX(reg)));
347 EMIT_CHECK(emit_emit_u8(ctx, 0x50 | (reg & 0x07)));
348 }
349 return INFIX_SUCCESS;
350}
351
353 if (ctx->arch == EMIT_ARCH_X86_64) {
354 EMIT_CHECK(emit_x86_rex(ctx, false, false, false, EMIT_REG_NEEDS_REX(reg)));
355 EMIT_CHECK(emit_emit_u8(ctx, 0x58 | (reg & 0x07)));
356 }
357 return INFIX_SUCCESS;
358}
359
361 emit_register_t dest,
362 emit_register_t base,
363 int32_t offset) {
364 if (ctx->arch == EMIT_ARCH_X86_64) {
365 uint8_t mod = (offset == 0 && (base & 0x07) != 5) ? 0x00 : ((offset >= -128 && offset <= 127) ? 0x40 : 0x80);
366 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(dest), false, EMIT_REG_NEEDS_REX(base)));
367 EMIT_CHECK(emit_emit_u8(ctx, 0x8B));
368 EMIT_CHECK(emit_emit_u8(ctx, mod | ((dest & 0x07) << 3) | (base & 0x07)));
369 if ((base & 0x07) == 4)
370 EMIT_CHECK(emit_emit_u8(ctx, 0x24));
371 if (mod == 0x40)
372 EMIT_CHECK(emit_emit_u8(ctx, (uint8_t)offset));
373 else if (mod == 0x80)
374 EMIT_CHECK(emit_emit_u32(ctx, (uint32_t)offset));
375 }
376 return INFIX_SUCCESS;
377}
378
380 emit_register_t base,
381 int32_t offset,
382 emit_register_t src) {
383 if (ctx->arch == EMIT_ARCH_X86_64) {
384 uint8_t mod = (offset == 0 && (base & 0x07) != 5) ? 0x00 : ((offset >= -128 && offset <= 127) ? 0x40 : 0x80);
385 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(src), false, EMIT_REG_NEEDS_REX(base)));
386 EMIT_CHECK(emit_emit_u8(ctx, 0x89));
387 EMIT_CHECK(emit_emit_u8(ctx, mod | ((src & 0x07) << 3) | (base & 0x07)));
388 if ((base & 0x07) == 4)
389 EMIT_CHECK(emit_emit_u8(ctx, 0x24));
390 if (mod == 0x40)
391 EMIT_CHECK(emit_emit_u8(ctx, (uint8_t)offset));
392 else if (mod == 0x80)
393 EMIT_CHECK(emit_emit_u32(ctx, (uint32_t)offset));
394 }
395 return INFIX_SUCCESS;
396}
397
399 if (ctx->arch == EMIT_ARCH_X86_64) {
400 uint64_t load_offset = ctx->current_section->size;
401 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(dest), false, false));
402 EMIT_CHECK(emit_emit_u8(ctx, 0x8B));
403 EMIT_CHECK(emit_emit_u8(ctx, 0x05 | ((dest & 0x07) << 3)));
404 EMIT_CHECK(emit_emit_u32(ctx, 0));
405 EMIT_CHECK(emit_add_relocation(ctx, sym, load_offset + 3, 4, 7));
406 }
407 return INFIX_SUCCESS;
408}
409
411 if (ctx->arch == EMIT_ARCH_X86_64) {
412 uint64_t store_offset = ctx->current_section->size;
413 EMIT_CHECK(emit_x86_rex(ctx, true, EMIT_REG_NEEDS_REX(src), false, false));
414 EMIT_CHECK(emit_emit_u8(ctx, 0x89));
415 EMIT_CHECK(emit_emit_u8(ctx, 0x05 | ((src & 0x07) << 3)));
416 EMIT_CHECK(emit_emit_u32(ctx, 0));
417 EMIT_CHECK(emit_add_relocation(ctx, sym, store_offset + 3, 4, 7));
418 }
419 return INFIX_SUCCESS;
420}
421
422/* Floating Point Operations */
424 if (ctx->arch == EMIT_ARCH_X86_64) {
425 EMIT_CHECK(emit_emit_u8(ctx, 0xF2));
426 EMIT_CHECK(emit_x86_rex(ctx, false, EMIT_REG_NEEDS_REX(dest), false, EMIT_REG_NEEDS_REX(src)));
427 EMIT_CHECK(emit_emit_u8(ctx, 0x0F));
428 EMIT_CHECK(emit_emit_u8(ctx, 0x10));
429 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((dest & 0x07) << 3) | (src & 0x07)));
430 }
431 return INFIX_SUCCESS;
432}
433
435 if (ctx->arch == EMIT_ARCH_X86_64) {
436 EMIT_CHECK(emit_emit_u8(ctx, 0xF2));
437 EMIT_CHECK(emit_x86_rex(ctx, false, EMIT_REG_NEEDS_REX(dest), false, EMIT_REG_NEEDS_REX(src)));
438 EMIT_CHECK(emit_emit_u8(ctx, 0x0F));
439 EMIT_CHECK(emit_emit_u8(ctx, 0x58));
440 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((dest & 0x07) << 3) | (src & 0x07)));
441 }
442 return INFIX_SUCCESS;
443}
444
446 if (ctx->arch == EMIT_ARCH_X86_64) {
447 EMIT_CHECK(emit_emit_u8(ctx, 0xF2));
448 EMIT_CHECK(emit_x86_rex(ctx, false, EMIT_REG_NEEDS_REX(dest), false, EMIT_REG_NEEDS_REX(src)));
449 EMIT_CHECK(emit_emit_u8(ctx, 0x0F));
450 EMIT_CHECK(emit_emit_u8(ctx, 0x5C));
451 EMIT_CHECK(emit_emit_u8(ctx, 0xC0 | ((dest & 0x07) << 3) | (src & 0x07)));
452 }
453 return INFIX_SUCCESS;
454}
infix_registry_t * reg
Definition 501_direct_marshalling.c:209
INFIX_API INFIX_NODISCARD infix_status emit_add_relocation(emit_context_t *ctx, const char *name, uint64_t offset, uint8_t size, uint8_t inst_size)
Definition emit.c:333
Public API for the emit JIT code generation system.
INFIX_EMIT_API infix_status emit_emit_u8(emit_context_t *ctx, uint8_t value)
Definition emit.c:282
@ EMIT_ARCH_X86_64
Definition emit.h:31
INFIX_EMIT_API infix_status emit_emit_u64(emit_context_t *ctx, uint64_t value)
Definition emit.c:299
INFIX_EMIT_API infix_status emit_emit_u32(emit_context_t *ctx, uint32_t value)
Definition emit.c:291
Internal structures for the emit JIT code generation system.
INFIX_API infix_status emit_math_movsd_reg(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:423
INFIX_API infix_status emit_math_addsd(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:434
INFIX_API infix_status emit_math_subsd(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:445
INFIX_API infix_status emit_math_and(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:152
INFIX_API infix_status emit_math_movq_gpr_xmm(emit_context_t *ctx, emit_register_t gpr_dest, emit_register_t xmm_src)
Definition emit_math.c:47
static const uint8_t x86_jcc_opcodes[16]
Definition emit_math.c:277
INFIX_API infix_status emit_math_pop(emit_context_t *ctx, emit_register_t reg)
Definition emit_math.c:352
INFIX_API infix_status emit_math_add_imm(emit_context_t *ctx, emit_register_t dest, int32_t imm)
Definition emit_math.c:82
INFIX_API infix_status emit_math_store_reg(emit_context_t *ctx, emit_register_t base, int32_t offset, emit_register_t src)
Definition emit_math.c:379
INFIX_API infix_status emit_math_load_sym(emit_context_t *ctx, emit_register_t dest, const char *sym)
Definition emit_math.c:398
INFIX_API infix_status emit_math_jmp(emit_context_t *ctx, const char *label)
Definition emit_math.c:280
INFIX_API infix_status emit_math_not(emit_context_t *ctx, emit_register_t reg)
Definition emit_math.c:188
INFIX_API infix_status emit_math_shl(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:212
INFIX_API infix_status emit_math_or(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:164
INFIX_API infix_status emit_math_add(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:70
INFIX_API infix_status emit_math_store_sym(emit_context_t *ctx, const char *sym, emit_register_t src)
Definition emit_math.c:410
INFIX_API infix_status emit_math_epilogue(emit_context_t *ctx)
Definition emit_math.c:330
INFIX_API infix_status emit_math_jmp_cc(emit_context_t *ctx, emit_cc_t cc, const char *label)
Definition emit_math.c:293
INFIX_API infix_status emit_math_mul(emit_context_t *ctx, emit_register_t src)
Definition emit_math.c:120
INFIX_API infix_status emit_math_test(emit_context_t *ctx, emit_register_t a, emit_register_t b)
Definition emit_math.c:265
INFIX_API infix_status emit_math_load_reg(emit_context_t *ctx, emit_register_t dest, emit_register_t base, int32_t offset)
Definition emit_math.c:360
INFIX_API infix_status emit_math_prologue(emit_context_t *ctx)
Definition emit_math.c:320
INFIX_API infix_status emit_math_sub(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:95
INFIX_API infix_status emit_math_neg(emit_context_t *ctx, emit_register_t reg)
Definition emit_math.c:200
INFIX_API infix_status emit_math_xor(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:176
#define EMIT_REG_NEEDS_REX(reg)
Definition emit_math.c:26
#define EMIT_CHECK(x)
Definition emit_math.c:19
INFIX_API infix_status emit_math_imul_imm(emit_context_t *ctx, emit_register_t dest, int32_t imm)
Definition emit_math.c:132
INFIX_API infix_status emit_math_mov_reg(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:58
INFIX_API infix_status emit_math_cmp(emit_context_t *ctx, emit_register_t a, emit_register_t b)
Definition emit_math.c:240
static infix_status emit_x86_rex(emit_context_t *ctx, bool w, bool r, bool x, bool b)
Definition emit_math.c:28
INFIX_API infix_status emit_math_shr(emit_context_t *ctx, emit_register_t dest, emit_register_t src)
Definition emit_math.c:226
INFIX_API infix_status emit_math_cmp_imm(emit_context_t *ctx, emit_register_t reg, int32_t imm)
Definition emit_math.c:252
INFIX_API infix_status emit_math_sub_imm(emit_context_t *ctx, emit_register_t dest, int32_t imm)
Definition emit_math.c:107
INFIX_API infix_status emit_math_push(emit_context_t *ctx, emit_register_t reg)
Definition emit_math.c:344
INFIX_API infix_status emit_math_call(emit_context_t *ctx, const char *name)
Definition emit_math.c:307
INFIX_API infix_status emit_math_ret(emit_context_t *ctx)
Definition emit_math.c:338
INFIX_API infix_status emit_math_mov_imm(emit_context_t *ctx, emit_register_t dest, uint64_t imm)
Definition emit_math.c:36
Math operations for JIT code generation.
emit_cc_t
Definition emit_math.h:24
emit_register_t
Definition emit_math.h:43
@ EMIT_REG_RCX
Definition emit_math.h:45
infix_status
Enumerates the possible status codes returned by infix API functions.
Definition infix.h:435
@ INFIX_SUCCESS
Definition infix.h:436
@ INFIX_ERROR_INVALID_ARGUMENT
Definition infix.h:438
#define INFIX_API
Symbol visibility macro.
Definition infix.h:114
INFIX_INTERNAL void _infix_clear_error(void)
Clears the thread-local error state.
Definition error.c:268
Definition emit_internals.h:50
emit_architecture_t arch
Definition emit_internals.h:51
emit_section_t * current_section
Definition emit_internals.h:55
uint64_t size
Definition emit_internals.h:26