static char* GetAccessName(Symbol p) { if (p->aname != NULL) return p->aname; switch (p->kind) { case SK_Constant: p->aname = FormatName("$%s", p->name); break; case SK_String: case SK_Label: p->aname = FormatName(".%s", p->name); break; case SK_Variable: case SK_Temp: if (p->level == 0) { p->aname = p->name; } else if (p->sclass == TK_STATIC) { p->aname = FormatName("%s.%d", p->name, TempNum++); } else { p->aname = FormatName("%d(%%ebp)", AsVar(p)->offset); } break; case SK_Function: p->aname = p->name; break; case SK_Offset: { Symbol base = p->link; int n = AsVar(p)->offset; if (base->level == 0 || base->sclass == TK_STATIC) { p->aname = FormatName("%s%s%d", GetAccessName(base), n >= 0 ? "+" : "", n); } else { n += AsVar(base)->offset; p->aname = FormatName("%d(%%ebp)", n); } } break; default: assert(0); } return p->aname; }
void PutASMCode(int code, Symbol opds[]) { char *fmt = ASMTemplate[code]; char *prefix = NULL; int i; PutChar('\t'); while (*fmt) { switch (*fmt) { case ';': PutString("\n\t"); break; case '%': fmt++; if (*fmt == 'b') { prefix = "BYTE PTR "; fmt++; } else if (*fmt == 'w') { prefix = "WORD PTR "; fmt++; } else if (*fmt == 'd') { prefix = "DWORD PTR "; fmt++; } else prefix = NULL; i = *fmt - '0'; if (opds[i]->reg != NULL) { PutString(opds[i]->reg->name); } else { if (prefix && opds[i]->kind != SK_Constant && opds[i]->kind != SK_Function) { PutString(prefix); } PutString(GetAccessName(opds[i])); } break; default: PutChar(*fmt); break; } fmt++; } PutChar('\n'); }
void DefineGlobal(Symbol p) { Align(p); if (p->sclass != TK_STATIC) { Export(p); } Print("%s:\t", GetAccessName(p)); }
void DefineCommData(Symbol p) { GetAccessName(p); if (p->sclass == TK_STATIC) { Print(".lcomm\t%s,%d\n", p->aname, p->ty->size); } else { Print(".comm\t%s,%d\n", p->aname, p->ty->size); } }
void DefineCommData(Symbol p) { Align(p); GetAccessName(p); if (p->sclass == TK_STATIC) { Print("%s\t", p->aname); Space(p->ty->size); } else { Print("COMM\t%s:%d\n", p->aname, p->ty->size); } }
void Compiler::PutASMCode(const char *str, Symbol opds[]) { int i; const char *fmt = str; PutChar('\t'); while (*fmt) { switch (*fmt) { case ';': PutString("\n\t"); break; case '%': // Linux: // TEMPLATE(X86_MOVI4, "movl %1, %0") fmt++; if (*fmt == '%') { PutChar('%'); } else { i = *fmt - '0'; if (opds[i]->reg != NULL) { PutString((opds[i]->reg->name).c_str()); } else { PutString(GetAccessName(opds[i]).c_str()); } } break; default: PutChar(*fmt); break; } fmt++; } PutChar('\n'); }
void PutASMCode(int code, Symbol opds[]) { char *fmt = ASMTemplate[code]; int i; PutChar('\t'); while (*fmt) { switch (*fmt) { case ';': PutString("\n\t"); break; case '%': fmt++; if (*fmt == '%') { PutChar('%'); } else { i = *fmt - '0'; if (opds[i]->reg != NULL) { PutString(opds[i]->reg->name); } else { PutString(GetAccessName(opds[i])); } } break; default: PutChar(*fmt); break; } fmt++; } PutChar('\n'); }
void DefineLabel(Symbol p) { Print("%s:\n", GetAccessName(p)); }
void DefineAddress(Symbol p) { Print(".long\t%s", GetAccessName(p)); }
void Export(Symbol p) { Print(".globl\t%s\n\n", GetAccessName(p)); }
/** * Get a symbol's name in assembly */ static char* GetAccessName(Symbol p) { if (p->aname != NULL) return p->aname; switch (p->kind) { case SK_Constant: if (p->name[0] == '0' && p->name[1] == 'x') p->aname = FormatName("0%sH", &p->name[2]); else p->aname = p->name; break; case SK_String: case SK_IRegister: case SK_Label: p->aname = p->name; break; case SK_Variable: case SK_Temp: if (p->level == 0) { p->aname = FormatName("_%s", p->name); } else if (p->sclass == TK_STATIC) { p->aname = FormatName("%s%d", p->name, TempNum++); } else { p->aname = FormatName("(%d)[ebp]", AsVar(p)->offset); } break; case SK_Function: p->aname = FormatName("_%s", p->name); break; case SK_Offset: { Symbol base = p->link; int n = AsVar(p)->offset; if (base->level == 0 || base->sclass == TK_STATIC) { p->aname = FormatName("%s%s%d", GetAccessName(base), n >= 0 ? "+" : "", n); } else { n += AsVar(base)->offset; p->aname = FormatName("(%d)[ebp]", n); } } break; default: assert(0); } return p->aname; }
void DefineAddress(Symbol p) { Print("DWORD\t%s", GetAccessName(p)); }
void Export(Symbol p) { Print("PUBLIC %s\n\n", GetAccessName(p)); }
void Import(Symbol p) { Print("EXTRN %s:NEAR32\n\n", GetAccessName(p)); }