int code_whileclause(ASTNode whileclause,int BASEREG){ CODE86 *code; ASTNode cond,stmt; char *label[2]; int opr; int i; OPR oprand; cond=whileclause->firstchild; stmt=cond->nextsibling; whileclause->codes.head=whileclause->codes.tail=NULL; for(i=0;i<2;i++) label[i]=new_label(LABEL_JMP,NULL,0); /* .L0 */ code=newcode(PS_LABEL,NULL,NULL,label[0]); code_link_one(&whileclause->codes,code); /* cond codes */ opr=code_cond(cond,BASEREG); switch(opr){ case ODD: oprand=OP_JP; break; case NEQ: oprand=OP_JE; break; case EQL: oprand=OP_JNE; break; case LSS: oprand=OP_JGE; break; case GTR: oprand=OP_JLE; break; case LEQ: oprand=OP_JG; break; case GEQ: oprand=OP_JL; break; } code_link(&whileclause->codes,&cond->codes); /* if false goto .L1 */ code=newcode(oprand,NULL,NULL,label[1]); code_link_one(&whileclause->codes,code); /* stmt */ code_stmt(stmt,BASEREG); code_link(&whileclause->codes,&stmt->codes); /* jmp .L0 */ code=newcode(OP_JMP,NULL,NULL,label[0]); code_link_one(&whileclause->codes,code); /* .L1 */ code=newcode(PS_LABEL,NULL,NULL,label[1]); code_link_one(&whileclause->codes,code); return 0; }
void geninit( void ) { VMRef c1; copycode(); c1 = newcode(OBJINIT,4l,0l,curloc,NullVMRef); curloc += 4; if ( !NullRef(lastinit) ) { Code *c = VMAddr(Code,lastinit); c->value.v = c1; VMDirty(lastinit); } lastinit = c1; return; } /* geninit */
int code_globalvar(ASTNode root){ ASTNode varlist=root->firstchild; ASTNode p=varlist; CODE86 *code; int size,align; SYM sym; root->codes.head=root->codes.tail=NULL; while(p){ if(p->type==Ident) sym=p->sym; else sym=p->firstchild->sym; if(sym==NULL)fprintf(stderr,"************var sym not found\n"); size=sym->size; if(size<16) align=4; else if(size<64) align=16; else align=64; code=newcode(PS_COMM,newdessrc(IMM,size,NULL,NONE,0,0),newdessrc(IMM,align,NULL,NONE,0,0),(void *)sym->name); p->codes.head=p->codes.tail=code; code_link(&root->codes,&p->codes); p=p->nextsibling; } return 0; }
PUBLIC void genmodule( WORD mod ) { VMRef v = VMNew( sizeof (asm_Module) ); asm_Module * m = VMAddr( asm_Module, v ); int i; VMlock(v); trace("MODULE %d",mod); genend(); /* finish off last module */ m->next = NullVMRef; m->start = codeptr(); m->refs = NullVMRef; m->id = mod; m->linked = FALSE; m->file_name = infile_duplicate; for ( i = 0; i < LOCAL_HASHSIZE ; i++ ) { m->symtab[ i ].head = NullVMRef, m->symtab[ i ].entries = 0; } /* if this is a library module, we do not link it by default but */ /* only if it is referenced. */ if (!inlib) { asm_Module * tm = VMAddr( asm_Module, tailmodule ); tailmodule = tm->next = v; m->linked = TRUE; if ( NullRef( firstmodule ) ) firstmodule = v; } VMunlock(curmod); curmod = v; /* leave new curmod locked */ (void)newcode( (WORD)OBJMODULE, 0L, 0L, curloc,v ); curloc = 0; lastinit = NullVMRef; return; } /* genmodule */
PUBLIC void copycode( void ) { if( codepos == 0 ) return; if( codepos <= 4 ) (void)newcode((WORD) OBJLITERAL, codepos,0l,curloc,*((INT *)codevec)); else { VMRef vmr = VMNew((int)codepos); UBYTE *v = VMAddr(UBYTE,vmr); codesize += codepos; memcpy((char *)v, (char *)codevec, (int)codepos); (void)newcode((WORD) OBJCODE, codepos,0l,curloc,vmr); } curloc += codepos; codepos = 0; }
int code_call(ASTNode call,int BASEREG){ CODE86 *code; ASTNode ident; SYM sym; call->codes.head=call->codes.tail=NULL; ident=call->firstchild; sym=ident->sym; code=newcode(OP_CALL,NULL,NULL,sym->name); code_link_one(&call->codes,code); return 0; }
int code_assign(ASTNode stmt,int BASEREG){ CODE86 *code; ASTNode lval=stmt->firstchild; SYM sym=lval->firstchild->sym; ASTNode expi=lval->firstchild->nextsibling; ASTNode exp=lval->nextsibling; stmt->codes.head=stmt->codes.tail=0; if(expi==NULL){ if(code_exptest(exp,BASEREG)==2){ code=newcode(OP_MOVL,code_exp_ds(exp,BASEREG),code_exp_ds(lval,BASEREG),NULL); code_link_one(&stmt->codes,code); }else{ code_exp(exp,BASEREG); code_link(&stmt->codes,&exp->codes); code=newcode(OP_MOVL,newdessrc(REG,0,NULL,EAX,0,0),code_exp_ds(lval,BASEREG),NULL); code_link_one(&stmt->codes,code); } }else { if(code_exptest(expi,BASEREG)==2){ if(code_exptest(exp,BASEREG)==2){ code=newcode(OP_MOVL,code_exp_ds(exp,BASEREG),code_exp_ds(lval,BASEREG),NULL); code_link_one(&stmt->codes,code); }else{ code_exp(exp,BASEREG); code_link(&stmt->codes,&exp->codes); code=newcode(OP_MOVL,newdessrc(REG,0,NULL,EAX,0,0),code_exp_ds(lval,BASEREG),NULL); code_link_one(&stmt->codes,code); } }else{ code_exp(exp,BASEREG); code_link(&stmt->codes,&exp->codes); code=newcode(OP_PUSHL,newdessrc(REG,0,NULL,EAX,0,0),NULL,NULL); code_link_one(&stmt->codes,code); code_exp(expi,BASEREG); code_link(&stmt->codes,&expi->codes); code=newcode(OP_POPL,newdessrc(REG,0,NULL,ECX,0,0),NULL,NULL); code_link_one(&stmt->codes,code); /* index is in eax */ if(sym->memtype==Stack){ code=newcode(OP_MOVL,newdessrc(REG,0,NULL,ECX,0,0),newdessrc(REG_OFFSET_INDEX,EAX,NULL,BASEREG,sym->offset,4),NULL); code_link_one(&stmt->codes,code); }else{ code=newcode(OP_MOVL,newdessrc(REG,0,NULL,ECX,0,0),newdessrc(STATIC_INDEX,EAX,sym,NONE,0,4),NULL); code_link_one(&stmt->codes,code); } } } return 0; }
int code_program(ASTNode root){ SYMTAB symtab=root->symtab; SYM sym; ASTNode p; CODE86 *code; CODELIST *list; root->codes.head=root->codes.tail=NULL; /*generate file psuedo code*/ code=newcode(PS_FILE,NULL,NULL,infn); root->codes.head=code; root->codes.tail=code; /*generate bss data segment*/ p=root->firstchild; // printf("enter code_program\n"); while(p){ switch(p->type){ case FuncDef: code_function(p); break; case ConstDecl: code_globalconst(p); break; case VarDecl: code_globalvar(p); break; case FuncDecl: p->codes.head=p->codes.tail=NULL; break; default: fprintf(stderr,"unknown compunit"); p->codes.head=p->codes.tail=NULL; } p=p->nextsibling; //fprintf(stderr,"compunit checked\n"); } p=root->firstchild; while(p){ //fprintf(stderr,"compunit link\n"); code_link(&root->codes,&p->codes); p=p->nextsibling; } return 0; }
PUBLIC void genend() { asm_Module *m; copycode(); m = VMAddr( asm_Module, curmod ); m->length = curloc; m->end = newcode((WORD)OBJEND,0l,0l,curloc,0l); endmodule(); return; } /* genend */
int code_exp(ASTNode exp,int BASEREG){ CODE86 *code; ASTNode exp1,exp2; SYM sym; exp->codes.head=exp->codes.tail=NULL; if(exp->type==Number){ code=newcode(OP_MOVL,newdessrc(IMM,exp->val,NULL,NONE,0,0),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&exp->codes,code); return 0; }else if(exp->type==LVal){ if(exp->firstchild->nextsibling==NULL){ /* exp is a scalar */ code=newcode(OP_MOVL,code_exp_ds(exp,BASEREG),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&exp->codes,code); return 0; }else{ sym=exp->firstchild->sym; exp1=exp->firstchild->nextsibling; if(code_exptest(exp1,BASEREG)==2){ int index=exp1->val; if(sym->memtype==Stack){ code=newcode(OP_MOVL,newdessrc(REG_OFFSET,0,NULL,BASEREG,index*4+sym->offset,0),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&exp->codes,code); }else{ code=newcode(OP_MOVL,newdessrc(STATIC_OFFSET,0,sym,NONE,index*4,0),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&exp->codes,code); } return 0; }else{ code_exp(exp1,BASEREG); code_link(&exp->codes,&exp1->codes); /* index is in eax */ if(sym->memtype==Stack){ code=newcode(OP_MOVL,newdessrc(REG_OFFSET_INDEX,EAX,NULL,BASEREG,sym->offset,4),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&exp->codes,code); }else{ code=newcode(OP_MOVL,newdessrc(STATIC_INDEX,EAX,sym,NONE,0,4),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&exp->codes,code); } return 0; } } }else if(exp->firstchild->type==UnaryOp){ Opr opr=exp->firstchild->opr; exp1=exp->firstchild->nextsibling; code_exp(exp1,BASEREG); code_link(&exp->codes,&exp1->codes); if(opr==MINUS){ code=newcode(OP_NEGL,newdessrc(REG,0,NULL,EAX,0,0),NULL,NULL); code_link_one(&exp->codes,code); } }else { Opr opr=exp->firstchild->nextsibling->opr; exp1=exp->firstchild; exp2=exp->firstchild->nextsibling->nextsibling; code_exp(exp2,BASEREG); code_link(&exp->codes,&exp2->codes); /* pushl %eax */ code=newcode(OP_PUSHL,newdessrc(REG,0,NULL,EAX,0,0),NULL,NULL); code_link_one(&exp->codes,code); code_exp(exp1,BASEREG); code_link(&exp->codes,&exp1->codes); /* popl %ecx */ code=newcode(OP_POPL,newdessrc(REG,0,NULL,ECX,0,0),NULL,NULL); code_link_one(&exp->codes,code); switch(opr){ case PLUS: code=newcode(OP_ADDL,newdessrc(REG,0,NULL,ECX,0,0),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&exp->codes,code); break; case MINUS: code=newcode(OP_SUBL,newdessrc(REG,0,NULL,ECX,0,0),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&exp->codes,code); break; case MULTI: code=newcode(OP_IMULL,newdessrc(REG,0,NULL,ECX,0,0),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&exp->codes,code); break; case DIVIDE: code=newcode(OP_CLTD,NULL,NULL,NULL); code_link_one(&exp->codes,code); code=newcode(OP_IDIVL,newdessrc(REG,0,NULL,ECX,0,0),NULL,NULL); code_link_one(&exp->codes,code); break; case MOD: code=newcode(OP_CLTD,NULL,NULL,NULL); code_link_one(&exp->codes,code); code=newcode(OP_IDIVL,newdessrc(REG,0,NULL,ECX,0,0),NULL,NULL); code_link_one(&exp->codes,code); /* mov %edx, %eax */ code=newcode(OP_MOVL,newdessrc(REG,0,NULL,EDX,0,0),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&exp->codes,code); break; } } return 0; }
int code_blockconst(ASTNode constdecl,int BASEREG){ ASTNode p=constdecl->firstchild; ASTNode pp; SYM sym; int val,offset,size,listsize; CODE86 *code; int pushflag=0; CODELIST pushlist,poplist,initlist; constdecl->codes.head=constdecl->codes.tail=NULL; pushlist.head=pushlist.tail=NULL; poplist.head=poplist.tail=NULL; initlist.head=initlist.tail=NULL; while(p){ switch(p->type){ case ConstIdent: pp=p->firstchild; sym=pp->sym; pp=pp->nextsibling; val=pp->val; offset=sym->offset; code=newcode(OP_MOVL,newdessrc(IMM,val,NULL,NONE,0,0),newdessrc(REG_OFFSET,0,NULL,BASEREG,offset,0),NULL); p->codes.head=p->codes.tail=code; break; case ConstArray: p->codes.head=p->codes.tail=NULL; pp=p->firstchild; sym=pp->sym; offset=sym->offset; size=sym->size; if(size==0)break; //empty array such as const int a[0] pp=pp->nextsibling; if(pp->type!=ConstList) pp=pp->nextsibling; listsize=pp->list_size; if(listsize*4<size){ pushflag=1; /* leal offset(%ebp/%esi),%edx*/ code=newcode(OP_LEAL,newdessrc(REG_OFFSET,0,NULL,BASEREG,offset,0),newdessrc(REG,0,NULL,EDX,0,0),NULL); code_link_one(&initlist,code); /* movl $0,%eax */ code=newcode(OP_MOVL,newdessrc(IMM,0,NULL,NONE,0,0),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&initlist,code); /* movl size/4 ,%ecx */ code=newcode(OP_MOVL,newdessrc(IMM,size/4,NULL,NONE,0,0),newdessrc(REG,0,NULL,ECX,0,0),NULL); code_link_one(&initlist,code); /* movl %edx, %edi */ code=newcode(OP_MOVL,newdessrc(REG,size/4,NULL,EDX,0,0),newdessrc(REG,0,NULL,EDI,0,0),NULL); code_link_one(&initlist,code); /* rep stosl */ code=newcode(OP_REP_STOSL,NULL,NULL,NULL); code_link_one(&initlist,code); } pp=pp->firstchild; while(pp){ /* movl val,offset(%ebp/%esi) */ code=newcode(OP_MOVL,newdessrc(IMM,pp->val,NULL,NONE,0,0),newdessrc(REG_OFFSET,0,NULL,BASEREG,offset,0),NULL); code_link_one(&initlist,code); offset+=4; pp=pp->nextsibling; } break; } code_link(&initlist,&p->codes); p=p->nextsibling; } if(pushflag){ /*pushl %edi*/ code=newcode(OP_PUSHL,newdessrc(REG,0,NULL,EDI,0,0),NULL,NULL);; code_link_one(&pushlist,code); /* popl %edi */ code=newcode(OP_POPL,newdessrc(REG,0,NULL,EDI,0,0),NULL,NULL);; code_link_one(&poplist,code); } code_link(&constdecl->codes,&pushlist); code_link(&constdecl->codes,&initlist); code_link(&constdecl->codes,&poplist); return 0; }
int code_cond(ASTNode cond,int BASEREG){ CODE86 *code; int opr; int unaryflag; int test1,test2; ASTNode p,exp1,exp2; p=cond->firstchild; cond->codes.head=cond->codes.tail=NULL; if(p->type==OddOp){ opr=p->opr; unaryflag=1; }else{ opr=p->nextsibling->opr; unaryflag=0; } if(unaryflag){ exp1=cond->firstchild->nextsibling; code_exp(exp1,BASEREG); code_link(&cond->codes,&exp1->codes); code=newcode(OP_TESTL,newdessrc(IMM,1,NULL,NONE,0,0),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&cond->codes,code); }else{ exp1=cond->firstchild; exp2=exp1->nextsibling->nextsibling; test1=code_exptest(exp1,BASEREG); test2=code_exptest(exp2,BASEREG); if(test2==0){ if(test1==1){ code_exp(exp2,BASEREG); code_link(&cond->codes,&exp2->codes); /* exp2 result is in %eax now */ code=newcode(OP_CMPL,newdessrc(REG,0,NULL,EAX,0,0),code_exp_ds(exp1,BASEREG),NULL); code_link_one(&cond->codes,code); }else{ code_exp(exp2,BASEREG); code_link(&cond->codes,&exp2->codes); /* exp2 result is in %eax now */ /* pushl %eax */ code=newcode(OP_PUSHL,newdessrc(REG,0,NULL,EAX,0,0),NULL,NULL); code_link_one(&cond->codes,code); code_exp(exp1,BASEREG); code_link(&cond->codes,&exp1->codes); /* exp1 result is in %eax now */ /* popl %ecx */ code=newcode(OP_POPL,newdessrc(REG,0,NULL,ECX,0,0),NULL,NULL); code_link_one(&cond->codes,code); /* cmpl %ecx,%eax */ code=newcode(OP_CMPL,newdessrc(REG,0,NULL,ECX,0,0),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&cond->codes,code); } }else { code_exp(exp1,BASEREG); code_link(&cond->codes,&exp1->codes); /* exp1 result is in %eax now */ code=newcode(OP_CMPL,code_exp_ds(exp2,BASEREG),newdessrc(REG,0,NULL,EAX,0,0),NULL); code_link_one(&cond->codes,code); } } return opr; }
void genpatch( word op ) { word type = rdint(); int size = (int)op & 0x7; copycode(); trace("Read PATCH"); switch( type ) { default: error("genpatch: Illegal patch type: %x",type); return; case OBJMODSIZE: trace("MODSIZE"); (void)newcode(op,size,type,curloc,0L); break; case OBJMODNUM: trace("MODNUM"); (void)newcode(op,size,type,curloc,0L); break; case OBJCODESYMB: if (!smtopt) error("CODESYMB directive encountered without split module table mode set"); case OBJLABELREF: case OBJDATASYMB: case OBJDATAMODULE: #ifdef NEW_STUBS case OBJCODESTUB: case OBJADDRSTUB: #endif { VMRef v = rdsymb(); Symbol * s; if (type == OBJDATAMODULE) { movesym( v ); /* implicit GLOBAL declaration */ } s = VMAddr( Symbol, v ); trace( "Single level %s %s %#x", #ifdef NEW_STUBS type == OBJCODESTUB ? "CODESTUB" : type == OBJADDRSTUB ? "ADDRSTUB" : #endif type == OBJDATASYMB ? "DATASYMB" : type == OBJDATAMODULE ? "DATAMODULE" : type == OBJCODESYMB ? "CODESYMB" : "LABELREF" , s->name, v ); refsymbol_nondef( v ); (void)newcode( op, size, type, curloc, v ); break; } case OBJPATCH: case OBJPATCH + 1: case OBJPATCH + 2: case OBJPATCH + 3: case OBJPATCH + 4: case OBJPATCH + 5: case OBJPATCH + 6: case OBJPATCH + 7: case OBJPATCH + 8: case OBJPATCH + 9: case OBJPATCH + 10: case OBJPATCH + 11: case OBJPATCH + 12: { Patch *p; word pword = 0; /* patch data */ int ptype; /* patch type */ VMRef pv = VMNew(sizeof(Patch)); if (type != PATCHSWAP) /* no patch data for swap patch */ pword = rdint(); /* patch data */ p = VMAddr(Patch,pv); p->word = pword; p->type = ptype = (int)rdint(); /* patch type */ patchpatch(pv, ptype); /* patch in value of type, or another patch */ (void)newcode(op,size,type,curloc,pv); break; } } curloc += size; return; } /* genpatch */
CODE::CODE() { newcode(m_data); charto16x(m_data,m_str); }
void readfile( void ) { VMRef v; Symbol * s; word op = 0; /* * Quick Test. * Determine if the first byte in the input file is a GHOF * directive. If not then do not bother to parse the rest * of the file. */ op = getc( infd ); if (op >= 0x40) { #if defined __ARM && (defined RS6000 || defined __SUN4) /* only support AOF -> GHOF conversion when cross linking */ if (op == 0xC3 || op == 0xC5) { s_aof * pAOF; uword iCodeSize; char * pTempFileName; trace( "Assuming file is in AOF format" ); pTempFileName = malloc( strlen( infile_duplicate ) + 5 /* strlen( ".ghof" ) */ + 1 ); if (pTempFileName == NULL) { error( "Out of memory allocating temporary file name" ); return; } strcpy( pTempFileName, infile_duplicate ); strcat( pTempFileName, ".ghof" ); file_trace( "creating GHOF copy of AOF file '%s'", infile_duplicate ); pAOF = open_aof( infile_duplicate ); if (pAOF == NULL) { error( "Failed to reopen file in AOF mode" ); return; } (void)convert_aof( pAOF, pTempFileName, bSharedLib, bTinyModel, bDeviceDriver ); /* Open the temporary file again */ file_trace( "opening GHOF copy '%s'", pTempFileName ); infd = freopen( pTempFileName, "rb", infd ); if (infd == NULL) { error( "Unable to reopen temporary file %s", pTempFileName ); return; } else file_trace( "copy opened" ); free( pTempFileName ); /* drop throiugh into normal readfile() code */ } else #endif /* __ARM and (RS6000 or __SUN4) */ { error( "Input file is not in GHOF format" ); return; } } else { ungetc( (char)op, infd ); } do { op = rdint(); trace("OP = %x, curloc = %x, codepos = %x",op,curloc, codepos); switch( op ) { default: error( "Illegal linker directive '%x'", op ); break; case EOF: return; case OBJCODE: { word size = rdint(); if (size < 0) error( "Negative sized code directive encountered (%x)", size ); trace("CODE %d",size); while( size-- ) genbyte(rdch()); break; } case OBJBSS: { word size = rdint(); if (size < 0) error("Negative sized bss defined"); trace("BSS %d",size); while( size-- ) genbyte(0L); break; } case OBJWORD: genpatch( OBJWORD ); break; case OBJSHORT: genpatch( OBJSHORT ); break; case OBJBYTE: genpatch( OBJBYTE ); break; case OBJINIT: geninit(); break; case OBJMODULE: genmodule(rdint()); break; case OBJBYTESEX: if( bytesex != 0 ) error("bytesex already set"); bytesex = rdint(); trace("BYTESEX %d",bytesex); break; case OBJREF: v = rdsymb(); movesym(v); /* XXX - all REF symbols are implicitly global */ refsymbol_nondef(v); break; case OBJGLOBAL: v = rdsymb(); s = VMAddr(Symbol,v); movesym(v); if (s->referenced) { refsymbol_def(v); } break; case OBJLABEL: v = rdsymb(); s = VMAddr(Symbol,v); trace("LABEL %s",s->name); if( s->type != S_UNBOUND ) { if (!inlib) warn( "Duplicate definition of symbol '%s' defined in file '%s'", s->name, s->file_name ); } else { if (s->AOFassumedData) { error( "(AOF) Symbol '%s' has been assumed to be data in file '%s'", s->name, s->file_name ); s->AOFassumedData = FALSE; } copycode(); s->type = S_CODESYMB; s->value.v = codeptr(); s->module = curmod; s->file_name = infile_duplicate; if (s->referenced) refsymbol_def(v); { int len = strlen( s->name ); /* hack to insert correct name for resident libraries */ VMlock( v ); if (len > 8 && strcmp( s->name + len - 8, ".library" ) == 0 && VMAddr( asm_Module, curmod )->id != -1 ) { VMAddr( asm_Module, curmod )->file_name = s->name; } VMunlock( v ); } } break; case OBJDATA: case OBJCOMMON: { word size = rdint(); if (size < 0) error("Negative sized data/common directive encountered"); v = rdsymb(); s = VMAddr(Symbol,v); trace("%s %d %s",op== OBJDATA ? "DATA" : "COMMON",size,s->name); if( s->type != S_UNBOUND ) { if( s->type != S_COMMSYMB) { if (!inlib) warn("Duplicate data definition of symbol '%s' defined in file '%s'",s->name, s->file_name); } else { if( s->value.w < size ) s->value.w = size; } } else { s->type = op== OBJDATA ? S_DATASYMB : S_COMMSYMB; s->value.w = size; s->module = curmod; s->file_name = infile_duplicate; if(s->referenced) refsymbol_def(v); } (void)newcode(op,0,0,curloc,v); break; } case OBJCODETABLE: { if (!smtopt) error("CODETABLE directive encountered without split module table mode set"); v = rdsymb(); s = VMAddr(Symbol,v); #if 0 /* problems for .MaxCodeP */ movesym(v); /* implicit global directive */ #endif trace("%s %s","CODETABLE",s->name); if ( s->type != S_UNBOUND ) { if (!inlib) warn("Duplicate definition of symbol '%s' defined in file '%s'", s->name, s->file_name); } else { if (s->AOFassumedData) { error( "(AOF) Symbol '%s' has been assumed to be data in file '%s'", s->name, s->file_name ); s->AOFassumedData = FALSE; } s->type = S_FUNCSYMB; s->value.w = 4; s->module = curmod; s->file_name = infile_duplicate; if(s->referenced) refsymbol_def(v); } (void)newcode(op,0,0,curloc,v); break; } } } while( op != EOF ); return; }
int code_function(ASTNode function){ CODELIST *list; CODELIST envstore,envrestore,stackalloc,stackrestore,statements; CODE86 *code; ASTNode func_block=function->firstchild->nextsibling; ASTNode p=function; SYMTAB symtab=func_block->symtab; SYM sym=function->firstchild->sym; int maxsize; char *symlabel; char *lfblabel; char *lfelabel; /*omp env init */ omp_flag=0; omp_count=0; func_sym=sym; omp_functions.head=omp_functions.tail=NULL; // printf("enter code_function\n"); stack_allocate(symtab,0); maxsize=symtab->size_max; function->codes.head=function->codes.tail=NULL; /* .text */ code=newcode(PS_TEXT,NULL,NULL,NULL); code_link_one(&p->codes,code); /* .globl */ code=newcode(PS_GLOBL,NULL,NULL,(void *)sym); code_link_one(&p->codes,code); /* .type */ code=newcode(PS_TYPE,NULL,NULL,(void *)sym); code_link_one(&p->codes,code); /* .label */ symlabel=new_label(LABEL_SYM,(void *)sym,0); code=newcode(PS_LABEL,NULL,NULL,(void *)symlabel); code_link_one(&p->codes,code); /* .LFB */ lfblabel=new_label(LABEL_LFB,NULL,0); lfelabel=new_label(LABEL_LFE,NULL,0); code=newcode(PS_LABEL,NULL,NULL,(void *)lfblabel); code_link_one(&p->codes,code); /* pushl %ebp */ code=newcode(OP_PUSHL,newdessrc(REG,0,NULL,EBP,0,0),NULL,NULL);; code_link_one(&p->codes,code); /* movl %esp, %ebp */ code=newcode(OP_MOVL,newdessrc(REG,0,NULL,ESP,0,0),newdessrc(REG,0,NULL,EBP,0,0),NULL); code_link_one(&p->codes,code); /* stackalloc */ stackalloc.head=stackalloc.tail=NULL; /* subl maxsize, %esp */ code=newcode(OP_SUBL,newdessrc(IMM,maxsize,NULL,NONE,0,0),newdessrc(REG,0,NULL,ESP,0,0),NULL); code_link_one(&stackalloc,code); /* envstore */ envstore.head=envstore.tail=NULL; /* block */ statements.head=statements.tail=NULL; code_block(func_block,EBP); code_link(&statements,&func_block->codes); /* evnrestore */ envrestore.head=envrestore.tail=NULL; /* stackrestore */ stackrestore.head=stackrestore.tail=NULL; /* addl maxsize, %esp */ code=newcode(OP_ADDL,newdessrc(IMM,maxsize,NULL,NONE,0,0),newdessrc(REG,0,NULL,ESP,0,0),NULL); code_link_one(&stackrestore,code); /******************* link codes ************/ code_link(&p->codes,&stackalloc); code_link(&p->codes,&envstore); code_link(&p->codes,&statements); code_link(&p->codes,&envrestore); code_link(&p->codes,&stackrestore); /* leave */ code=newcode(OP_LEAVE,NULL,NULL,NULL);; code_link_one(&p->codes,code); /* ret */ code=newcode(OP_RET,NULL,NULL,NULL); code_link_one(&p->codes,code); /* .LFE */ code=newcode(PS_LABEL,NULL,NULL,(void *)lfelabel); code_link_one(&p->codes,code); /* .size */ code=newcode(PS_SIZE,NULL,newdessrc(IMM,1,NULL,NONE,0,0),(void *)sym); code_link_one(&p->codes,code); code_link(&p->codes,&omp_functions); return 0; }
int code_ifclause(ASTNode ifclause,int BASEREG){ ASTNode cond,stmt1,stmt2; CODE86 *code; int elseflag; char *label[2]; int i; int opr; OPR oprand; cond=ifclause->firstchild; stmt1=cond->nextsibling; stmt2=stmt1->nextsibling; ifclause->codes.head=ifclause->codes.tail=NULL; if(stmt2){ elseflag=1; }else{ elseflag=0; } if(elseflag){ for(i=0;i<2;i++) label[i]=new_label(LABEL_JMP,NULL,0); /* opr.code */ opr=code_cond(cond,BASEREG); code_link(&ifclause->codes,&cond->codes); switch(opr){ case ODD: oprand=OP_JP; break; case NEQ: oprand=OP_JE; break; case EQL: oprand=OP_JNE; break; case LSS: oprand=OP_JGE; break; case GTR: oprand=OP_JLE; break; case LEQ: oprand=OP_JG; break; case GEQ: oprand=OP_JL; break; } /* if false goto .L0 */ code=newcode(oprand,NULL,NULL,label[0]); code_link_one(&ifclause->codes,code); /* true:then */ code_stmt(stmt1,BASEREG); code_link(&ifclause->codes,&stmt1->codes); /* jmp .L1 */ code=newcode(OP_JMP,NULL,NULL,label[1]); code_link_one(&ifclause->codes,code); /* .L0 */ code=newcode(PS_LABEL,NULL,NULL,label[0]); code_link_one(&ifclause->codes,code); /* false:else */ code_stmt(stmt2,BASEREG); code_link(&ifclause->codes,&stmt2->codes); /* .L1 out */ code=newcode(PS_LABEL,NULL,NULL,label[1]); code_link_one(&ifclause->codes,code); }else{ for(i=0;i<1;i++) label[i]=new_label(LABEL_JMP,NULL,0); opr=code_cond(cond,BASEREG); code_link(&ifclause->codes,&cond->codes); switch(opr){ case ODD: oprand=OP_JP; break; case NEQ: oprand=OP_JE; break; case EQL: oprand=OP_JNE; break; case LSS: oprand=OP_JGE; break; case GTR: oprand=OP_JLE; break; case LEQ: oprand=OP_JG; break; case GEQ: oprand=OP_JL; break; } /* if false goto .L0 */ code=newcode(oprand,NULL,NULL,label[0]); code_link_one(&ifclause->codes,code); /* true:then */ code_stmt(stmt1,BASEREG); code_link(&ifclause->codes,&stmt1->codes); /* .L0 out */ code=newcode(PS_LABEL,NULL,NULL,label[0]); code_link_one(&ifclause->codes,code); } return 0; }
int code_globalconst(ASTNode root){ ASTNode constlist=root->firstchild; ASTNode p=constlist; ASTNode pp; CODE86 *code; SYM sym; int size,align; int num; char *label; root->codes.head=root->codes.tail=NULL; while(p){ p->codes.head=p->codes.head=NULL; if(p->type==ConstIdent){ sym=p->firstchild->sym; size=sym->size; if(size<16) align=4; else if(size<64) align=16; else align=64; /* .globl */ code=newcode(PS_GLOBL,NULL,NULL,(void *)sym); code_link_one(&p->codes,code); /* .section rodata */ code=newcode(PS_SECTION,NULL,NULL,(void *)STR_RODATA); code_link_one(&p->codes,code); /* .align */ code=newcode(PS_ALIGN,newdessrc(IMM,align,NULL,NONE,0,0),NULL,NULL); code_link_one(&p->codes,code); /* .type */ code=newcode(PS_TYPE,NULL,NULL,(void *)sym); code_link_one(&p->codes,code); /* .size */ code=newcode(PS_SIZE,newdessrc(IMM,size,NULL,NONE,0,0),newdessrc(IMM,0,NULL,NONE,0,0),(void *)sym); code_link_one(&p->codes,code); /* symbol label */ label=new_label(LABEL_SYM,(void *)sym,0); code=newcode(PS_LABEL,NULL,NULL,(void *)label); code_link_one(&p->codes,code); /* .long */ num=p->firstchild->nextsibling->val; code=newcode(PS_LONG,newdessrc(IMM,num,NULL,NONE,0,0),NULL,NULL); code_link_one(&p->codes,code); }else{ sym=p->firstchild->sym; size=sym->size; if(size<16) align=4; else if(size<64) align=16; else align=64; /* .globl */ code=newcode(PS_GLOBL,NULL,NULL,(void *)sym); code_link_one(&p->codes,code); /* .section rodata */ code=newcode(PS_SECTION,NULL,NULL,(void *)STR_RODATA); code_link_one(&p->codes,code); /* .align */ code=newcode(PS_ALIGN,newdessrc(IMM,align,NULL,NONE,0,0),NULL,NULL); code_link_one(&p->codes,code); /* .type */ code=newcode(PS_TYPE,NULL,NULL,(void *)sym); code_link_one(&p->codes,code); /* .size */ code=newcode(PS_SIZE,newdessrc(IMM,size,NULL,NONE,0,0),newdessrc(IMM,0,NULL,NONE,0,0),(void *)sym); code_link_one(&p->codes,code); /* symbol label */ label=new_label(LABEL_SYM,(void *)sym,0); code=newcode(PS_LABEL,NULL,NULL,(void *)label); code_link_one(&p->codes,code); /* .long */ pp=p->firstchild; while(pp->type!=ConstList){ /*if(pp->type==Number)fprintf(stderr,"*************Number\n"); else if(pp->type==Ident)fprintf(stderr,"*************Ident\n"); else fprintf(stderr,"*************??\n"); */ pp=pp->nextsibling; } pp=pp->firstchild; while(pp){ num=pp->val; code=newcode(PS_LONG,newdessrc(IMM,num,NULL,NONE,0,0),NULL,NULL); code_link_one(&p->codes,code); size-=4; pp=pp->nextsibling; } /* .zero */ if(size>0){ code=newcode(PS_ZERO,newdessrc(IMM,size,NULL,NONE,0,0),NULL,NULL); code_link_one(&p->codes,code); } } code_link(&root->codes,&p->codes); p=p->nextsibling; } return 0; }
int code_block(ASTNode block,int BASEREG){ CODE86 *code; PRAGMA *prag; char *labelmp; int skiplink=0; ASTNode p=block->firstchild; ASTNode pp; //fprintf(stderr,"enter a block\n"); while(p){ switch(p->type){ case VarDecl: /* no need to generate code for var decl */ p->codes.head=p->codes.tail=NULL; break; case ConstDecl: p->codes.head=p->codes.tail=NULL; code_blockconst(p,BASEREG); break; case FuncDecl: /* no need to generate code for funcdecl */ p->codes.head=p->codes.tail=NULL; break; case CompilerDirective: //fprintf(stderr,"***************get one directive *\n"); prag=check_pragma(p->str); p->codes.head=p->codes.tail=NULL; if(prag->type==OMP){ pp=p->nextsibling; if( omp_flag){ code_error("not suppored omp in another omp directive\n"); } else if( (pp==NULL)||(pp->type==VarDecl) || (pp->type==ConstDecl) ||(pp->type==FuncDecl) ){ code_error("pragma omp must be followed by a stmt\n"); break; }else{ omp_flag=1; labelmp=code_omp_stmt(pp,BASEREG); /* pushl 0 *2 */ code=newcode(OP_PUSHL,newdessrc(IMM,0,NULL,NONE,0,0),NULL,NULL); code_link_one(&p->codes,code); code=newcode(OP_PUSHL,newdessrc(IMM,0,NULL,NONE,0,0),NULL,NULL); code_link_one(&p->codes,code); /* pushl %ebp */ code=newcode(OP_PUSHL,newdessrc(REG,0,NULL,EBP,0,0),NULL,NULL); code_link_one(&p->codes,code); /* pushl ompfunc */ code=newcode(OP_PUSHL,newdessrc(IMM,0,NULL,NONE,0,0),NULL,(void *)labelmp); code_link_one(&p->codes,code); /* call GOMP_parallel */ code=newcode(OP_CALL,NULL,NULL,(void *)STR_GOMPP); code_link_one(&p->codes,code); /* addl $16,%esp */ code=newcode(OP_ADDL,newdessrc(IMM,16,NULL,NONE,0,0),newdessrc(REG,0,NULL,ESP,0,0),NULL); code_link_one(&p->codes,code); omp_flag=0; skiplink=1; } }else{ fprintf(stderr,"unsupported pragma \n"); } break; default: p->codes.head=p->codes.tail=NULL; //fprintf(stderr,"checked one statements item\n"); code_stmt(p,BASEREG); } code_link(&block->codes,&p->codes); if(skiplink){ skiplink=0; p=pp->nextsibling; }else{ p=p->nextsibling; } } return 0; }
char *code_omp_stmt(ASTNode stmt,int BASEREG){ CODE86 *code; CODELIST omplist; char *lfe,*lfb,*ompf; omp_count+=1; ompf=new_label(LABEL_SYM,(void *)func_sym,omp_count); lfe=new_label(LABEL_LFE,NULL,0); lfb=new_label(LABEL_LFB,NULL,0); omplist.head=omplist.tail=NULL; code=newcode(PS_TYPE,newdessrc(IMM,1,NULL,NONE,0,0),NULL,(void *)ompf); code_link_one(&omplist,code); code=newcode(PS_LABEL,NULL,NULL,(void *)ompf); code_link_one(&omplist,code); code=newcode(PS_LABEL,NULL,NULL,(void *)lfb); code_link_one(&omplist,code); /* pushl %ebp */ code=newcode(OP_PUSHL,newdessrc(REG,0,NULL,EBP,0,0),NULL,NULL);; code_link_one(&omplist,code); /* movl %esp, %ebp */ code=newcode(OP_MOVL,newdessrc(REG,0,NULL,ESP,0,0),newdessrc(REG,0,NULL,EBP,0,0),NULL); code_link_one(&omplist,code); /* pushl %esi */ code=newcode(OP_PUSHL,newdessrc(REG,0,NULL,ESI,0,0),NULL,NULL);; code_link_one(&omplist,code); /* movl 8(%ebp),%esi */ code=newcode(OP_MOVL,newdessrc(REG_OFFSET,0,NULL,EBP,8,0),newdessrc(REG,0,NULL,ESI,0,0),NULL); code_link_one(&omplist,code); /* generate function code */ code_stmt(stmt,ESI); code_link(&omplist,&stmt->codes); /* popl %esi */ code=newcode(OP_POPL,newdessrc(REG,0,NULL,ESI,0,0),NULL,NULL);; code_link_one(&omplist,code); /* leave */ code=newcode(OP_LEAVE,NULL,NULL,NULL);; code_link_one(&omplist,code); /* ret */ code=newcode(OP_RET,NULL,NULL,NULL); code_link_one(&omplist,code); /* .lfb */ code=newcode(PS_LABEL,NULL,NULL,(void *)lfe); code_link_one(&omplist,code); /* .size */ code=newcode(PS_SIZE,NULL,newdessrc(IMM,2,NULL,NONE,0,0),ompf); code_link_one(&omplist,code); code_link(&omp_functions,&omplist); return ompf; }