📄 oxccai.c
字号:
/* 1 ADDRESS MODE */
case jmploopop:
case jmpcontinueop:
case jmpbreakop:
case jmpgotoop:
ENCODE(jmp, LWORD, s1: LOCATION, dat: pnode->d.data->Uulong);
break;
case ljmptrueop:
case ljmpfalseop:
case jmptrueop:
case jmpfalseop:
break;
case retdataop:
break;
/* 2 ADDRESS MODE */
case getvalop:
case derefop:
case assignop:
case duptmpop:
case truthop:
case negop:
case complop:
case notop:
case copyop:
case castop:
case clrdatop:
case compsavop:
case totmpop:
case retstructop:
case switchop:
case argop:
break;
/* 3 ADDRESS MODE */
case plusop:
case minusop:
case mulop:
case divop:
case lshop:
case rshop:
case modop:
case orop:
case xorop:
case andop:
break;
case eqop:
case neqop:
case ltop:
case gtop:
case leop:
case geop:
break;
case getbitfieldop:
case putbitfieldop:
break;
case callfuncop:
break;
default:
break;
}
return iv->cod_usedtail;
}
static int
get_size(int type, int size)
{
switch(type)
{
case D_ARRAY:
case D_STRUCT:
case D_FUNCTION:
return 4;
default:
return size;
}
return 0;
}
static void
set_op(PND pnd, PopA ptr, unsigned char otype)
{
unsigned char optype = otype & 0xe0;
unsigned char isize = otype & 0x1f;
pnd->data = (DATUM *)ptr;
if(optype <= OPIMMED4)
{
pnd->dtype = optype >> 5;
pnd->quals = Q_CONST;
pnd->size = isize;
pnd->opsize = get_size(pnd->dtype, isize);
pnd->atype = A_IMMED;
#if 0
switch(pnd->dtype)
{
case D_SIGNED:
{
if(isize > 8)
{
memcpy(&pnd->data, ptr, isize);
}
else if(isize == 8)
{
pnd->data.Udouble = *((double*)ptr);
}
else
{
long l[2];
l[0] = 0;
l[1] = 0;
if(isize == 4)
l[0] = *((long*)ptr);
else if(isize == 2)
l[0] = *((short*)ptr);
else if(isize == 1)
l[0] = *((char*)ptr);
if(l[0] < 0)
l[1] = -1;
pnd->data.Udouble = *((double*)l);
}
break;
}
case D_UNSIGNED:
case D_POINTER:
{
if(isize > 8)
{
memcpy(&pnd->data, ptr, isize);
}
else if(isize == 8)
{
pnd->data.Udouble = *((double*)ptr);
}
else
{
unsigned long l[2];
l[0] = 0;
l[1] = 0;
if(isize == 4)
l[0] = *((unsigned long*)ptr);
else if(isize == 2)
l[0] = *((unsigned short*)ptr);
else if(isize == 1)
l[0] = *((unsigned char*)ptr);
pnd->data.Udouble = *((double*)l);
}
break;
}
case D_FLOAT:
{
if(isize == 4)
{
pnd->data.Udouble = *((float*)ptr);
}
else if(isize > 8)
{
#if SUPPORT_LONG_DOUBLE
pnd->data.Ulongdouble = *((long double)ptr);
#else
pnd->data.Udouble = 0.0;
#endif
}
else
{
pnd->data.Udouble = *((double*)ptr);
}
break;
}
}/* END: switch */
#endif
} /* END: OPIMMED */
else
{
unsigned short type = GS(ptr->dtype);
pnd->dtype = type & 0xff;
pnd->quals = (type >> 8) & 0xff;
pnd->size = GL(ptr->dsize);
pnd->opsize = get_size(pnd->dtype, pnd->size);
pnd->atype = GS(ptr->atype);
if(optype == OPAUTO)
{
if(GL(ptr->pofs) >= 0)
{
pnd->atype &= ~A_AUTO;
pnd->atype |= A_PARAM;
}
}
}
}
static void *
decode_anf(Piv iv, unsigned char *p)
{
void *dptr;
void *lptr;
void *rptr;
if(iv->debug >= '1')
cfeprintf("DECODE inst(%u) `%s'\n", *p, oxgenops[*p]);
if(*p == 0)
return POP->next;
iv->ob->p = p;
switch(*p)
{
case regainop:
case grabop:
case retvoidop:
{/* 0 address mode */
break;
}
case jmploopop:
case jmpcontinueop:
case jmpbreakop:
case jmpgotoop:
case ljmptrueop:
case jmptrueop:
case ljmpfalseop:
case jmpfalseop:
case funcstartop:
case funcstopop:
case retdataop:
{/* 1 address mode */
dptr = (p+8);
set_op(&iv->ob->d, dptr, p[1]);
break;
}
case getvalop:
case derefop:
case assignop:
case duptmpop:
case truthop:
case aliastmpop:
case negop:
case complop:
case notop:
case copyop:
case clrdatop:
case compsavop:
case totmpop:
case retstructop:
case switchop:
case argop:
case castop:
{/* 2 address mode */
dptr = (p+8);
lptr = (((char*)dptr) + (p[1] & 0x1f));
set_op(&iv->ob->d, dptr, p[1]);
set_op(&iv->ob->l, lptr, p[2]);
break;
}
case plusop:
case minusop:
case mulop:
case divop:
case modop:
case orop:
case xorop:
case andop:
case eqop:
case neqop:
case ltop:
case gtop:
case leop:
case geop:
case lshop:
case rshop:
case getbitfieldop:
case callfuncop:
case putbitfieldop:
{/* 3 address mode */
dptr = (p+8);
lptr = (((char*)dptr) + (p[1] & 0x1f));
rptr = (((char*)lptr) + (p[2] & 0x1f));
set_op(&iv->ob->d, dptr, p[1]);
set_op(&iv->ob->l, lptr, p[2]);
set_op(&iv->ob->r, rptr, p[3]);
break;
}
default:
{
return POP->next;
}
}/* END: switch(*p) */
/* Save pointers to the machine instructions generated by this ANF code */
iv->ob->startinst = iv->cod;
iv->ob->endinst = gen_inst(iv, iv->ob);
if(iv->cod != iv->ob->startinst)
{/* instructions were generated */
link_ob(iv);
}
return POP->next;
}/* END: decode_anf() */
static void *
skip_bracket(unsigned char *p)
{
long opcode = *p;
int opcount = 0;
for(;;)
{
if(*p == opcode)
++opcount;
else if(*p == endop && GL(POP->data) == opcode)
{
if(--opcount == 0) {
return p;
}
}
else if(*p == endfileop || *p == endallop)
{
PERROR(pName ":ERROR: Malformed input file3=%u=%p",*p, p);
}
p = POP->next;
}
return 0;
}
static void *
do_arrayelem(Piv iv, unsigned char *p)
{/* Arrange output for the stack machine */
void *sp = p;
unsigned char *q = skip_bracket(p);
void *sadims[10];
void *sadimsq[10];
void *spdims[10];
void *spdimsq[10];
int sacnt, spcnt, i;
/* Scan over the bracket and pick up the dimension computations */
sacnt = spcnt = 0;
p = POP->next;
while(p < q)
{
if(*p == arraydimsop)
{
void *qq = skip_bracket(p);
sadims[sacnt] = p;
sadimsq[sacnt++] = qq;
p = qq;
}
else if(*p == ptrdimsop)
{
void *qq = skip_bracket(p);
spdims[spcnt] = p;
spdimsq[spcnt++] = qq;
p = qq;
}
p = POP->next;
}
/* Dump the dimension computations in stack order */
for(i = spcnt-1; i >= 0; --i)
{
do_bracket(iv, spdims[i], spdimsq[i]);
}
for(i = sacnt-1; i >= 0; --i)
{
do_bracket(iv, sadims[i], sadimsq[i]);
}
/* Dump the remainder of the array element bracket */
p = sp;
sacnt = spcnt = 0;
p = POP->next;
while(p < q)
{
if(*p == arraydimsop)
p = ((Pop)sadimsq[sacnt++])->next;
else if(*p == ptrdimsop)
p = ((Pop)spdimsq[spcnt++])->next;
else
p = do_something(iv, p);
}
return ((Pop)q)->next;
}
static int
funcret_used(PopT op, unsigned char *p)
{
long tmpnum;
if( op->dtype == 0
&& op->dsize == 0)
{
return 1; /* void function */
}
tmpnum = op->tmpnum;
while(*p != funcexitop)
{
if(*p && *p <= (unsigned char)100)
{
unsigned char *qp = p+8;
if(*p == callfuncop)
{/* function using same temp */
if(GL(((PopT)qp)->tmpnum) == tmpnum)
{
return 1; /* not used earlier */
}
}
else
{
if((p[1]&0xe0) == OPRET)
{
if(GL(((PopT)qp)->tmpnum) == tmpnum)
{
return 0; /* ret used */
}
}
qp += p[1]&0x1f;
if((p[2]&0xe0) == OPRET)
{
if(GL(((PopT)qp)->tmpnum) == tmpnum)
{
return 0; /* ret used */
}
}
qp += p[2]&0x1f;
if((p[3]&0xe0) == OPRET)
{
if(GL(((PopT)qp)->tmpnum) == tmpnum)
{
return 0; /* ret used */
}
}
}
}
p = POP->next;
}
return 1; /* ret not used */
}
static unsigned char
check_for_builtin(Piv iv, unsigned char *p, int flag)
{
short symnum;
long key[2];
unsigned char *result;
if(flag == 0)
{
symnum = GS(((PopA)(p+20))->symnum);
}
else if(flag == 1)
{
symnum = GS(((PopI)(p+16))->s.symnum);
}
else if(flag == 2)
{
symnum = GS(POPI->s.symnum);
}
else return 0;
key[0] = symnum;
key[1] = 0;
if(SymFind(iv->builtintbl, key, &result) == 1)
return *result;
return 0;
}
static void *
do_funcall(Piv iv, unsigned char *p)
{
void *sp = p;
unsigned char *q = skip_bracket(p);
int argcnt, i, dump;
void *argloads[100];
void *argloadsq[100];
char *callop = 0;
unsigned char builtin = 0;
/* Scan over the bracket and pick up argument loads */
argcnt = 0;
p = POP->next;
while(p < q)
{
if(*p == getvalop && callop == 0)
{
builtin = check_for_builtin(iv, p, 0);
}
else if(*p == callfuncop)
callop = p;
else if(*p == argloadop)
{
void *qq = skip_bracket(p);
argloads[argcnt] = p;
argloadsq[argcnt++] = qq;
p = qq;
}
p = POP->next;
}
/* Check out whether the function return is used */
dump = funcret_used((PopT)(callop+8), q);
/* Calling an interpreter builtin ?? */
if(builtin)
{
iv->in_builtin = 1;
/* Dump the argument loads in order */
/* The ARG instruction will be suppressed because iv->in_builtin > 0 */
for(i = 0; i < argcnt; ++i)
{
do_bracket(iv, argloads[i], argloadsq[i]);
}
}
else
{
/* Generate the CALLSETUP instruction */
p = sp;
p = POP->next;
while(p < q)
{
if(*p == argloadop)
break;
else
p = do_something(iv, p);
}
/* Dump the argument loads in order */
for(i = 0; i < argcnt; ++i)
{
do_bracket(iv, argloads[i], argloadsq[i]);
}
/* Generate the CALL instruction */
}
return ((Pop)q)->next;
}
static void *
do_cond(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);
p = POP->next;
while(p < q)
{
p = do_something(iv, p);
}
return ((Pop)q)->next;
}
static void *
do_twopath(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);
p = POP->next;
while(p < q)
{
p = do_something(iv, p);
}
return ((Pop)q)->next;
}
static void *
do_logical(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);
p = POP->next;
while(p < q)
{
p = do_something(iv, p);
}
return ((Pop)q)->next;
}
static void *
do_binop(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);
p = POP->next;
while(p < q)
{
p = do_something(iv, p);
}
return ((Pop)q)->next;
}
static void *
do_strelem(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);
p = POP->next;
while(p < q)
{
p = do_something(iv, p);
}
return ((Pop)q)->next;
}
static void *
do_ptrelem(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);
p = POP->next;
while(p < q)
{
p = do_something(iv, p);
}
return ((Pop)q)->next;
}
static void *
do_argload(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);
p = POP->next;
while(p < q)
{
p = do_something(iv, p);
}
return ((Pop)q)->next;
}
static void *
do_preincr(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);
p = POP->next;
while(p < q)
{
p = do_something(iv, p);
}
return ((Pop)q)->next;
}
static void *
do_postincr(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);
p = POP->next;
while(p < q)
{
p = do_something(iv, p);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -