📄 w32incl.c
字号:
#include "cv.h"
static int isStdCall(Symbol f);
extern int atoi(char *);
extern char *InputFileName;
static int lastlinenr = -1;
#ifdef BUILTIN_ASM
/* asmcode - emit assembly language specified by asm */
void asmcode(char *str, Symbol argv[])
{
for ( ; *str; str++)
if (*str == '%' && str[1] >= 0 && str[1] <= 9)
print("%s", argv[*++str]->x.name);
else
print("%c", *str);
print("\n");
}
#endif
void ResetRegistersMasks(void)
{
tmask[IREG] = (1 << EDI) | (1 << ESI) | (1 << EBX) |
(1 << EDX) | (1 << ECX) | (1 << EAX);
vmask[IREG] = 0;
}
void SetRegistersMasks(void)
{
if (OptimizeFlag && FunctionInfo.hasCalls == 0 &&
FunctionInfo.hasBlockMove == 0 &&
FunctionInfo.hasDiv == 0) {
tmask[IREG] = (1 << EDX) | (1 << ECX) | (1 << EAX) | (1 << ESI) | (1 << EDI) | (1 << EBX);
vmask[IREG] = (1 << ESI) | (1 << EBX) | (1 << EDI);
FunctionInfo.leafFunction = 1;
}
else if (OptimizeFlag && FunctionInfo.hasBlockMove == 0 &&
FunctionInfo.NestedCalls == 0 && FunctionInfo.hasDiv == 0) {
tmask[IREG] = (1 << EDX) | (1 << ECX) | (1 << EAX) |(1 << ESI) |(1 << EDI) | (1 << EBX);
vmask[IREG] = (1 << EBX)|(1<<ESI)|(1 << EDI);
FunctionInfo.leafFunction = 0;
}
else
if (OptimizeFlag &&
FunctionInfo.hasBlockMove == 0 && FunctionInfo.hasDiv == 0)
{
tmask[IREG] = (1 << EDX) | (1 << ECX) | (1 << EAX) |(1 << ESI) |(1 << EDI) | (1 << EBX);
vmask[IREG] = (1 << EBX)|(1 << ESI)|(1 << EDI);
FunctionInfo.leafFunction = 0;
}
else
if (OptimizeFlag &&
FunctionInfo.hasBlockMove == 0)
{
tmask[IREG] = (1 << EDX) | (1 << ECX) | (1 << EAX) |(1 << ESI) |(1 << EDI) | (1 << EBX);
vmask[IREG] = (1 << EBX)|(1 << ESI);
FunctionInfo.leafFunction = 0;
}
else
{
tmask[IREG] = (1 << EDX) | (1 << ECX) | (1 << EAX) |(1 << ESI) |(1 << EDI) | (1 << EBX);
vmask[IREG] = (1 << EBX);
FunctionInfo.leafFunction = 0;
}
}
static Symbol ShiftWildCard;
static Symbol shiftreg[32];
static Symbol DivisorWildCard;
static Symbol divisorreg[32];
static void progbeg(int argc,char *argv[])
{
int i;
{
union {
char c;
int i;
} u;
u.i = 0;
u.c = 1;
swap = (unsigned)(u.i == 1) != IR->little_endian;
}
parseflags(argc, argv);
intreg[EAX] = mkreg("%%eax", EAX, 1, IREG);
intreg[EDX] = mkreg("%%edx", EDX, 1, IREG);
intreg[ECX] = mkreg("%%ecx", ECX, 1, IREG);
intreg[EBX] = mkreg("%%ebx", EBX, 1, IREG);
intreg[ESI] = mkreg("%%esi", ESI, 1, IREG);
intreg[EDI] = mkreg("%%edi", EDI, 1, IREG);
shortreg[EAX] = mkreg("%%ax", EAX, 1, IREG);
shortreg[ECX] = mkreg("%%cx", ECX, 1, IREG);
shortreg[EDX] = mkreg("%%dx", EDX, 1, IREG);
shortreg[EBX] = mkreg("%%bx", EBX, 1, IREG);
shortreg[ESI] = mkreg("%%si", ESI, 1, IREG);
shortreg[EDI] = mkreg("%%di", EDI, 1, IREG);
charreg[EAX] = mkreg("%%al", EAX, 1, IREG);
charreg[ECX] = mkreg("%%cl", ECX, 1, IREG);
charreg[EDX] = mkreg("%%dl", EDX, 1, IREG);
charreg[EBX] = mkreg("%%bl", EBX, 1, IREG);
for (i = 0; i < 8; i++)
fltreg[i] = mkreg("%d", i, 0, FREG);
memcpy(shiftreg,intreg,32*sizeof(Symbol));
shiftreg[ECX] = NULL;
ShiftWildCard = mkwildcard(shiftreg);
memcpy(divisorreg,intreg,32*sizeof(Symbol));
divisorreg[EDX] = NULL;
divisorreg[EAX] = NULL;
DivisorWildCard = mkwildcard(divisorreg);
rmap[C] = mkwildcard(charreg);
rmap[S] = mkwildcard(shortreg);
rmap[P] = rmap[B] = rmap[U] = rmap[I] = mkwildcard(intreg);
rmap[F] = rmap[D] = rmap[L] = mkwildcard(fltreg);
ResetRegistersMasks();
tmask[FREG] = 0xff;
vmask[FREG] = 0;
if (glevel > 2) {
print("\t.extern\t__ShadowStack\n");
print("\t.data\n");
print("_$Module:\n");
defstring(strlen(InputFileName)+1,InputFileName,1);
}
print("\t.text\n");
cseg = 0;
quo = mkreg("%%eax", EAX, 1, IREG);
quo->x.regnode->mask |= 1<<EDX;
rem = mkreg("%%edx", EDX, 1, IREG);
rem->x.regnode->mask |= 1<<EAX;
InstallIntrinsics();
}
static void segment(int n)
{
if (n == cseg)
return;
cseg = n;
if (n == CODE)
print("\t.text\n");
else if (cseg == BSS)
print("\t.bss\n");
else if (cseg == DATA || cseg == LIT)
print("\t.data\n");
}
static void progend(void)
{
segment(0);
}
extern Symbol askreg(Symbol rs,unsigned rmask[]);
static void target(Node p)
{
assert(p);
switch (p->op) {
case RSHI: case RSHU: case LSHI: case LSHU:
if (generic(p->kids[1]->op) != CNST
&& !( generic(p->kids[1]->op) == INDIR
&& p->kids[1]->kids[0]->op == VREG+P
&& p->kids[1]->syms[RX]->u.t.cse
&& generic(p->kids[1]->syms[RX]->u.t.cse->op) == CNST)) {
rtarget(p, 1, intreg[ECX]);
// setreg(p, intreg[EAX]);
p->syms[RX] = ShiftWildCard;
}
break;
case MULU:
setreg(p, quo);
rtarget(p, 0, intreg[EAX]);
break;
case DIVI: case DIVU:
setreg(p, quo);
rtarget(p, 0, intreg[EAX]);
rtarget(p, 1, intreg[ECX]);
// p->kids[1]->syms[RX] = DivisorWildCard;
break;
case MODI: case MODU:
setreg(p, rem);
rtarget(p, 0, intreg[EAX]);
rtarget(p, 1, intreg[ECX]);
// p->kids[1]->syms[RX] = DivisorWildCard;
break;
case ASGNB:
rtarget(p, 0, intreg[EDI]);
if (p->kids[0]->op == INDIRP ||
p->kids[0]->op == ADDP) {
Node pnode;
pnode = p->kids[0];
if (pnode->syms[RX] != intreg[EDI]) {
Node q = newnode(LOADP,
pnode, NULL, pnode->syms[0]);
p->kids[0] = p->kids[0]->x.kids[0] = q;
q->x.kids[0] = q->kids[0];
setreg(q,intreg[EDI]);
}
}
rtarget(p, 1, intreg[ESI]);
if (p->kids[1]->op == INDIRB) {
if (p->kids[1]->kids[0]->op == INDIRP ||
p->kids[1]->kids[0]->op == ADDP) {
Node pnode;
pnode = p->kids[1]->kids[0];
if (pnode->syms[RX] != intreg[ESI]) {
Node q = newnode(LOADP,
pnode, NULL, pnode->syms[0]);
p->kids[1]->kids[0] = p->kids[1]->kids[0]->x.kids[0] = q;
q->x.kids[0] = q->kids[0];
setreg(q,intreg[ESI]);
}
}
}
break;
case ARGB:
rtarget(p->kids[0], 0, intreg[ESI]);
break;
case CALLI: case CALLV:
setreg(p, intreg[EAX]);
break;
case RETI:
rtarget(p, 0, intreg[EAX]);
break;
}
}
static void clobber(Node p)
{
static int nstack = 0;
assert(p);
nstack = ckstack(p, nstack);
switch (p->op) {
case DIVI: case DIVU: case MULU:
spill(1 << EDX, IREG, p);
break;
#if 0
case MODI: case MODU:
spill(1 << EAX, IREG, p);
break;
#endif
case ASGNB: case ARGB:
spill(1<<ECX | 1<<ESI | 1<<EDI, IREG, p);
break;
case EQD: case LED: case GED: case LTD: case GTD: case NED:
case EQF: case LEF: case GEF: case LTF: case GTF: case NEF:
spill(1<<EAX, IREG, p);
break;
case CALLI:
case CALLD:
case CALLF:
case CALLV:
case CALLL:
spill(1<<EDX|1<<ECX,IREG,p);
break;
case ASGNL:
case SUBL:
case ADDL:
case MULL:
case DIVL:
case MODL:
case BCOML:
case BORL:
case BANDL:
case LSHL:
case RSHL:
case GEL:
case LTL:
case EQLO:
case NEL:
case GTL:
case LEL:
case ARGL:
spill((1<< EAX|1 << ECX|1 <<EDX),IREG,p);
break;
}
}
int clobbersWhich(Node p)
{
if (p == NULL) return 0;
switch (p->op) {
case DIVI: case DIVU: case MULU:
case MODI: case MODU:
return (1 << EAX)|(1 << EDX);
case ASGNB: case ARGB:
return (1<<ECX | 1<<ESI | 1<<EDI);
case EQD: case LED: case GED: case LTD: case GTD: case NED:
case EQF: case LEF: case GEF: case LTF: case GTF: case NEF:
return (1<<EAX);
case CALLI:
case CALLD:
case CALLF:
case CALLV:
case CALLL:
return (1<<EAX|1<<EDX|1<<ECX);
case ASGNL:
case SUBL:
case ADDL:
case MULL:
case DIVL:
case MODL:
case BCOML:
case BORL:
case BANDL:
case LSHL:
case RSHL:
case GEL:
case LTL:
case EQLO:
case NEL:
case GTL:
case LEL:
case ARGL:
return (1<< EAX|1 << ECX|1 <<EDX);
}
return 0;
}
#define isfp(p) (optype((p)->op)==F || optype((p)->op)==D)
static int ckstack(Node p,int n)
{
int i;
for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++)
if (isfp(p->x.kids[i]))
n--;
if (isfp(p) && p->count > 0)
n++;
if (n > 8)
error(StrTab[433]); // <expression too complicated\n>
debug(fprint(2, "(ckstack(%x)=%d)\n", p, n));
assert(n >= 0);
return n;
}
static int hasargs(Node p)
{
assert(p);
assert(generic(p->op) == CALL);
assert(p->syms[0]);
if (p->x.Flags)
return LBURG_MAX;
if (p->syms[0]->u.c.v.i > 0)
return 0;
return LBURG_MAX;
}
static Node cacheMemOp=NULL;
static int cacheMemOpResult=0;
static int memop(Node p)
{
if (cacheMemOp == p)
return cacheMemOpResult;
cacheMemOp = p;
assert(p);
assert(generic(p->op) == ASGN);
assert(p->kids[0]);
assert(p->kids[1]);
if (generic(p->kids[1]->kids[0]->op) == INDIR
&& sametree(p->kids[0], p->kids[1]->kids[0]->kids[0])) {
cacheMemOpResult = 0;
}
else
cacheMemOpResult = LBURG_MAX;
return cacheMemOpResult;
}
static int incrmem(Node p)
{
Node kid1;
assert(p);
kid1 = p->kids[1];
if (kid1 == NULL) return LBURG_MAX;
if (kid1->kids[0] == NULL) return LBURG_MAX;
if (kid1->kids[0]->kids[0] == NULL) return LBURG_MAX;
if (kid1->kids[0]->kids[0]->syms[0] == NULL) {
if (p->kids[0] == NULL)
return LBURG_MAX;
if (p->kids[0]->syms[0])
return LBURG_MAX;
if (sametree(kid1->kids[0]->kids[0],p->kids[0]))
return 0;
return LBURG_MAX;
}
if (p->kids[0] == NULL) return LBURG_MAX;
if (p->kids[0]->syms[0] == NULL) return LBURG_MAX;
if (p->kids[1]->kids[0]->kids[0]->syms[0] != p->kids[0]->syms[0]) {
if (p->kids[0]->syms[2] == NULL) return LBURG_MAX;
if (p->kids[0]->op != VREG+P) return LBURG_MAX;
if (p->kids[1]->kids[0]->kids[0]->syms[2] != p->kids[0]->syms[2])
return LBURG_MAX;
}
return 0;
}
static int dequal(Node p,int v)
{
assert(p);
if (p->op == CNSTD &&
p->syms[0]->u.c.v.d == (double)v)
return 0;
return LBURG_MAX;
}
static int fequal(Node p,int v)
{
assert(p);
if (p->op == CNSTF &&
p->syms[0]->u.c.v.f == (float)v)
return 0;
return LBURG_MAX;
}
static Node cacheimmOpShort=NULL;
static int cacheimmOpShortResult=0;
static int immediateOpShort(Node p)
{
Node kid1;
Symbol sym;
assert(p);
if (p == cacheimmOpShort)
return cacheimmOpShortResult;
cacheimmOpShort = p;
cacheimmOpShortResult = LBURG_MAX;
kid1 = p->kids[1];
if (kid1 == NULL) return LBURG_MAX;
if (kid1->kids[0] == NULL) return LBURG_MAX;
if (kid1->kids[0]->kids[0] == NULL) return LBURG_MAX;
if (kid1->kids[0]->kids[0]->kids[0] == NULL) return LBURG_MAX;
if (kid1->kids[0]->kids[0]->kids[0]->kids[0] == NULL) return LBURG_MAX;
if (p->kids[0] == NULL) return LBURG_MAX;
sym = kid1->kids[0]->kids[0]->kids[0]->kids[0]->syms[0];
if (sym == NULL) {
sym = kid1->kids[0]->kids[0]->kids[0]->kids[0]->syms[2];
if (sym == NULL) return LBURG_MAX;
if (sym != p->kids[0]->syms[2] || sym->x.wildcard)
return LBURG_MAX;
cacheimmOpShortResult = 0;
return 0;
}
if (sym != p->kids[0]->syms[0] && p->kids[0]->syms[0] == NULL) {
sym = kid1->kids[0]->kids[0]->kids[0]->kids[0]->syms[2];
if (sym == NULL) return LBURG_MAX;
if (sym != p->kids[0]->syms[2] || sym->x.wildcard)
return LBURG_MAX;
cacheimmOpShortResult = 0;
return 0;
}
if (sym == p->kids[0]->syms[0]) {
cacheimmOpShortResult = 0;
return 0;
}
return LBURG_MAX;
}
#if 0
static int iszero(Node p)
{
if ((p->op == CNSTI || p->op == CNSTU)
&& p->syms[0] &&
p->syms[0]->isconstant &&
p->syms[0]->u.c.v.i == 0)
return 0;
return LBURG_MAX;
}
static int iscon8(Node p)
{
if ((p->op == CNSTI || p->op == CNSTU)
&& p->syms[0] && (p->syms[0]->u.value & ~0xff) == 0)
return 0;
return LBURG_MAX;
}
static int iscon16(Node p)
{
if ((p->op == CNSTI || p->op == CNSTU)
&& p->syms[0] && (p->syms[0]->u.c.v.i & ~0xffff) == 0)
return 0;
return LBURG_MAX;
}
#endif
#ifndef ASM_LIB
static int sametree(Node p,Node q)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -