2020-02-16 01:19:05 +00:00
|
|
|
U0 ParsePush(CPrsStack *ps,I64 val)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
2020-02-16 01:19:05 +00:00
|
|
|
ps->stack[++ps->ptr]=val;
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 01:19:05 +00:00
|
|
|
I64 ParsePop(CPrsStack *ps)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
2020-02-16 01:19:05 +00:00
|
|
|
return ps->stack[ps->ptr--];
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 01:19:05 +00:00
|
|
|
U0 ParsePush2(CPrsStack *ps,I64 val)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
2020-02-16 01:19:05 +00:00
|
|
|
ps->stack2[++ps->ptr2]=val;
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 01:19:05 +00:00
|
|
|
I64 ParsePop2(CPrsStack *ps)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
2020-02-16 01:19:05 +00:00
|
|
|
return ps->stack2[ps->ptr2--];
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 01:19:05 +00:00
|
|
|
U0 ParsePopDeref(CPrsStack *ps)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
2020-02-15 23:03:01 +00:00
|
|
|
I64 i=ParsePop(ps);
|
|
|
|
CHashClass *tmpc=ParsePop(ps);
|
2020-02-15 20:01:48 +00:00
|
|
|
if (i.u16[0]!=IC_DEREF) {
|
2020-02-15 23:03:01 +00:00
|
|
|
ParsePush(ps,tmpc);
|
|
|
|
ParsePush(ps,i);
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
I64 ParseKeyWord(CCompCtrl *cc)
|
2020-02-16 06:07:34 +00:00
|
|
|
{//Convert cur token to $LK,"KEYWORD",A="FF:::/Compiler/OpCodes.DD,KEYWORD"$ or -1.
|
2020-02-15 20:01:48 +00:00
|
|
|
CHashGeneric *tmph;
|
|
|
|
if (cc->token==TK_IDENT &&(tmph=cc->hash_entry) && tmph->type&HTT_KEYWORD)
|
|
|
|
return tmph->user_data0;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:03:01 +00:00
|
|
|
CHashClass *ParseClassNew()
|
2020-02-15 20:01:48 +00:00
|
|
|
{/*Ptrs to classes are handled by
|
|
|
|
allocating 5 structures for each
|
|
|
|
new class and representing a pointer
|
2020-02-16 03:37:50 +00:00
|
|
|
to a class by advancing 1 struct forward
|
|
|
|
for one * and two forward for two **.
|
2020-02-15 20:01:48 +00:00
|
|
|
*/
|
|
|
|
I64 i;
|
|
|
|
CHashClass *res=CAlloc(sizeof(CHashClass)*(PTR_STARS_NUM+1),Fs->code_heap),
|
|
|
|
*tmpc=res;
|
|
|
|
for (i=0;i<=PTR_STARS_NUM;i++) {
|
|
|
|
tmpc->type=HTT_CLASS;
|
|
|
|
tmpc->raw_type=RT_PTR;
|
|
|
|
tmpc->size=sizeof(U8 *);
|
2020-02-16 00:20:04 +00:00
|
|
|
tmpc->ptr_stars_count=i;
|
2020-02-15 20:01:48 +00:00
|
|
|
tmpc++;
|
|
|
|
}
|
2020-02-16 00:26:51 +00:00
|
|
|
res->last_in_member_list=&res->member_list_and_root;
|
2020-02-15 20:01:48 +00:00
|
|
|
res->size=0;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:03:01 +00:00
|
|
|
CHashFun *ParseFunNew()
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
I64 i;
|
|
|
|
CHashFun *res=CAlloc(sizeof(CHashFun)*(PTR_STARS_NUM+1),Fs->code_heap),
|
|
|
|
*tmpf=res;
|
|
|
|
for (i=0;i<=PTR_STARS_NUM;i++) {
|
|
|
|
tmpf->type=HTT_FUN;
|
|
|
|
tmpf->raw_type=RT_PTR;
|
|
|
|
tmpf->size=sizeof(U8 *);
|
2020-02-16 00:20:04 +00:00
|
|
|
tmpf->ptr_stars_count=i;
|
2020-02-15 20:01:48 +00:00
|
|
|
tmpf++;
|
|
|
|
}
|
2020-02-16 00:26:51 +00:00
|
|
|
res->last_in_member_list=&res->member_list_and_root;
|
2020-02-15 20:01:48 +00:00
|
|
|
res->size=0;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
CIntermediateCode *ICAdd(CCompCtrl *cc,
|
2020-02-15 20:01:48 +00:00
|
|
|
I64 opcode_and_precedence,I64 arg, CHashClass *c,I64 flags=0)
|
|
|
|
{
|
|
|
|
CIntermediateCode *tmpi=MAlloc(sizeof(CIntermediateCode));
|
|
|
|
tmpi->ic_code=opcode_and_precedence.u16[0];
|
|
|
|
tmpi->ic_precedence=opcode_and_precedence.u16[1];
|
|
|
|
tmpi->ic_data=arg;
|
|
|
|
tmpi->ic_class=c;
|
|
|
|
if (cc->pass_trace) {
|
|
|
|
Bts(&cc->flags,CCf_PASS_TRACE_PRESENT);
|
|
|
|
flags|=ICF_PASS_TRACE;
|
|
|
|
}
|
2020-02-16 00:20:04 +00:00
|
|
|
if (cc->lock_count)
|
2020-02-15 20:01:48 +00:00
|
|
|
flags|=ICF_LOCK;
|
|
|
|
tmpi->ic_flags=flags;
|
|
|
|
tmpi->ic_line=cc->last_line_num;
|
2020-02-15 22:53:02 +00:00
|
|
|
QueueInsert(tmpi,cc->coc.coc_head.last);
|
2020-02-15 20:01:48 +00:00
|
|
|
return tmpi;
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
U0 COCInit(CCompCtrl *cc)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
CCodeCtrl *tmpcbh=&cc->coc;
|
2020-02-15 22:53:02 +00:00
|
|
|
QueueInit(&tmpcbh->coc_head.next);
|
|
|
|
QueueInit(&tmpcbh->coc_next_misc);
|
2020-02-15 20:01:48 +00:00
|
|
|
tmpcbh->coc_head.ic_code=IC_END;
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
U0 COCPush(CCompCtrl *cc)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
CCodeCtrl *tmpcbh=MAlloc(sizeof(CCodeCtrl));
|
2020-02-16 03:32:01 +00:00
|
|
|
MemCopy(tmpcbh,&cc->coc,sizeof(CCodeCtrl));
|
2020-02-15 20:01:48 +00:00
|
|
|
cc->coc.coc_next=tmpcbh;
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
CCompCtrl *COCPopNoFree(CCompCtrl *cc)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
CCodeCtrl *tmpcbh=cc->coc.coc_next;
|
2020-02-16 03:32:01 +00:00
|
|
|
MemCopy(&cc->coc,tmpcbh,sizeof(CCodeCtrl));
|
2020-02-15 20:01:48 +00:00
|
|
|
return tmpcbh;
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
U0 COCPop(CCompCtrl *cc)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
Free(COCPopNoFree(cc));
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
U0 COCAppend(CCompCtrl *cc, CCodeCtrl *tmpcbh)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
if (tmpcbh->coc_head.next!=&cc->coc.coc_head.next) {
|
|
|
|
cc->coc.coc_head.last->next=tmpcbh->coc_head.next;
|
|
|
|
tmpcbh->coc_head.next->last=cc->coc.coc_head.last;
|
|
|
|
cc->coc.coc_head.last=tmpcbh->coc_head.last;
|
|
|
|
tmpcbh->coc_head.last->next=&cc->coc.coc_head.next;
|
|
|
|
}
|
|
|
|
if (tmpcbh->coc_next_misc!=&cc->coc.coc_next_misc) {
|
|
|
|
cc->coc.coc_last_misc->next=tmpcbh->coc_next_misc;
|
|
|
|
tmpcbh->coc_next_misc->last=cc->coc.coc_last_misc;
|
|
|
|
cc->coc.coc_last_misc=tmpcbh->coc_last_misc;
|
|
|
|
tmpcbh->coc_last_misc->next=&cc->coc.coc_next_misc;
|
|
|
|
}
|
|
|
|
Free(tmpcbh);
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
CCodeMisc *COCMiscNew(CCompCtrl *cc,I64 ty)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
CCodeMisc *res=CAlloc(sizeof(CCodeMisc));
|
|
|
|
res->addr=INVALID_PTR;
|
|
|
|
res->type=ty;
|
2020-02-15 22:53:02 +00:00
|
|
|
QueueInsert(res,cc->coc.coc_last_misc);
|
2020-02-15 20:01:48 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
CCodeMisc *COCGoToLabelFind(CCompCtrl *cc,U8 *name)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
CCodeMisc *cm=cc->coc.coc_next_misc;
|
|
|
|
while (cm!=&cc->coc.coc_next_misc) {
|
|
|
|
if ((cm->type==CMT_GOTO_LABEL||cm->type==CMT_ASM_LABEL) &&
|
2020-02-16 03:32:01 +00:00
|
|
|
!StrCompare(cm->str,name))
|
2020-02-15 20:01:48 +00:00
|
|
|
return cm;
|
|
|
|
cm=cm->next;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
I64 COCFloatConstFind(CCompCtrl *cc,F64 d)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
I64 i;
|
|
|
|
CCodeMisc *cm=cc->coc.coc_next_misc;
|
|
|
|
while (cm!=&cc->coc.coc_next_misc) {
|
|
|
|
if (cm->type==CMT_FLOAT_CONSTS) {
|
|
|
|
for (i=0;i<cm->num_consts;i++)
|
|
|
|
if (cm->float_consts[i]==d)
|
|
|
|
return cm->addr+i*sizeof(F64);
|
|
|
|
if (cm->num_consts<CM_CONSTS_NUM) {
|
|
|
|
cm->float_consts[cm->num_consts++]=d;
|
|
|
|
return cm->addr+i*sizeof(F64);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cm=cm->next;
|
|
|
|
}
|
|
|
|
cm=COCMiscNew(cc,CMT_FLOAT_CONSTS);
|
|
|
|
cm->float_consts=MAlloc(CM_CONSTS_NUM*sizeof(F64));
|
|
|
|
cm->float_consts[cm->num_consts++]=d;
|
|
|
|
return cm->addr;
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
U0 COCDel(CCompCtrl *cc,CCodeCtrl *coc)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
CCodeMisc *cm,*cm1;
|
|
|
|
U8 *undef=NULL;
|
2020-02-15 22:53:02 +00:00
|
|
|
QueueDel(&coc->coc_head.next);
|
2020-02-15 20:01:48 +00:00
|
|
|
cm=coc->coc_next_misc;
|
|
|
|
while (cm!=&coc->coc_next_misc) {
|
|
|
|
cm1=cm->next;
|
|
|
|
switch (cm->type) {
|
|
|
|
case CMT_GOTO_LABEL:
|
|
|
|
case CMT_ASM_LABEL:
|
|
|
|
if (!(cm->flags&CMF_DEFINED)) {
|
|
|
|
undef=cm->str;
|
|
|
|
cm->str=NULL;
|
2020-02-16 00:20:04 +00:00
|
|
|
} else if (!cm->use_count) {
|
2020-02-15 20:01:48 +00:00
|
|
|
PrintWarn("Unused label %s\n",cm->str);
|
|
|
|
LexWarn(cc,"Unused label at ");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CMT_JMP_TABLE:
|
|
|
|
Free(cm->jmp_table);
|
|
|
|
break;
|
|
|
|
case CMT_FLOAT_CONSTS:
|
|
|
|
Free(cm->float_consts);
|
|
|
|
break;
|
|
|
|
case CMT_ARRAY_DIM:
|
2020-02-16 00:26:51 +00:00
|
|
|
LinkedListDel(cm->dim);
|
2020-02-15 20:01:48 +00:00
|
|
|
break;
|
|
|
|
case CMT_HASH_ENTRY:
|
|
|
|
HashDel(cm->h);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Free(cm->str);
|
|
|
|
Free(cm);
|
|
|
|
cm=cm1;
|
|
|
|
}
|
|
|
|
if (undef) {
|
|
|
|
PrintErr("Undefined goto label %s\n",undef);
|
|
|
|
Free(undef);
|
|
|
|
LexExcept(cc,"Undefined goto label at ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-15 23:38:06 +00:00
|
|
|
U0 COCHeaderPut(CCompCtrl *cc,I64 pass,Bool put)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
CIntermediateCode *tmpi;
|
|
|
|
if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT)) {
|
|
|
|
if (put) {
|
|
|
|
if (Bt(&cc->saved_pass_trace,pass-1)) {
|
|
|
|
"$$IV,1$$Pass %d:$$IV,0$$\n",pass-1;
|
|
|
|
tmpi=cc->coc.coc_head.next;
|
|
|
|
while (tmpi->ic_code) {
|
|
|
|
if (tmpi->ic_flags&ICF_PASS_TRACE)
|
|
|
|
ICPut(cc,tmpi);
|
|
|
|
tmpi=tmpi->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (Bt(&cc->saved_pass_trace,pass))
|
|
|
|
"$$IV,1$$Pass %d:$$IV,0$$\n",pass;
|
|
|
|
}
|
|
|
|
cc->pass=pass;
|
|
|
|
}
|
|
|
|
|
2020-02-16 03:37:50 +00:00
|
|
|
U8 *COCCompile(CCompCtrl *cc,I64 *_code_size,CDebugInfo **_debug,I64 *_type)
|
2020-02-15 20:01:48 +00:00
|
|
|
{
|
|
|
|
U8 *res;
|
|
|
|
CCodeMisc *lb;
|
|
|
|
I64 i,code_size,last_code_size;
|
|
|
|
|
|
|
|
COptReg reg_offsets[REG_REGS_NUM];
|
2020-02-16 03:37:50 +00:00
|
|
|
if (_debug) *_debug=NULL;
|
2020-02-15 20:01:48 +00:00
|
|
|
cc->pass=0;
|
|
|
|
COCHeaderPut(cc,1,TRUE);
|
|
|
|
OptPass012(cc);
|
|
|
|
COCHeaderPut(cc,2,TRUE);
|
|
|
|
OptPass012(cc);
|
|
|
|
COCHeaderPut(cc,3,TRUE);
|
|
|
|
OptPass3(cc,reg_offsets);
|
|
|
|
COCHeaderPut(cc,4,TRUE);
|
|
|
|
OptPass4(cc,reg_offsets,_type);
|
|
|
|
COCHeaderPut(cc,5,TRUE);
|
|
|
|
OptPass5(cc);
|
|
|
|
COCHeaderPut(cc,6,TRUE);
|
|
|
|
OptPass6(cc);
|
|
|
|
COCHeaderPut(cc,7,TRUE);
|
|
|
|
|
|
|
|
lb=cc->coc.coc_next_misc;
|
|
|
|
while (lb!=&cc->coc.coc_next_misc) {
|
|
|
|
if (lb->type==CMT_JMP_TABLE) {
|
|
|
|
for (i=0;i<lb->range;i++)
|
|
|
|
lb->jmp_table[i]=OptLabelFwd(lb->jmp_table[i]);
|
2020-02-16 00:45:35 +00:00
|
|
|
lb->default=OptLabelFwd(lb->default);
|
2020-02-15 20:01:48 +00:00
|
|
|
}
|
|
|
|
lb=lb->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
COCHeaderPut(cc,7,FALSE);
|
|
|
|
OptPass789A(cc,reg_offsets,NULL,NULL);
|
|
|
|
COCHeaderPut(cc,8,FALSE);
|
|
|
|
OptPass789A(cc,reg_offsets,NULL,NULL);
|
|
|
|
COCHeaderPut(cc,9,FALSE);
|
|
|
|
code_size=OptPass789A(cc,reg_offsets,NULL,NULL);
|
|
|
|
do {
|
|
|
|
last_code_size=code_size;
|
|
|
|
COCHeaderPut(cc,9,FALSE);
|
|
|
|
code_size=OptPass789A(cc,reg_offsets,NULL,NULL);
|
|
|
|
if (code_size>last_code_size) {
|
|
|
|
"Pass:9 Code Size\n";
|
|
|
|
LexExcept(cc,"Compiler Optimization Error at ");
|
|
|
|
}
|
|
|
|
} while (code_size<last_code_size);
|
|
|
|
|
|
|
|
if (cc->flags&CCF_AOT_COMPILE)
|
|
|
|
res=MAlloc(code_size);
|
|
|
|
else {
|
|
|
|
res=MAlloc(code_size,Fs->code_heap);
|
|
|
|
if (cc->htc.fun)
|
|
|
|
Fs->last_fun=cc->htc.fun;
|
|
|
|
}
|
|
|
|
COCHeaderPut(cc,10,FALSE);
|
2020-02-16 03:37:50 +00:00
|
|
|
code_size=OptPass789A(cc,reg_offsets,res,_debug);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
|
|
COCDel(cc,&cc->coc);
|
|
|
|
if (Bt(&cc->opts,OPTf_TRACE)) {
|
|
|
|
if (cc->flags&CCF_AOT_COMPILE) {
|
|
|
|
if (cc->aotc->seg_size==16)
|
|
|
|
Un(res,code_size,16);
|
|
|
|
else if (cc->aotc->seg_size==64)
|
|
|
|
Un(res,code_size,64);
|
|
|
|
else
|
|
|
|
Un(res,code_size,32);
|
|
|
|
} else
|
|
|
|
Un(res,code_size,64);
|
|
|
|
}
|
|
|
|
if (_code_size) *_code_size=code_size;
|
|
|
|
cc->saved_pass_trace=cc->pass_trace;
|
|
|
|
return res;
|
|
|
|
}
|