Add function to print strings from generated code

This commit is contained in:
Maxime Chevalier-Boisvert 2020-09-17 17:09:42 -04:00 коммит произвёл Alan Wu
Родитель 77cfdb24d4
Коммит b8a3f2ed61
6 изменённых файлов: 118 добавлений и 7 удалений

Просмотреть файл

@ -151,6 +151,7 @@ COMMONOBJS = array.$(OBJEXT) \
vm_sync.$(OBJEXT) \
vm_trace.$(OBJEXT) \
ujit_asm.$(OBJEXT) \
ujit_utils.$(OBJEXT) \
ujit_compile.$(OBJEXT) \
$(COROUTINE_OBJ) \
$(DTRACE_OBJ) \

Просмотреть файл

@ -1084,15 +1084,13 @@ void jmp8(CodeBlock cb, int8_t offset)
}
*/
/*
/// jmp - Jump with relative 32-bit offset
void jmp32(CodeBlock cb, int32_t offset)
// jmp - Jump with relative 32-bit offset
void jmp32(codeblock_t* cb, int32_t offset)
{
cb.writeASM("jmp", ((offset > 0)? "+":"-") ~ to!string(offset));
cb.writeByte(JMP_REL32_OPCODE);
cb.writeInt(offset, 32);
//cb.writeASM("jmp", ((offset > 0)? "+":"-") ~ to!string(offset));
cb_write_byte(cb, 0xE9);
cb_write_int(cb, offset, 32);
}
*/
/// lea - Load Effective Address
void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src)

Просмотреть файл

@ -265,6 +265,7 @@ void js(codeblock_t* cb, size_t label_idx);
void jz(codeblock_t* cb, size_t label_idx);
void jmp(codeblock_t* cb, size_t label_idx);
void jmp_rm(codeblock_t* cb, x86opnd_t opnd);
void jmp32(codeblock_t* cb, int32_t offset);
void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
void neg(codeblock_t* cb, x86opnd_t opnd);

Просмотреть файл

@ -7,8 +7,10 @@
#include "insns_info.inc"
#include "ujit_compile.h"
#include "ujit_asm.h"
#include "ujit_utils.h"
// TODO: give ujit_examples.h some more meaningful file name
// eg ujit_hook.h
#include "ujit_examples.h"
// Code generation context

96
ujit_utils.c Normal file
Просмотреть файл

@ -0,0 +1,96 @@
#include <stdio.h>
#include <string.h>
#include "ujit_utils.h"
#include "ujit_asm.h"
// Save caller-save registers on the stack before a C call
void push_regs(codeblock_t* cb)
{
push(cb, RAX);
push(cb, RCX);
push(cb, RDX);
push(cb, RSI);
push(cb, RDI);
push(cb, R8);
push(cb, R9);
push(cb, R10);
push(cb, R11);
pushfq(cb);
}
// Restore caller-save registers from the after a C call
void pop_regs(codeblock_t* cb)
{
popfq(cb);
pop(cb, R11);
pop(cb, R10);
pop(cb, R9);
pop(cb, R8);
pop(cb, RDI);
pop(cb, RSI);
pop(cb, RDX);
pop(cb, RCX);
pop(cb, RAX);
}
static void print_str_fn(const char* str)
{
printf("%s", str);
}
/*
void printInt(CodeBlock as, X86Opnd opnd)
{
extern (C) void printIntFn(int64_t v)
{
writefln("%s", v);
}
size_t opndSz;
if (opnd.isImm)
opndSz = 64;
else if (opnd.isGPR)
opndSz = opnd.reg.size;
else if (opnd.isMem)
opndSz = opnd.mem.size;
else
assert (false);
as.pushRegs();
if (opndSz < 64)
as.movsx(cargRegs[0].opnd(64), opnd);
else
as.mov(cargRegs[0].opnd(64), opnd);
// Call the print function
as.ptr(scrRegs[0], &printIntFn);
as.call(scrRegs[0]);
as.popRegs();
}
*/
// Print a constant string to stdout
void print_str(codeblock_t* cb, const char* str)
{
//as.comment("printStr(\"" ~ str ~ "\")");
size_t len = strlen(str);
push_regs(cb);
// Load the string address and jump over the string data
lea(cb, RDI, mem_opnd(8, RIP, 5));
jmp32(cb, (int32_t)len + 1);
// Write the string chars and a null terminator
for (size_t i = 0; i < len; ++i)
cb_write_byte(cb, (uint8_t)str[i]);
cb_write_byte(cb, 0);
// Call the print function
mov(cb, RAX, const_ptr_opnd(&print_str_fn));
call(cb, RAX);
pop_regs(cb);
}

13
ujit_utils.h Normal file
Просмотреть файл

@ -0,0 +1,13 @@
#ifndef UJIT_UTILS_H
#define UJIT_UTILS_H 1
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "ujit_asm.h"
void push_regs(codeblock_t* cb);
void pop_regs(codeblock_t* cb);
void print_str(codeblock_t* cb, const char* str);
#endif // #ifndef UJIT_UTILS_H