📄 w32incl.c
字号:
sprintf(buf,"\tmovl\t%%%%ebp,%%%%esp\n\tsubl\t$%d,%%%%esp\n",stackAdjust+framesize);
print(buf);
}
if (hasExceptions) {
print("\txchg\t%%eax,%%ecx\n");
print("\tmov\t-16(%%ebp),%%eax\n");
/*
The built-in assembler has problems with
assembling the instruction
mov %eax,%fs:0x0
*/
print("\t.byte\t100\n");
print("\t.byte\t163\n");
print("\t.long\t0x0\n");
print("\txchg\t%%eax,%%ecx\n");
/* print("\tmov\t%%ecx,%%fs:__except_list\n"); */
}
if (um & (1 << EDI))
print("\tpopl\t%%edi\n");
if (um & (1 << ESI))
print("\tpopl\t%%esi\n");
if (um & (1 << EBX))
print("\tpopl\t%%ebx\n");
if (FunctionInfo.noFrame == 0) {
if (hasAllocA/*mo > 0*/ || framesize > 0 || glevel > 2) {
print("\tleave\n");
}
else if (mo > 0)
print("\tpopl\t%%ebp\n");
}
if (glevel > 4)
print("\tmovl\t%%ebp,__ShadowStack\n");
if (FunctionInfo.mmxCalls)
print("\temms\n");
if (IsStdCall && mo) {
print("\tret\t$%d\n",mo);
}
else print("\tret\n");
{ int l = genlabel(1);
print("%s%d:\n",LABELFORMAT, l);
print("\t.size\t%s,%s%d-%s\n", f->x.name,LABELFORMAT, l, f->x.name);
if (glevel > 2) {
print("\t.data\n");
print("\t.align\t2\n");
print("_$F%s:\n",f->name);
defstring(1+strlen(f->name),f->name,1);
print("\t.text\n");
}
}
if (hasExceptions) {
if (!ExceptionExternsDeclared) {
print("\t.extern\t__except_handler3\n");
print("\t.extern\t__except_list\n");
ExceptionExternsDeclared = 1;
}
hasExceptions = 0;
}
if (OptimizeFlag) {
SendToOptimizer();
}
else
outflush();
inFunctionCode = 0;
OptimizeFlag = saveOptimFlag;
ResetRegistersMasks();
if (IntermediateLanguageFile) {
dumpEndFn(f->name);
}
}
static void defsymbol(Symbol p)
{
if (p->scope >= LOCAL && p->sclass == STATIC)
p->x.name = stringf("%s%d",LABELFORMAT, genlabel(1));
else if (p->generated)
p->x.name = stringf("%s%s",LABELFORMAT, p->name);
else if (p->scope == GLOBAL || p->sclass == EXTERN) {
if (p->Flags) {
if (p->Flags == STDCALLATTRIBUTE) {
Type ty;
int argsize = 0;
ty = p->type;
if (ty && ty->op == FUNCTION && ty->u.f.proto) {
int i;
for (i=0; ty->u.f.proto[i];i++) {
if (ty->u.f.proto[i])
argsize += roundup(ty->u.f.proto[i]->size,4);
}
}
if (ty && ty->op == FUNCTION)
p->x.name = stringf("_%s@%d",p->name,argsize);
else
p->x.name = stringf("_%s",p->name);
}
else if (p->Flags == DLLIMPORTATTRIBUTE) {
p->x.name = stringf("__imp__%s",p->name);
}
else p->x.name = stringf("_%s", p->name);
}
else p->x.name = stringf("_%s", p->name);
}
else
p->x.name = p->name;
}
static void address(Symbol q,Symbol p,int n)
{
if (p->scope == GLOBAL
|| p->sclass == STATIC || p->sclass == EXTERN)
q->x.name = stringf("%s%s%d",
p->x.name, n >= 0 ? "+" : "", n);
else {
q->x.offset = p->x.offset + n;
q->x.name = stringd(q->x.offset);
}
q->x.ArraySymbol = p;
}
static void defconst(int ty,Value v)
{
switch (ty) {
case C:
print("\t.byte\t%d\n", v.uc);
return;
case S:
print("\t.word\t%d\n", v.ss);
return;
case I:
print("\t.long\t%d\n", v.i);
return;
case U:
print("\t.long\t0x%x\n", v.u);
return;
case P:
print("\t.long\t0x%x\n", v.p);
return;
case F:
print("\t.long\t0x%x\n", *(unsigned *) &v.f);
return;
case L:
{
double d = v.d;
__int64 i64 = d;
print("\t.long\t0x%x\n",(int)i64);
print("\t.long\t0x%x\n",(int)(i64 >> 32));
return;
}
case D:{
unsigned *p = (unsigned *) &v.d;
print("\t.long\t0x%x,0x%x\n", p[swap], p[1 - swap]);
return;
}
}
assert(0);
}
static void defaddress(Symbol p)
{
print("\t.long\t%s\n", p->x.name);
}
extern int NeedsLineReset;
void PutLineNumber(int lineno)
{
if (lastlinenr == lineno) return;
print("\t.line\t%d\n",lineno);
if ((glevel > 3) && cseg == CODE) {
int relativeLn = lineno - cfunc->src.y;
if (NeedsLineReset || lastlinenr != lineno-1) {
if ((relativeLn < 256 && NeedsLineReset == 0)
|| FunctionInfo.FnNrOfLines < 256)
print("\tmovb\t$%d,-8(%%ebp)\n",relativeLn);
else {
print("\tmovw\t$%d,-8(%%ebp)\n",relativeLn);
}
}
else
print("\tincl\t-8(%%ebp)\n");
NeedsLineReset = 0;
}
lastlinenr = lineno;
}
static void defstring(int n,char *s,int siz)
{
int i,val;
char *sizeString;
if (siz == 1)
sizeString = "byte";
else {
sizeString = "word";
n = n/2;
}
val = (siz == 1)? *s : *(unsigned short *)s;
print("\t.%s\t%d%c",sizeString,val,(n==1)?'\n':',');
s += siz;
if (n <= 1) return;
n--;
i = 1;
while (n > 0) {
val = (siz == 1)?*s:*(unsigned short *)s;
if (n > 1 && (i!=15)) print("%d,",val);
else print("%d",val);
if (n > 1 && i==15) {
print("\n\t.%s\t",sizeString);
i = 0;
}
else if (n == 1) print("\n");
s += siz;
n--;
i++;
}
}
static void export(Symbol p)
{
print("\t.globl\t%s\n", p->x.name);
}
static void
import(Symbol p)
{
// int oldseg = cseg;
if (p->ref > 0 &&!IsIntrinsic(p->name)) {
// segment(0);
print("\t.extern\t%s\n", p->x.name);
// segment(oldseg);
}
}
static int ntypes;
static void global (Symbol p)
{
int a;
/*
All definitions will start at an address multiple of four.
I think that is all that the x86 requires.
*/
if (p->type && p->type->op == DOUBLE)
a = 3;
else
a = 2;
print("\t.align\t%d\n",a);
if (!p->generated) {
print("\t.type\t%s,%s", p->x.name,
isfunc(p->type) ? "function" : "object");
print("\n");
}
if (p->u.seg == BSS) {
if (p->sclass == STATIC)
print("\t.lcomm\t%s,%d\n", p->x.name, p->type->size);
else
print("\t.comm\t%s,%d\n", p->x.name, p->type->size);
} else {
if (!p->generated)
print("\t.size\t%s,%d\n", p->x.name, p->type->size);
print("%s:\n", p->x.name);
}
}
static void
space(int n)
{
if (cseg != BSS)
print("\t.space\t%d\n", n);
}
static char *currentfile; /* current file name */
static void stabblock ARGS((int, int, Symbol*));
static void stabinit ARGS((char *, int, char *[]));
static void stabline ARGS((Coordinate *));
static void stabsym ARGS((Symbol));
static void stabtype ARGS((Symbol));
static void asgncode ARGS((Type, int));
static void dbxout ARGS((Type));
static int emittype ARGS((Type, int, int));
/* asgncode - assign type code to ty */
static void asgncode(Type ty,int lev)
{
if (ty->x.marked || ty->x.typeno)
return;
ty->x.marked = 1;
switch (ty->op) {
case VOLATILE: case CONST: case VOLATILE+CONST:
asgncode(ty->type, lev);
ty->x.typeno = ty->type->x.typeno;
break;
case POINTER: case FUNCTION: case ARRAY:
asgncode(ty->type, lev + 1);
/* fall thru */
case VOID: case CHAR: case SHORT: case INT: case UNSIGNED:
case FLOAT: case DOUBLE:
break;
case STRUCT: case UNION: {
Field p;
for (p = fieldlist(ty); p; p = p->link)
asgncode(p->type, lev + 1);
/* fall thru */
case ENUM:
if (ty->x.typeno == 0)
ty->x.typeno = ++ntypes;
if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9'))
dbxout(ty);
break;
}
default:
assert(0);
}
}
/* dbxout - output .stabs entry for type ty */
static void dbxout(Type ty)
{
}
/* stabblock - output a stab entry for '{' or '}' at level lev */
static void stabblock(int brace,int lev,Symbol *p)
{
if (brace == '{') {
while (*p) {
stabsym(*p++);
}
}
}
/* stabinit - initialize stab output */
static void stabinit(char *file,int argc,char *argv[])
{
if (file && *file) {
print("\t.file \"%s\"\n",file);
currentfile = file;
}
}
/* stabline - emit stab entry for source coordinate *cp */
static void stabline(Coordinate *cp)
{
PutLineNumber(cp->y);
}
/* stabsym - output a code view entry for symbol p */
static void stabsym(Symbol pSym)
{
int t,c,l;
char SymbolRecord[90],*p;
if (glevel == 0) return;
if (pSym->name == NULL) return;
if (isfunc(pSym->type) ) return;
if (pSym->sclass == TYPEDEF) return;
if (pSym->generated || pSym->computed)
return;
c = *pSym->name;
if (c >= '0' && c <= '9') return;
memset(SymbolRecord,0,90);
p = SymbolRecord + 2;
if (pSym->sclass == STATIC) {
*(unsigned short *)p = 0x201;
p += 2;
}
else if (pSym->scope == GLOBAL) {
*(unsigned short *)p = 0x202; /* Public symbol */
p += 2;
}
else return;
p += 6; /* Skip offset and section until code generation */
t = GetType(pSym);
*(unsigned short *)p = t;
p += 2;
p = PutLengthPrefixedName(p,pSym->name);
l = (p - SymbolRecord) - 2;
p = SymbolRecord;
*(unsigned short *)p = l;
AddToCVData(SymbolRecord,l+2,pSym->x.name);
}
/* stabtype - output a stab entry for type *p */
static void stabtype(Symbol p)
{
int c,n;
if (p->src.file == NULL) {
return; /* built in type */
}
if (p->uses == NULL || p->type == NULL) {
return; /* not used */
}
if (p->type->x.marked == 0) return;
if (p->sclass == TYPEDEF) c = 'T';
else c = 't';
n = GetFileNumber(p->src.file);
fprintf(xrefFile,"%c %s %d %d",c,p->name,n,p->src.y);
if (p->type->x.pointerEmitted) {
Type ty;
ty = p->type;
if (ty) {
if (ty->x.pointerEmitted) {
fprintf(xrefFile," *");
}
}
}
fprintf(xrefFile,"\n");
}
static int isStdCall(Symbol f)
{
Type typePtr;
if (f == NULL) return 0;
if (f->Flags) return 1;
typePtr = f->type;
while (typePtr) {
if (typePtr->op == STDCALL) {
return 1;
}
typePtr = typePtr->type;
}
return 0;
}
extern void WriteLocalsDebugInfo(Symbol f,int lineno);
Interface x86IR = {
1, 1, 0, /* char */
2, 2, 0, /* short */
4, 4, 0, /* int */
4, 4, 1, /* float */
8, 4, 1, /* double */
4, 4, 0, /* T * */
0, 1, 0, /* struct so that ARGB keeps stack aligned */
1, /* little_endian */
0, /* mulops_calls */
0, /* wants_callb */
1, /* wants_argb */
0, /* left_to_right */
0, /* wants_dag */
address,
blockbeg,
blockend,
defaddress,
defconst,
defstring,
defsymbol,
emit0,
export,
function,
gen,
global,
import,
local,
progbeg,
progend,
segment,
space,
stabblock, 0, WriteLocalsDebugInfo, stabinit, stabline, stabsym, stabtype,
{1, blkfetch, blkstore, blkloop,
_label,
_rule,
_nts,
_kids,
_opname,
_arity,
_string,
_templates,
_isinstruction,
_ntname,
emit2,
doarg,
target,
clobber,
}
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -