📄 w32incl.c
字号:
return p == NULL && q == NULL
|| p && q && p->op == q->op && p->syms[0] == q->syms[0]
&& sametree(p->kids[0], q->kids[0])
&& sametree(p->kids[1], q->kids[1]);
}
#endif
static void emit0(Node q)
{
#if 0/*_EMIT_DEBUG*/
Node p = q;
for (; p; p = p->x.next) {
if (p->op == LABEL+V) {
assert(p->syms[0]);
fprint(2,"# %s:\n", p->syms[0]->x.name);
} else {
int i;
fprint(2,"# node%c%d %s count=%d", p->x.listed ? '\'' : '#', p->x.inst,
opname(p->op), p->count);
for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++)
fprint(2," #%d", p->kids[i]->x.inst);
for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++) {
if (p->syms[i]->x.name)
fprint(2," %s", p->syms[i]->x.name);
if (p->syms[i]->name != p->syms[i]->x.name)
fprint(2," (%s)", p->syms[i]->name);
}
fprint(2,"\n");
}
}
fprint(2,"\n--------\n");
#endif
emit(q);
}
void EmitBooleanAssignment(Node p)
{
int i1,i2,invert;
int doExchange;
char *dst,tmpName[4],*reg;
i1 = atoi(p->kids[0]->syms[0]->name);
i2 = atoi(p->kids[1]->syms[0]->name);
reg = p->syms[RX]->x.name;
if (p->x.oldop == NEI && i1 == -1 && i2 == 0) {
print("\tsbbl\t%s,%s\n",reg,reg);
return;
}
if (!strcmp(reg,"%esi") || !strcmp(reg,"%edi")) {
print("\txchgl\t%s,%%eax\n",reg);
dst = "%al";
doExchange = 1;
}
else {
tmpName[0] = '%';
tmpName[1] = reg[2];
tmpName[2] = 'l';
tmpName[3] = 0;
doExchange = 0;
dst = tmpName;
}
print("\tset");
if (i1 == 0 && i2 == 1) {
invert = 1;
}
else if (i1 == 1 && i2 == 2) {
invert = 2;
}
else invert = 0;
switch (p->x.oldop) {
case EQI:
if (invert)
print("ne");
else
print("e");
break;
case NEI:
if (invert)
print("e");
else
print("ne");
break;
case LTI:
if (invert)
print("ge");
else
print("l");
break;
case LTU:
if (invert)
print("ae");
else
print("b");
break;
case LEI:
if (invert)
print("g");
else
print("le");
break;
case LEU:
if (invert)
print("a");
else
print("be");
break;
case GTI:
if (invert)
print("le");
else
print("g");
break;
case GTU:
if (invert)
print("be");
else
print("a");
break;
case GEI:
if (invert)
print("l");
else
print("ge");
break;
case GEU:
if (invert)
print("b");
else
print("ae");
break;
default:
fatal("Emit",StrTab[11],123);// <Unknown operation in boolean assignment\n>
break;
}
print("\t%s\n",dst);
if (doExchange)
print("\txchgl\t%%eax,%s\n",reg);
print("\tandl\t$1,%s\n",reg);
if (i1 == 0 && i2 == -1) {
print("\tdecl\t%s\n",reg);
return;
}
else if (invert == 2 || (i1 == 2 && i2 == 1)) {
print("\tincl\t%s\n",reg);
return;
}
if (invert == 0) {
if (i1 != 1 || i2 != 0) {
print("\tdecl\t%s\n",reg);
if ((i2-i1) != -1)
print("\tandl\t$%d,%s\n",i2-i1,reg);
if (i1 != 0)
print("\taddl\t$%d,%s\n",i1,reg);
}
}
// printf("boolean assignment\n");
}
static void emit2(Node p)
{
#define preg(f) ((f)[getregnum(p->x.kids[0])]->x.name)
switch (p->op) {
case CVCI:
print("\tmovsbl\t%s,%s\n",
preg(charreg),
p->syms[RX]->x.name);
break;
case CVCU:
print("\tmovzbl\t%s,%s\n",
preg(charreg),
p->syms[RX]->x.name);
break;
case CVSI:
print("\tmovswl\t%s,%s\n",
preg(shortreg),
p->syms[RX]->x.name);
break;
case CVSU:
print("\tmovzwl\t%s,%s\n",
preg(shortreg),
p->syms[RX]->x.name);
break;
case CVIC: case CVIS:
case CVUC: case CVUS:
{ char *dst = shortreg[getregnum(p)]->x.name;
char *src = preg(shortreg);
if (dst != src)
print("\tmovl\t%s,%s\n", src, dst);
}
break;
case JUMPI:
EmitBooleanAssignment(p);
break;
}
}
static void doarg(Node p)
{
int roundedsize = p->syms[0]->u.c.v.i;
Value v;
roundedsize = (3 + roundedsize) & ~3;
assert(p && p->syms[0]);
mkactual(4, roundedsize);
p->syms[1] = p->syms[0];
if (roundedsize != p->syms[0]->u.c.v.i) {
v.i = roundedsize;
p->syms[0] = constant(inttype,v);
}
}
static void blkfetch(int k,int off,int reg,int tmp)
{
}
static void blkstore(int k,int off,int reg,int tmp)
{
}
static void blkloop(int dreg,int doff,int sreg,int soff,int size,int tmps[])
{
}
static void local(Symbol p)
{
if (isfloat(p->type) || p->type->op == LONGLONG)
p->sclass = AUTO;
if (askregvar(p, rmap[ttob(p->type)]) == 0)
mkauto(p);
}
#define LABELFORMAT "_$"
int inFunctionCode = 0;
int FunctionHasCalls;
int ExceptionExternsDeclared=0;
int hasAllocA;
extern int ediIsSaved,esiIsSaved;
static void dumpEndFn(char *name)
{
int out=0;
char tmpbuf[400],outbuf[400];
sprintf(tmpbuf,"end of %s. Unused: ",name);
if ((usedmask[0] & 1) == 0) {strcat(tmpbuf," eax");out++;}
if ((usedmask[0] & (1 << 1)) == 0) {strcat(tmpbuf," ecx");out++;}
if ((usedmask[0] & (1 << 2)) == 0) {strcat(tmpbuf," edx");out++;}
if ((usedmask[0] & (1 << 3)) == 0) {strcat(tmpbuf," ebx");out++;}
if ((usedmask[0] & (1 << 6)) == 0) {strcat(tmpbuf," esi");out++;}
if ((usedmask[0] & (1 << 7)) == 0) {strcat(tmpbuf," edi ");out++;}
if (out == 0) strcat(tmpbuf," none.");
if (FunctionInfo.leafFunction) strcat(tmpbuf,"Leaf fn");
strcat(tmpbuf,"\n");
if (strlen(tmpbuf) < 79)
for (out=0; out< 79-strlen(tmpbuf);out++) {
if (out > 150) {
break;
}
outbuf[out] = '-';
}
outbuf[out] = 0;
strcat(outbuf,tmpbuf);
fprintf(ilFile,"%s",outbuf);
}
static void dumpFnStart(char *name)
{
char tmpbuf[200],outbuf[200];
if (IntermediateLanguageFile) {
int i;
fprintf(ilFile,"\n");
sprintf(tmpbuf,"Function %s\n",name);
for (i=0; i<79-strlen(tmpbuf);i++)
outbuf[i] = '-';
outbuf[i] = 0;
strcat(outbuf,tmpbuf);
fprintf(ilFile,"%s",outbuf);
}
}
void RestoreGlevelStack(void)
{
print("\tmovl\t%%ebp,__ShadowStack\n");
#if 0
if (glevel == 3) {
if (FunctionInfo.FnNrOfLines < 256)
print("\tmovb\t$0,-8(%%ebp)\n");
else
print("\tmovw\t$0,-8(%%ebp)\n");
}
#endif
}
static void SetupGlevelStack(Symbol f)
{
if (glevel > 2) {
print("\tpushl\t$_$Module\n");
print("\tpushl\t$%d\n",f->src.y << 16);
print("\tpushl\t$_$F%s\n",f->name);
print("\tmovl\t%%ebp,__ShadowStack\n");
FunctionInfo.pushedRegs += 12;
lastlinenr = f->src.y;
if(!strcmp(f->name,"main")|| !strcmp(f->name,"WinMain")) {
print("\t.extern\t__lccStackTrace\n");
print("\t.extern\t_signal\n");
print("\t.extern\t__plccStackTrace\n");
print("\t.globl\t__debuglevel\n");
print("\t.data\n__debuglevel:\n\t.long\t%d\n",glevel);
print("\t.text\n");
print("\tpushl\t$__lccStackTrace\n");
print("\tpushl\t$11\n");
print("\tcall\t_signal\n");
print("\taddl\t$8,%%esp\n");
print("\tmovl\t$__lccStackTrace,%%eax\n");
print("\tmovl\t%%eax,__plccStackTrace\n");
}
}
}
static void function(Symbol f,Symbol caller[],Symbol callee[],int n)
{
register int i;
int IsStdCall,stackAdjust=0;
int r;
int mo,startOffset,um,prologueEnd;
int saveOptimFlag;
dumpFnStart(cfunc->name);
inFunctionCode = 0;
saveOptimFlag = OptimizeFlag;
if (hasExceptions)
OptimizeFlag = 0;
outflush();
inFunctionCode = 1;
usedmask[0] = usedmask[1] = 0;
freemask[0] = freemask[1] = ~(unsigned) 0;
SetupRegisterVariables();
startOffset = offset = 4 + 4;
for (i = 0; callee[i]; i++) {
Symbol p = callee[i];
Symbol q = caller[i];
assert(q);
p->x.offset = q->x.offset = offset;
if (OptimizeFlag && p->sclass == REGISTER && p->x.regnode) {
q->x = p->x;
q->x.name = stringf("%d",p->x.offset);
usedmask[0] |= p->x.regnode->mask;
}
else {
if (p->sclass == REGISTER)
p->sclass = AUTO;
p->x.name = q->x.name = stringf("%d", p->x.offset);
}
offset += roundup(q->type->size, 4);
}
assert(caller[i] == 0);
mo = offset - startOffset;
offset = maxoffset = 0;
r = BuildBasicBlocks();
if (r == 0) {
ResetRegistersMasks();
OptimizeFlag = 0;
startOffset = offset = 4 + 4;
for (i = 0; callee[i]; i++) {
Symbol p = callee[i];
Symbol q = caller[i];
assert(q);
p->x.offset = q->x.offset = offset;
if (p->sclass == REGISTER)
p->sclass = AUTO;
p->x.name = q->x.name = stringf("%d", p->x.offset);
p->x.regnode = NULL;
offset += roundup(q->type->size, 4);
}
usedmask[0] = usedmask[1] = 0;
freemask[0] = freemask[1] = ~(unsigned) 0;
mo = offset - startOffset;
offset = maxoffset = 0;
}
gencode(caller, callee);
AnalyzeSecondPass();
IsStdCall = isStdCall(f);
if (IsStdCall) {
char fname[80];
sprintf(fname,"_%s@%d",f->name,mo);
f->x.name = stringf(fname);
}
print("\t.type\t%s,function\n", f->x.name);
print("%s:\n", f->x.name);
prologueEnd = 0;
framesize = roundup(maxoffset, 4);
if (hasExceptions) {
int offset = (glevel > 2) ? 16 : 0;
OptimizeFlag = 0;
print("\tpush\t%%ebp\n");
print("\tmovl\t%%esp,%%ebp\n");
SetupGlevelStack(f);
print("\tpushl\t$-1\n");
print("\tpushl\t$_$ExcepData\n");
print("\tpushl\t$__except_handler3\n");
print("\t.byte\t100\n");
print("\t.byte\t161\n");
print("\t.long\t0\n");
print("\tpush\t%%eax\n");
print("\t.byte\t100\n");
print("\t.byte\t137\n");
print("\t.byte\t37\n");
print("\t.long\t0\n");
print("\tsubl\t$12,%%esp\n");
print("\tpushl\t%%ebx\n");
print("\tpushl\t%%esi\n");
print("\tpushl\t%%edi\n");
print("\tmovl\t%%esp,-%d(%%ebp)\n",24+offset);
f->x.PrologueEnd = 44;
um = (1 << EBX)|(1 << ESI)|(1 << EDI);
}
else {
if (hasExceptions == 0 &&
glevel < 3 &&
hasAllocA == 0 && framesize == 0 &&
FunctionInfo.leafFunction) {
FunctionInfo.noFrame = 1;
}
else
if (hasAllocA || glevel > 2 || mo > 0 || framesize > 0) {
print("\tpushl\t%%ebp\n");
print("\tmovl\t%%esp,%%ebp\n");
prologueEnd += 3;
}
SetupGlevelStack(f);
if (framesize > 0) {
if (framesize < 4096) {
print("\tsubl\t$%d,%%esp\n", framesize);
prologueEnd += 3;
}
else {
print("\t.extern\t__stackprobe\n");
print("\tmovl\t$%d,%%eax\n",framesize);
print("\tcall\t__stackprobe\n");
prologueEnd += 10;
}
if (trapuv && framesize >= 4) {
int lab = genlabel(1);
print("\tmovl\t$%d,%%ecx\n",framesize/4);
print("_$%d:\n",lab);
print("\tdecl\t%%ecx\n");
print("\tmovl\t$0xFFFA5A5A,(%%esp,%%ecx,4)\n");
print("\tjne\t_$%d\n",lab);
prologueEnd += 14;
}
}
um = usedmask[0];
if (um & (1 << EBX)) {
print("\tpushl\t%%ebx\n");
prologueEnd++;
stackAdjust += 4;
}
ediIsSaved = esiIsSaved = 0;
if (um & (1 << ESI)) {
print("\tpushl\t%%esi\n");
esiIsSaved = 1;
prologueEnd++;
stackAdjust += 4;
}
if (um & (1 << EDI)) {
print("\tpushl\t%%edi\n");
if ((vmask[0] & (1 << EDI)) == 0)
ediIsSaved = 1;
prologueEnd++;
stackAdjust += 4;
}
FunctionInfo.pushedRegs = stackAdjust;
f->x.PrologueEnd = prologueEnd;
}
emitcode();
if (hasAllocA) {
char buf[40];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -