void unregstr(const char* str) { htab_entry_t e = hash_find_e(&str_registry, (hash_key) (str<(char*)0x100?op2string((int)str):str)); if(!e) { /* whine ? */ return; } e->e = (hash_elem) (((unsigned int)e->e)-1); if(!e->e) { char*k = e->key; hash_delelem(&str_registry, (hash_key) str); _strfree(k); } }
char* regstr(const char* str) { if(!str) { return "{null}"; } else { htab_entry_t e = hash_find_e(&str_registry, (hash_key) (str<(char*)0x100?op2string((int)str):str)); char* ret; if(!e) { ret = _strdup(str); hash_addelem(&str_registry, (hash_key) ret, (hash_elem) 1); /*printf("register string \"%s\" (1)\n", ret);*/ } else { e->e = (hash_elem) (((unsigned int)e->e)+1); ret = (char*) e->key; /*printf("register string \"%s\" (%u)\n", ret, (unsigned int)e->e);*/ } return ret; } }
char* instr2string(Instr* instr, int align, FunctionConfig* fc) { static char buf[100]; const char* n; int oc = 0, off = 0; n = instrName(instr->type, &oc); if (align) off += sprintf(buf, "%-7s", n); else off += sprintf(buf, "%s", n); // print value type if needed bool typeVisible = false; ValType vt = instr->vtype; // do operands show type? if (instr->form == OF_1) { if (opTypeVisible(&(instr->dst))) typeVisible = true; } if (instr->form == OF_2) { if (opTypeVisible(&(instr->dst))) typeVisible = true; if (opTypeVisible(&(instr->src))) typeVisible = true; // special case: conversions (MOVSX/MOVZX) // if source type not visible, make it so if (((instr->type == IT_MOVSX) || (instr->type == IT_MOVZX)) && !opTypeVisible(&(instr->src))) { typeVisible = false; vt = opValType(&(instr->src)); } } if (instr->form == OF_3) { if (opTypeVisible(&(instr->dst))) typeVisible = true; if (opTypeVisible(&(instr->src))) typeVisible = true; if (opTypeVisible(&(instr->src2))) typeVisible = true; } // is type implicitly known via instruction name? if (instr->vtype == VT_Implicit) typeVisible = true; if (vt == VT_None) { if ((instr->form >= OF_1) && (instr->form <= OF_3)) vt = opValType(&(instr->dst)); } if (typeVisible) vt = VT_None; // suppress type as already shown if (vt != VT_None) { char vtc = ' '; switch(vt) { case VT_8: vtc = 'b'; break; case VT_16: vtc = 'w'; break; case VT_32: vtc = 'l'; break; case VT_64: vtc = 'q'; break; case VT_Implicit: break; default: assert(0); } if (vtc != ' ') { int nlen = strlen(n); if (buf[nlen] == ' ') buf[nlen] = vtc; else { buf[nlen] = vtc; buf[nlen+1] = 0; off++; } } } switch(instr->form) { case OF_0: assert(instr->dst.type == OT_None); assert(instr->src.type == OT_None); assert(instr->src2.type == OT_None); break; case OF_1: assert(instr->dst.type != OT_None); assert(instr->src.type == OT_None); assert(instr->src2.type == OT_None); off += sprintf(buf+off, " %s", op2string(&(instr->dst), instr->vtype, fc)); break; case OF_2: assert(instr->dst.type != OT_None); assert(instr->src.type != OT_None); assert(instr->src2.type == OT_None); off += sprintf(buf+off, " %s", op2string(&(instr->src), instr->vtype, fc)); off += sprintf(buf+off, ",%s", op2string(&(instr->dst), instr->vtype, fc)); break; case OF_3: assert(instr->dst.type != OT_None); assert(instr->src.type != OT_None); assert(instr->src2.type != OT_None); off += sprintf(buf+off, " %s", op2string(&(instr->src2), instr->vtype, fc)); off += sprintf(buf+off, ",%s", op2string(&(instr->src), instr->vtype, fc)); off += sprintf(buf+off, ",%s", op2string(&(instr->dst), instr->vtype, fc)); break; default: assert(0); } return buf; }
static inline const char* node_compare_tag(const char* n) { return n<((const char*)0x100) ? op2string((int)n) : n; }