cg.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 953 行 · 第 1/2 页
C
953 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdarg.h>
#include "standard.h"
#include "cg.h"
#include "bckdef.h"
#include "cgdefs.h"
#include "typclass.h"
#include "typedef.h"
#include "cfloat.h"
#include "cgaux.h"
#include "model.h"
#include "hostsys.h"
#include "cgstub.h"
#include "feprotos.h"
#include "stubdata.h"
extern int TempId;
extern void DumpTree(n *);
extern type_def *TypeAddress(cg_type);
extern char *CopyStr(char*,char*);
extern char *ACopyOf(char *);
extern void VerTipe(cg_type ,cg_type *);
extern n *Binary(cg_op ,n *,n *,cg_type );
extern char *Tipe(cg_type );
extern void VerLabel(l *);
extern char *Label(l *);
extern void Action(char *,... );
extern void NoDanglers(void);
extern n *NewNode(nclass ,cg_type );
extern void Code(char *,... );
extern void VerAuto(a *);
extern void VerNode(n *);
extern char *Name(pointer );
extern char *Op(cg_op );
extern void NotDefault(cg_type );
extern void CGError(char *,... );
extern void VerBack(b *);
extern char *LToS(signed_32 );
extern void DumpT(n *);
extern void VerOp(cg_op ,cg_op *);
extern void Find(char *,pointer *,pointer );
extern n *Unary(cg_op ,n *,cg_type );
extern void CRefLabel(l *lb);
extern void CDefLabel(l *lb);
extern void DRefLabel(l *lb);
extern void DDefLabel(l *lb);
extern pointer LkAddBack(sym_handle,pointer);
extern pointer CGAlloc( unsigned size );
extern pointer DoCGAlloc( unsigned size, pointer ra );
extern void CGFree( pointer chunk );
extern void CGFreeSize( pointer chunk, int size );
extern unsigned_32 BETypeLength( cg_type );
/********************************************************************/
/* Handle feedback for auto locations */
/********************************************************************/
typedef struct auto_locn AUTO_LOCN;
struct auto_locn {
AUTO_LOCN* next;
sym s;
unsigned offset;
};
#define AUTO_PACK 4
static AUTO_LOCN*auto_locations;
static unsigned next_auto_offset;
static void addAutoLocn( sym s, cg_type type )
{
AUTO_LOCN* curr;
curr = CGAlloc( sizeof( AUTO_LOCN ) );
curr->s = s;
curr->offset = next_auto_offset;
curr->next = auto_locations;
auto_locations = curr;
next_auto_offset += ( BETypeLength( type ) + AUTO_PACK - 1 )
& ( - AUTO_PACK );
}
static void dumpAutoLocn( void )
{
AUTO_LOCN* curr;
if( auto_locations ) {
for( ; ; ) {
curr = auto_locations;
if( ! curr ) break;
auto_locations = curr->next;
if( ((pointer)TEMP_LOC_YES) == FEAuxInfo( curr->s, TEMP_LOC_NAME ) ) {
Action( "TEMP_LOC_TELL offset=%h symbol=%s%n"
, curr->offset
, Name( curr->s ) );
FEAuxInfo( (sym_handle)curr->offset, TEMP_LOC_TELL );
}
CGFree( curr );
}
Action( "%n" );
}
}
#undef AUTO_PACK
/********************************************************************/
/* end of auto locations */
/********************************************************************/
/* verification */
extern void CGDone( n *nd ) {
/*******************************/
// CGError( "OOPS!" );
Action( "CGDone( %t )%n%n", nd );
VerNode( nd );
DumpTree( nd );
NoDanglers();
}
extern void CGTrash( n *nd ) {
/********************************/
Action( "CGTrash( %t )%n%n", nd );
VerNode( nd );
DumpT( nd );
}
static int EvalNo = { 0 };
extern n *CGEval( n *nd ) {
/********************************/
n *new;
char buff[80];
char *endptr;
Action( "CGEval( %t )", nd );
VerNode( nd );
endptr = CopyStr( "[eval", buff );
endptr = CopyStr( LToS( ++EvalNo ), endptr );
endptr = CopyStr( "]", endptr );
new = NewNode( LEAF, nd->t );
new->l = (n *)ACopyOf( buff );
DumpTree( nd );
Code( "evaluate ===> %s%n", new->l );
Action( " -> %t%n%n", new );
return( new );
}
extern n *CGVolatile( n *nd ) {
/************************************/
Action( "CGVolatile( %t ) -> %t%n", nd, nd );
VerNode( nd );
return( nd );
}
extern n *CGAttr( n *nd, cg_sym_attr attr ) {
/**************************************************/
Action( "CGAttr( %t, %l ) -> %t%n", nd, attr, nd );
VerNode( nd );
// should check the attr?
return( nd );
}
static int DupNo = { 0 };
static n *CGDuplicateArray[ 2 ];
extern n **CGDuplicate( n *nd ) {
/************************************/
n *new1;
n *new2;
char buff[80];
char *endptr;
Action( "CGDuplicate( %t )", nd );
VerNode( nd );
endptr = CopyStr( "[dup", buff );
endptr = CopyStr( LToS( ++DupNo ), endptr );
endptr = CopyStr( "]", endptr );
new1 = NewNode( LEAF, nd->t );
new1->l = (n *)ACopyOf( buff );
endptr = CopyStr( "[dup", buff );
endptr = CopyStr( LToS( ++DupNo ), endptr );
endptr = CopyStr( "]", endptr );
new2 = NewNode( LEAF, nd->t );
new2->l = (n *)ACopyOf( buff );
DumpT( nd );
Code( "duplicate ===> %s %s%n", new1->l, new2->l );
CGDuplicateArray[ 0 ] = new1;
CGDuplicateArray[ 1 ] = new2;
Action( " -> %t %t%n", new1, new2 );
return( CGDuplicateArray );
}
static int inlineTypeEquivalent( cg_type t1, cg_type t2 )
{
return TypeAddress( t1 )->refno == TypeAddress( t2 )->refno;
}
extern void CGProcDecl( sym s, cg_type t ) {
/**********************************************/
b *bk;
Action( "%n==================================================%n" );
Action( "CGProcDecl" );
Action( "( %s, %s )", Name(s), Tipe(t) );
Attrs(s);
CClass(s);
bk = FEBack(s);
VerBack(bk);
Code( "Routine %s%n", Name(s) );
if( Inlines ) {
#if 0
if( Inlines->t != t ) {
#else
if( ! inlineTypeEquivalent( Inlines->t, t ) ) {
#endif
CGError( "Declared type of inline '%s' does not match", Name(s) );
}
if( Inlines->h != s ) {
char name[80];
CopyStr( Name(Inlines->h), name );
CGError( "Expecting inline for '%s', got '%s'", name, Name(s) );
}
} else {
DDefLabel( bk->lp );
InProc = s;
}
}
extern void CGParmDecl( sym s, cg_type t ) {
/*************************************************/
ip *iparm;
int i;
addAutoLocn( s, t );
Action( "CGParmDecl" );
Action( "( %s, %s )", Name(s), Tipe(t) );
Attrs(s);
Code( "Parm %s%n", Name(s) );
if( Inlines ) {
Inlines->d++;
if( Inlines->d > Inlines->c ) {
CGError( "Too many parameters for inline '%s'", Name(Inlines->h) );
}
iparm = Inlines->p;
for( i = 1; i < Inlines->d; ++i ) {
iparm = iparm->n;
}
#if 0
if( iparm->t != t ) {
#else
if( ! inlineTypeEquivalent( iparm->t, t ) ) {
#endif
CGError( "Type of parm %d to inline '%s' does not match",
Inlines->d, Name(Inlines->h) );
}
}
}
extern void CGAutoDecl( sym s, cg_type t ) {
/**********************************************/
addAutoLocn( s, t );
Action( "CGAutoDecl" );
Action( "( %s, %s )", Name(s), Tipe(t) );
Attrs(s);
Code( "Auto %s%n", Name(s) );
}
extern label_handle CGLastParm() {
/*********************************/
Action( "CGLastParm()%n" );
return( NULL );
}
extern void Attrs( sym s ) {
/******************************/
fe_attr a;
Action( "\n----" );
a = FEAttr( s );
if( a & FE_PROC ) Action( " FE_PROC" );
if( a & FE_STATIC ) Action( " FE_STATIC" );
if( a & FE_GLOBAL ) Action( " FE_GLOBAL" );
if( a & FE_IMPORT ) Action( " FE_IMPORT" );
if( a & FE_CONSTANT ) Action( " FE_CONSTANT" );
if( a & FE_MEMORY ) Action( " FE_MEMORY" );
if( a & FE_VISIBLE ) Action( " FE_VISIBLE" );
if( a & FE_NOALIAS ) Action( " FE_NOALIAS" );
if( a & FE_UNIQUE ) Action( " FE_UNIQUE" );
if( a & FE_COMMON ) Action( " FE_COMMON" );
if( a & FE_ADDR_TAKEN ) Action( " FE_ADDR_TAKEN" );
if( a & FE_VOLATILE ) Action( " FE_VOLATILE" );
Action( " seg id %d%n", FESegID( s ) );
}
extern void DumpCClass( call_class c ) {
/******************************************/
#if _TARGET & ( _TARG_IAPX86 | _TARG_80386 )
if( c & FAR ) Action( "FAR " );
if( c & ROUTINE_RETURN ) Action( "ROUTINE_RETURN " );
if( c & SPECIAL_RETURN ) Action( "SPECIAL_RETURN " );
#endif
if( c & CALLER_POPS ) Action( "CALLER_POPS " );
if( c & NO_MEMORY_CHANGED ) Action( "NO_MEMORY_CHANGED " );
if( c & NO_MEMORY_READ ) Action( "NO_MEMORY_READ " );
if( c & SUICIDAL ) Action( "SUICIDAL " );
}
extern void CClass( sym s ) {
/********************************/
call_class *pc;
pc = FEAuxInfo( FEAuxInfo( s, AUX_LOOKUP ), CALL_CLASS );
DumpCClass( *pc );
Action( "%n" );
}
extern void CG3WayControl( n *e, l *lt, l *eq, l *gt ) {
/**********************************************************/
Action( "CG3WayControl" );
Action( "( %s, ", Label(lt) );
Action( "%s, ", Label( eq ) );
Action( "%s )%n", Label( gt ) );
Code( "IF_ARITH %s", Label( lt ) );
Code( " %s", Label( eq ) );
Code( " %s ", Label( gt ) );
CRefLabel( lt );
CRefLabel( eq );
CRefLabel( gt );
VerNode( e );
DumpTree( e );
NoDanglers();
}
extern void CGControl( cg_op o, n *e, l *lb ) {
/**************************************************/
Action( "CGControl" );
VerCGCtrl( TRUE, o, e, lb );
}
extern void VerCGCtrl( bool ver, cg_op o, n *e, l *lb ) {
/***********************************************************/
if( ver ) {
VerOp( o, ControlOps );
}
if( o == O_IF_TRUE || o == O_IF_FALSE ) {
VerNode( e );
} else if( e != NULL ) {
CGError( "3rd Parm to CGControl must be NULL if 2nd parm !== O_IF_ ... " );
}
if( o != O_LABEL_RETURN ) {
Action( "( %s, %t, %s )%n", Op(o), e, Label(lb) );
Code( "%s %s ", Op(o), Label(lb) );
} else {
Action( "( %s, %t, NULL )%n", Op(o), e );
Code( "%s%n", Op(o) );
}
if( e != NULL ) {
DumpTree( e );
} else {
Code( "%n" );
}
switch( o ) {
case O_GOTO:
case O_IF_TRUE:
case O_IF_FALSE:
case O_INVOKE_LABEL:
CRefLabel( lb );
break;
case O_LABEL:
CDefLabel( lb );
break;
}
Action( "%n" );
NoDanglers();
}
extern n *CGCompare( cg_op o, n *l, n *r, cg_type t ) {
/************************************************************/
n *new;
Action( "CGCompare" );
VerNode(l);
VerNode(r);
VerOp(o,CompareOps);
Action( "( %s, %t, %t, %s )", Op(o), l, r, Tipe( t ) );
new = Binary(o,l,r,T_BOOLEAN);
Action( " -> %t%n", new );
return( new );
}
extern n *CGFlow( cg_op o, n *l, n *r ) {
/**********************************************/
n *new;
Action( "CGFlow" );
VerNode(l);
if( o != O_FLOW_NOT ) {
VerNode(r);
} else if( r != NULL ) {
CGError( "3rd Parm to CGFlow( O_FLOW_NOT, ... must be null" );
}
VerOp(o,FlowOps);
Action( "( %s, %t, %t )", Op(o), l, r );
new = Binary(o,l,r,T_BOOLEAN);
Action( " -> %t%n", new );
return( new );
}
extern sh *CGSelInit() {
/****************************/
sh *s;
Action( "CGSelInit()" );
s=CGAlloc(sizeof(sh));
s->o=NULL;
s->r=NULL;
s->i=++SelId;
Action( " -> %d%n", SelId );
return(s);
}
extern void CGSelCase( sh *s, l *lb, signed_32 v ) {
/******************************************************/
Action( "CGSelCase" );
Action( "( %d, %l, %s )%n", s->i, v, Label( lb ) );
CRefLabel( lb );
SelRange(s,v,v,lb);
}
extern void CGSelRange( sh *s, signed_32 lo, signed_32 hi, l *lb ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?