};
-#define R_HASH_INVALID_INDEXVAL ((ruint)-1)
+#define R_HASH_INVALID_INDEXVAL ((rulong)-1)
#define r_hash_size(__h__) (1 << (__h__)->nbits)
#define r_hash_mask(__h__) (r_hash_size(__h__) - 1)
RVM_OBJECTS += $(OUTDIR)/rvmcpu.o
RVM_OBJECTS += $(OUTDIR)/rvmoperator.o
RVM_OBJECTS += $(OUTDIR)/rvmcodemap.o
+RVM_OBJECTS += $(OUTDIR)/rvmrelocmap.o
RVM_OBJECTS += $(OUTDIR)/rvmcodegen.o
RVM_OBJECTS += $(OUTDIR)/rvmreg.o
RVM_OBJECTS += $(OUTDIR)/rvmscope.o
start = rvm_codegen_addins(cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, DA, args));
- rvm_codemap_addindex(cg->codemap, name, namesize, start);
+ rvm_codemap_addoffset(cg->codemap, rvm_codemap_lookup_s(cg->codemap, ".code"), name, namesize, start);
return start;
}
start = rvm_codegen_addins(cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, R0, 0));
- rvm_codemap_addindex(cg->codemap, name, namesize, start);
+ rvm_codemap_addoffset(cg->codemap, rvm_codemap_lookup_s(cg->codemap, ".code"), name, namesize, start);
return start;
}
}
-void rvm_codemap_pushloopblock(rvm_codemap_t *codemap, rulong begin, rulong size)
-{
- rvm_loopblock_t loop;
- loop.begin = begin;
- loop.size = size;
- r_array_add(codemap->blocks, &loop);
-}
-
-
-void rvm_codemap_poploopblock(rvm_codemap_t *codemap)
-{
- ruint len;
- if ((len = r_array_length(codemap->blocks)) > 0) {
- r_array_setlength(codemap->blocks, len - 1);
- }
-}
-
-
-rvm_loopblock_t *rvm_codemap_currentloopblock(rvm_codemap_t *codemap)
+void rvm_codemap_clear(rvm_codemap_t *codemap)
{
- ruint len;
- if ((len = r_array_length(codemap->blocks)) > 0) {
- return (rvm_loopblock_t*)r_array_slot(codemap->blocks, len - 1);
- }
- return NULL;
+ r_hash_removeall(codemap->hash);
+ r_array_setlength(codemap->labels, 0);
}
-void rvm_codemap_clear(rvm_codemap_t *codemap)
+rvm_codelabel_t *rvm_codemap_label(rvm_codemap_t *codemap, rlong index)
{
- r_hash_removeall(codemap->hash);
- r_array_setlength(codemap->labels, 0);
+ if (index < 0)
+ return NULL;
+ return r_array_index(codemap->labels, index, rvm_codelabel_t*);
}
-static rvm_codelabel_t *rvm_codemap_dolookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
+static rlong rvm_codemap_dolookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
{
rstr_t lookupstr = {(char*)name, namesize};
- return (rvm_codelabel_t *)r_hash_lookup(codemap->hash, &lookupstr);
+ return r_hash_lookup_indexval(codemap->hash, &lookupstr);
}
-static rvm_codelabel_t *rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
+static rlong rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
{
rvm_codelabel_t *label;
+ rlong labelidx = -1;
- label = rvm_codemap_dolookup(codemap, name, namesize);
- if (!label) {
+ labelidx = rvm_codemap_dolookup(codemap, name, namesize);
+ if (labelidx < 0) {
label = r_zmalloc(sizeof(*label));
- label->name = r_rstrdup(name, namesize);
- r_hash_insert(codemap->hash, label->name, label);
- r_array_add(codemap->labels, &label);
+ labelidx = r_array_add(codemap->labels, &label);
+ if (name) {
+ label->name = r_rstrdup(name, namesize);
+ r_hash_insert_indexval(codemap->hash, label->name, labelidx);
+ }
}
- return label;
+ return labelidx;
}
-rvm_codelabel_t *rvm_codemap_addindex(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rulong index)
+rlong rvm_codemap_addoffset(rvm_codemap_t *codemap, rulong base, const rchar *name, ruint namesize, rulong offset)
{
- rvm_codelabel_t *label = rvm_codemap_add(codemap, name, namesize);
+ rlong labelidx = rvm_codemap_add(codemap, name, namesize);
+ rvm_codelabel_t *label = rvm_codemap_label(codemap, labelidx);
if (label) {
- label->loc.index = index;
+ label->base = base;
+ label->loc.index = offset;
label->type = RVM_CODELABEL_INDEX;
}
- return label;
+ return labelidx;
}
-rvm_codelabel_t *rvm_codemap_addindex_s(rvm_codemap_t *codemap, const rchar *name, rulong index)
+rlong rvm_codemap_addoffset_s(rvm_codemap_t *codemap, rulong base, const rchar *name, rulong offset)
{
- return rvm_codemap_addindex(codemap, name, r_strlen(name), index);
+ return rvm_codemap_addoffset(codemap, base, name, r_strlen(name), offset);
}
-rvm_codelabel_t *rvm_codemap_addpointer(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rvm_asmins_t *ptr)
+rlong rvm_codemap_addpointer(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rvm_asmins_t *ptr)
{
- rvm_codelabel_t *label = rvm_codemap_add(codemap, name, namesize);
+ rlong labelidx = rvm_codemap_add(codemap, name, namesize);
+ rvm_codelabel_t *label = rvm_codemap_label(codemap, labelidx);
if (label) {
label->loc.ptr = ptr;
label->type = RVM_CODELABEL_POINTER;
}
- return label;
+ return labelidx;
}
-rvm_codelabel_t *rvm_codemap_addpointer_s(rvm_codemap_t *codemap, const rchar *name, rvm_asmins_t *ptr)
+rlong rvm_codemap_addpointer_s(rvm_codemap_t *codemap, const rchar *name, rvm_asmins_t *ptr)
{
return rvm_codemap_addpointer(codemap, name, r_strlen(name), ptr);
}
-rvm_codelabel_t *rvm_codemap_invalid_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
+rlong rvm_codemap_invalid_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
{
- rvm_codelabel_t *label = rvm_codemap_add(codemap, name, namesize);
+ rlong labelidx = rvm_codemap_add(codemap, name, namesize);
+ rvm_codelabel_t *label = rvm_codemap_label(codemap, labelidx);
if (label) {
label->type = RVM_CODELABEL_INVALID;
}
- return label;
+ return labelidx;
}
-rvm_codelabel_t *rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name)
+rlong rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name)
{
return rvm_codemap_invalid_add(codemap, name, r_strlen(name));
}
-rvm_codelabel_t *rvm_codemap_lastlabel(rvm_codemap_t *codemap)
+rlong rvm_codemap_lastlabel(rvm_codemap_t *codemap)
{
- if (r_array_size(codemap->labels)) {
- return (rvm_codelabel_t*)r_array_last(codemap->labels, rvm_codelabel_t*);
- }
- return NULL;
+ return r_array_length(codemap->labels) - 1;
}
-rvm_codelabel_t *rvm_codemap_lookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
+rlong rvm_codemap_lookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
{
rstr_t lookupstr = {(char*)name, namesize};
- rvm_codelabel_t *label = (rvm_codelabel_t *)r_hash_lookup(codemap->hash, &lookupstr);
+ rlong labelidx = r_hash_lookup_indexval(codemap->hash, &lookupstr);
- if (!label)
- label = rvm_codemap_invalid_add(codemap, name, namesize);
- return label;
+ if (labelidx < 0)
+ labelidx = rvm_codemap_invalid_add(codemap, name, namesize);
+ return labelidx;
}
-
-rvm_codelabel_t *rvm_codemap_lookup_s(rvm_codemap_t *codemap, const rchar *name)
+rlong rvm_codemap_lookup_s(rvm_codemap_t *codemap, const rchar *name)
{
return rvm_codemap_lookup(codemap, name, r_strlen(name));
}
} rvm_loopblock_t;
+typedef struct rvm_codelabel_s {
+ enum {
+ RVM_CODELABEL_INDEX = 0,
+ RVM_CODELABEL_POINTER,
+ RVM_CODELABEL_INVALID,
+ } type;
+ rulong base;
+ union {
+ rulong index;
+ rpointer ptr;
+ } loc;
+ rstr_t *name;
+ rulong size; // Optional, used for function declarations
+} rvm_codelabel_t;
+
+
typedef struct rvm_codemap_s {
rarray_t *blocks;
rarray_t *labels;
rvm_codemap_t *rvm_codemap_create();
void rvm_codemap_destroy(rvm_codemap_t *codemap);
void rvm_codemap_clear(rvm_codemap_t *codemap);
-rvm_codelabel_t *rvm_codemap_invalid_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize);
-rvm_codelabel_t *rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name);
-rvm_codelabel_t *rvm_codemap_addindex(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rulong index);
-rvm_codelabel_t *rvm_codemap_addindex_s(rvm_codemap_t *codemap, const rchar *name, rulong index);
-rvm_codelabel_t *rvm_codemap_addpointer(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rvm_asmins_t *ptr);
-rvm_codelabel_t *rvm_codemap_addpointer_s(rvm_codemap_t *codemap, const rchar *name, rvm_asmins_t *ptr);
-rvm_codelabel_t *rvm_codemap_lookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize);
-rvm_codelabel_t *rvm_codemap_lookup_s(rvm_codemap_t *codemap, const rchar *name);
-rvm_codelabel_t *rvm_codemap_lastlabel(rvm_codemap_t *codemap);
-
-void rvm_codemap_pushloopblock(rvm_codemap_t *codemap, rulong begin, rulong size);
-void rvm_codemap_poploopblock(rvm_codemap_t *codemap);
-rvm_loopblock_t *rvm_codemap_currentloopblock(rvm_codemap_t *codemap);
+rlong rvm_codemap_invalid_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize);
+rlong rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name);
+rlong rvm_codemap_addoffset(rvm_codemap_t *codemap, rulong base, const rchar *name, ruint namesize, rulong offset);
+rlong rvm_codemap_addoffset_s(rvm_codemap_t *codemap, rulong base, const rchar *name, rulong offset);
+rlong rvm_codemap_addpointer(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rvm_asmins_t *ptr);
+rlong rvm_codemap_addpointer_s(rvm_codemap_t *codemap, const rchar *name, rvm_asmins_t *ptr);
+rlong rvm_codemap_lookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize);
+rlong rvm_codemap_lookup_s(rvm_codemap_t *codemap, const rchar *name);
+rlong rvm_codemap_lastlabel(rvm_codemap_t *codemap);
+rvm_codelabel_t *rvm_codemap_label(rvm_codemap_t *codemap, rlong index);
+
#ifdef __cplusplus
}
static void rvm_op_ret(rvmcpu_t *cpu, rvm_asmins_t *ins)
{
- RVM_CPUREG_SETU(cpu, PC, RVM_CPUREG_GETU(cpu, LR));
+ RVM_CPUREG_SETU(cpu, PC, RVM_CPUREG_GETU(cpu, LR));
}
str += ret;
sz -= ret;
- if (pi->type == RVM_DTYPE_DOUBLE) {
- if ((ret = rvm_snprintf(str, sz, "%f ", pi->data.d)) < 0)
+
+ if (RVM_REG_GETTYPE(&pi->data) == RVM_DTYPE_DOUBLE) {
+ if ((ret = rvm_snprintf(str, sz, "%f ", RVM_REG_GETD(&pi->data))) < 0)
return ret;
- } else if (pi->type == RVM_DTYPE_LONG) {
- if ((ret = rvm_snprintf(str, sz, "%ld ", (long)pi->data.u)) < 0)
+ } else if (RVM_REG_GETTYPE(&pi->data) == RVM_DTYPE_LONG) {
+ if ((ret = rvm_snprintf(str, sz, "%ld ", RVM_REG_GETL(&pi->data))) < 0)
return ret;
} else {
- if ((ret = rvm_snprintf(str, sz, "0x%lx ", (unsigned long)pi->data.u)) < 0)
+ if ((ret = rvm_snprintf(str, sz, "0x%lx ", (unsigned long)RVM_REG_GETU(&pi->data))) < 0)
return ret;
}
do {
pi = RVM_REG_GETIP(regpc);
if (pi->da) {
- if (pi->type == RVM_DTYPE_DOUBLE) {
- RVM_REG_SETD(regda, pi->data.d);
- } else {
- RVM_REG_SETU(regda, pi->data.u);
- }
- RVM_REG_SETTYPE(regda, pi->type);
- RVM_REG_ASSIGNFLAGS(regda, (pi->type >= RVM_DTYPE_STRING) ? RVM_INFOBIT_ROBJECT : 0);
+ *regda = pi->data;
}
ops[pi->opcode](cpu, pi);
RVM_REG_INCIP(regpc, 1);
do {
pi = RVM_REG_GETIP(regpc);
if (pi->da) {
- if (pi->type == RVM_DTYPE_DOUBLE) {
- RVM_REG_SETD(regda, pi->data.d);
- } else {
- RVM_REG_SETU64(regda, pi->data.u);
- }
- RVM_REG_SETTYPE(regda, pi->type);
- RVM_REG_ASSIGNFLAGS(regda, (pi->type >= RVM_DTYPE_STRING) ? RVM_INFOBIT_ROBJECT : 0);
+ *regda = pi->data;
}
ops[pi->opcode](cpu, pi);
rvm_cpu_dumpregs(pi, cpu);
a.op1 = (ruint8)op1;
a.op2 = (ruint8)op2;
a.op3 = (ruint8)op3;
- a.data.u = (rword)data;
- a.type = RVM_DTYPE_POINTER;
+ rvm_reg_setpointer(&a.data, data);
if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
a.da = 1;
return a;
a.op1 = (ruint8)op1;
a.op2 = (ruint8)op2;
a.op3 = (ruint8)op3;
- a.data.u = (rword)data;
- a.type = RVM_DTYPE_SWIID;
+ rvm_reg_setunsigned(&a.data, data);
+ RVM_REG_SETTYPE(&a.data, RVM_DTYPE_SWIID)
if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
a.da = 1;
return a;
a.op1 = (ruint8)op1;
a.op2 = (ruint8)op2;
a.op3 = (ruint8)op3;
- a.data.u = (rword)data;
- a.type = RVM_DTYPE_FUNCTION;
+ rvm_reg_setunsigned(&a.data, data);
+ RVM_REG_SETTYPE(&a.data, RVM_DTYPE_FUNCTION)
if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
a.da = 1;
return a;
a.op1 = (ruint8)op1;
a.op2 = (ruint8)op2;
a.op3 = (ruint8)op3;
- a.data.u = (rword)data;
+ rvm_reg_setunsigned(&a.data, data);
if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
a.da = 1;
return a;
a.op1 = (ruint8)op1;
a.op2 = (ruint8)op2;
a.op3 = (ruint8)op3;
- a.data.u = (rword)data;
- a.type = RVM_DTYPE_LONG;
+ rvm_reg_setlong(&a.data, data);
if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
a.da = 1;
return a;
}
-rvm_asmins_t rvm_asmb(rword opcode, rword op1, rword op2, rword op3, rword data)
+rvm_asmins_t rvm_asmb(rword opcode, rword op1, rword op2, rword op3, ruint data)
{
rvm_asmins_t a;
a.op1 = (ruint8)op1;
a.op2 = (ruint8)op2;
a.op3 = (ruint8)op3;
- a.data.u = (rword)(data ? 1 : 0);
- a.type = RVM_DTYPE_BOOLEAN;
+ rvm_reg_setboolean(&a.data, data);
if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
a.da = 1;
return a;
a.op1 = (ruint8)op1;
a.op2 = (ruint8)op2;
a.op3 = (ruint8)op3;
- a.data.d = data;
- a.type = RVM_DTYPE_DOUBLE;
+ rvm_reg_setdouble(&a.data, data);
if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
a.da = 1;
-
return a;
}
a.op1 = (ruint8)op1;
a.op2 = (ruint8)op2;
a.op3 = (ruint8)op3;
- a.data.p.p1 = p1;
- a.data.p.p2 = p2;
- a.type = RVM_DTYPE_PAIR;
+ rvm_reg_setpair(&a.data, p1, p2);
if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
a.da = 1;
return a;
a.op1 = (ruint8)op1;
a.op2 = (ruint8)op2;
a.op3 = (ruint8)op3;
- a.data.u = (rword)pReloc;
+ RVM_REG_SETP(&a.data, pReloc);
a.flags = RVM_ASMINS_RELOC;
a.da = 1;
return a;
}
-/*
- * On success return NULL, otherwise
- * return a pointer to undefined label
- */
-rvm_codelabel_t *rvm_relocate(rvm_asmins_t *code, rsize_t size)
-{
- rvm_codelabel_t *label;
- rvm_asmins_t *reloc;
- rulong relocindex;
- rulong off;
-
-// code->data.u = reloc - code;
-
- for (off = 0; off < size; off++, code++) {
- if (code->flags & RVM_ASMINS_RELOC) {
- label = (rvm_codelabel_t *)code->data.u;
- if (label->type == RVM_CODELABEL_INDEX) {
- relocindex = label->loc.index;
- code->data.u = relocindex - off;
- code->flags &= ~RVM_ASMINS_RELOC;
- } else if (label->type == RVM_CODELABEL_POINTER) {
- reloc = label->loc.ptr;
- code->data.u = reloc - code;
- code->flags &= ~RVM_ASMINS_RELOC;
- } else {
- return label;
- }
- }
- }
- return NULL;
-}
+//rvm_codelabel_t *rvm_relocate(rvm_asmins_t *code, rsize_t size)
+//{
+// rvm_codelabel_t *label;
+// rvm_asmins_t *reloc;
+// rulong relocindex;
+// rulong off;
+//
+// for (off = 0; off < size; off++, code++) {
+// if (code->flags & RVM_ASMINS_RELOC) {
+// label = (rvm_codelabel_t *)RVM_REG_GETP(&code->data);
+// if (label->type == RVM_CODELABEL_INDEX) {
+// relocindex = label->loc.index;
+// RVM_REG_SETU(&code->data, relocindex - off);
+// code->flags &= ~RVM_ASMINS_RELOC;
+// } else if (label->type == RVM_CODELABEL_POINTER) {
+// reloc = (rvm_asmins_t *)label->loc.ptr;
+// RVM_REG_SETU(&code->data, reloc - code);
+// code->flags &= ~RVM_ASMINS_RELOC;
+// } else {
+// return label;
+// }
+// }
+// }
+// return NULL;
+//}
rvmreg_t *rvm_cpu_alloc_global(rvmcpu_t *cpu)
#define RVM_ASMINS_RELOC (1 << 0)
struct rvm_asmins_s {
- union {
- ruint64 u;
- rdouble d;
- rpair_t p;
- } data;
+ rvmreg_t data;
ruint16 op1:RVM_OPERAND_BITS;
ruint16 op2:RVM_OPERAND_BITS;
ruint16 op3:RVM_OPERAND_BITS;
ruint16 da:1;
- ruint32 opcode:8;
- ruint32 swi:(RVM_SWI_TABLE_BITS + RVM_SWI_NUM_BITS);
- ruint32 type:5;
- ruint32 flags:3;
+ ruint16 swi;
+ ruint8 flags;
+ ruint8 opcode;
};
-typedef struct rvm_codelabel_s {
- enum {
- RVM_CODELABEL_INDEX = 0,
- RVM_CODELABEL_POINTER,
- RVM_CODELABEL_INVALID,
- } type;
- union {
- rulong index;
- rvm_asmins_t *ptr;
- } loc;
- rstr_t *name;
- rulong size; // Optional, used for function declarations
-} rvm_codelabel_t;
-
-
struct rvm_opmap_s;
struct rvmcpu_s {
rint rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off);
rint rvm_cpu_getswi(rvmcpu_t *cpu, const rchar *swiname, rsize_t size);
rint rvm_cpu_getswi_s(rvmcpu_t *cpu, const rchar *swiname);
-rvm_codelabel_t *rvm_relocate(rvm_asmins_t *code, rsize_t size);
rvmreg_t *rvm_cpu_alloc_global(rvmcpu_t *cpu);
int rvm_cpu_setreg(rvmcpu_t *cpu, rword regnum, const rvmreg_t *src);
rvmreg_t * rvm_cpu_getreg(rvmcpu_t *cpu, rword regnum);
rvm_asmins_t rvm_asm(rword opcode, rword op1, rword op2, rword op3, rword data);
rvm_asmins_t rvm_asma(rword opcode, rword op1, rword op2, rword op3, rchar *data, rulong size);
rvm_asmins_t rvm_asml(rword opcode, rword op1, rword op2, rword op3, rlong data);
-rvm_asmins_t rvm_asmb(rword opcode, rword op1, rword op2, rword op3, rword data);
+rvm_asmins_t rvm_asmb(rword opcode, rword op1, rword op2, rword op3, ruint data);
rvm_asmins_t rvm_asmd(rword opcode, rword op1, rword op2, rword op3, rdouble data);
rvm_asmins_t rvm_asmp(rword opcode, rword op1, rword op2, rword op3, rpointer data);
rvm_asmins_t rvm_asms(rword opcode, rword op1, rword op2, rword op3, rword data);
}
+void rvm_reg_setpair(rvmreg_t *r, ruint p1, ruint p2)
+{
+
+ RVM_REG_SETPAIR(r, p1, p2);
+ RVM_REG_SETTYPE(r, RVM_DTYPE_PAIR);
+ RVM_REG_CLRFLAG(r, RVM_INFOBIT_ROBJECT);
+}
+
+
+void rvm_reg_setstrptr(rvmreg_t *r, rchar *s, ruint size)
+{
+ RVM_REG_SETSTR(r, s, size);
+ RVM_REG_SETTYPE(r, RVM_DTYPE_STRPTR);
+ RVM_REG_CLRFLAG(r, RVM_INFOBIT_ROBJECT);
+}
+
+
void rvm_reg_setarray(rvmreg_t *r, robject_t *ptr)
{
RVM_REG_SETP(r, ptr);
RVM_REG_SETFLAG(r, RVM_INFOBIT_ROBJECT);
}
+rvmreg_t rvm_reg_create_pair(ruint p1, ruint p2)
+{
+ rvmreg_t r;
+ r_memset(&r, 0, sizeof(r));
+ rvm_reg_setpair(&r, p1, p2);
+ return r;
+}
+
+
+rvmreg_t rvm_reg_create_strptr(rchar *s, ruint size)
+{
+ rvmreg_t r;
+ r_memset(&r, 0, sizeof(r));
+ rvm_reg_setstrptr(&r, s, size);
+ return r;
+}
+
rvmreg_t rvm_reg_create_double(rdouble d)
{
}
+void rvm_reg_setboolean(rvmreg_t *r, ruint b)
+{
+ RVM_REG_SETU(r, b ? 1 : 0);
+ RVM_REG_SETTYPE(r, RVM_DTYPE_BOOLEAN);
+ RVM_REG_CLRFLAG(r, RVM_INFOBIT_ROBJECT);
+}
+
+
void rvm_reg_setdouble(rvmreg_t *r, rdouble d)
{
RVM_REG_SETD(r, d);
RVM_REG_SETTYPE(r, RVM_DTYPE_DOUBLE);
RVM_REG_CLRFLAG(r, RVM_INFOBIT_ROBJECT);
+}
+
+void rvm_reg_setpointer(rvmreg_t *r, rpointer p)
+{
+ RVM_REG_SETP(r, p);
+ RVM_REG_SETTYPE(r, RVM_DTYPE_POINTER);
+ RVM_REG_CLRFLAG(r, RVM_INFOBIT_ROBJECT);
}
#define RVM_CPUREG_SETU64(__cpu__, __r__, __val__) RVM_REG_SETU64(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
#define RVM_REG_GETPAIR(__r__) (__r__)->v.pair
-#define RVM_REG_SETPAIR(__r__, __val__) do { (__r__)->v.pair = (ruint64)(__val__); } while (0)
+#define RVM_REG_SETPAIR(__r__, __val1__, __val2__) do { (__r__)->v.pair.p1 = (__val1__); (__r__)->v.pair.p2 = (__val2__);} while (0)
#define RVM_CPUREG_GETPAIR(__cpu__, __r__) RVM_CPUREG_PTR(__cpu__, __r__)->v.pair
-#define RVM_CPUREG_SETPAIR(__cpu__, __r__, __val__) RVM_REG_SETPAIR(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
+#define RVM_CPUREG_SETPAIR(__cpu__, __r__, __val1__, __val2__) RVM_REG_SETPAIR(RVM_CPUREG_PTR(__cpu__, __r__), __val1__, __val2__)
+
+#define RVM_REG_GETSTRSIZE(__r__) (__r__)->size
+#define RVM_REG_GETSTR(__r__) (__r__)->v.s
+#define RVM_REG_SETSTR(__r__, __str__, __size__) do { (__r__)->v.s = (__str__); if ((__size__) == (ruint)-1) (__r__)->size = r_strlen(__str__); else (__r__)->size = (__size__);} while (0)
+#define RVM_CPUREG_GETSTR(__cpu__, __r__) RVM_REG_GETSTR(RVM_CPUREG_PTR(__cpu__, __r__))
+#define RVM_CPUREG_SETSTR(__cpu__, __r__, __str__, __size__) RVM_REG_SETSTR(RVM_CPUREG_PTR(__cpu__, __r__), __str__, __size__)
#define RVM_REG_GETIP(__r__) (rvm_asmins_t*)((__r__)->v.p)
rvmreg_t rvm_reg_create_harray();
rvmreg_t rvm_reg_create_double(rdouble d);
rvmreg_t rvm_reg_create_long(rlong l);
+rvmreg_t rvm_reg_create_pair(ruint p1, ruint p2);
+rvmreg_t rvm_reg_create_strptr(rchar *s, ruint size);
void rvm_reg_init(rvmreg_t *reg);
void rvm_reg_cleanup(rvmreg_t *reg);
rvmreg_t *rvm_reg_copy(rvmreg_t *dst, const rvmreg_t *src);
void rvm_reg_setflag(rvmreg_t *r, ruint16 flag);
void rvm_reg_clrflag(rvmreg_t *r, ruint16 flag);
void rvm_reg_setunsigned(rvmreg_t *r, rword u);
+void rvm_reg_setboolean(rvmreg_t *r, ruint b);
void rvm_reg_setlong(rvmreg_t *r, rlong l);
void rvm_reg_setdouble(rvmreg_t *r, rdouble d);
+void rvm_reg_setpointer(rvmreg_t *r, rpointer p);
+void rvm_reg_setpair(rvmreg_t *r, ruint p1, ruint p2);
+void rvm_reg_setstrptr(rvmreg_t *r, rchar *s, ruint size);
void rvm_reg_setstring(rvmreg_t *r, rstring_t *ptr);
void rvm_reg_setarray(rvmreg_t *r, robject_t *ptr);
void rvm_reg_setharray(rvmreg_t *r, robject_t *ptr);
--- /dev/null
+#include "rvmrelocmap.h"
+#include "rmem.h"
+
+rvm_relocmap_t *rvm_relocmap_create()
+{
+ rvm_relocmap_t *relocmap;
+
+ relocmap = (rvm_relocmap_t*)r_zmalloc(sizeof(*relocmap));
+ if (!relocmap)
+ return NULL;
+ relocmap->records = r_array_create(sizeof(rvm_relocrecord_t));
+ return relocmap;
+}
+
+
+void rvm_relocmap_destroy(rvm_relocmap_t *relocmap)
+{
+ r_object_destroy((robject_t*)relocmap->records);
+}
+
+
+void rvm_relocmap_clear(rvm_relocmap_t *relocmap)
+{
+ r_array_setlength(relocmap->records, 0);
+}
+
+
+rvm_relocrecord_t *rvm_relocmap_add(rvm_relocmap_t *relocmap, rulong offset, rulong label)
+{
+ rvm_relocrecord_t record;
+ rint index;
+ record.offset = offset;
+ record.label = label;
+
+ index = r_array_add(relocmap->records, &record);
+ return (rvm_relocrecord_t *)r_array_slot(relocmap->records, index);
+}
+
+
+rvm_relocrecord_t *rvm_relocmap_get(rvm_relocmap_t *relocmap, rulong index)
+{
+ if (index >= r_array_length(relocmap->records))
+ return NULL;
+ return (rvm_relocrecord_t *)r_array_slot(relocmap->records, index);
+}
+
+
+rulong rvm_relocmap_length(rvm_relocmap_t *relocmap)
+{
+ return r_array_length(relocmap->records);
+}
+
+
+rlong rvm_relocmap_relocate(rvm_relocmap_t *relocmap, rvm_codemap_t *codemap, rvm_asmins_t *code)
+{
+ rlong index;
+ rvm_codelabel_t *label;
+ rvm_relocrecord_t *reloc;
+
+ for (index = 0; index < r_array_length(relocmap->records); index++) {
+ reloc = rvm_relocmap_get(relocmap, index);
+ label = rvm_codemap_label(codemap, reloc->label);
+ if (label == NULL || label->type == RVM_CODELABEL_INVALID)
+ return index;
+ code[reloc->offset].data.v.u64 = (ruint64)(code + label->loc.index);
+ }
+ return -1;
+}
--- /dev/null
+#ifndef _RVMRELOCMAP_H_
+#define _RVMRELOCMAP_H_
+
+#include "rtypes.h"
+#include "rarray.h"
+#include "rhash.h"
+#include "rstring.h"
+#include "rvmcpu.h"
+#include "rvmcodemap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct rvm_relocrecord_s {
+ rulong offset;
+ rulong label;
+} rvm_relocrecord_t;
+
+
+typedef struct rvm_relocmap_s {
+ rarray_t *records;
+} rvm_relocmap_t;
+
+
+rvm_relocmap_t *rvm_relocmap_create();
+void rvm_relocmap_destroy(rvm_relocmap_t *relocmap);
+void rvm_relocmap_clear(rvm_relocmap_t *relocmap);
+rvm_relocrecord_t *rvm_relocmap_add(rvm_relocmap_t *relocmap, rulong offset, rulong label);
+rvm_relocrecord_t *rvm_relocmap_get(rvm_relocmap_t *relocmap, rulong index);
+rulong rvm_relocmap_length(rvm_relocmap_t *relocmap);
+rlong rvm_relocmap_relocate(rvm_relocmap_t *relocmap, rvm_codemap_t *codemap, rvm_asmins_t *code);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
#include <stdio.h>
#include "common.h"
#include "rvmcodemap.h"
+#include "rvmrelocmap.h"
{
ruint ret = 0;
ruint off = 0;
- rvm_codelabel_t l_add2 = {RVM_CODELABEL_POINTER};
- rvm_codelabel_t l_add3 = {RVM_CODELABEL_POINTER};
rvm_asmins_t vmcode[256];
rvmcpu_t *vm = rvm_cpu_create_default();
rvm_codemap_t *codemap = rvm_codemap_create();
+ rvm_relocmap_t *relocmap = rvm_relocmap_create();
rvm_cpu_addswitable(vm, common_calltable);
- vmcode[off++] = rvm_asmx(RVM_B, DA, XX, XX, rvm_codemap_lookup_s(codemap, "l_main"));
+ rvm_relocmap_add(relocmap, off, rvm_codemap_lookup_s(codemap, "l_main"));
+ vmcode[off++] = rvm_asmx(RVM_BX, DA, XX, XX, rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, "l_main")));
/*
* R0 = R0 + R1
*/
- l_add2.loc.ptr = &vmcode[off];
+ rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "l_add2", off - 1);
vmcode[off++] = rvm_asm(RVM_ADD, R0, R0, R1, 0);
vmcode[off++] = rvm_asm(RVM_RET, XX, XX, XX, 0);
/*
* R0 = R0 + R1 + R2
*/
- l_add3.loc.ptr = &vmcode[off];
+ rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "l_add3", off - 1);
vmcode[off++] = rvm_asm(RVM_PUSHM,DA, XX, XX, BIT(R7)|BIT(R8)|BIT(SP)|BIT(LR));
vmcode[off++] = rvm_asm(RVM_PUSH, R2, XX, XX, 0);
- vmcode[off++] = rvm_asmx(RVM_BL, DA, XX, XX, &l_add2);
+ rvm_relocmap_add(relocmap, off, rvm_codemap_lookup_s(codemap, "l_add2"));
+ vmcode[off++] = rvm_asmx(RVM_BXL, DA, XX, XX, rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, "l_add2")));
vmcode[off++] = rvm_asm(RVM_POP, R1, XX, XX, 0);
- vmcode[off++] = rvm_asmx(RVM_BL, DA, XX, XX, &l_add2);
+ rvm_relocmap_add(relocmap, off, rvm_codemap_lookup_s(codemap, "l_add2"));
+ vmcode[off++] = rvm_asmx(RVM_BXL, DA, XX, XX, rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, "l_add2")));
vmcode[off++] = rvm_asm(RVM_POPM, DA, XX, XX, BIT(R7)|BIT(R8)|BIT(SP)|BIT(LR));
vmcode[off++] = rvm_asm(RVM_RET, XX, XX, XX, 0);
/*
*
*/
- rvm_codemap_addpointer_s(codemap, "l_main", &vmcode[off]);
+ rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "l_main", off - 1);
vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
vmcode[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 2);
- vmcode[off++] = rvm_asmx(RVM_BL, DA, XX, XX, &l_add2);
+ rvm_relocmap_add(relocmap, off, rvm_codemap_lookup_s(codemap, "l_add2"));
+ vmcode[off++] = rvm_asmx(RVM_BXL, DA, XX, XX, rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, "l_add2")));
VMTEST_REG(vmcode, off, 0, 3, "BL/RET");
vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
vmcode[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 2);
vmcode[off++] = rvm_asm(RVM_MOV, R2, DA, XX, 4);
- vmcode[off++] = rvm_asmx(RVM_BL, DA, XX, XX, &l_add3);
+ rvm_relocmap_add(relocmap, off, rvm_codemap_lookup_s(codemap, "l_add3"));
+ vmcode[off++] = rvm_asmx(RVM_BXL, DA, XX, XX, rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, "l_add3")));
VMTEST_REG(vmcode, off, 0, 7, "BL/RET");
vmcode[off++] = rvm_asm(RVM_EXT, R0, XX, XX, 0);
- rvm_relocate(vmcode, off);
+ rvm_relocmap_relocate(relocmap, codemap, vmcode);
+
#ifdef EXECDEBUG
ret = rvm_cpu_exec_debug(vm, vmcode, 0);
#else
#endif
rvm_cpu_destroy(vm);
rvm_codemap_destroy(codemap);
+ rvm_relocmap_destroy(relocmap);
return 0;
}
rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
- rvm_relocate(rvm_codegen_getcode(cg, 0), rvm_codegen_getcodesize(cg));
-
-
rvm_asm_dump(rvm_codegen_getcode(cg, 0), rvm_codegen_getcodesize(cg));
rvm_cpu_exec_debug(cpu, rvm_codegen_getcode(cg, 0), 0);
{
rvm_codemap_t *codemap = rvm_codemap_create();
- rvm_codemap_addindex_s(codemap, "add2", 0);
- rvm_codemap_addindex_s(codemap, "add3", 3);
- rvm_codemap_addindex_s(codemap, "sub2", 7);
+ rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "add2", 0);
+ rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "add3", 3);
+ rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "sub2", 7);
codelabel_print_info(codemap, "add2");
codelabel_print_info(codemap, "add7");
#include "rvmcpu.h"
#include <stdio.h>
-//#define EXECDEBUG 1
+#define EXECDEBUG 1
#define VMTEST_REG(code, index, reg, val, msg) \
rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
- rvm_relocate(rvm_codegen_getcode(cg, 0), rvm_codegen_getcodesize(cg));
-
-
rvm_asm_dump(rvm_codegen_getcode(cg, 0), rvm_codegen_getcodesize(cg));
rvm_cpu_exec_debug(cpu, rvm_codegen_getcode(cg, 0), 0);
vmcode[off++] = rvm_asm(RVM_PRN, R0, XX, XX, 0);
vmcode[off++] = rvm_asm(RVM_EXT, R0, XX, XX, 0);
-
- rvm_relocate(vmcode, off);
ret = rvm_cpu_exec(vm, vmcode, 0);
fprintf(stdout, "R0 = %ld (%ld operations)\n", (unsigned long) RVM_CPUREG_GETU(vm, R0), (unsigned long)RVM_CPUREG_GETU(vm, R5));
rvm_cpu_destroy(vm);
rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
l2 = rvm_codegen_getcodesize(co->cg);
rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0)); /* Will be re-written later */
- rvm_codemap_addindex_s(co->cg->codemap, "rpa_match", rvm_codegen_getcodesize(co->cg));
+ rvm_codemap_addoffset_s(co->cg->codemap, rvm_codemap_lookup_s(co->cg->codemap, ".code"), "rpa_match", rvm_codegen_getcodesize(co->cg));
rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(TP)|BIT(FP)|BIT(SP)|BIT(LR)));
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, R0, XX, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
l2 = rvm_codegen_getcodesize(co->cg);
rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0)); /* Will be re-written later */
- rvm_codemap_addindex_s(co->cg->codemap, "rpa_match_abc", rvm_codegen_getcodesize(co->cg));
+ rvm_codemap_addoffset_s(co->cg->codemap, rvm_codemap_lookup_s(co->cg->codemap, ".code"), "rpa_match_abc", rvm_codegen_getcodesize(co->cg));
codegen_rpa_match_char(co, 'a', ' ');
codegen_rpa_match_char(co, 'b', '?');
codegen_rpa_match_char(co, 'c', '+');
rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R4, DA, XX, rvm_scope_lookup_s(co->scope, "rpa_match")->data.offset));
rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R0, DA, XX, rvm_scope_lookup_s(co->scope, "rpa_match_abc")->data.offset));
-// rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, R4, XX, XX, 0));
- rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, R0, PC, DA, (rvm_codegen_getcodesize(co->cg) - rvm_codemap_lookup_s(co->cg->codemap, "rpa_match_abc")->loc.index + 1) * sizeof(rvm_asmins_t)));
- rvm_codegen_addins(co->cg, rvm_asmx(RVM_BL, DA, XX, XX, rvm_codemap_lookup_s(co->cg->codemap, "rpa_match")));
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, R4, XX, XX, 0));
+// rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, R0, PC, DA, (rvm_codegen_getcodesize(co->cg) - rvm_codemap_lookup_s(co->cg->codemap, "rpa_match_abc")->loc.index + 1) * sizeof(rvm_asmins_t)));
+// rvm_codegen_addins(co->cg, rvm_asmx(RVM_BL, DA, XX, XX, rvm_codemap_lookup_s(co->cg->codemap, "rpa_match")));
rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xabc));
rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
- unresolved = rvm_relocate(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
- if (unresolved) {
- fprintf(stderr, "ERROR: Undefined reference to: %s\n", unresolved->name->str);
- goto end;
- }
-
if (debuginfo) {
fprintf(stdout, "\nGenerated Code:\n");
rvm_asm_dump(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
rvm_codegen_addins(cg, rvm_asm(RVM_OPSWI(rvm_cpu_getswi_s(cpu, "print")), R0, XX, XX, 0)); // print
rvm_codegen_addins(cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
- rvm_relocate(rvm_codegen_getcode(cg, 0), rvm_codegen_getcodesize(cg));
rvm_cpu_exec_debug(cpu, rvm_codegen_getcode(cg, 0), 0);
rvm_cpu_destroy(cpu);
rvm_codegen_destroy(cg);
cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, -cs.codesize));
- rvm_codemap_poploopblock(co->cg->codemap);
codegen_print_callback(stat, name, userdata, input, size, reason);
codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
exec:
- rvm_relocate(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
-
if (debuginfo) {
fprintf(stdout, "\nGenerated Code:\n");
rvm_asm_dump(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
vmcode[off++] = rvm_asm(RVM_EXT, R0, XX, XX, 0);
- rvm_relocate(vmcode, off);
ret = rvm_cpu_exec(vm, vmcode, 0);
fprintf(stdout, "R0 = %ld (%ld operations)\n", (unsigned long) RVM_CPUREG_GETU(vm, R0), (unsigned long)RVM_CPUREG_GETU(vm, R5));
rvm_cpu_destroy(vm);
rvm_codegen_addins(cg, rvm_asm(RVM_OPSWI(rvm_cpu_getswi_s(cpu, "str_to_double")), R0, R0, XX, 0));
rvm_codegen_funcend(cg);
-
- rvm_relocate(rvm_codegen_getcode(cg, 0), rvm_codegen_getcodesize(cg));
rvm_cpu_exec_debug(cpu, rvm_codegen_getcode(cg, 0), 0);
rvm_cpu_destroy(cpu);
rvm_opmap_destroy(opmap);