432 lines
11 KiB
Plaintext
432 lines
11 KiB
Plaintext
void CbPutClass(ClassStruct *c)
|
|
{
|
|
I8 i;
|
|
if (!c) return;
|
|
if (c->ptr_cnt>4) {
|
|
PrintFErr("put_class ptrcnt=%d\r\n",c->ptr_cnt);
|
|
while (TRUE)
|
|
//TODO:
|
|
SwapInNext;
|
|
}
|
|
for (i=0;i<c->ptr_cnt;i++)
|
|
PutChar('*');
|
|
c-=sizeof(ClassStruct)*c->ptr_cnt;
|
|
if (c->str)
|
|
PutS(c->str);
|
|
else {
|
|
PrintFErr("put_class str=NULL\r\n");
|
|
while (TRUE)
|
|
//TODO:
|
|
SwapInNext;
|
|
}
|
|
PutChar(CH_SPACE);
|
|
}
|
|
|
|
|
|
void CbPutIcParam(IcParam *p)
|
|
{
|
|
if (p->ptype)
|
|
PrintF("%Z %Z %Z ",
|
|
p->type&IT_MASK,"ST_IT_TYPES",
|
|
p->ptype&IT_MASK,"ST_IT_TYPES",
|
|
p->type>>4,"ST_TY_TYPES");
|
|
else
|
|
PrintF("%Z %Z ",
|
|
p->type&IT_MASK,"ST_IT_TYPES",
|
|
p->type>>4,"ST_TY_TYPES");
|
|
switch (p->type>>4) {
|
|
case TY_IMM>>4:
|
|
PrintF("#%X",p->disp);
|
|
break;
|
|
case TY_REG>>4:
|
|
PrintF("%Z",p->reg,"ST_U8_REGS");
|
|
break;
|
|
case TY_DISP>>4:
|
|
PrintF("%X[%Z]",p->disp,p->reg,"ST_U8_REGS");
|
|
break;
|
|
case TY_RIP_DISP32>>4:
|
|
PrintF("[%X]",p->disp);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CbPutIc(IntermediateCode *tempi)
|
|
{
|
|
U8 opcode=tempi->ic_opcode;
|
|
if (opcode>=EC_END_EXP && opcode!=EC_NOP1) {
|
|
PrintF("%15ts %016X ",
|
|
SysTextSub(opcode,"ST_INTERMEDIATE_CODE")+4,
|
|
tempi->ic_data);
|
|
if (tempi->r.type&TY_MASK) {
|
|
CbPutIcParam(&tempi->r);
|
|
cout "<-";
|
|
}
|
|
if (tempi->p1.type&TY_MASK)
|
|
CbPutIcParam(&tempi->p1);
|
|
cout ",";
|
|
if (tempi->p2.type&TY_MASK)
|
|
CbPutIcParam(&tempi->p2);
|
|
cout ",";
|
|
if (tempi->p3.type&TY_MASK)
|
|
CbPutIcParam(&tempi->p3);
|
|
cout " ";
|
|
CbPutClass(tempi->ic_class);
|
|
if (tempi->ic_flags & ICF_P3_TO_DOUBLE)
|
|
PutS("$$FG,LTBLUE$$p3d$$FG$$ ");
|
|
if (tempi->ic_flags & ICF_P3_TO_INT)
|
|
PutS("$$FG,GREEN$$p3i$$FG$$ ");
|
|
if (tempi->ic_flags & ICF_P2_TO_DOUBLE)
|
|
PutS("$$FG,LTBLUE$$p2d$$FG$$ ");
|
|
if (tempi->ic_flags & ICF_P2_TO_INT)
|
|
PutS("$$FG,GREEN$$p2i$$FG$$ ");
|
|
if (tempi->ic_flags & ICF_P1_TO_DOUBLE)
|
|
PutS("$$FG,LTBLUE$$p1d$$FG$$ ");
|
|
if (tempi->ic_flags & ICF_P1_TO_INT)
|
|
PutS("$$FG,GREEN$$p1i$$FG$$ ");
|
|
if (tempi->ic_flags & ICF_R_TO_DOUBLE)
|
|
PutS("$$FG,LTBLUE$$rd$$FG$$ ");
|
|
if (tempi->ic_flags & ICF_R_TO_INT)
|
|
PutS("$$FG,GREEN$$ri$$FG$$ ");
|
|
if (tempi->ic_flags & ICF_USE_DOUBLE)
|
|
PutS("[double] ");
|
|
if (tempi->ic_flags & ICF_USE_UNSIGNED)
|
|
PutS("[unsigned] ");
|
|
if (tempi->ic_flags & ICF_USE_INT)
|
|
PutS("[int] ");
|
|
if (tempi->ic_flags & ICF_NO_DEPEND_RESULT)
|
|
PutS("-DEP ");
|
|
if (tempi->ic_flags & ICF_DEPEND_RESULT)
|
|
PutS("+DEP ");
|
|
if (tempi->ic_flags & ICF_NOT_ADDRESS)
|
|
PutS("(NOT_ADDRESS) ");
|
|
if (tempi->ic_flags & ICF_PUSH_RESULT)
|
|
PutS("(PUSH) ");
|
|
if (tempi->ic_flags & ICF_PUSH_CMP)
|
|
PutS("(PUSH_CMP) ");
|
|
if (tempi->ic_flags & ICF_POP_CMP)
|
|
PutS("(POP_CMP) ");
|
|
if (tempi->ic_flags & ICF_RCX_CMP)
|
|
PutS("(RCX_CMP) ");
|
|
if (tempi->ic_flags & ICF_RCX_CMP2)
|
|
PutS("(RCX_CMP2) ");
|
|
CrLf;
|
|
}
|
|
}
|
|
|
|
void CbInitOutPtrs(LexCbStack *ll)
|
|
{
|
|
CodeBlk *cb=MAllocZ(sizeof(CodeBlk));
|
|
cb->next=NULL;
|
|
ll->cb_out_first=cb;
|
|
ll->cb_out_last=cb;
|
|
ll->cb_misc_list=NULL;
|
|
ll->cb_misc_list_end=&ll->cb_misc_list;
|
|
ll->cb_out_ptr=&cb->data;
|
|
ll->cb_out_end=ll->cb_out_ptr+sizeof(IntermediateCode)*CB_IC_CNT;
|
|
ll->cb_last_out_ptr=&cb->data;
|
|
}
|
|
|
|
void CbInitInPtrs(LexCbStack *ll)
|
|
{
|
|
CodeBlk *cb=ll->cb_out_first;
|
|
ll->cb_in_first=cb;
|
|
ll->cb_in_ptr=&cb->data;
|
|
ll->cb_in_end=ll->cb_in_ptr+sizeof(IntermediateCode)*CB_IC_CNT;
|
|
}
|
|
|
|
void CbPutAllIc(LexStruct *lx)
|
|
{
|
|
IntermediateCode *tempi;
|
|
CbInitInPtrs(&lx->cb);
|
|
tempi=lx->cb.cb_in_ptr;
|
|
while (tempi->ic_opcode) {
|
|
if (tempi->ic_flags&ICF_TRACE)
|
|
CbPutIc(tempi);
|
|
tempi+=sizeof(IntermediateCode);
|
|
}
|
|
}
|
|
|
|
void CbAddIc(LexStruct *lx,
|
|
U8 opcode_and_precidence,U8 arg, ClassStruct *c,U8 flags=0)
|
|
{
|
|
IntermediateCode *tempi=lx->cb.cb_out_ptr;
|
|
CodeBlk *cb,*cb1;
|
|
lx->cb.cb_last_out_ptr=tempi;
|
|
tempi->ic_opcode=opcode_and_precidence.u2[0];
|
|
tempi->ic_precidence=opcode_and_precidence.u2[1];
|
|
tempi->ic_data=arg;
|
|
tempi->ic_class=c;
|
|
if (Bt(&lx->flags,LFf_OPT_TRACE)) {
|
|
Bts(&lx->flags,LFf_OPT_TRACE_PRESENT);
|
|
flags|=ICF_TRACE;
|
|
}
|
|
tempi->ic_flags=flags;
|
|
tempi->ic_line=lx->lag_line_num;
|
|
if (lx->flags & LF_PARSE_TRACE)
|
|
CbPutIc(tempi);
|
|
|
|
tempi+=sizeof(IntermediateCode);
|
|
if (tempi>=lx->cb.cb_out_end) {
|
|
cb=MAllocZ(sizeof(CodeBlk));
|
|
cb->next=NULL;
|
|
cb1=lx->cb.cb_out_last;
|
|
cb1->next=cb;
|
|
lx->cb.cb_out_last=cb;
|
|
tempi=&cb->data;
|
|
lx->cb.cb_out_end=tempi+sizeof(IntermediateCode)*CB_IC_CNT;
|
|
}
|
|
lx->cb.cb_out_ptr=tempi;
|
|
}
|
|
|
|
IntermediateCode *CbGetIc1(LexCbStack *lx)
|
|
{
|
|
IntermediateCode *tempi=lx->cb_in_ptr,
|
|
*tempi1=tempi+sizeof(IntermediateCode);
|
|
CodeBlk *cb;
|
|
if (tempi1>=lx->cb_in_end) {
|
|
cb=tempi1-sizeof(IntermediateCode)*CB_IC_CNT-offset(CodeBlk.data);
|
|
cb=cb->next;
|
|
tempi1=&cb->data;
|
|
lx->cb_in_end=tempi1+sizeof(IntermediateCode)*CB_IC_CNT;
|
|
}
|
|
lx->cb_in_ptr=tempi1;
|
|
return tempi;
|
|
}
|
|
|
|
void CbPush(LexStruct *lx)
|
|
{
|
|
LexCbStack *templ=MAlloc(sizeof(LexCbStack));
|
|
MemCpy(templ,&lx->cb,sizeof(LexCbStack));
|
|
if (lx->cb.cb_misc_list_end==&lx->cb.cb_misc_list)
|
|
templ->cb_misc_list_end=&templ->cb_misc_list;
|
|
lx->cb.cb_next=templ;
|
|
}
|
|
|
|
void CbPop(LexStruct *lx)
|
|
{
|
|
LexCbStack *templ=lx->cb.cb_next;
|
|
MemCpy(&lx->cb,templ,sizeof(LexCbStack));
|
|
if (templ->cb_misc_list_end==&templ->cb_misc_list)
|
|
lx->cb.cb_misc_list_end=&lx->cb.cb_misc_list;
|
|
Free(templ);
|
|
}
|
|
|
|
CbMiscStruct *CbFindGotoLabel(LexStruct *lx,I1 *name)
|
|
{
|
|
CbMiscStruct *templ=lx->cb.cb_misc_list;
|
|
while (templ) {
|
|
if (templ->type==CBMT_GOTO_LABEL) {
|
|
if (!StrCmp(templ->str,name))
|
|
return templ;
|
|
}
|
|
templ=templ->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
CbMiscStruct *CbMiscNew(LexStruct *lx,U8 t)
|
|
{
|
|
CbMiscStruct *result=MAllocZ(sizeof(CbMiscStruct));
|
|
lx->cb.cb_misc_list_end->next=result;
|
|
lx->cb.cb_misc_list_end=result;
|
|
result->address=INVALID_PTR;
|
|
result->type=t;
|
|
return result;
|
|
}
|
|
|
|
|
|
void DelCbMiscList(LexStruct *lx)
|
|
{
|
|
CbMiscStruct *mc=lx->cb.cb_misc_list,*mc1;
|
|
while (mc) {
|
|
mc1=mc->next;
|
|
if (mc->type==CBMT_GOTO_LABEL &&
|
|
!mc->address) {
|
|
lx->cb.cb_misc_list=NULL; //prevent recursion
|
|
PrintFErr("%S%s\r\n","ST_UNDEFINED_GOTO_LABEL",mc->str);
|
|
throw(EXCEPT_COMPILER,1);
|
|
}
|
|
Free(mc->str);
|
|
Free(mc->jmp_table);
|
|
Free(mc);
|
|
mc=mc1;
|
|
}
|
|
}
|
|
|
|
LexStruct *CbPopNoFree(LexStruct *lx)
|
|
{
|
|
LexCbStack *templ=lx->cb.cb_next;
|
|
MemCpy(&lx->cb,templ,sizeof(LexCbStack));
|
|
if (templ->cb_misc_list_end==&templ->cb_misc_list)
|
|
lx->cb.cb_misc_list_end=&lx->cb.cb_misc_list;
|
|
return templ;
|
|
}
|
|
|
|
void CbAppend(LexStruct *lx, LexCbStack *ll)
|
|
{
|
|
IntermediateCode *tempi;
|
|
CbInitInPtrs(ll);
|
|
do {
|
|
tempi=CbGetIc1(ll);
|
|
if (tempi->ic_opcode) {
|
|
CbAddIc(lx,tempi->ic_opcode+tempi->ic_precidence<<16,tempi->ic_data,
|
|
tempi->ic_class,tempi->ic_flags);
|
|
}
|
|
} while (tempi->ic_opcode);
|
|
DelLinkedList(ll->cb_out_first);
|
|
|
|
if (ll->cb_misc_list_end!=&ll->cb_misc_list) {
|
|
lx->cb.cb_misc_list_end->next=ll->cb_misc_list;
|
|
lx->cb.cb_misc_list_end=ll->cb_misc_list_end;
|
|
}
|
|
Free(ll);
|
|
}
|
|
|
|
void CbCombine(LexStruct *lx)
|
|
{
|
|
CodeBlk *cb=lx->cb.cb_out_first,*cb1,*cb2;
|
|
I8 i=0,j=sizeof(IntermediateCode)*CB_IC_CNT;
|
|
void *ptr;
|
|
while (cb) {
|
|
i++;
|
|
cb=cb->next;
|
|
}
|
|
if (i>1) {
|
|
cb1=MAlloc(i*j+offset(CodeBlk.data));
|
|
cb1->next=NULL;
|
|
cb=lx->cb.cb_out_first;
|
|
ptr=&cb1->data;
|
|
while (cb) {
|
|
cb2=cb->next;
|
|
MemCpy(ptr,&cb->data,j);
|
|
ptr+=j;
|
|
Free(cb);
|
|
cb=cb2;
|
|
}
|
|
lx->cb.cb_out_first=cb1;
|
|
}
|
|
}
|
|
|
|
U1 *CbCompile(LexStruct *lx,ClassStruct *fun_class,
|
|
U8 *code_size,DbgInfo **dbg_info,U8 *type=NULL)
|
|
{
|
|
U1 *result;
|
|
I8 register_offsets[NUM_REGS],min_line=MAX_I8,max_line=0;
|
|
if (dbg_info)
|
|
*dbg_info=NULL;
|
|
|
|
CbCombine(lx);
|
|
if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) {
|
|
if (Bt(&lx->pass_trace_mask,0)) {
|
|
coutln "$$IV 1$$Before Pass 1:$$IV 0$$";
|
|
CbPutAllIc(lx);
|
|
}
|
|
}
|
|
CmpOptPass1(lx,fun_class,TRUE);
|
|
if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) {
|
|
if (Bt(&lx->pass_trace_mask,1)) {
|
|
coutln "$$IV 1$$After Pass 1:$$IV 0$$";
|
|
CbPutAllIc(lx);
|
|
}
|
|
}
|
|
CmpOptPass2(lx,fun_class,register_offsets);
|
|
if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) {
|
|
if (Bt(&lx->pass_trace_mask,2)) {
|
|
coutln "$$IV 1$$After Pass 2:$$IV 0$$";
|
|
CbPutAllIc(lx);
|
|
}
|
|
}
|
|
CmpOptPass3(lx,register_offsets,type);
|
|
if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) {
|
|
if (Bt(&lx->pass_trace_mask,3)) {
|
|
coutln "$$IV 1$$After Pass 3:$$IV 0$$";
|
|
CbPutAllIc(lx);
|
|
}
|
|
}
|
|
CmpOptPass4(lx);
|
|
if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) {
|
|
if (Bt(&lx->pass_trace_mask,4)) {
|
|
coutln "$$IV 1$$After Pass 4:$$IV 0$$";
|
|
CbPutAllIc(lx);
|
|
}
|
|
}
|
|
CmpOptPass5(lx,fun_class);
|
|
if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) {
|
|
if (Bt(&lx->pass_trace_mask,5)) {
|
|
coutln "$$IV 1$$After Pass 5:$$IV 0$$";
|
|
CbPutAllIc(lx);
|
|
}
|
|
}
|
|
|
|
if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT))
|
|
if (Bt(&lx->pass_trace_mask,6))
|
|
coutln "$$IV 1$$Pass 6:$$IV 0$$";
|
|
CmpOptPass678(lx,fun_class,register_offsets,NULL,6,dbg_info,&min_line,&max_line);
|
|
|
|
if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT))
|
|
if (Bt(&lx->pass_trace_mask,7))
|
|
coutln "$$IV 1$$Pass 7:$$IV 0$$";
|
|
*code_size=CmpOptPass678(lx,fun_class,register_offsets,NULL,7,dbg_info,&min_line,&max_line);
|
|
|
|
result=MAlloc(*code_size);
|
|
if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT))
|
|
if (Bt(&lx->pass_trace_mask,8))
|
|
coutln "$$IV 1$$Pass 8:$$IV 0$$";
|
|
*code_size=CmpOptPass678(lx,fun_class,register_offsets,result,8,dbg_info,&min_line,&max_line);
|
|
|
|
DelLinkedList(lx->cb.cb_out_first);
|
|
DelCbMiscList(lx);
|
|
if (Bt(&lx->flags,LFf_COMPILE_TRACE)) {
|
|
if (lx->a) {
|
|
if (lx->a->seg_size==16)
|
|
CallExtStr("Dasm2",result,*code_size,16);
|
|
else if (lx->a->seg_size==64)
|
|
CallExtStr("Dasm2",result,*code_size,64);
|
|
else
|
|
CallExtStr("Dasm2",result,*code_size,32);
|
|
} else
|
|
CallExtStr("Dasm2",result,*code_size,64);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void DelHashTable(SysHashTable *tempht)
|
|
{
|
|
I8 i;
|
|
SysHashEntry *temph,*temph1;
|
|
ClassStruct *tempc;
|
|
GlblVarStruct *tempg;
|
|
if (!tempht) return;
|
|
for (i=0;i<=tempht->mask;i++) {
|
|
temph=tempht->body[i];
|
|
while (temph) {
|
|
temph1=temph->next;
|
|
if (!(temph->type&HTT_DICT_WORD))
|
|
Free(temph->str);
|
|
if (temph->type & (HTT_FUNCTION | HTT_CLASS |
|
|
HTT_STR_CONST | HTT_GLBL_VAR |
|
|
HTT_SYS_SYMBOL)) {
|
|
Free(temph->source_link);
|
|
Free(temph->index);
|
|
if (temph->type & (HTT_FUNCTION | HTT_CLASS)) {
|
|
tempc=temph;
|
|
Free(tempc->debug);
|
|
Free(tempc->import_name);
|
|
DelMemberList(tempc);
|
|
//assumes code not on heap
|
|
} else if (temph->type&HTT_STR_CONST)
|
|
Free(temph><(StrConstStruct *)->data);
|
|
else if (temph->type&HTT_GLBL_VAR) {
|
|
tempg=temph;
|
|
DelLinkedList(tempg->dim_list);
|
|
Free(tempg->import_name);
|
|
}
|
|
}
|
|
Free(temph);
|
|
temph=temph1;
|
|
}
|
|
}
|
|
Free(tempht);
|
|
}
|
|
|