pub/libjit_ir.h \
pub/libjit.h
-PRIV_HEADERS = priv/ir/ir_defs.h \
- priv/host-x86/x86h_defs.h \
- priv/host-generic/host_regs.h
+PRIV_HEADERS = priv/host-x86/x86h_defs.h \
+ priv/host-generic/host_regs.h \
+ priv/main/jit_globals.h \
+ priv/main/vex_util.h
-LIB_OBJS = priv/ir/ir_defs.o \
+LIB_OBJS = \
+ priv/ir/ir_defs.o \
+ priv/main/jit_main.o \
+ priv/main/jit_globals.o \
+ priv/main/vex_util.o \
priv/host-x86/x86h_defs.o \
priv/host-x86/isel_x86.o \
priv/host-generic/host_regs.o \
PUB_INCLUDES = -Ipub
-PRIV_INCLUDES = -Ipub -Ipriv/ir -Ipriv/host-generic -Ipriv/host-x86
+PRIV_INCLUDES = -Ipriv/ir -Ipriv/main -Ipriv/host-generic -Ipriv/host-x86
APP_OBJS = test_main.o
libjit.a: $(LIB_OBJS)
ar clq libjit.a $(LIB_OBJS)
-%.o: %.c
- $(CC) $(CCFLAGS) $(PRIV_INCLUDES) -c -o $@ $<
-
clean:
rm -f $(APP_OBJS) $(LIB_OBJS) libjit.a vex
+ALL_HEADERS = $(PUB_HEADERS) $(PRIV_HEADERS)
+ALL_INCLUDES = $(PUB_INCLUDES) $(PRIV_INCLUDES)
+
+priv/ir/ir_defs.o: $(ALL_HEADERS) priv/ir/ir_defs.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir/ir_defs.o \
+ -c priv/ir/ir_defs.c
+
+priv/main/jit_main.o: $(ALL_HEADERS) priv/main/jit_main.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/main/jit_main.o \
+ -c priv/main/jit_main.c
+
+priv/main/jit_globals.o: $(ALL_HEADERS) priv/main/jit_globals.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/main/jit_globals.o \
+ -c priv/main/jit_globals.c
+
+priv/main/vex_util.o: $(ALL_HEADERS) priv/main/vex_util.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/main/vex_util.o \
+ -c priv/main/vex_util.c
+
+priv/host-x86/x86h_defs.o: $(ALL_HEADERS) priv/host-x86/x86h_defs.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host-x86/x86h_defs.o \
+ -c priv/host-x86/x86h_defs.c
+
+priv/host-x86/isel_x86.o: $(ALL_HEADERS) priv/host-x86/isel_x86.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host-x86/isel_x86.o \
+ -c priv/host-x86/isel_x86.c
+
+priv/host-generic/host_regs.o: $(ALL_HEADERS) priv/host-generic/host_regs.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host-generic/host_regs.o \
+ -c priv/host-generic/host_regs.c
+
+priv/host-generic/reg_alloc.o: $(ALL_HEADERS) priv/host-generic/reg_alloc.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host-generic/reg_alloc.o \
+ -c priv/host-generic/reg_alloc.c
#ifndef __HOST_REGS_H
#define __HOST_REGS_H
+#include "libjit_basictypes.h"
+
/*---------------------------------------------------------*/
/*--- Representing HOST REGISTERS ---*/
}
HRegClass;
-extern void ppHRegClass ( FILE*, HRegClass );
+extern void ppHRegClass ( HRegClass );
/* Print an HReg in a generic (non-target-specific) way. */
-extern void ppHReg ( FILE*, HReg );
+extern void ppHReg ( HReg );
/* Construct/destruct. */
extern HReg mkHReg ( UInt regno, HRegClass rc, Bool virtual );
}
HRegUsage;
-extern void ppHRegUsage ( FILE*, HRegUsage* );
+extern void ppHRegUsage ( HRegUsage* );
extern void initHRegUsage ( HRegUsage* );
}
HRegRemap;
-extern void ppHRegRemap ( FILE*, HRegRemap* );
+extern void ppHRegRemap ( HRegRemap* );
extern void initHRegRemap ( HRegRemap* );
extern void addToHRegRemap ( HRegRemap*, HReg, HReg );
extern HReg lookupHRegRemap ( HRegRemap*, HReg );
HInstrArray;
extern HInstrArray* newHInstrArray ( void );
-extern void deleteHInstrArray ( HInstrArray* );
extern void addHInstr ( HInstrArray*, HInstr* );
/*---------------------------------------------------------------*/
#include "libjit_basictypes.h"
-#include "ir_defs.h"
+#include "libjit_ir.h"
+#include "libjit.h"
+
+#include "vex_util.h"
#include "host_regs.h"
#include "x86h_defs.h"
for (i = 0; i < env->n_vregmap; i++)
if (env->vregmap[i].ir_name == tmp)
return env->vregmap[i].vreg;
- panic("lookupIRTemp");
+ vpanic("lookupIRTemp");
}
static void addInstr ( ISelEnv* env, X86Instr* instr )
{
addHInstr(env->code, instr);
- ppX86Instr(stdout, instr);
- printf("\n");
+ ppX86Instr(instr);
+ vex_printf("\n");
}
static HReg newVRegI ( ISelEnv* env )
static X86Instr* mk_MOV_RR ( HReg src, HReg dst )
{
- assert(hregClass(src) == HRcInt);
- assert(hregClass(dst) == HRcInt);
+ vassert(hregClass(src) == HRcInt);
+ vassert(hregClass(dst) == HRcInt);
return X86Instr_Alu32R(Xalu_MOV, X86RMI_Reg(src), dst);
}
*/
static HReg iselIntExpr_R ( ISelEnv* env, IRExpr* e )
{
- assert(e);
- assert(typeOfIRExpr(env->type_env,e) == Ity_I32);
+ vassert(e);
+ vassert(typeOfIRExpr(env->type_env,e) == Ity_I32);
switch (e->tag) {
} /* switch (e->tag) */
/* We get here if no pattern matched. */
- ppIRExpr(stderr, e);
- panic("iselExprI: cannot reduce tree");
+ ppIRExpr(e);
+ vpanic("iselExprI: cannot reduce tree");
}
*/
static X86AMode* iselIntExpr_AMode ( ISelEnv* env, IRExpr* e )
{
- assert(e);
- assert(typeOfIRExpr(env->type_env,e) == Ity_I32);
+ vassert(e);
+ vassert(typeOfIRExpr(env->type_env,e) == Ity_I32);
/* Add32(expr1, Shl32(expr2, imm)) */
if (e->tag == Iex_Binop
static X86RMI* iselIntExpr_RMI ( ISelEnv* env, IRExpr* e )
{
- assert(e);
- assert(typeOfIRExpr(env->type_env,e) == Ity_I32);
+ vassert(e);
+ vassert(typeOfIRExpr(env->type_env,e) == Ity_I32);
/* special case: immediate */
if (e->tag == Iex_Const
static X86RI* iselIntExpr_RI ( ISelEnv* env, IRExpr* e )
{
- assert(e);
- assert(typeOfIRExpr(env->type_env,e) == Ity_I32);
+ vassert(e);
+ vassert(typeOfIRExpr(env->type_env,e) == Ity_I32);
/* special case: immediate */
if (e->tag == Iex_Const
void iselStmt ( ISelEnv* env, IRStmt* stmt )
{
- fprintf(stdout, "-- ");
- ppIRStmt(stdout, stmt);
- fprintf(stdout, "\n");
+ vex_printf("-- ");
+ ppIRStmt(stmt);
+ vex_printf("\n");
switch (stmt->tag) {
default: break;
}
- ppIRStmt(stderr, stmt);
- panic("iselStmt");
+ ppIRStmt(stmt);
+ vpanic("iselStmt");
}
void iselNext ( ISelEnv* env, IRNext* next )
{
- fprintf(stdout, "-- ");
- ppIRNext(stdout, next);
- fprintf(stdout, "\n");
+ vex_printf("-- ");
+ ppIRNext(next);
+ vex_printf("\n");
switch (next->tag) {
case Inx_UJump: {
- assert(next->Inx.UJump.dst->tag == Ico_U32);
+ vassert(next->Inx.UJump.dst->tag == Ico_U32);
addInstr(env, X86Instr_Alu32R(
Xalu_MOV,
X86RMI_Imm(next->Inx.UJump.dst->Ico.U32),
return;
}
default:
- ppIRNext(stderr, next);
- panic("iselNext");
+ ppIRNext(next);
+ vpanic("iselNext");
}
}
IRStmt* stmt;
/* Make up an initial environment to use. */
- ISelEnv* env = malloc(sizeof(ISelEnv));
+ ISelEnv* env = LibVEX_Alloc(sizeof(ISelEnv));
env->vreg_ctr = 0;
/* Set up output code array. */
/* Make up an IRTemp -> virtual HReg mapping. This doesn't
change as we go along. */
env->n_vregmap = bb->tyenv->map_used;
- env->vregmap = malloc(env->n_vregmap * sizeof(VRegMaplet));
+ env->vregmap = LibVEX_Alloc(env->n_vregmap * sizeof(VRegMaplet));
/* For each IR temporary, allocate a suitably-kinded virtual
register. */
env->vregmap[i].ir_name = bb->tyenv->map[i].name;
switch (bb->tyenv->map[i].type) {
case Ity_I32: hreg = mkHReg(i, HRcInt, True); break;
- default: panic("iselBB: IRTemp type");
+ default: vpanic("iselBB: IRTemp type");
}
env->vregmap[i].vreg = hreg;
}
/*---------------------------------------------------------------*/
#include "libjit_basictypes.h"
+#include "libjit.h"
+
+#include "vex_util.h"
#include "host_regs.h"
#include "x86h_defs.h"
/* --------- Registers. --------- */
-void ppHRegX86 ( FILE* f, HReg reg )
+void ppHRegX86 ( HReg reg )
{
Int r;
static Char* ireg32_names[8]
= { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi" };
/* Be generic for all virtual regs. */
if (hregIsVirtual(reg)) {
- ppHReg(f, reg);
+ ppHReg(reg);
return;
}
/* But specific for real regs. */
switch (hregClass(reg)) {
case HRcInt:
r = hregNumber(reg);
- assert(r >= 0 && r < 8);
- fprintf(f, "%s", ireg32_names[r]);
+ vassert(r >= 0 && r < 8);
+ vex_printf("%s", ireg32_names[r]);
return;
case HRcFloat:
r = hregNumber(reg);
- assert(r >= 0 && r < 6);
- fprintf(f, "%%fake%d", r);
+ vassert(r >= 0 && r < 6);
+ vex_printf("%%fake%d", r);
return;
case HRcVector:
- panic("ppHRegX86: real vector reg");
+ vpanic("ppHRegX86: real vector reg");
default:
- panic("ppHRegX86");
+ vpanic("ppHRegX86");
}
}
/* --------- X86AMode: memory address expressions. --------- */
X86AMode* X86AMode_IR ( UInt imm32, HReg reg ) {
- X86AMode* am = malloc(sizeof(X86AMode));
+ X86AMode* am = LibVEX_Alloc(sizeof(X86AMode));
am->tag = Xam_IR;
am->Xam.IR.imm = imm32;
am->Xam.IR.reg = reg;
}
X86AMode* X86AMode_IRRS ( UInt imm32, HReg base, HReg index, Int shift ) {
- X86AMode* am = malloc(sizeof(X86AMode));
+ X86AMode* am = LibVEX_Alloc(sizeof(X86AMode));
am->tag = Xam_IRRS;
am->Xam.IRRS.imm = imm32;
am->Xam.IRRS.base = base;
am->Xam.IRRS.index = index;
am->Xam.IRRS.shift = shift;
- assert(shift >= 0 && shift <= 3);
+ vassert(shift >= 0 && shift <= 3);
return am;
}
-void ppX86AMode ( FILE* f, X86AMode* am ) {
+void ppX86AMode ( X86AMode* am ) {
switch (am->tag) {
case Xam_IR:
- fprintf(f, "0x%x(", am->Xam.IR.imm);
- ppHRegX86(f, am->Xam.IR.reg);
- fprintf(f, ")");
+ vex_printf("0x%x(", am->Xam.IR.imm);
+ ppHRegX86(am->Xam.IR.reg);
+ vex_printf(")");
return;
case Xam_IRRS:
- fprintf(f, "0x%x(", am->Xam.IRRS.imm);
- ppHRegX86(f, am->Xam.IRRS.base);
- fprintf(f, ",");
- ppHRegX86(f, am->Xam.IRRS.index);
- fprintf(f, ",%d)", am->Xam.IRRS.shift);
+ vex_printf("0x%x(", am->Xam.IRRS.imm);
+ ppHRegX86(am->Xam.IRRS.base);
+ vex_printf(",");
+ ppHRegX86(am->Xam.IRRS.index);
+ vex_printf(",%d)", am->Xam.IRRS.shift);
return;
default:
- panic("ppX86AMode");
+ vpanic("ppX86AMode");
}
}
addHRegUse(u, HRmRead, am->Xam.IRRS.index);
return;
default:
- panic("addRegUsage_X86AMode");
+ vpanic("addRegUsage_X86AMode");
}
}
am->Xam.IRRS.index = lookupHRegRemap(m, am->Xam.IRRS.index);
return;
default:
- panic("mapRegs_X86AMode");
+ vpanic("mapRegs_X86AMode");
}
}
/* --------- Operand, which can be reg, immediate or memory. --------- */
X86RMI* X86RMI_Imm ( UInt imm32 ) {
- X86RMI* op = malloc(sizeof(X86RMI));
+ X86RMI* op = LibVEX_Alloc(sizeof(X86RMI));
op->tag = Xrmi_Imm;
op->Xrmi.Imm.imm32 = imm32;
return op;
}
X86RMI* X86RMI_Reg ( HReg reg ) {
- X86RMI* op = malloc(sizeof(X86RMI));
+ X86RMI* op = LibVEX_Alloc(sizeof(X86RMI));
op->tag = Xrmi_Reg;
op->Xrmi.Reg.reg = reg;
return op;
}
X86RMI* X86RMI_Mem ( X86AMode* am ) {
- X86RMI* op = malloc(sizeof(X86RMI));
+ X86RMI* op = LibVEX_Alloc(sizeof(X86RMI));
op->tag = Xrmi_Mem;
op->Xrmi.Mem.am = am;
return op;
}
-void ppX86RMI ( FILE* f, X86RMI* op ) {
+void ppX86RMI ( X86RMI* op ) {
switch (op->tag) {
case Xrmi_Imm:
- fprintf(f, "$0x%x", op->Xrmi.Imm.imm32);
+ vex_printf("$0x%x", op->Xrmi.Imm.imm32);
return;
case Xrmi_Reg:
- ppHRegX86(f, op->Xrmi.Reg.reg);
+ ppHRegX86(op->Xrmi.Reg.reg);
return;
case Xrmi_Mem:
- ppX86AMode(f, op->Xrmi.Mem.am);
+ ppX86AMode(op->Xrmi.Mem.am);
return;
default:
- panic("ppX86RMI");
+ vpanic("ppX86RMI");
}
}
addRegUsage_X86AMode(u, op->Xrmi.Mem.am);
return;
default:
- panic("addRegUsage_X86RMI");
+ vpanic("addRegUsage_X86RMI");
}
}
mapRegs_X86AMode(m, op->Xrmi.Mem.am);
return;
default:
- panic("mapRegs_X86RMI");
+ vpanic("mapRegs_X86RMI");
}
}
/* --------- Operand, which can be reg or immediate only. --------- */
X86RI* X86RI_Imm ( UInt imm32 ) {
- X86RI* op = malloc(sizeof(X86RI));
+ X86RI* op = LibVEX_Alloc(sizeof(X86RI));
op->tag = Xri_Imm;
op->Xri.Imm.imm32 = imm32;
return op;
}
X86RI* X86RI_Reg ( HReg reg ) {
- X86RI* op = malloc(sizeof(X86RI));
+ X86RI* op = LibVEX_Alloc(sizeof(X86RI));
op->tag = Xri_Reg;
op->Xri.Reg.reg = reg;
return op;
}
-void ppX86RI ( FILE* f, X86RI* op ) {
+void ppX86RI ( X86RI* op ) {
switch (op->tag) {
case Xri_Imm:
- fprintf(f, "$0x%x", op->Xri.Imm.imm32);
+ vex_printf("$0x%x", op->Xri.Imm.imm32);
return;
case Xri_Reg:
- ppHRegX86(f, op->Xri.Reg.reg);
+ ppHRegX86(op->Xri.Reg.reg);
return;
default:
- panic("ppX86RI");
+ vpanic("ppX86RI");
}
}
addHRegUse(u, HRmRead, op->Xri.Reg.reg);
return;
default:
- panic("addRegUsage_X86RI");
+ vpanic("addRegUsage_X86RI");
}
}
op->Xri.Reg.reg = lookupHRegRemap(m, op->Xri.Reg.reg);
return;
default:
- panic("mapRegs_X86RI");
+ vpanic("mapRegs_X86RI");
}
}
/* --------- Operand, which can be reg or memory only. --------- */
X86RM* X86RM_Reg ( HReg reg ) {
- X86RM* op = malloc(sizeof(X86RM));
+ X86RM* op = LibVEX_Alloc(sizeof(X86RM));
op->tag = Xrm_Reg;
op->Xrm.Reg.reg = reg;
return op;
}
X86RM* X86RM_Mem ( X86AMode* am ) {
- X86RM* op = malloc(sizeof(X86RM));
+ X86RM* op = LibVEX_Alloc(sizeof(X86RM));
op->tag = Xrm_Mem;
op->Xrm.Mem.am = am;
return op;
}
-void ppX86RM ( FILE* f, X86RM* op ) {
+void ppX86RM ( X86RM* op ) {
switch (op->tag) {
case Xrm_Mem:
- ppX86AMode(f, op->Xrm.Mem.am);
+ ppX86AMode(op->Xrm.Mem.am);
return;
case Xrm_Reg:
- ppHRegX86(f, op->Xrm.Reg.reg);
+ ppHRegX86(op->Xrm.Reg.reg);
return;
default:
- panic("ppX86RM");
+ vpanic("ppX86RM");
}
}
addHRegUse(u, mode, op->Xrm.Reg.reg);
return;
default:
- panic("addRegUsage_X86RM");
+ vpanic("addRegUsage_X86RM");
}
}
op->Xrm.Reg.reg = lookupHRegRemap(m, op->Xrm.Reg.reg);
return;
default:
- panic("mapRegs_X86RM");
+ vpanic("mapRegs_X86RM");
}
}
/* --------- Instructions. --------- */
-void ppX86AluOp ( FILE* f, X86AluOp op ) {
+void ppX86AluOp ( X86AluOp op ) {
Char* name;
switch (op) {
case Xalu_MOV: name = "mov"; break;
case Xalu_AND: name = "and"; break;
case Xalu_OR: name = "or"; break;
case Xalu_XOR: name = "xor"; break;
- default: panic("ppX86AluOp");
+ default: vpanic("ppX86AluOp");
}
- fprintf(f, "%s", name);
+ vex_printf("%s", name);
}
-void ppX86ShiftOp ( FILE* f, X86ShiftOp op ) {
+void ppX86ShiftOp ( X86ShiftOp op ) {
Char* name;
switch (op) {
case Xsh_SHL: name = "shl"; break;
case Xsh_SAR: name = "sar"; break;
case Xsh_ROL: name = "rol"; break;
case Xsh_ROR: name = "ror"; break;
- default: panic("ppX86ShiftOp");
+ default: vpanic("ppX86ShiftOp");
}
- fprintf(f, "%s", name);
+ vex_printf("%s", name);
}
X86Instr* X86Instr_Alu32R ( X86AluOp op, X86RMI* src, HReg dst ) {
- X86Instr* i = malloc(sizeof(X86Instr));
+ X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
i->tag = Xin_Alu32R;
i->Xin.Alu32R.op = op;
i->Xin.Alu32R.src = src;
}
X86Instr* X86Instr_Alu32M ( X86AluOp op, X86RI* src, X86AMode* dst ) {
- X86Instr* i = malloc(sizeof(X86Instr));
+ X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
i->tag = Xin_Alu32M;
i->Xin.Alu32M.op = op;
i->Xin.Alu32M.src = src;
}
X86Instr* X86Instr_Sh32 ( X86ShiftOp op, UInt src, X86RM* dst ) {
- X86Instr* i = malloc(sizeof(X86Instr));
+ X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
i->tag = Xin_Sh32;
i->Xin.Sh32.op = op;
i->Xin.Sh32.src = src;
}
X86Instr* X86Instr_RET ( void ) {
- X86Instr* i = malloc(sizeof(X86Instr));
+ X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
i->tag = Xin_RET;
return i;
}
-void ppX86Instr ( FILE* f, X86Instr* i ) {
+void ppX86Instr ( X86Instr* i ) {
switch (i->tag) {
case Xin_Alu32R:
- ppX86AluOp(f, i->Xin.Alu32R.op);
- fprintf(f, "l ");
- ppX86RMI(f, i->Xin.Alu32R.src);
- fprintf(f, ",");
- ppHRegX86(f, i->Xin.Alu32R.dst);
+ ppX86AluOp(i->Xin.Alu32R.op);
+ vex_printf("l ");
+ ppX86RMI(i->Xin.Alu32R.src);
+ vex_printf(",");
+ ppHRegX86(i->Xin.Alu32R.dst);
return;
case Xin_Alu32M:
- ppX86AluOp(f, i->Xin.Alu32M.op);
- fprintf(f, "l ");
- ppX86RI(f, i->Xin.Alu32M.src);
- fprintf(f, ",");
- ppX86AMode(f, i->Xin.Alu32M.dst);
+ ppX86AluOp(i->Xin.Alu32M.op);
+ vex_printf("l ");
+ ppX86RI(i->Xin.Alu32M.src);
+ vex_printf(",");
+ ppX86AMode(i->Xin.Alu32M.dst);
return;
case Xin_Sh32:
- ppX86ShiftOp(f, i->Xin.Sh32.op);
- fprintf(f, "l ");
+ ppX86ShiftOp(i->Xin.Sh32.op);
+ vex_printf("l ");
if (i->Xin.Sh32.src == 0)
- fprintf(f, " %%cl,");
+ vex_printf(" %%cl,");
else
- fprintf(f, " $%d,", i->Xin.Sh32.src);
- ppX86RM(f, i->Xin.Sh32.dst);
+ vex_printf(" $%d,", i->Xin.Sh32.src);
+ ppX86RM(i->Xin.Sh32.dst);
return;
case Xin_RET:
- fprintf(f, "ret");
+ vex_printf("ret");
return;
default:
- panic("ppX86Instr");
+ vpanic("ppX86Instr");
}
}
addHRegUse(u, HRmRead, hregX86_EAX());
return;
default:
- ppX86Instr(stderr, i);
- panic("getRegUsage_X86Instr");
+ ppX86Instr(i);
+ vpanic("getRegUsage_X86Instr");
}
}
case Xin_RET:
return;
default:
- ppX86Instr(stderr, i);
- panic("mapRegs_X86Instr");
+ ppX86Instr(i);
+ vpanic("mapRegs_X86Instr");
}
}
X86Instr* genSpill_X86 ( HReg rreg, Int offset )
{
- assert(!hregIsVirtual(rreg));
+ vassert(!hregIsVirtual(rreg));
switch (hregClass(rreg)) {
case HRcInt:
return
X86AMode_IR(offset + 0x1000,
hregX86_EBP()));
default:
- ppHRegClass(stderr, hregClass(rreg));
- panic("genSpill_X86: unimplemented regclass");
+ ppHRegClass(hregClass(rreg));
+ vpanic("genSpill_X86: unimplemented regclass");
}
}
X86Instr* genReload_X86 ( HReg rreg, Int offset )
{
- assert(!hregIsVirtual(rreg));
+ vassert(!hregIsVirtual(rreg));
switch (hregClass(rreg)) {
case HRcInt:
return
hregX86_EBP())),
rreg );
default:
- ppHRegClass(stderr, hregClass(rreg));
- panic("genReload_X86: unimplemented regclass");
+ ppHRegClass(hregClass(rreg));
+ vpanic("genReload_X86: unimplemented regclass");
}
}
+
+/*---------------------------------------------------------------*/
+/*--- end x86h_defs.c ---*/
+/*---------------------------------------------------------------*/
6 real float regs, and 0 real vector regs.
*/
-extern void ppHRegX86 ( FILE*, HReg );
+extern void ppHRegX86 ( HReg );
extern HReg hregX86_EAX ( void );
extern HReg hregX86_EBX ( void );
extern X86AMode* X86AMode_IR ( UInt, HReg );
extern X86AMode* X86AMode_IRRS ( UInt, HReg, HReg, Int );
-extern void ppX86AMode ( FILE*, X86AMode* );
+extern void ppX86AMode ( X86AMode* );
/* --------- Operand, which can be reg, immediate or memory. --------- */
extern X86RMI* X86RMI_Reg ( HReg );
extern X86RMI* X86RMI_Mem ( X86AMode* );
-extern void ppX86RMI ( FILE*, X86RMI* );
+extern void ppX86RMI ( X86RMI* );
/* --------- Operand, which can be reg or immediate only. --------- */
extern X86RI* X86RI_Imm ( UInt );
extern X86RI* X86RI_Reg ( HReg );
-extern void ppX86RI ( FILE*, X86RI* );
+extern void ppX86RI ( X86RI* );
/* --------- Operand, which can be reg or memory only. --------- */
extern X86RM* X86RM_Reg ( HReg );
extern X86RM* X86RM_Mem ( X86AMode* );
-extern void ppX86RM ( FILE*, X86RM* );
+extern void ppX86RM ( X86RM* );
/* --------- Instructions. --------- */
}
X86AluOp;
-extern void ppX86AluOp ( FILE*, X86AluOp );
+extern void ppX86AluOp ( X86AluOp );
/* --------- */
}
X86ShiftOp;
-extern void ppX86ShiftOp ( FILE*, X86ShiftOp );
+extern void ppX86ShiftOp ( X86ShiftOp );
/* --------- */
extern X86Instr* X86Instr_Sh32 ( X86ShiftOp, UInt, X86RM* );
extern X86Instr* X86Instr_RET ( void );
-extern void ppX86Instr ( FILE*, X86Instr* );
+extern void ppX86Instr ( X86Instr* );
/* Five functions that insulate the register allocator from details
of the underlying instruction set. */
/*---------------------------------------------------------------*/
#include "libjit_basictypes.h"
-#include "ir_defs.h"
+#include "libjit_ir.h"
+#include "libjit.h"
+#include "vex_util.h"
/*---------------------------------------------------------------*/
/*--- Printing the IR ---*/
/*---------------------------------------------------------------*/
-void ppIRType ( FILE* f, IRType ty )
+void ppIRType ( IRType ty )
{
switch (ty) {
- case Ity_Bit: fprintf(f, "Bit"); break;
- case Ity_I8: fprintf(f, "I8"); break;
- case Ity_I16: fprintf(f, "I16"); break;
- case Ity_I32: fprintf(f, "I32"); break;
- case Ity_I64: fprintf(f, "I64"); break;
- default: panic("ppIRType");
+ case Ity_Bit: vex_printf( "Bit"); break;
+ case Ity_I8: vex_printf( "I8"); break;
+ case Ity_I16: vex_printf( "I16"); break;
+ case Ity_I32: vex_printf( "I32"); break;
+ case Ity_I64: vex_printf( "I64"); break;
+ default: vpanic("ppIRType");
}
}
-void ppIRConst ( FILE* f, IRConst* con )
+void ppIRConst ( IRConst* con )
{
switch (con->tag) {
- case Ico_U8: fprintf(f, "0x%x", (UInt)(con->Ico.U8)); break;
- case Ico_U16: fprintf(f, "0x%x", (UInt)(con->Ico.U16)); break;
- case Ico_U32: fprintf(f, "0x%x", (UInt)(con->Ico.U32)); break;
- case Ico_U64: fprintf(f, "0x%llx", (ULong)(con->Ico.U64)); break;
- default: panic("ppIRConst");
+ case Ico_U8: vex_printf( "0x%x", (UInt)(con->Ico.U8)); break;
+ case Ico_U16: vex_printf( "0x%x", (UInt)(con->Ico.U16)); break;
+ case Ico_U32: vex_printf( "0x%x", (UInt)(con->Ico.U32)); break;
+ case Ico_U64: vex_printf( "0x%llx", (ULong)(con->Ico.U64)); break;
+ default: vpanic("ppIRConst");
}
}
-void ppIRTemp ( FILE* f, IRTemp tmp )
+void ppIRTemp ( IRTemp tmp )
{
- fprintf(f, "t%d", tmp);
+ vex_printf( "t%d", tmp);
}
-void ppIROp ( FILE* f, IROp op )
+void ppIROp ( IROp op )
{
switch (op) {
- case Iop_Add32: fprintf(f, "Add32"); break;
- case Iop_Sub32: fprintf(f, "Sub32"); break;
- case Iop_Mul32: fprintf(f, "Mul32"); break;
- case Iop_Or32: fprintf(f, "Or32"); break;
- case Iop_And32: fprintf(f, "And32"); break;
- case Iop_Xor32: fprintf(f, "Xor32"); break;
- case Iop_Shl32: fprintf(f, "Shl32"); break;
- case Iop_Shr32: fprintf(f, "Shr32"); break;
- case Iop_Sar32: fprintf(f, "Sar32"); break;
- case Iop_Not32: fprintf(f, "Not32"); break;
- case Iop_Neg32: fprintf(f, "Neg32"); break;
- default: panic("ppIROp");
+ case Iop_Add32: vex_printf( "Add32"); break;
+ case Iop_Sub32: vex_printf( "Sub32"); break;
+ case Iop_Mul32: vex_printf( "Mul32"); break;
+ case Iop_Or32: vex_printf( "Or32"); break;
+ case Iop_And32: vex_printf( "And32"); break;
+ case Iop_Xor32: vex_printf( "Xor32"); break;
+ case Iop_Shl32: vex_printf( "Shl32"); break;
+ case Iop_Shr32: vex_printf( "Shr32"); break;
+ case Iop_Sar32: vex_printf( "Sar32"); break;
+ case Iop_Not32: vex_printf( "Not32"); break;
+ case Iop_Neg32: vex_printf( "Neg32"); break;
+ default: vpanic("ppIROp");
}
}
-void ppIRExpr ( FILE* f, IRExpr* e )
+void ppIRExpr ( IRExpr* e )
{
switch (e->tag) {
case Iex_Get:
- fprintf(f, "GET(%d,%d)", e->Iex.Get.offset, e->Iex.Get.size);
+ vex_printf( "GET(%d,%d)", e->Iex.Get.offset, e->Iex.Get.size);
break;
case Iex_Tmp:
- ppIRTemp(f, e->Iex.Tmp.tmp);
+ ppIRTemp(e->Iex.Tmp.tmp);
break;
case Iex_Binop:
- ppIROp(f, e->Iex.Binop.op);
- fprintf(f, "(");
- ppIRExpr(f, e->Iex.Binop.arg1);
- fprintf(f, ",");
- ppIRExpr(f, e->Iex.Binop.arg2);
- fprintf(f, ")");
+ ppIROp(e->Iex.Binop.op);
+ vex_printf( "(" );
+ ppIRExpr(e->Iex.Binop.arg1);
+ vex_printf( "," );
+ ppIRExpr(e->Iex.Binop.arg2);
+ vex_printf( ")" );
break;
case Iex_Unop:
- ppIROp(f, e->Iex.Unop.op);
- fprintf(f, "(");
- ppIRExpr(f, e->Iex.Unop.arg);
- fprintf(f, ")");
+ ppIROp(e->Iex.Unop.op);
+ vex_printf( "(" );
+ ppIRExpr(e->Iex.Unop.arg);
+ vex_printf( ")" );
break;
case Iex_LDle:
- fprintf(f, "LDle<");
- ppIRType(f, e->Iex.LDle.ty);
- fprintf(f,">(");
- ppIRExpr(f, e->Iex.LDle.addr);
- fprintf(f,")");
+ vex_printf( "LDle<" );
+ ppIRType(e->Iex.LDle.ty);
+ vex_printf( ">(" );
+ ppIRExpr(e->Iex.LDle.addr);
+ vex_printf( ")" );
break;
case Iex_Const:
- ppIRConst(f, e->Iex.Const.con);
+ ppIRConst(e->Iex.Const.con);
break;
default:
- panic("ppIExpr");
+ vpanic("ppIExpr");
}
}
-void ppIRStmt ( FILE* f, IRStmt* s )
+void ppIRStmt ( IRStmt* s )
{
switch (s->tag) {
case Ist_Put:
- fprintf(f, "Put(%d,%d) = ", s->Ist.Put.offset, s->Ist.Put.size);
- ppIRExpr(f, s->Ist.Put.expr);
+ vex_printf( "Put(%d,%d) = ", s->Ist.Put.offset, s->Ist.Put.size);
+ ppIRExpr(s->Ist.Put.expr);
break;
case Ist_Tmp:
- ppIRTemp(f, s->Ist.Tmp.tmp);
- fprintf(f," = ");
- ppIRExpr(f, s->Ist.Tmp.expr);
+ ppIRTemp(s->Ist.Tmp.tmp);
+ vex_printf( " = " );
+ ppIRExpr(s->Ist.Tmp.expr);
break;
case Ist_STle:
- fprintf(f, "STle(");
- ppIRExpr(f, s->Ist.STle.addr);
- fprintf(f, ") = ");
- ppIRExpr(f, s->Ist.STle.data);
+ vex_printf( "STle(");
+ ppIRExpr(s->Ist.STle.addr);
+ vex_printf( ") = ");
+ ppIRExpr(s->Ist.STle.data);
break;
default:
- panic("ppIRStmt");
+ vpanic("ppIRStmt");
}
}
-void ppIRNext ( FILE* f, IRNext* nx )
+void ppIRNext ( IRNext* nx )
{
switch (nx->tag) {
case Inx_UJump:
- fprintf(f, "UJump ");
- ppIRConst(f, nx->Inx.UJump.dst);
+ vex_printf( "UJump ");
+ ppIRConst(nx->Inx.UJump.dst);
break;
case Inx_CJump01:
- fprintf(f,"CJump01 (");
- ppIRExpr(f, nx->Inx.CJump01.cond);
- fprintf(f, ") ");
- ppIRConst(f, nx->Inx.CJump01.dst0);
- fprintf(f, " ");
- ppIRConst(f, nx->Inx.CJump01.dst1);
+ vex_printf( "CJump01 (" );
+ ppIRExpr(nx->Inx.CJump01.cond);
+ vex_printf( ") ");
+ ppIRConst(nx->Inx.CJump01.dst0);
+ vex_printf( " ");
+ ppIRConst(nx->Inx.CJump01.dst1);
break;
case Inx_IJump:
- fprintf(f, "IJump ");
- ppIRExpr(f, nx->Inx.IJump.dst);
+ vex_printf( "IJump ");
+ ppIRExpr(nx->Inx.IJump.dst);
break;
default:
- panic("ppIRNext");
+ vpanic("ppIRNext");
}
}
-void ppIRTypeEnv ( FILE* f, IRTypeEnv* env ) {
+void ppIRTypeEnv ( IRTypeEnv* env ) {
UInt i;
for (i = 0; i < env->map_used; i++) {
if (i % 8 == 0)
- fprintf(f, " ");
- ppIRTemp(f, env->map[i].name);
- fprintf(f, ":");
- ppIRType(f, env->map[i].type);
+ vex_printf( " ");
+ ppIRTemp(env->map[i].name);
+ vex_printf( ":");
+ ppIRType(env->map[i].type);
if (i % 8 == 7)
- fprintf(f, "\n");
+ vex_printf( "\n");
else
- fprintf(f, " ");
+ vex_printf( " ");
}
if (env->map_used > 0 && env->map_used % 8 != 7)
- fprintf(f, "\n");
+ vex_printf( "\n");
}
-void ppIRBB ( FILE* f, IRBB* bb )
+void ppIRBB ( IRBB* bb )
{
IRStmt* s;
- ppIRTypeEnv(f, bb->tyenv);
+ ppIRTypeEnv(bb->tyenv);
for (s = bb->stmts; s; s = s->link) {
- fprintf(f, " ");
- ppIRStmt(f, s);
- fprintf(f, "\n");
+ vex_printf( " ");
+ ppIRStmt(s);
+ vex_printf( "\n");
}
- fprintf(f, " ");
- ppIRNext(f, bb->next);
- fprintf(f, "\n");
+ vex_printf( " ");
+ ppIRNext(bb->next);
+ vex_printf( "\n");
}
IRConst* IRConst_U8 ( UChar u8 )
{
- IRConst* c = malloc(sizeof(IRConst));
+ IRConst* c = LibVEX_Alloc(sizeof(IRConst));
c->tag = Ico_U8;
c->Ico.U8 = u8;
return c;
}
IRConst* IRConst_U16 ( UShort u16 )
{
- IRConst* c = malloc(sizeof(IRConst));
+ IRConst* c = LibVEX_Alloc(sizeof(IRConst));
c->tag = Ico_U16;
c->Ico.U16 = u16;
return c;
}
IRConst* IRConst_U32 ( UInt u32 )
{
- IRConst* c = malloc(sizeof(IRConst));
+ IRConst* c = LibVEX_Alloc(sizeof(IRConst));
c->tag = Ico_U32;
c->Ico.U32 = u32;
return c;
}
IRConst* IRConst_U64 ( ULong u64 )
{
- IRConst* c = malloc(sizeof(IRConst));
+ IRConst* c = LibVEX_Alloc(sizeof(IRConst));
c->tag = Ico_U64;
c->Ico.U64 = u64;
return c;
/* Constructors -- IRExpr */
IRExpr* IRExpr_Get ( Int off, Int sz ) {
- IRExpr* e = malloc(sizeof(IRExpr));
+ IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
e->tag = Iex_Get;
e->Iex.Get.offset = off;
e->Iex.Get.size = sz;
return e;
}
IRExpr* IRExpr_Tmp ( IRTemp tmp ) {
- IRExpr* e = malloc(sizeof(IRExpr));
+ IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
e->tag = Iex_Tmp;
e->Iex.Tmp.tmp = tmp;
return e;
}
IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
- IRExpr* e = malloc(sizeof(IRExpr));
+ IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
e->tag = Iex_Binop;
e->Iex.Binop.op = op;
e->Iex.Binop.arg1 = arg1;
return e;
}
IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ) {
- IRExpr* e = malloc(sizeof(IRExpr));
+ IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
e->tag = Iex_Unop;
e->Iex.Unop.op = op;
e->Iex.Unop.arg = arg;
return e;
}
IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr ) {
- IRExpr* e = malloc(sizeof(IRExpr));
+ IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
e->tag = Iex_LDle;
e->Iex.LDle.ty = ty;
e->Iex.LDle.addr = addr;
return e;
}
IRExpr* IRExpr_Const ( IRConst* con ) {
- IRExpr* e = malloc(sizeof(IRExpr));
+ IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
e->tag = Iex_Const;
e->Iex.Const.con = con;
return e;
/* Constructors -- IRStmt */
IRStmt* IRStmt_Put ( Int off, Int sz, IRExpr* value ) {
- IRStmt* s = malloc(sizeof(IRStmt));
+ IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
s->tag = Ist_Put;
s->link = NULL;
s->Ist.Put.offset = off;
return s;
}
IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* expr ) {
- IRStmt* s = malloc(sizeof(IRStmt));
+ IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
s->tag = Ist_Tmp;
s->link = NULL;
s->Ist.Tmp.tmp = tmp;
return s;
}
IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* value ) {
- IRStmt* s = malloc(sizeof(IRStmt));
+ IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
s->tag = Ist_STle;
s->link = NULL;
s->Ist.STle.addr = addr;
/* Constructors -- IRNext */
IRNext* IRNext_UJump ( IRConst* dst ) {
- IRNext* nx = malloc(sizeof(IRNext));
+ IRNext* nx = LibVEX_Alloc(sizeof(IRNext));
nx->tag = Inx_UJump;
nx->Inx.UJump.dst = dst;
return nx;
/* Constructors -- IRBB */
IRBB* mk_IRBB ( IRTypeEnv* env, IRStmt* stmts, IRNext* next ) {
- IRBB* bb = malloc(sizeof(IRBB));
+ IRBB* bb = LibVEX_Alloc(sizeof(IRBB));
bb->tyenv = env;
bb->stmts = stmts;
bb->next = next;
IRTypeEnv* newIRTypeEnv ( void )
{
- IRTypeEnv* env = malloc(sizeof(IRTypeEnv));
+ IRTypeEnv* env = LibVEX_Alloc(sizeof(IRTypeEnv));
env->map = NULL;
env->map_size = 0;
env->map_used = 0;
void addToIRTypeEnv ( IRTypeEnv* env, IRTemp tmp, IRType ty )
{
- assert(env);
- assert(env->map_used >= 0);
- assert(env->map_size >= 0);
- assert(env->map_used <= env->map_size);
+ vassert(env);
+ vassert(env->map_used >= 0);
+ vassert(env->map_size >= 0);
+ vassert(env->map_used <= env->map_size);
if (env->map_used < env->map_size) {
env->map[env->map_used].name = tmp;
env->map[env->map_used].type = ty;
} else {
Int i;
Int new_size = env->map_size==0 ? 8 : 2*env->map_size;
- IRTypeEnvMaplet* new_map = malloc(new_size * sizeof(IRTypeEnvMaplet));
+ IRTypeEnvMaplet* new_map
+ = LibVEX_Alloc(new_size * sizeof(IRTypeEnvMaplet));
for (i = 0; i < env->map_used; i++)
new_map[i] = env->map[i];
env->map = new_map;
for (i = 0; i < env->map_used; i++)
if (env->map[i].name == tmp)
return env->map[i].type;
- panic("lookupIRTypeEnv");
+ vpanic("lookupIRTypeEnv");
}
case Ico_U16: return Ity_I16;
case Ico_U32: return Ity_I32;
case Ico_U64: return Ity_I64;
- default: panic("typeOfIRExpr:Iex_Const");
+ default: vpanic("typeOfIRExpr:Iex_Const");
}
break;
case Iex_Binop:
default:
break;
}
- ppIRExpr(stderr,e);
- panic("typeOfIRExpr");
+ ppIRExpr(e);
+ vpanic("typeOfIRExpr");
}
--- /dev/null
+
+/*---------------------------------------------------------------*/
+/*--- ---*/
+/*--- This file (jit_globals.c) is ---*/
+/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
+/*--- ---*/
+/*---------------------------------------------------------------*/
+
+#include "libjit_basictypes.h"
+
+#include "vex_util.h"
+
+
+/* Global settings for the VEX library. These are the
+ only library-wide globals. */
+
+/* Are we started yet? */
+Bool vex_initdone = False;
+
+/* failure exit function */
+void (*vex_failure_exit) ( void ) = NULL;
+
+/* logging output function */
+void (*vex_log_bytes) ( Char*, Int nbytes ) = NULL;
+
+/* debug paranoia level */
+Int vex_debuglevel = 0;
+
+/* verbosity level */
+Int vex_verbosity = 0;
+
+/* Are we supporting valgrind checking? */
+Bool vex_valgrind_support = False;
+
+/* Max # guest insns per bb */
+Int vex_guest_insns_per_bb = 0;
+
+
+
+/*---------------------------------------------------------------*/
+/*--- end jit_globals.c ---*/
+/*---------------------------------------------------------------*/
--- /dev/null
+
+/*---------------------------------------------------------------*/
+/*--- ---*/
+/*--- This file (jit_globals.h) is ---*/
+/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
+/*--- ---*/
+/*---------------------------------------------------------------*/
+
+#ifndef __JIT_GLOBALS_H
+#define __JIT_GLOBALS_H
+
+#include "libjit_basictypes.h"
+
+
+/* Global settings for the JIT library. These are the
+ only library-wide globals. */
+
+/* Are we started yet? */
+extern Bool vex_initdone;
+
+/* failure exit function */
+extern void (*vex_failure_exit) ( void );
+
+/* logging output function */
+extern void (*vex_log_bytes) ( Char*, Int nbytes );
+
+/* debug paranoia level */
+extern Int vex_debuglevel;
+
+/* verbosity level */
+extern Int vex_verbosity;
+
+/* Are we supporting valgrind checking? */
+extern Bool vex_valgrind_support;
+
+/* Max # guest insns per bb */
+extern Int vex_guest_insns_per_bb;
+
+
+#endif /* ndef __JIT_GLOBALS_H */
+
+/*---------------------------------------------------------------*/
+/*--- end jit_globals.h ---*/
+/*---------------------------------------------------------------*/
--- /dev/null
+
+/*---------------------------------------------------------------*/
+/*--- ---*/
+/*--- This file (jit_main.c) is ---*/
+/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
+/*--- ---*/
+/*---------------------------------------------------------------*/
+
+#include "libjit.h"
+#include "jit_globals.h"
+#include "vex_util.h"
+
+
+/* This file contains the top level interface to the library. */
+
+/* --------- Initialise the library. --------- */
+
+/* Exported to library client. */
+
+void LibJIT_Init (
+ /* failure exit function */
+ void (*failure_exit) ( void ),
+ /* logging output function */
+ void (*log_bytes) ( Char*, Int nbytes ),
+ /* debug paranoia level */
+ Int debuglevel,
+ /* verbosity level */
+ Int verbosity,
+ /* Are we supporting valgrind checking? */
+ Bool valgrind_support,
+ /* Max # guest insns per bb */
+ Int guest_insns_per_bb
+)
+{
+ vassert(!vex_initdone);
+ vassert(failure_exit);
+ vex_failure_exit = failure_exit;
+ vassert(log_bytes);
+ vex_log_bytes = log_bytes;
+ vassert(debuglevel >= 0);
+ vex_debuglevel = debuglevel;
+ vassert(verbosity >= 0);
+ vex_verbosity = verbosity;
+ vex_valgrind_support = valgrind_support;
+ vassert(guest_insns_per_bb >= 1 && guest_insns_per_bb <= 100);
+ vex_guest_insns_per_bb = guest_insns_per_bb;
+ vex_initdone = True;
+}
+
+
+/* --------- Make a translation. --------- */
+
+/* Exported to library client. */
+
+TranslateResult LibJIT_Translate (
+ /* The instruction sets we are translating from and to. */
+ InsnSet iset_guest,
+ InsnSet iset_host,
+ /* IN: the block to translate, and its guest address. */
+ Char* guest_bytes,
+ Addr64 guest_bytes_addr,
+ /* OUT: the number of bytes actually read */
+ Int* guest_bytes_read,
+ /* IN: a place to put the resulting code, and its size */
+ Char* host_bytes,
+ Int host_bytes_size,
+ /* OUT: how much of the output area is used. */
+ Int* host_bytes_used,
+ /* IN: optionally, an instrumentation function. */
+ IRBB (*instrument) ( IRBB* ),
+ /* IN: optionally, an access check function for guest code. */
+ Bool (*byte_accessible) ( Addr64 )
+)
+{
+ vassert(vex_initdone);
+ LibJIT_Clear(False);
+ return TransOK;
+}
+
+
+
+/*---------------------------------------------------------------*/
+/*--- end jit_main.c ---*/
+/*---------------------------------------------------------------*/
--- /dev/null
+
+/*---------------------------------------------------------------*/
+/*--- ---*/
+/*--- This file (vex_util.c) is ---*/
+/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
+/*--- ---*/
+/*---------------------------------------------------------------*/
+
+#include "libjit_basictypes.h"
+#include "jit_globals.h"
+#include "vex_util.h"
+
+
+/*---------------------------------------------------------*/
+/*--- Storage ---*/
+/*---------------------------------------------------------*/
+
+#define N_STORAGE_BYTES 10000
+
+static Char storage[N_STORAGE_BYTES];
+static Int storage_used = 0;
+
+/* Exported to library client. */
+
+void* LibVEX_Alloc ( Int nbytes )
+{
+ vassert(vex_initdone);
+ vassert(nbytes > 0);
+ nbytes = (nbytes + 7) & ~8;
+ if (storage_used + nbytes > N_STORAGE_BYTES)
+ vpanic("VEX storage exhausted.\n"
+ "Increase N_STORAGE_BYTES and recompile.");
+ storage_used += nbytes;
+ return (void*)(&storage[storage_used - nbytes]);
+}
+
+/* Exported to library client. */
+
+void LibJIT_Clear ( void )
+{
+ vassert(vex_initdone);
+ storage_used = 0;
+}
+
+
+
+/*---------------------------------------------------------*/
+/*--- Bombing out ---*/
+/*---------------------------------------------------------*/
+
+__attribute__ ((noreturn))
+void vex_assert_fail ( const Char* expr,
+ const Char* file, Int line, const Char* fn )
+{
+ vex_printf( "\nvex: %s:%d (%s): Assertion `%s' failed.\n",
+ file, line, fn, expr );
+ (*vex_failure_exit)();
+}
+
+__attribute__ ((noreturn))
+void panic ( Char* str )
+{
+ vex_printf("\nvex: the `impossible' happened:\n %s\n", str);
+ (*vex_failure_exit)();
+}
+
+
+/*---------------------------------------------------------*/
+/*--- vex_printf ---*/
+/*---------------------------------------------------------*/
+
+/* This should be the only <...> include in the entire VEX library.
+ New code for vex_util.c should go above this point. */
+#include <stdarg.h>
+
+/* ---------------------------------------------------------------------
+ printf implementation. The key function, vg_vprintf(), emits chars
+ into a caller-supplied function. Distantly derived from:
+
+ vprintf replacement for Checker.
+ Copyright 1993, 1994, 1995 Tristan Gingold
+ Written September 1993 Tristan Gingold
+ Tristan Gingold, 8 rue Parmentier, F-91120 PALAISEAU, FRANCE
+
+ (Checker itself was GPL'd.)
+ ------------------------------------------------------------------ */
+
+static Char vex_toupper ( Char c )
+{
+ if (c >= 'a' && c <= 'z')
+ return c + ('A' - 'a');
+ else
+ return c;
+}
+
+static Int vex_strlen ( const Char* str )
+{
+ Int i = 0;
+ while (str[i] != 0) i++;
+ return i;
+}
+
+
+/* Some flags. */
+#define VG_MSG_SIGNED 1 /* The value is signed. */
+#define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */
+#define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */
+#define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */
+#define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */
+
+/* Copy a string into the buffer. */
+static UInt
+myvprintf_str ( void(*send)(Char), Int flags, Int width, Char* str,
+ Bool capitalise )
+{
+# define MAYBE_TOUPPER(ch) (capitalise ? vex_toupper(ch) : (ch))
+ UInt ret = 0;
+ Int i, extra;
+ Int len = vex_strlen(str);
+
+ if (width == 0) {
+ ret += len;
+ for (i = 0; i < len; i++)
+ send(MAYBE_TOUPPER(str[i]));
+ return ret;
+ }
+
+ if (len > width) {
+ ret += width;
+ for (i = 0; i < width; i++)
+ send(MAYBE_TOUPPER(str[i]));
+ return ret;
+ }
+
+ extra = width - len;
+ if (flags & VG_MSG_LJUSTIFY) {
+ ret += extra;
+ for (i = 0; i < extra; i++)
+ send(' ');
+ }
+ ret += len;
+ for (i = 0; i < len; i++)
+ send(MAYBE_TOUPPER(str[i]));
+ if (!(flags & VG_MSG_LJUSTIFY)) {
+ ret += extra;
+ for (i = 0; i < extra; i++)
+ send(' ');
+ }
+
+# undef MAYBE_TOUPPER
+
+ return ret;
+}
+
+/* Write P into the buffer according to these args:
+ * If SIGN is true, p is a signed.
+ * BASE is the base.
+ * If WITH_ZERO is true, '0' must be added.
+ * WIDTH is the width of the field.
+ */
+static UInt
+myvprintf_int64 ( void(*send)(Char), Int flags, Int base, Int width, ULong p)
+{
+ Char buf[40];
+ Int ind = 0;
+ Int i, nc = 0;
+ Bool neg = False;
+ Char *digits = "0123456789ABCDEF";
+ UInt ret = 0;
+
+ if (base < 2 || base > 16)
+ return ret;
+
+ if ((flags & VG_MSG_SIGNED) && (Long)p < 0) {
+ p = - (Long)p;
+ neg = True;
+ }
+
+ if (p == 0)
+ buf[ind++] = '0';
+ else {
+ while (p > 0) {
+ if (flags & VG_MSG_COMMA && 10 == base &&
+ 0 == (ind-nc) % 3 && 0 != ind)
+ {
+ buf[ind++] = ',';
+ nc++;
+ }
+ buf[ind++] = digits[p % base];
+ p /= base;
+ }
+ }
+
+ if (neg)
+ buf[ind++] = '-';
+
+ if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
+ for(; ind < width; ind++) {
+ vassert(ind < 39);
+ buf[ind] = (flags & VG_MSG_ZJUSTIFY) ? '0': ' ';
+ }
+ }
+
+ /* Reverse copy to buffer. */
+ ret += ind;
+ for (i = ind -1; i >= 0; i--) {
+ send(buf[i]);
+ }
+ if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
+ for(; ind < width; ind++) {
+ ret++;
+ send(' '); // Never pad with zeroes on RHS -- changes the value!
+ }
+ }
+ return ret;
+}
+
+
+/* A simple vprintf(). */
+static
+UInt vprintf_wrk ( void(*send)(Char), const Char *format, va_list vargs )
+{
+ UInt ret = 0;
+ int i;
+ int flags;
+ int width;
+ Bool is_long;
+
+ /* We assume that vargs has already been initialised by the
+ caller, using va_start, and that the caller will similarly
+ clean up with va_end.
+ */
+
+ for (i = 0; format[i] != 0; i++) {
+ if (format[i] != '%') {
+ send(format[i]);
+ ret++;
+ continue;
+ }
+ i++;
+ /* A '%' has been found. Ignore a trailing %. */
+ if (format[i] == 0)
+ break;
+ if (format[i] == '%') {
+ /* `%%' is replaced by `%'. */
+ send('%');
+ ret++;
+ continue;
+ }
+ flags = 0;
+ is_long = False;
+ width = 0; /* length of the field. */
+ if (format[i] == '(') {
+ flags |= VG_MSG_PAREN;
+ i++;
+ }
+ /* If ',' follows '%', commas will be inserted. */
+ if (format[i] == ',') {
+ flags |= VG_MSG_COMMA;
+ i++;
+ }
+ /* If '-' follows '%', justify on the left. */
+ if (format[i] == '-') {
+ flags |= VG_MSG_LJUSTIFY;
+ i++;
+ }
+ /* If '0' follows '%', pads will be inserted. */
+ if (format[i] == '0') {
+ flags |= VG_MSG_ZJUSTIFY;
+ i++;
+ }
+ /* Compute the field length. */
+ while (format[i] >= '0' && format[i] <= '9') {
+ width *= 10;
+ width += format[i++] - '0';
+ }
+ while (format[i] == 'l') {
+ i++;
+ is_long = True;
+ }
+
+ switch (format[i]) {
+ case 'd': /* %d */
+ flags |= VG_MSG_SIGNED;
+ if (is_long)
+ ret += myvprintf_int64(send, flags, 10, width,
+ (ULong)(va_arg (vargs, Long)));
+ else
+ ret += myvprintf_int64(send, flags, 10, width,
+ (ULong)(va_arg (vargs, Int)));
+ break;
+ case 'u': /* %u */
+ if (is_long)
+ ret += myvprintf_int64(send, flags, 10, width,
+ (ULong)(va_arg (vargs, ULong)));
+ else
+ ret += myvprintf_int64(send, flags, 10, width,
+ (ULong)(va_arg (vargs, UInt)));
+ break;
+ case 'p': /* %p */
+ ret += 2;
+ send('0');
+ send('x');
+ ret += myvprintf_int64(send, flags, 16, width,
+ (ULong)((UInt)va_arg (vargs, void *)));
+ break;
+ case 'x': /* %x */
+ if (is_long)
+ ret += myvprintf_int64(send, flags, 16, width,
+ (ULong)(va_arg (vargs, ULong)));
+ else
+ ret += myvprintf_int64(send, flags, 16, width,
+ (ULong)(va_arg (vargs, UInt)));
+ break;
+ case 'c': /* %c */
+ ret++;
+ send(va_arg (vargs, int));
+ break;
+ case 's': case 'S': { /* %s */
+ char *str = va_arg (vargs, char *);
+ if (str == (char*) 0) str = "(null)";
+ ret += myvprintf_str(send, flags, width, str, format[i]=='S');
+ break;
+ }
+# if 0
+ case 'y': { /* %y - print symbol */
+ Char buf[100];
+ Char *cp = buf;
+ Addr a = va_arg(vargs, Addr);
+
+ if (flags & VG_MSG_PAREN)
+ *cp++ = '(';
+ if (VG_(get_fnname_w_offset)(a, cp, sizeof(buf)-4)) {
+ if (flags & VG_MSG_PAREN) {
+ cp += VG_(strlen)(cp);
+ *cp++ = ')';
+ *cp = '\0';
+ }
+ ret += myvprintf_str(send, flags, width, buf, 0);
+ }
+ break;
+ }
+# endif
+ default:
+ break;
+ }
+ }
+ return ret;
+}
+
+
+/* A general replacement for printf(). Note that only low-level
+ debugging info should be sent via here. The official route is to
+ to use vg_message(). This interface is deprecated.
+*/
+static Char myprintf_buf[1000];
+static Int n_myprintf_buf;
+
+static void add_to_myprintf_buf ( Char c )
+{
+ if (c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/ ) {
+ (*vex_log_bytes)( myprintf_buf, vex_strlen(myprintf_buf) );
+ n_myprintf_buf = 0;
+ myprintf_buf[n_myprintf_buf] = 0;
+ }
+ myprintf_buf[n_myprintf_buf++] = c;
+ myprintf_buf[n_myprintf_buf] = 0;
+}
+
+UInt vex_printf ( const char *format, ... )
+{
+ UInt ret;
+ va_list vargs;
+ va_start(vargs,format);
+
+ n_myprintf_buf = 0;
+ myprintf_buf[n_myprintf_buf] = 0;
+ ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs );
+
+ if (n_myprintf_buf > 0) {
+ (*vex_log_bytes)( myprintf_buf, n_myprintf_buf );
+ }
+
+ va_end(vargs);
+
+ return ret;
+}
+
+
+/*---------------------------------------------------------------*/
+/*--- end vex_util.c ---*/
+/*---------------------------------------------------------------*/
/*---------------------------------------------------------------*/
/*--- ---*/
-/*--- This file (util.h) is ---*/
+/*--- This file (vex_util.h) is ---*/
/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
/*--- ---*/
/*---------------------------------------------------------------*/
-#ifndef __LIBJIT_UTIL_H
-#define __LIBJIT_UTIL_H
+#ifndef __VEX_UTIL_H
+#define __VEX_UTIL_H
#include "libjit_basictypes.h"
+/* Misc. */
+
+#define NULL ((void*)0)
+
+
/* Stuff for panicking and assertion. */
#define VG__STRING(__str) #__str
-#define assert(expr) \
+#define vassert(expr) \
((void) ((expr) ? 0 : \
(vex_assert_fail (VG__STRING(expr), \
__FILE__, __LINE__, \
extern void vex_assert_fail ( const Char* expr, const Char* file,
Int line, const Char* fn );
__attribute__ ((__noreturn__))
-extern void panic ( Char* str );
+extern void vpanic ( Char* str );
+
+
+/* Printing */
+
+__attribute__ ((format (printf, 1, 2)))
+extern UInt vex_printf ( const char *format, ... );
-#endif /* ndef __LIBJIT_UTIL_H */
+#endif /* ndef __VEX_UTIL_H */
/*---------------------------------------------------------------*/
-/*--- util.h ---*/
+/*--- vex_util.h ---*/
/*---------------------------------------------------------------*/
/* Initialise the translator. */
-extern Bool LibJIT_Init (
+extern void LibJIT_Init (
/* failure exit function */
void (*failure_exit) ( void ),
/* logging output function */
extern void LibJIT_Clear ( Bool show_stats );
-extern void* LibJIT_Alloc ( Int nbytes );
+extern void* LibVEX_Alloc ( Int nbytes );
/* Translate a basic block. */
extern void LibJIT_ShowStats ( void );
-endif /* ndef __LIBJIT_H */
+#endif /* ndef __LIBJIT_H */
/*---------------------------------------------------------------*/
/*--- libjit.h ---*/
#define False ((Bool)0)
+/* 32/64 bit addresses. */
+typedef UInt Addr32;
+typedef ULong Addr64;
+
+
#endif /* ndef __LIBJIT_BASICTYPES_H */
enum { Ity_Bit, Ity_I8, Ity_I16, Ity_I32, Ity_I64 }
IRType;
-extern void ppIRType ( FILE* f, IRType );
+extern void ppIRType ( IRType );
/* ------------------ Constants ------------------ */
extern IRConst* IRConst_U32 ( UInt );
extern IRConst* IRConst_U64 ( ULong );
-extern void ppIRConst ( FILE* f, IRConst* );
+extern void ppIRConst ( IRConst* );
/* ------------------ Temporaries ------------------ */
typedef int IRTemp;
-extern void ppIRTemp ( FILE* f, IRTemp );
+extern void ppIRTemp ( IRTemp );
/* ------------------ Binary and unary ops ------------------ */
}
IROp;
-extern void ppIROp ( FILE* f, IROp );
+extern void ppIROp ( IROp );
/* ------------------ Expressions ------------------ */
extern IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr );
extern IRExpr* IRExpr_Const ( IRConst* con );
-extern void ppIRExpr ( FILE* f, IRExpr* );
+extern void ppIRExpr ( IRExpr* );
/* ------------------ Statements ------------------ */
extern IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* expr );
extern IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* value );
-extern void ppIRStmt ( FILE* f, IRStmt* );
+extern void ppIRStmt ( IRStmt* );
/* ------------------ Basic block enders. ------------------ */
extern IRNext* IRNext_UJump ( IRConst* dst );
-extern void ppIRNext ( FILE* f, IRNext* );
+extern void ppIRNext ( IRNext* );
/* ------------------ Basic Blocks ------------------ */
}
IRTypeEnv;
-extern void ppIRTypeEnv ( FILE* f, IRTypeEnv* );
+extern void ppIRTypeEnv ( IRTypeEnv* );
/* Basic blocks contain 3 fields:
extern IRBB* mk_IRBB ( IRTypeEnv*, IRStmt*, IRNext* );
-extern void ppIRBB ( FILE* f, IRBB* );
+extern void ppIRBB ( IRBB* );
/*---------------------------------------------------------------*/