📄 cgen2.c
字号:
SrcLineCount = SrcLineNum; /* for error msgs 14-jul-89 */
if( tree->op.unroll_count != unroll_count ) {
unroll_count = tree->op.unroll_count;
BEUnrollCount( unroll_count );
}
if( tree->right->op.opr == OPR_FUNCTION ) { // if start of func
TREEPTR right;
SYM_ENTRY sym;
right = tree->right;
SymGet( &sym, right->op.func.sym_handle );
if( ! (sym.flags & SYM_REFERENCED) ) {
if( (sym.attrib & FLAG_INLINE)
&& (sym.stg_class != SC_NULL) ){
while( tree->right->op.opr != OPR_FUNCEND ){
tree = tree->left;
}
break;
}
}
}
EmitNodes( LinearizeTree( tree->right ) );
#ifdef __SEH__
if( tree->right->op.opr == OPR_FUNCTION ) { // if start of func
if( FuncNodePtr->func.flags & FUNC_USES_SEH ) {
GenerateTryBlock( tree->left );
}
}
#endif
if( tree->right->op.opr == OPR_FUNCEND ) break;
tree = tree->left;
}
return( tree );
}
static void DoInLineFunction( TREEPTR tree )
{ // Push some state info and use InLineDepth for turning some stuff off
struct func_save save;
++InLineDepth;
save.func = CurFunc;
save.func_handle = CurFuncHandle;
save.funcnode = FuncNodePtr;
save.cglabel_handles = CGLabelHandles;
save.labelindex = LabelIndex;
CurFuncHandle = 0;
FuncNodePtr = NULL;
CGLabelHandles = NULL;
LabelIndex = 0;
GenOptimizedCode( tree );
CurFunc = save.func;
SymGet( CurFunc, save.func_handle ); // must be done before changing CurFuncHandle
CurFuncHandle = save.func_handle;
FuncNodePtr = save.funcnode;
CGLabelHandles = save.cglabel_handles;
LabelIndex = save.labelindex;
--InLineDepth;
}
static TREEPTR FindFuncStmtTree( SYM_HANDLE sym_handle )
{
SYMPTR symptr;
symptr = SymGetPtr( sym_handle );
return( symptr->u.func.start_of_func );
}
void GenInLineFunc( SYM_HANDLE sym_handle )
{
TREEPTR tree;
tree = FindFuncStmtTree(sym_handle);
if( tree != NULL ) {
DoInLineFunction( tree );
}
}
bool IsInLineFunc( SYM_HANDLE sym_handle )
{
bool ret;
TREEPTR tree;
TREEPTR right;
ret = FALSE;
if( InLineDepth < MAX_INLINE_DEPTH ){
tree = FindFuncStmtTree(sym_handle);
if( tree != NULL ) {
right = tree->right;
if( !(right->op.func.flags & FUNC_INUSE) ){
ret = right->op.func.flags & FUNC_OK_TO_INLINE;
}
}
}
return( ret );
}
local void GenModuleCode()
{
TREEPTR tree;
tree = FirstStmt;
InLineDepth = 0;
// InLineFuncStack = NULL;
while( tree != NULL ) {
tree = GenOptimizedCode( tree );
tree = tree->left;
}
}
static void NoCodeGenDLL()
{
extern void FEMessage( msg_class, void * );
FEMessage( MSG_FATAL, "Unable to load code generator DLL" );
}
void DoCompile()
{
unsigned int /*jmp_buf*/ *old_env;
auto jmp_buf env;
auto cg_init_info cgi_info;
old_env = Environment;
if( ! setjmp( env ) ) {
Environment = &env;
if( BEDLLLoad( NULL ) ) {
#if _MACHINE == _PC
BEMemInit(); // cg has a strange static var that doesn't get reset
#endif
if( ! CompFlags.zu_switch_used ) TargetSwitches &= ~ FLOATING_SS;
if( Toggles & TOGGLE_DUMP_CG ){
GenSwitches |= ECHO_API_CALLS;
}
#ifdef POSITION_INDEPENDANT
if( CompFlags.rent ){
GenSwitches |= POSITION_INDEPENDANT;
}
#endif
cgi_info = BEInit( GenSwitches, TargetSwitches, OptSize, ProcRevision );
if( cgi_info.success ) {
#if 0
if( cgi_info.version.revision != II_REVISION ) WrongCodeGen();
#if _CPU == 386
if( cgi_info.version.target != II_TARG_80386 ) WrongCodeGen();
#elif _CPU == 370
if( cgi_info.version.target != II_TARG_370 ) WrongCodeGen();
#elif _CPU == 8086
if( cgi_info.version.target != II_TARG_8086 ) WrongCodeGen();
#elif _CPU == 0000
if( cgi_info.version.target != II_TARG_AXP ) WrongCodeGen();
#else
#error "Undefined _CPU type"
#endif
#endif
#if _CPU == 386
if( TargetSwitches & (P5_PROFILING|NEW_P5_PROFILING) ) {
FunctionProfileSegment = AddSegName( "TI", "DATA", SEGTYPE_INITFINI );
}
#endif
SetSegs();
BEStart();
EmitSegLabels(); /* 15-mar-92 */
if( GenSwitches & DBG_TYPES ) EmitDBType();
EmitSyms();
EmitCS_Strings();
SrcLineCount = 0;
FListSrcQue();
EmitDataQuads();
FreeDataQuads();
#ifdef __SEH__
TryRefno = NewRefno();
BEDefType( TryRefno, 1, sizeof( struct try_block ) );
TryTableBackHandles = NULL;
#endif
GenModuleCode();
FreeStrings();
FiniSegLabels(); /* 15-mar-92 */
if( ErrCount != 0 ) {
BEAbort();
}
BEStop();
FiniSegBacks(); /* 15-mar-92 */
FreeGblVars( GlobalSym );
FreeGblVars( SpecialSyms ); /* 05-dec-89 */
FreeExtVars(); /* 02-apr-92 */
#ifdef __SEH__
FreeTryTableBackHandles();
#endif
BEFini();
BEDLLUnload();
}
} else {
NoCodeGenDLL();
}
}
Environment = old_env;
}
local void EmitSyms( void )
{
SYM_HANDLE sym_handle;
auto SYM_ENTRY sym;
for( sym_handle = GlobalSym; sym_handle; ) {
SymGet( &sym, sym_handle );
EmitSym( &sym, sym_handle );
if( ( GenSwitches & DBG_LOCALS ) &&
( sym.sym_type->decl_type != TYPE_FUNCTION ) &&
( (sym.flags & SYM_TEMP) == 0 ) && /* 06-oct-93 */
( sym.stg_class != SC_TYPEDEF )) {
#if _CPU == 370
if( sym.stg_class != SC_EXTERN || sym.flags & SYM_REFERENCED){
DBModSym( sym_handle, TY_DEFAULT );
}
#else
DBModSym( sym_handle, TY_DEFAULT );
#endif
}
sym_handle = sym.handle;
}
}
local void EmitSym( SYMPTR sym, SYM_HANDLE sym_handle )
{
TYPEPTR typ;
int segment;
auto unsigned long size;
typ = sym->sym_type;
if( (GenSwitches & DBG_TYPES) && (sym->stg_class == SC_TYPEDEF) ) {
if( typ->decl_type != TYPE_TYPEDEF ) {
DBEndName( DBBegName( sym->name, DBG_NIL_TYPE ),
DBType( typ ) );
}
}
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
CGenType( typ ); /* create refno for ARRAY type, etc */
if( sym->stg_class != SC_EXTERN && /* if not imported */
sym->stg_class != SC_TYPEDEF ) {
if( ( sym->flags & SYM_FUNCTION ) == 0 ) {
segment = sym->u.var.segment;
if( (sym->flags & SYM_INITIALIZED) == 0 || segment == SEG_BSS){
BESetSeg( segment );
AlignIt( typ );
DGLabel( FEBack( sym_handle ) );
/* initialize all bytes to 0 */
/* if size > 64k, have to break it into chunks of 64k */
size = SizeOfArg( typ );
if( segment == SEG_BSS ) {
DGUBytes( size );
} else {
#if _CPU == 8086
while( size >= 0x10000 ) {
EmitZeros( 0x10000 );
size -= 0x10000;
if( size == 0 ) break;
if( segment != SEG_CONST && segment != SEG_DATA ) {
++segment;
BESetSeg( segment );
}
}
#endif
if( size != 0 ) EmitZeros( size );
}
}
}
}
}
local int DoFuncDefn( SYM_HANDLE funcsym_handle )
{
int parms_reversed;
SYM_HANDLE sym_handle;
int ret_type;
SSVar = NULL;
CurFunc = &CurFuncSym;
SymGet( CurFunc, funcsym_handle );
CurFuncHandle = funcsym_handle;
#if _MACHINE == _PC
if( ! CompFlags.zu_switch_used ) {
if( (CurFunc->attrib & FLAG_INTERRUPT) == FLAG_INTERRUPT ){
/* interrupt function */
TargetSwitches |= FLOATING_SS; /* force -zu switch on */
} else {
TargetSwitches &= ~ FLOATING_SS; /* turn it back off */
}
}
#endif
ret_type = CGenType( CurFunc->sym_type->object );
if( CompFlags.returns_promoted ) {
ret_type = FEParmType( NULL, NULL, ret_type );
}
CGProcDecl( funcsym_handle, ret_type );
#if _CPU == 386
if( TargetSwitches & P5_PROFILING ) {
char *fn_name = FEName( funcsym_handle );
size_t len = strlen( fn_name )+1;
segment_id old_segment;
old_segment = BESetSeg( FunctionProfileSegment );
FunctionProfileBlock = BENewBack( NULL );
DGLabel( FunctionProfileBlock );
DGInteger( 0, T_INTEGER );
DGInteger( -1, T_INTEGER );
DGInteger( 0, T_INTEGER );
DGInteger( 0, T_INTEGER );
DGBytes( len, fn_name );
len &= 0x03;
if( len ) {
DGIBytes( 4 - len, 0 );
}
BESetSeg( old_segment );
}
#endif
if( GenSwitches & DBG_LOCALS ) {
if( InLineDepth == 0 ){
DBModSym( CurFuncHandle, TY_DEFAULT );
}else{
DBBegBlock();
}
}
parms_reversed = 0;
sym_handle = CurFunc->u.func.parms;
if( sym_handle ) {
GetCallClass( CurFuncHandle );
if( CallClass & REVERSE_PARMS ) { /* 22-jan-90 */
ParmReverse( sym_handle );
parms_reversed = 1;
} else {
for( ; sym_handle; ) {
SYMPTR sym;
sym = SymGetPtr( sym_handle );
if( sym->sym_type->decl_type == TYPE_DOT_DOT_DOT ) break;
DoParmDecl( sym, sym_handle );
sym_handle = sym->handle;
}
}
}
CGLastParm();
DoAutoDecl( CurFunc->u.func.locals );
#ifdef __SEH__
if( FuncNodePtr->func.flags & FUNC_USES_SEH ) {
CGAutoDecl( TrySymHandle, TryRefno );
CallTryInit(); // generate call to __TryInit
}
#endif
return( parms_reversed );
}
local void DoParmDecl( SYMPTR sym, SYM_HANDLE sym_handle )
{
TYPEPTR typ;
int dtype;
typ = sym->sym_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
dtype = CGenType( typ );
CGParmDecl( sym_handle, dtype );
if( (GenSwitches & NO_OPTIMIZATION) /* 20-sep-88 */
#if _CPU == 386
|| ((! CompFlags.register_conventions) &&
CompFlags.debug_info_some)
#endif
) {
if( GenSwitches & DBG_LOCALS ) {
DBLocalSym( sym_handle, TY_DEFAULT );
}
}
}
local void ParmReverse( SYM_HANDLE sym_handle ) /* 22-jan-90 */
{
SYMPTR sym;
sym = SymGetPtr( sym_handle );
if( sym->handle ) {
ParmReverse( sym->handle );
sym = SymGetPtr( sym_handle );
}
DoParmDecl( sym, sym_handle );
}
local void DoAutoDecl( SYM_HANDLE sym_handle )
{
TYPEPTR typ;
cg_type dtype;
char emit_debug_info; /* 01-mar-91 */
char emit_extra_info; /* 25-nov-91 */
auto SYM_ENTRY sym;
while( sym_handle != 0 ) {
SymGet( &sym, sym_handle );
emit_debug_info = 0;
emit_extra_info = 0;
if( (GenSwitches & NO_OPTIMIZATION) ) emit_debug_info = 1;
if( sym.stg_class == SC_STATIC ) {
emit_debug_info = 0;
if( (sym.flags & SYM_EMITTED) == 0 ) {
if( sym.sym_type->decl_type != TYPE_VOID ) {
EmitSym( &sym, sym_handle );
emit_debug_info = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -