mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Introduce version_t struct. Will be needed for code invalidation.
This commit is contained in:
parent
a251059070
commit
3a74011ff8
7 changed files with 187 additions and 172 deletions
142
ujit_asm.c
142
ujit_asm.c
|
@ -14,7 +14,7 @@
|
|||
#include "ujit_asm.h"
|
||||
|
||||
// Compute the number of bits needed to encode a signed value
|
||||
size_t sig_imm_size(int64_t imm)
|
||||
uint32_t sig_imm_size(int64_t imm)
|
||||
{
|
||||
// Compute the smallest size this immediate fits in
|
||||
if (imm >= -128 && imm <= 127)
|
||||
|
@ -28,7 +28,7 @@ size_t sig_imm_size(int64_t imm)
|
|||
}
|
||||
|
||||
// Compute the number of bits needed to encode an unsigned value
|
||||
size_t unsig_imm_size(uint64_t imm)
|
||||
uint32_t unsig_imm_size(uint64_t imm)
|
||||
{
|
||||
// Compute the smallest size this immediate fits in
|
||||
if (imm <= 255)
|
||||
|
@ -41,7 +41,7 @@ size_t unsig_imm_size(uint64_t imm)
|
|||
return 64;
|
||||
}
|
||||
|
||||
x86opnd_t mem_opnd(size_t num_bits, x86opnd_t base_reg, int32_t disp)
|
||||
x86opnd_t mem_opnd(uint32_t num_bits, x86opnd_t base_reg, int32_t disp)
|
||||
{
|
||||
bool is_iprel = base_reg.as.reg.reg_type == REG_IP;
|
||||
|
||||
|
@ -54,7 +54,7 @@ x86opnd_t mem_opnd(size_t num_bits, x86opnd_t base_reg, int32_t disp)
|
|||
return opnd;
|
||||
}
|
||||
|
||||
x86opnd_t resize_opnd(x86opnd_t opnd, size_t num_bits)
|
||||
x86opnd_t resize_opnd(x86opnd_t opnd, uint32_t num_bits)
|
||||
{
|
||||
assert (num_bits % 8 == 0);
|
||||
x86opnd_t sub = opnd;
|
||||
|
@ -85,7 +85,7 @@ x86opnd_t const_ptr_opnd(const void *ptr)
|
|||
}
|
||||
|
||||
// Allocate a block of executable memory
|
||||
uint8_t* alloc_exec_mem(size_t mem_size)
|
||||
uint8_t* alloc_exec_mem(uint32_t mem_size)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
// Map the memory as executable
|
||||
|
@ -112,7 +112,7 @@ uint8_t* alloc_exec_mem(size_t mem_size)
|
|||
}
|
||||
|
||||
// Initialize a code block object
|
||||
void cb_init(codeblock_t* cb, uint8_t* mem_block, size_t mem_size)
|
||||
void cb_init(codeblock_t* cb, uint8_t* mem_block, uint32_t mem_size)
|
||||
{
|
||||
cb->mem_block = mem_block;
|
||||
cb->mem_size = mem_size;
|
||||
|
@ -122,30 +122,30 @@ void cb_init(codeblock_t* cb, uint8_t* mem_block, size_t mem_size)
|
|||
}
|
||||
|
||||
// Align the current write position to a multiple of bytes
|
||||
void cb_align_pos(codeblock_t* cb, size_t multiple)
|
||||
void cb_align_pos(codeblock_t* cb, uint32_t multiple)
|
||||
{
|
||||
// Compute the pointer modulo the given alignment boundary
|
||||
uint8_t* ptr = &cb->mem_block[cb->write_pos];
|
||||
size_t rem = ((size_t)ptr) % multiple;
|
||||
uint32_t rem = ((uint32_t)ptr) % multiple;
|
||||
|
||||
// If the pointer is already aligned, stop
|
||||
if (rem != 0)
|
||||
return;
|
||||
|
||||
// Pad the pointer by the necessary amount to align it
|
||||
size_t pad = multiple - rem;
|
||||
uint32_t pad = multiple - rem;
|
||||
cb->write_pos += pad;
|
||||
}
|
||||
|
||||
// Set the current write position
|
||||
void cb_set_pos(codeblock_t* cb, size_t pos)
|
||||
void cb_set_pos(codeblock_t* cb, uint32_t pos)
|
||||
{
|
||||
assert (pos < cb->mem_size);
|
||||
cb->write_pos = pos;
|
||||
}
|
||||
|
||||
// Get a direct pointer into the executable memory block
|
||||
uint8_t* cb_get_ptr(codeblock_t* cb, size_t index)
|
||||
uint8_t* cb_get_ptr(codeblock_t* cb, uint32_t index)
|
||||
{
|
||||
assert (index < cb->mem_size);
|
||||
return &cb->mem_block[index];
|
||||
|
@ -160,12 +160,12 @@ void cb_write_byte(codeblock_t* cb, uint8_t byte)
|
|||
}
|
||||
|
||||
// Write multiple bytes starting from the current position
|
||||
void cb_write_bytes(codeblock_t* cb, size_t num_bytes, ...)
|
||||
void cb_write_bytes(codeblock_t* cb, uint32_t num_bytes, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, num_bytes);
|
||||
|
||||
for (size_t i = 0; i < num_bytes; ++i)
|
||||
for (uint32_t i = 0; i < num_bytes; ++i)
|
||||
{
|
||||
uint8_t byte = va_arg(va, int);
|
||||
cb_write_byte(cb, byte);
|
||||
|
@ -175,7 +175,7 @@ void cb_write_bytes(codeblock_t* cb, size_t num_bytes, ...)
|
|||
}
|
||||
|
||||
// Write a signed integer over a given number of bits at the current position
|
||||
void cb_write_int(codeblock_t* cb, uint64_t val, size_t num_bits)
|
||||
void cb_write_int(codeblock_t* cb, uint64_t val, uint32_t num_bits)
|
||||
{
|
||||
assert (num_bits > 0);
|
||||
assert (num_bits % 8 == 0);
|
||||
|
@ -210,10 +210,10 @@ void cb_write_int(codeblock_t* cb, uint64_t val, size_t num_bits)
|
|||
default:
|
||||
{
|
||||
// Compute the size in bytes
|
||||
size_t num_bytes = num_bits / 8;
|
||||
uint32_t num_bytes = num_bits / 8;
|
||||
|
||||
// Write out the bytes
|
||||
for (size_t i = 0; i < num_bytes; ++i)
|
||||
for (uint32_t i = 0; i < num_bytes; ++i)
|
||||
{
|
||||
uint8_t byte_val = (uint8_t)(val & 0xFF);
|
||||
cb_write_byte(cb, byte_val);
|
||||
|
@ -224,7 +224,7 @@ void cb_write_int(codeblock_t* cb, uint64_t val, size_t num_bits)
|
|||
}
|
||||
|
||||
// Allocate a new label with a given name
|
||||
size_t cb_new_label(codeblock_t* cb, const char* name)
|
||||
uint32_t cb_new_label(codeblock_t* cb, const char* name)
|
||||
{
|
||||
//if (hasASM)
|
||||
// writeString(to!string(label) ~ ":");
|
||||
|
@ -232,7 +232,7 @@ size_t cb_new_label(codeblock_t* cb, const char* name)
|
|||
assert (cb->num_labels < MAX_LABELS);
|
||||
|
||||
// Allocate the new label
|
||||
size_t label_idx = cb->num_labels++;
|
||||
uint32_t label_idx = cb->num_labels++;
|
||||
|
||||
// This label doesn't have an address yet
|
||||
cb->label_addrs[label_idx] = 0;
|
||||
|
@ -242,14 +242,14 @@ size_t cb_new_label(codeblock_t* cb, const char* name)
|
|||
}
|
||||
|
||||
// Write a label at the current address
|
||||
void cb_write_label(codeblock_t* cb, size_t label_idx)
|
||||
void cb_write_label(codeblock_t* cb, uint32_t label_idx)
|
||||
{
|
||||
assert (label_idx < MAX_LABELS);
|
||||
cb->label_addrs[label_idx] = cb->write_pos;
|
||||
}
|
||||
|
||||
// Add a label reference at the current write position
|
||||
void cb_label_ref(codeblock_t* cb, size_t label_idx)
|
||||
void cb_label_ref(codeblock_t* cb, uint32_t label_idx)
|
||||
{
|
||||
assert (label_idx < MAX_LABELS);
|
||||
assert (cb->num_refs < MAX_LABEL_REFS);
|
||||
|
@ -262,17 +262,17 @@ void cb_label_ref(codeblock_t* cb, size_t label_idx)
|
|||
// Link internal label references
|
||||
void cb_link_labels(codeblock_t* cb)
|
||||
{
|
||||
size_t orig_pos = cb->write_pos;
|
||||
uint32_t orig_pos = cb->write_pos;
|
||||
|
||||
// For each label reference
|
||||
for (size_t i = 0; i < cb->num_refs; ++i)
|
||||
for (uint32_t i = 0; i < cb->num_refs; ++i)
|
||||
{
|
||||
size_t ref_pos = cb->label_refs[i].pos;
|
||||
size_t label_idx = cb->label_refs[i].label_idx;
|
||||
uint32_t ref_pos = cb->label_refs[i].pos;
|
||||
uint32_t label_idx = cb->label_refs[i].label_idx;
|
||||
assert (ref_pos < cb->mem_size);
|
||||
assert (label_idx < MAX_LABELS);
|
||||
|
||||
size_t label_addr = cb->label_addrs[label_idx];
|
||||
uint32_t label_addr = cb->label_addrs[label_idx];
|
||||
assert (label_addr < cb->mem_size);
|
||||
|
||||
// Compute the offset from the reference's end to the label
|
||||
|
@ -327,7 +327,7 @@ bool sib_needed(x86opnd_t opnd)
|
|||
}
|
||||
|
||||
// Compute the size of the displacement field needed for a memory operand
|
||||
size_t disp_size(x86opnd_t opnd)
|
||||
uint32_t disp_size(x86opnd_t opnd)
|
||||
{
|
||||
assert (opnd.type == OPND_MEM);
|
||||
|
||||
|
@ -340,7 +340,7 @@ size_t disp_size(x86opnd_t opnd)
|
|||
// Compute the required displacement size
|
||||
if (opnd.as.mem.disp != 0)
|
||||
{
|
||||
size_t num_bits = sig_imm_size(opnd.as.mem.disp);
|
||||
uint32_t num_bits = sig_imm_size(opnd.as.mem.disp);
|
||||
assert (num_bits <= 32 && "displacement does not fit in 32 bits");
|
||||
|
||||
// x86 can only encode 8-bit and 32-bit displacements
|
||||
|
@ -400,7 +400,7 @@ void cb_write_rm(
|
|||
x86opnd_t r_opnd,
|
||||
x86opnd_t rm_opnd,
|
||||
uint8_t opExt,
|
||||
size_t op_len,
|
||||
uint32_t op_len,
|
||||
...)
|
||||
{
|
||||
assert (op_len > 0 && op_len <= 3);
|
||||
|
@ -455,7 +455,7 @@ void cb_write_rm(
|
|||
// Write the opcode bytes to the code block
|
||||
va_list va;
|
||||
va_start(va, op_len);
|
||||
for (size_t i = 0; i < op_len; ++i)
|
||||
for (uint32_t i = 0; i < op_len; ++i)
|
||||
{
|
||||
uint8_t byte = va_arg(va, int);
|
||||
cb_write_byte(cb, byte);
|
||||
|
@ -479,7 +479,7 @@ void cb_write_rm(
|
|||
}
|
||||
else
|
||||
{
|
||||
size_t dsize = disp_size(rm_opnd);
|
||||
uint32_t dsize = disp_size(rm_opnd);
|
||||
if (dsize == 0 || rm_opnd.as.mem.is_iprel)
|
||||
mod = 0;
|
||||
else if (dsize == 8)
|
||||
|
@ -547,7 +547,7 @@ void cb_write_rm(
|
|||
// Add the displacement
|
||||
if (rm_opnd.type == OPND_MEM)
|
||||
{
|
||||
size_t dsize = disp_size(rm_opnd);
|
||||
uint32_t dsize = disp_size(rm_opnd);
|
||||
if (dsize > 0)
|
||||
cb_write_int(cb, rm_opnd.as.mem.disp, dsize);
|
||||
}
|
||||
|
@ -566,7 +566,7 @@ void write_rm_unary(
|
|||
//cb.writeASM(mnem, opnd);
|
||||
|
||||
// Check the size of opnd0
|
||||
size_t opndSize;
|
||||
uint32_t opndSize;
|
||||
if (opnd.type == OPND_REG || opnd.type == OPND_MEM)
|
||||
opndSize = opnd.num_bits;
|
||||
else
|
||||
|
@ -608,7 +608,7 @@ void cb_write_rm_multi(
|
|||
*/
|
||||
|
||||
// Check the size of opnd0
|
||||
size_t opndSize = opnd0.num_bits;
|
||||
uint32_t opndSize = opnd0.num_bits;
|
||||
|
||||
// Check the size of opnd1
|
||||
if (opnd1.type == OPND_REG || opnd1.type == OPND_MEM)
|
||||
|
@ -696,7 +696,7 @@ void cb_write_shift(
|
|||
//cb.writeASM(mnem, opnd0, opnd1);
|
||||
|
||||
// Check the size of opnd0
|
||||
size_t opndSize;
|
||||
uint32_t opndSize;
|
||||
if (opnd0.type == OPND_REG || opnd0.type == OPND_MEM)
|
||||
opndSize = opnd0.num_bits;
|
||||
else
|
||||
|
@ -733,7 +733,7 @@ void cb_write_shift(
|
|||
|
||||
// Encode a relative jump to a label (direct or conditional)
|
||||
// Note: this always encodes a 32-bit offset
|
||||
void cb_write_jcc(codeblock_t* cb, const char* mnem, uint8_t op0, uint8_t op1, size_t label_idx)
|
||||
void cb_write_jcc(codeblock_t* cb, const char* mnem, uint8_t op0, uint8_t op1, uint32_t label_idx)
|
||||
{
|
||||
//cb.writeASM(mnem, label);
|
||||
|
||||
|
@ -857,7 +857,7 @@ void call_ptr(codeblock_t* cb, x86opnd_t scratch_reg, uint8_t* dst_ptr)
|
|||
}
|
||||
|
||||
/// call - Call to label with 32-bit offset
|
||||
void call_label(codeblock_t* cb, size_t label_idx)
|
||||
void call_label(codeblock_t* cb, uint32_t label_idx)
|
||||
{
|
||||
//cb.writeASM("call", label);
|
||||
|
||||
|
@ -1049,37 +1049,37 @@ void imul(CodeBlock cb, X86Opnd opnd0, X86Opnd opnd1, X86Opnd opnd2)
|
|||
*/
|
||||
|
||||
/// jcc - relative jumps to a label
|
||||
void ja (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "ja" , 0x0F, 0x87, label_idx); }
|
||||
void jae (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jae" , 0x0F, 0x83, label_idx); }
|
||||
void jb (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jb" , 0x0F, 0x82, label_idx); }
|
||||
void jbe (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jbe" , 0x0F, 0x86, label_idx); }
|
||||
void jc (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jc" , 0x0F, 0x82, label_idx); }
|
||||
void je (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "je" , 0x0F, 0x84, label_idx); }
|
||||
void jg (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jg" , 0x0F, 0x8F, label_idx); }
|
||||
void jge (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jge" , 0x0F, 0x8D, label_idx); }
|
||||
void jl (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jl" , 0x0F, 0x8C, label_idx); }
|
||||
void jle (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jle" , 0x0F, 0x8E, label_idx); }
|
||||
void jna (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jna" , 0x0F, 0x86, label_idx); }
|
||||
void jnae(codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnae", 0x0F, 0x82, label_idx); }
|
||||
void jnb (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnb" , 0x0F, 0x83, label_idx); }
|
||||
void jnbe(codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnbe", 0x0F, 0x87, label_idx); }
|
||||
void jnc (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnc" , 0x0F, 0x83, label_idx); }
|
||||
void jne (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jne" , 0x0F, 0x85, label_idx); }
|
||||
void jng (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jng" , 0x0F, 0x8E, label_idx); }
|
||||
void jnge(codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnge", 0x0F, 0x8C, label_idx); }
|
||||
void jnl (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnl" , 0x0F, 0x8D, label_idx); }
|
||||
void jnle(codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnle", 0x0F, 0x8F, label_idx); }
|
||||
void jno (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jno" , 0x0F, 0x81, label_idx); }
|
||||
void jnp (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnp" , 0x0F, 0x8b, label_idx); }
|
||||
void jns (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jns" , 0x0F, 0x89, label_idx); }
|
||||
void jnz (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnz" , 0x0F, 0x85, label_idx); }
|
||||
void jo (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jo" , 0x0F, 0x80, label_idx); }
|
||||
void jp (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jp" , 0x0F, 0x8A, label_idx); }
|
||||
void jpe (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jpe" , 0x0F, 0x8A, label_idx); }
|
||||
void jpo (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jpo" , 0x0F, 0x8B, label_idx); }
|
||||
void js (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "js" , 0x0F, 0x88, label_idx); }
|
||||
void jz (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jz" , 0x0F, 0x84, label_idx); }
|
||||
void jmp (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jmp" , 0xFF, 0xE9, label_idx); }
|
||||
void ja (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "ja" , 0x0F, 0x87, label_idx); }
|
||||
void jae (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jae" , 0x0F, 0x83, label_idx); }
|
||||
void jb (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jb" , 0x0F, 0x82, label_idx); }
|
||||
void jbe (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jbe" , 0x0F, 0x86, label_idx); }
|
||||
void jc (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jc" , 0x0F, 0x82, label_idx); }
|
||||
void je (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "je" , 0x0F, 0x84, label_idx); }
|
||||
void jg (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jg" , 0x0F, 0x8F, label_idx); }
|
||||
void jge (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jge" , 0x0F, 0x8D, label_idx); }
|
||||
void jl (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jl" , 0x0F, 0x8C, label_idx); }
|
||||
void jle (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jle" , 0x0F, 0x8E, label_idx); }
|
||||
void jna (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jna" , 0x0F, 0x86, label_idx); }
|
||||
void jnae(codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jnae", 0x0F, 0x82, label_idx); }
|
||||
void jnb (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jnb" , 0x0F, 0x83, label_idx); }
|
||||
void jnbe(codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jnbe", 0x0F, 0x87, label_idx); }
|
||||
void jnc (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jnc" , 0x0F, 0x83, label_idx); }
|
||||
void jne (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jne" , 0x0F, 0x85, label_idx); }
|
||||
void jng (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jng" , 0x0F, 0x8E, label_idx); }
|
||||
void jnge(codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jnge", 0x0F, 0x8C, label_idx); }
|
||||
void jnl (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jnl" , 0x0F, 0x8D, label_idx); }
|
||||
void jnle(codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jnle", 0x0F, 0x8F, label_idx); }
|
||||
void jno (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jno" , 0x0F, 0x81, label_idx); }
|
||||
void jnp (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jnp" , 0x0F, 0x8b, label_idx); }
|
||||
void jns (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jns" , 0x0F, 0x89, label_idx); }
|
||||
void jnz (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jnz" , 0x0F, 0x85, label_idx); }
|
||||
void jo (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jo" , 0x0F, 0x80, label_idx); }
|
||||
void jp (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jp" , 0x0F, 0x8A, label_idx); }
|
||||
void jpe (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jpe" , 0x0F, 0x8A, label_idx); }
|
||||
void jpo (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jpo" , 0x0F, 0x8B, label_idx); }
|
||||
void js (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "js" , 0x0F, 0x88, label_idx); }
|
||||
void jz (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jz" , 0x0F, 0x84, label_idx); }
|
||||
void jmp (codeblock_t* cb, uint32_t label_idx) { cb_write_jcc(cb, "jmp" , 0xFF, 0xE9, label_idx); }
|
||||
|
||||
/// jcc - relative jumps to a pointer (32-bit offset)
|
||||
void ja_ptr (codeblock_t* cb, uint8_t* ptr) { cb_write_jcc_ptr(cb, "ja" , 0x0F, 0x87, ptr); }
|
||||
|
@ -1233,13 +1233,13 @@ void movzx(codeblock_t* cb, x86opnd_t dst, x86opnd_t src)
|
|||
{
|
||||
cb.writeASM("movzx", dst, src);
|
||||
|
||||
size_t dstSize;
|
||||
uint32_t dstSize;
|
||||
if (dst.isReg)
|
||||
dstSize = dst.reg.size;
|
||||
else
|
||||
assert (false, "movzx dst must be a register");
|
||||
|
||||
size_t srcSize;
|
||||
uint32_t srcSize;
|
||||
if (src.isReg)
|
||||
srcSize = src.reg.size;
|
||||
else if (src.isMem)
|
||||
|
@ -1281,7 +1281,7 @@ void neg(codeblock_t* cb, x86opnd_t opnd)
|
|||
}
|
||||
|
||||
// nop - Noop, one or multiple bytes long
|
||||
void nop(codeblock_t* cb, size_t length)
|
||||
void nop(codeblock_t* cb, uint32_t length)
|
||||
{
|
||||
switch (length)
|
||||
{
|
||||
|
@ -1335,7 +1335,7 @@ void nop(codeblock_t* cb, size_t length)
|
|||
|
||||
default:
|
||||
{
|
||||
size_t written = 0;
|
||||
uint32_t written = 0;
|
||||
while (written + 9 <= length)
|
||||
{
|
||||
nop(cb, 9);
|
||||
|
|
102
ujit_asm.h
102
ujit_asm.h
|
@ -15,10 +15,10 @@
|
|||
typedef struct LabelRef
|
||||
{
|
||||
// Position in the code block where the label reference exists
|
||||
size_t pos;
|
||||
uint32_t pos;
|
||||
|
||||
// Label which this refers to
|
||||
size_t label_idx;
|
||||
uint32_t label_idx;
|
||||
|
||||
} labelref_t;
|
||||
|
||||
|
@ -29,13 +29,13 @@ typedef struct CodeBlock
|
|||
uint8_t* mem_block;
|
||||
|
||||
// Memory block size
|
||||
size_t mem_size;
|
||||
uint32_t mem_size;
|
||||
|
||||
/// Current writing position
|
||||
size_t write_pos;
|
||||
uint32_t write_pos;
|
||||
|
||||
// Table of registered label addresses
|
||||
size_t label_addrs[MAX_LABELS];
|
||||
uint32_t label_addrs[MAX_LABELS];
|
||||
|
||||
// Table of registered label names
|
||||
// Note that these should be constant strings only
|
||||
|
@ -45,10 +45,10 @@ typedef struct CodeBlock
|
|||
labelref_t label_refs[MAX_LABEL_REFS];
|
||||
|
||||
// Number of labels registeered
|
||||
size_t num_labels;
|
||||
uint32_t num_labels;
|
||||
|
||||
// Number of references to labels
|
||||
size_t num_refs;
|
||||
uint32_t num_refs;
|
||||
|
||||
// TODO: system for disassembly/comment strings, indexed by position
|
||||
|
||||
|
@ -214,7 +214,7 @@ static const x86opnd_t R15B = { OPND_REG, 8, .as.reg = { REG_GP, 15 }};
|
|||
#define C_ARG_REGS ( (x86opnd_t[]){ RDI, RSI, RDX, RCX, R8, R9 } )
|
||||
|
||||
// Memory operand with base register and displacement/offset
|
||||
x86opnd_t mem_opnd(size_t num_bits, x86opnd_t base_reg, int32_t disp);
|
||||
x86opnd_t mem_opnd(uint32_t num_bits, x86opnd_t base_reg, int32_t disp);
|
||||
|
||||
// Immediate number operand
|
||||
x86opnd_t imm_opnd(int64_t val);
|
||||
|
@ -238,24 +238,24 @@ x86opnd_t const_ptr_opnd(const void *ptr);
|
|||
)
|
||||
|
||||
// Code block methods
|
||||
uint8_t* alloc_exec_mem(size_t mem_size);
|
||||
void cb_init(codeblock_t* cb, uint8_t* mem_block, size_t mem_size);
|
||||
void cb_align_pos(codeblock_t* cb, size_t multiple);
|
||||
void cb_set_pos(codeblock_t* cb, size_t pos);
|
||||
uint8_t* cb_get_ptr(codeblock_t* cb, size_t index);
|
||||
uint8_t* alloc_exec_mem(uint32_t mem_size);
|
||||
void cb_init(codeblock_t* cb, uint8_t* mem_block, uint32_t mem_size);
|
||||
void cb_align_pos(codeblock_t* cb, uint32_t multiple);
|
||||
void cb_set_pos(codeblock_t* cb, uint32_t pos);
|
||||
uint8_t* cb_get_ptr(codeblock_t* cb, uint32_t index);
|
||||
void cb_write_byte(codeblock_t* cb, uint8_t byte);
|
||||
void cb_write_bytes(codeblock_t* cb, size_t num_bytes, ...);
|
||||
void cb_write_int(codeblock_t* cb, uint64_t val, size_t num_bits);
|
||||
size_t cb_new_label(codeblock_t* cb, const char* name);
|
||||
void cb_write_label(codeblock_t* cb, size_t label_idx);
|
||||
void cb_label_ref(codeblock_t* cb, size_t label_idx);
|
||||
void cb_write_bytes(codeblock_t* cb, uint32_t num_bytes, ...);
|
||||
void cb_write_int(codeblock_t* cb, uint64_t val, uint32_t num_bits);
|
||||
uint32_t cb_new_label(codeblock_t* cb, const char* name);
|
||||
void cb_write_label(codeblock_t* cb, uint32_t label_idx);
|
||||
void cb_label_ref(codeblock_t* cb, uint32_t label_idx);
|
||||
void cb_link_labels(codeblock_t* cb);
|
||||
|
||||
// Encode individual instructions into a code block
|
||||
void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
||||
void and(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
||||
void call_ptr(codeblock_t* cb, x86opnd_t scratch_reg, uint8_t* dst_ptr);
|
||||
void call_label(codeblock_t* cb, size_t label_idx);
|
||||
void call_label(codeblock_t* cb, uint32_t label_idx);
|
||||
void call(codeblock_t* cb, x86opnd_t opnd);
|
||||
void cmova(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
|
||||
void cmovae(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
|
||||
|
@ -291,36 +291,36 @@ void cmp(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
|||
void cdq(codeblock_t* cb);
|
||||
void cqo(codeblock_t* cb);
|
||||
void int3(codeblock_t* cb);
|
||||
void ja(codeblock_t* cb, size_t label_idx);
|
||||
void jae(codeblock_t* cb, size_t label_idx);
|
||||
void jb(codeblock_t* cb, size_t label_idx);
|
||||
void jbe(codeblock_t* cb, size_t label_idx);
|
||||
void jc(codeblock_t* cb, size_t label_idx);
|
||||
void je(codeblock_t* cb, size_t label_idx);
|
||||
void jg(codeblock_t* cb, size_t label_idx);
|
||||
void jge(codeblock_t* cb, size_t label_idx);
|
||||
void jl(codeblock_t* cb, size_t label_idx);
|
||||
void jle(codeblock_t* cb, size_t label_idx);
|
||||
void jna(codeblock_t* cb, size_t label_idx);
|
||||
void jnae(codeblock_t* cb, size_t label_idx);
|
||||
void jnb(codeblock_t* cb, size_t label_idx);
|
||||
void jnbe(codeblock_t* cb, size_t label_idx);
|
||||
void jnc(codeblock_t* cb, size_t label_idx);
|
||||
void jne(codeblock_t* cb, size_t label_idx);
|
||||
void jng(codeblock_t* cb, size_t label_idx);
|
||||
void jnge(codeblock_t* cb, size_t label_idx);
|
||||
// void jnl(codeblock_t* cb, size_t label_idx); // this conflicts with jnl(3)
|
||||
void jnle(codeblock_t* cb, size_t label_idx);
|
||||
void jno(codeblock_t* cb, size_t label_idx);
|
||||
void jnp(codeblock_t* cb, size_t label_idx);
|
||||
void jns(codeblock_t* cb, size_t label_idx);
|
||||
void jnz(codeblock_t* cb, size_t label_idx);
|
||||
void jo(codeblock_t* cb, size_t label_idx);
|
||||
void jp(codeblock_t* cb, size_t label_idx);
|
||||
void jpe(codeblock_t* cb, size_t label_idx);
|
||||
void jpo(codeblock_t* cb, size_t label_idx);
|
||||
void js(codeblock_t* cb, size_t label_idx);
|
||||
void jz(codeblock_t* cb, size_t label_idx);
|
||||
void ja(codeblock_t* cb, uint32_t label_idx);
|
||||
void jae(codeblock_t* cb, uint32_t label_idx);
|
||||
void jb(codeblock_t* cb, uint32_t label_idx);
|
||||
void jbe(codeblock_t* cb, uint32_t label_idx);
|
||||
void jc(codeblock_t* cb, uint32_t label_idx);
|
||||
void je(codeblock_t* cb, uint32_t label_idx);
|
||||
void jg(codeblock_t* cb, uint32_t label_idx);
|
||||
void jge(codeblock_t* cb, uint32_t label_idx);
|
||||
void jl(codeblock_t* cb, uint32_t label_idx);
|
||||
void jle(codeblock_t* cb, uint32_t label_idx);
|
||||
void jna(codeblock_t* cb, uint32_t label_idx);
|
||||
void jnae(codeblock_t* cb, uint32_t label_idx);
|
||||
void jnb(codeblock_t* cb, uint32_t label_idx);
|
||||
void jnbe(codeblock_t* cb, uint32_t label_idx);
|
||||
void jnc(codeblock_t* cb, uint32_t label_idx);
|
||||
void jne(codeblock_t* cb, uint32_t label_idx);
|
||||
void jng(codeblock_t* cb, uint32_t label_idx);
|
||||
void jnge(codeblock_t* cb, uint32_t label_idx);
|
||||
// void jnl(codeblock_t* cb, uint32_t label_idx); // this conflicts with jnl(3)
|
||||
void jnle(codeblock_t* cb, uint32_t label_idx);
|
||||
void jno(codeblock_t* cb, uint32_t label_idx);
|
||||
void jnp(codeblock_t* cb, uint32_t label_idx);
|
||||
void jns(codeblock_t* cb, uint32_t label_idx);
|
||||
void jnz(codeblock_t* cb, uint32_t label_idx);
|
||||
void jo(codeblock_t* cb, uint32_t label_idx);
|
||||
void jp(codeblock_t* cb, uint32_t label_idx);
|
||||
void jpe(codeblock_t* cb, uint32_t label_idx);
|
||||
void jpo(codeblock_t* cb, uint32_t label_idx);
|
||||
void js(codeblock_t* cb, uint32_t label_idx);
|
||||
void jz(codeblock_t* cb, uint32_t label_idx);
|
||||
void ja_ptr(codeblock_t* cb, uint8_t* ptr);
|
||||
void jae_ptr(codeblock_t* cb, uint8_t* ptr);
|
||||
void jb_ptr(codeblock_t* cb, uint8_t* ptr);
|
||||
|
@ -351,7 +351,7 @@ void jpe_ptr(codeblock_t* cb, uint8_t* ptr);
|
|||
void jpo_ptr(codeblock_t* cb, uint8_t* ptr);
|
||||
void js_ptr(codeblock_t* cb, uint8_t* ptr);
|
||||
void jz_ptr(codeblock_t* cb, uint8_t* ptr);
|
||||
void jmp(codeblock_t* cb, size_t label_idx);
|
||||
void jmp(codeblock_t* cb, uint32_t label_idx);
|
||||
void jmp_ptr(codeblock_t* cb, uint8_t* ptr);
|
||||
void jmp_rm(codeblock_t* cb, x86opnd_t opnd);
|
||||
void jmp32(codeblock_t* cb, int32_t offset);
|
||||
|
@ -359,7 +359,7 @@ void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
|
|||
void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
|
||||
void movsx(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
|
||||
void neg(codeblock_t* cb, x86opnd_t opnd);
|
||||
void nop(codeblock_t* cb, size_t length);
|
||||
void nop(codeblock_t* cb, uint32_t length);
|
||||
void not(codeblock_t* cb, x86opnd_t opnd);
|
||||
void or(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
||||
void pop(codeblock_t* cb, x86opnd_t reg);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Print the bytes in a code block
|
||||
void print_bytes(codeblock_t* cb)
|
||||
{
|
||||
for (size_t i = 0; i < cb->write_pos; ++i)
|
||||
for (uint32_t i = 0; i < cb->write_pos; ++i)
|
||||
{
|
||||
printf("%02X", (int)cb->mem_block[i]);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ void check_bytes(codeblock_t* cb, const char* bytes)
|
|||
|
||||
if (cb->write_pos != num_bytes)
|
||||
{
|
||||
fprintf(stderr, "incorrect encoding length, expected %ld, got %ld\n",
|
||||
fprintf(stderr, "incorrect encoding length, expected %ld, got %d\n",
|
||||
num_bytes,
|
||||
cb->write_pos
|
||||
);
|
||||
|
@ -35,7 +35,7 @@ void check_bytes(codeblock_t* cb, const char* bytes)
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_bytes; ++i)
|
||||
for (uint32_t i = 0; i < num_bytes; ++i)
|
||||
{
|
||||
char byte_str[] = {0, 0, 0, 0};
|
||||
strncpy(byte_str, bytes + (2 * i), 2);
|
||||
|
@ -46,7 +46,7 @@ void check_bytes(codeblock_t* cb, const char* bytes)
|
|||
|
||||
if (cb_byte != byte)
|
||||
{
|
||||
fprintf(stderr, "incorrect encoding at position %ld, expected %02X, got %02X\n",
|
||||
fprintf(stderr, "incorrect encoding at position %d, expected %02X, got %02X\n",
|
||||
i,
|
||||
(int)byte,
|
||||
(int)cb_byte
|
||||
|
@ -92,7 +92,7 @@ void run_tests()
|
|||
// call
|
||||
{
|
||||
cb_set_pos(cb, 0);
|
||||
size_t fn_label = cb_new_label(cb, "foo");
|
||||
uint32_t fn_label = cb_new_label(cb, "foo");
|
||||
call_label(cb, fn_label);
|
||||
cb_link_labels(cb);
|
||||
check_bytes(cb, "E8FBFFFFFF");
|
||||
|
@ -131,14 +131,14 @@ void run_tests()
|
|||
// jcc
|
||||
{
|
||||
cb_set_pos(cb, 0);
|
||||
size_t loop_label = cb_new_label(cb, "loop");
|
||||
uint32_t loop_label = cb_new_label(cb, "loop");
|
||||
jge(cb, loop_label);
|
||||
cb_link_labels(cb);
|
||||
check_bytes(cb, "0F8DFAFFFFFF");
|
||||
}
|
||||
{
|
||||
cb_set_pos(cb, 0);
|
||||
size_t loop_label = cb_new_label(cb, "loop");
|
||||
uint32_t loop_label = cb_new_label(cb, "loop");
|
||||
jo(cb, loop_label);
|
||||
cb_link_labels(cb);
|
||||
check_bytes(cb, "0F80FAFFFFFF");
|
||||
|
|
|
@ -154,7 +154,7 @@ uint8_t* ujit_compile_entry(const rb_iseq_t *iseq, uint32_t insn_idx)
|
|||
/*
|
||||
Compile a sequence of bytecode instructions starting at `insn_idx`.
|
||||
*/
|
||||
uint8_t *
|
||||
void
|
||||
ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, ctx_t* ctx, uint32_t* num_instrs)
|
||||
{
|
||||
assert (cb != NULL);
|
||||
|
@ -170,16 +170,14 @@ ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, ctx_t* ctx, uint32_
|
|||
rb_bug("out of executable memory (outlined block)");
|
||||
}
|
||||
|
||||
// Get a pointer to the current write position in the code block
|
||||
uint8_t *code_ptr = cb_get_ptr(cb, cb->write_pos);
|
||||
|
||||
// Last operation that was successfully compiled
|
||||
opdesc_t* p_last_op = NULL;
|
||||
|
||||
// Initialize JIT state object
|
||||
jitstate_t jit = { 0 };
|
||||
jit.iseq = iseq;
|
||||
jit.start_idx = insn_idx;
|
||||
jitstate_t jit = {
|
||||
iseq,
|
||||
insn_idx
|
||||
};
|
||||
|
||||
// For each instruction to compile
|
||||
for (;;) {
|
||||
|
@ -236,8 +234,6 @@ ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, ctx_t* ctx, uint32_
|
|||
pc += insn_len(opcode);
|
||||
}
|
||||
}
|
||||
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -1055,7 +1051,7 @@ void
|
|||
ujit_init_codegen(void)
|
||||
{
|
||||
// Initialize the code blocks
|
||||
size_t mem_size = 128 * 1024 * 1024;
|
||||
uint32_t mem_size = 128 * 1024 * 1024;
|
||||
uint8_t* mem_block = alloc_exec_mem(mem_size);
|
||||
cb = █
|
||||
cb_init(cb, mem_block, mem_size/2);
|
||||
|
|
|
@ -15,7 +15,7 @@ typedef struct JITState
|
|||
const rb_iseq_t *iseq;
|
||||
|
||||
// Index in the iseq of the opcode we are replacing
|
||||
uint32_t start_idx;
|
||||
const uint32_t start_idx;
|
||||
|
||||
// Index of the current instruction being compiled
|
||||
uint32_t insn_idx;
|
||||
|
@ -42,7 +42,7 @@ typedef struct OpDesc
|
|||
|
||||
uint8_t* ujit_compile_entry(const rb_iseq_t *iseq, uint32_t insn_idx);
|
||||
|
||||
uint8_t *ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, ctx_t* ctx, uint32_t* num_instrs);
|
||||
void ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, ctx_t* ctx, uint32_t* num_instrs);
|
||||
|
||||
void ujit_init_codegen(void);
|
||||
|
||||
|
|
57
ujit_core.c
57
ujit_core.c
|
@ -70,12 +70,12 @@ ctx_stack_opnd(ctx_t* ctx, int32_t idx)
|
|||
}
|
||||
|
||||
// Retrieve a basic block version for an (iseq, idx) tuple
|
||||
uint8_t* find_block_version(blockid_t block, const ctx_t* ctx)
|
||||
version_t* find_block_version(blockid_t block, const ctx_t* ctx)
|
||||
{
|
||||
// If there exists a version for this block id
|
||||
st_data_t st_version;
|
||||
if (rb_st_lookup(version_tbl, (st_data_t)&block, &st_version)) {
|
||||
return (uint8_t*)st_version;
|
||||
return (version_t*)st_version;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -86,23 +86,24 @@ uint8_t* find_block_version(blockid_t block, const ctx_t* ctx)
|
|||
}
|
||||
|
||||
// Compile a new block version immediately
|
||||
uint8_t* gen_block_version(blockid_t blockid, const ctx_t* ctx)
|
||||
version_t* gen_block_version(blockid_t blockid, const ctx_t* ctx)
|
||||
{
|
||||
// Copy the context object to avoid modifying it
|
||||
// Allocate a version object
|
||||
version_t* p_version = malloc(sizeof(version_t));
|
||||
memcpy(&p_version->blockid, &blockid, sizeof(blockid_t));
|
||||
memcpy(&p_version->ctx, ctx, sizeof(ctx_t));
|
||||
|
||||
// Compile the block version
|
||||
ctx_t ctx_copy = *ctx;
|
||||
|
||||
uint32_t num_instrs = 0;
|
||||
uint8_t* p_block = ujit_compile_block(blockid.iseq, blockid.idx, &ctx_copy, &num_instrs);
|
||||
|
||||
// Need to allocate the blockid on the heap
|
||||
// to store it in the hash table
|
||||
blockid_t* p_blockid = (blockid_t*)malloc(sizeof(blockid_t));
|
||||
memcpy(p_blockid, &blockid, sizeof(blockid_t));
|
||||
p_version->start_pos = cb->write_pos;
|
||||
ujit_compile_block(blockid.iseq, blockid.idx, &ctx_copy, &num_instrs);
|
||||
p_version->end_pos = cb->write_pos;
|
||||
|
||||
// Keep track of the new block version
|
||||
st_insert(version_tbl, (st_data_t)p_blockid, (st_data_t)p_block);
|
||||
st_insert(version_tbl, (st_data_t)&p_version->blockid, (st_data_t)p_version);
|
||||
|
||||
return p_block;
|
||||
return p_version;
|
||||
}
|
||||
|
||||
// Called by the generated code when a branch stub is executed
|
||||
|
@ -132,31 +133,29 @@ uint8_t* branch_stub_hit(uint32_t branch_idx, uint32_t target_idx)
|
|||
}
|
||||
|
||||
// Try to find a compiled version of this block
|
||||
uint8_t* block_ptr = find_block_version(target, target_ctx);
|
||||
version_t* p_version = find_block_version(target, target_ctx);
|
||||
|
||||
// If this block hasn't yet been compiled
|
||||
if (!block_ptr)
|
||||
if (!p_version)
|
||||
{
|
||||
//fprintf(stderr, "compiling block\n");
|
||||
block_ptr = gen_block_version(target, target_ctx);
|
||||
p_version = gen_block_version(target, target_ctx);
|
||||
}
|
||||
|
||||
// Update the branch target address
|
||||
branch->dst_addrs[target_idx] = block_ptr;
|
||||
|
||||
//fprintf(stderr, "rewrite branch at %d\n", branch->start_pos);
|
||||
uint8_t* dst_addr = cb_get_ptr(cb, p_version->start_pos);
|
||||
branch->dst_addrs[target_idx] = dst_addr;
|
||||
|
||||
// Rewrite the branch with the new jump target address
|
||||
assert (branch->dst_addrs[0] != NULL);
|
||||
assert (branch->dst_addrs[1] != NULL);
|
||||
size_t cur_pos = cb->write_pos;
|
||||
uint32_t cur_pos = cb->write_pos;
|
||||
cb_set_pos(cb, branch->start_pos);
|
||||
branch->gen_fn(cb, branch->dst_addrs[0], branch->dst_addrs[1], branch->shape);
|
||||
assert (cb->write_pos <= branch->end_pos);
|
||||
cb_set_pos(cb, cur_pos);
|
||||
|
||||
// Return a pointer to the compiled block version
|
||||
return block_ptr;
|
||||
return dst_addr;
|
||||
}
|
||||
|
||||
// Get a version or stub corresponding to a branch target
|
||||
|
@ -169,10 +168,12 @@ uint8_t* get_branch_target(
|
|||
uint32_t target_idx
|
||||
)
|
||||
{
|
||||
uint8_t* block_code = find_block_version(target, ctx);
|
||||
version_t* p_version = find_block_version(target, ctx);
|
||||
|
||||
if (block_code)
|
||||
return block_code;
|
||||
if (p_version)
|
||||
{
|
||||
return cb_get_ptr(cb, p_version->start_pos);
|
||||
}
|
||||
|
||||
// Generate an outlined stub that will call
|
||||
// branch_stub_hit(uint32_t branch_idx, uint32_t target_idx)
|
||||
|
@ -216,12 +217,10 @@ void gen_branch(
|
|||
uint8_t* dst_addr0 = get_branch_target(target0, ctx0, ocb, num_branches, 0);
|
||||
uint8_t* dst_addr1 = get_branch_target(target1, ctx1, ocb, num_branches, 1);
|
||||
|
||||
uint32_t start_pos = (uint32_t)cb->write_pos;
|
||||
|
||||
// Call the branch generation function
|
||||
uint32_t start_pos = cb->write_pos;
|
||||
gen_fn(cb, dst_addr0, dst_addr1, SHAPE_DEFAULT);
|
||||
|
||||
uint32_t end_pos = (uint32_t)cb->write_pos;
|
||||
uint32_t end_pos = cb->write_pos;
|
||||
|
||||
// Register this branch entry
|
||||
branch_t branch_entry = {
|
||||
|
|
24
ujit_core.h
24
ujit_core.h
|
@ -45,6 +45,26 @@ typedef struct BlockId
|
|||
// Null block id constant
|
||||
static const blockid_t BLOCKID_NULL = { 0, 0 };
|
||||
|
||||
// Basic block version
|
||||
typedef struct BlockVersion
|
||||
{
|
||||
// Basic block this is a version of
|
||||
blockid_t blockid;
|
||||
|
||||
// Context at the start of the block
|
||||
ctx_t ctx;
|
||||
|
||||
// Positions where the generated code starts and ends
|
||||
uint32_t start_pos;
|
||||
uint32_t end_pos;
|
||||
|
||||
// TODO
|
||||
// TODO: list of incoming branches, branch entries
|
||||
// TODO
|
||||
// incoming;
|
||||
|
||||
} version_t;
|
||||
|
||||
/// Branch code shape enumeration
|
||||
enum uint8_t
|
||||
{
|
||||
|
@ -90,8 +110,8 @@ x86opnd_t ctx_stack_push(ctx_t* ctx, size_t n);
|
|||
x86opnd_t ctx_stack_pop(ctx_t* ctx, size_t n);
|
||||
x86opnd_t ctx_stack_opnd(ctx_t* ctx, int32_t idx);
|
||||
|
||||
uint8_t* find_block_version(blockid_t block, const ctx_t* ctx);
|
||||
uint8_t* gen_block_version(blockid_t block, const ctx_t* ctx);
|
||||
version_t* find_block_version(blockid_t block, const ctx_t* ctx);
|
||||
version_t* gen_block_version(blockid_t block, const ctx_t* ctx);
|
||||
|
||||
void gen_branch(
|
||||
const ctx_t* src_ctx,
|
||||
|
|
Loading…
Add table
Reference in a new issue