static void eppic_prtarray(type_t*t, ull mem, int level, int idx) { int i; int j, size=1; for(j=idx+1; t->idxlst[j]; j++) size *= t->idxlst[j]; size *= t->type==V_REF ? eppic_defbsize() : t->size; /* start printing */ eppic_msg("{"); eppic_msg("\n"); eppic_indent(level+1, 1); for(i=0; i<t->idxlst[idx]; i++, mem += size) { if(t->idxlst[idx+1]) { eppic_msg("[%d] = ", i); eppic_prtarray(t, mem, level+1, idx+1); } else { /* time to deref and print final type */ value_t *v=eppic_newval(), *vr=eppic_newval(); int *pi=t->idxlst; t->idxlst=0; eppic_duptype(&vr->type, t); eppic_pushref(&vr->type, 1); if(eppic_defbsize()==8) vr->v.ull=mem; else vr->v.ul=(ul)mem; eppic_do_deref(1, v, vr); if(is_ctype(v->type.type) || !(i%NBUNDLE)) eppic_msg("[%2d] ", i); eppic_ptype2(&v->type, v, level+1, 0, 0, 0, 1); eppic_msg(", "); /* anything else then struct/unions, print in buddles */ if(!is_ctype(v->type.type) && !((i+1)%NBUNDLE)) { eppic_msg("\n"); eppic_indent(level+1, 1); } eppic_freeval(v); eppic_freeval(vr); t->idxlst=pi; } } eppic_msg("\n"); eppic_indent(level, 1); eppic_msg("}"); }
LIBM32DASM_API m32::InstructionType m32::get_type(uint32_t instruction) { if(is_rtype(instruction) == true) { return RTYPE; } if(is_jtype(instruction) == true) { return JTYPE; } if(is_ctype(instruction) == true) { return CTYPE; } // I-type is most expensive to check, we'll do it last.. if(is_itype(instruction) == true) { return ITYPE; } // If all else fails, it must be invalid.. return INVALID; }
/* this is called when we duplicate a list of automatic variables */ var_t* eppic_dupvlist(var_t*vl) { var_t*nv=(var_t*)eppic_newvlist(); /* new root */ var_t*vp; for(vp=vl->next; vp !=vl; vp=vp->next) { var_t*v=eppic_newvar(vp->name); /* new var_t*/ v->dv=vp->dv; v->dv->refcount++; v->ini=vp->ini; eppic_dupval(v->v, vp->v); /* we start with a new array for automatic variable */ eppic_refarray(v->v, -1); v->v->arr=0; eppic_setarray(&v->v->arr); /* can't check ctypes for initialisation */ if(is_ctype(v->v->type.type)) v->ini=1; eppic_enqueue(nv, v); } return nv; }
void eppic_dupdata(value_t *v, value_t *vs) { if(is_ctype(vs->type.type) || vs->type.type == V_STRING) { v->v.data=eppic_alloc(vs->type.size); memmove(v->v.data, vs->v.data, vs->type.size); } }
void eppic_freedata(value_t *v) { if(is_ctype(v->type.type) || v->type.type == V_STRING) { if(v->v.data) eppic_free(v->v.data); v->v.data=0; } eppic_refarray(v, -1); }
void eppic_valindex(value_t *var, value_t *idx, value_t *ret) { if(is_ctype(idx->type.type)) { eppic_error("Invalid indexing type"); } else { array_t*a; a=eppic_getarrval(&var->arr, idx); /* this is the first level of indexing through a variable */ eppic_dupval(ret, a->val); ret->set=1; ret->setval=a->val; } }
void eppic_do_deref(int n, value_t *v, value_t *ref) { ull madr, new_madr; if(n > ref->type.ref) { eppic_error("Too many levels of dereference"); }else { if(eppic_defbsize()==4) madr=(ull)ref->v.ul; else madr=ref->v.ull; /* copy the target type to the returned value_t's type_t*/ eppic_duptype(&v->type, &ref->type); /* do a number of deferences according to PTR value_t */ while(n--) { eppic_popref(&v->type, 1); if(!v->type.ref) { /* make sure the pointer is pointing into the vmcore */ if(is_ctype(v->type.type)) { v->v.data=eppic_alloc(v->type.size); eppic_getmem(madr, v->v.data, v->type.size); } else { /* get the data from the system image */ switch(TYPE_SIZE(&v->type)) { case 1: eppic_getmem(madr, &v->v.uc, 1); break; case 2: eppic_getmem(madr, &v->v.us, 2); break; case 4: eppic_getmem(madr, &v->v.ul, 4); break; case 8: eppic_getmem(madr, &v->v.ull, 8); break; } } } else { /* get the pointer at this address */ if(eppic_defbsize()==4) { eppic_getmem(madr, &v->v.ul, 4); new_madr=v->v.ul; } else { eppic_getmem(madr, &v->v.ull, 8); new_madr=v->v.ull; } } /* remember this address. For the '&' operator */ v->mem=madr; madr=new_madr; } } /* we can always assign to a reference */ v->set=1; v->setval=v; v->setfct=eppic_setderef; }
LIBM32DASM_API bool m32::is_itype(uint32_t instruction) { return !is_rtype(instruction) && !is_jtype(instruction) && !is_ctype(instruction); }
/* this is the main variable declaration function. We support the global scope attribute that make the declared variable accessible to all function from all scripts. By default the scope of a variable either the statement block where it was declared (or first used): { int var; ... } Then it's scope is the block itself. Or the file, if it was declared outside of a function. Storage is by default 'automatic' and can be made permanent by using the 'static' keywork in the declaration. 'Volatile' and 'register' storage classes are supported but have no effect. */ var_t* eppic_vardecl(dvar_t*dv, type_t*t) { var_t*vlist=eppic_newvlist(); var_t*var; /* type *and* dv can have ref counts. First comes from typedef parsing second comes from the declaration itself */ dv->ref += t->ref; /* add one level of ref for arrays */ if(dv->idx) dv->ref++; /* reset ref level for tests below */ eppic_popref(t, t->ref); TAG(vlist); if(!t->type) { int sto=eppic_isstor(t->typattr); eppic_freetype(t); t=eppic_newbtype(0); t->typattr |= sto; } else if(t->type==V_BASE && !dv->ref) { eppic_chksign(t); eppic_chksize(t); } /* is this a new typedef declaration ? */ /* typedef is considered just like any other storage class */ if(eppic_istdef(t->typattr)) { eppic_tdef_decl(dv, t); return 0; } while(dv) { /* disalow var names that match against already defined vars */ if(dv->name[0]) { type_t *t=eppic_getctype(V_TYPEDEF, dv->name, 1); if(t) { eppic_freetype(t); eppic_warning("Variable '%s' already defined as typedef.\n"); } } /* some sanity checks here that apply to both var and struct declarations */ if(is_ctype(t->type) && !dv->ref) { if(dv->name[0]) { if(!instruct) { if(!eppic_isxtern(t->typattr)) { eppic_freesvs(vlist); eppic_error("struct/union instances not supported, please use pointers"); } } else if(eppic_ispartial(t)) { eppic_freesvs(vlist); eppic_error("Reference to incomplete type"); } } } if(dv->nbits) { if(t->type != V_BASE) { eppic_freesvs(vlist); eppic_error("Bit fields can only be of integer type"); } if(dv->idx) { eppic_freesvs(vlist); eppic_error("An array of bits ? Come on..."); } } var=eppic_newvar(dv->name); t->fct=dv->fct; eppic_duptype(&var->v->type, t); eppic_pushref(&var->v->type, dv->ref); var->dv=dv; TAG(var); if(t->type == V_STRING) { eppic_setstrval(var->v, ""); } eppic_setpos(&dv->pos); /* toff */ /* add to parsing list */ if(var->name[0]) { var_t *plist=eppic_newvlist(); eppic_enqueue(plist, var); eppic_addsvs(S_PARSE, eppic_dupvlist(plist)); } eppic_enqueue(vlist, var); next: dv=dv->next; } eppic_free(t); TAG(vlist); return vlist; }