📄 cgen2.c
字号:
static cg_name TryExceptionInfoAddr()
{
cg_name name;
name = TryFieldAddr( offsetof( struct try_block, exception_info ) );
// name = CGUnary( O_POINTS, name, T_POINTER );
// name = CGUnary( O_POINTS, name, T_POINTER );
return( name );
}
static void SetTryTable( back_handle except_table )
{
cg_name name;
cg_name table;
name = TryFieldAddr( offsetof( struct try_block, scope_table ) );
table = CGBackName( except_table, T_POINTER );
CGDone( CGAssign( name, table, T_POINTER ) );
}
static void SetTryScope( int scope )
{
cg_name name;
name = TryFieldAddr( offsetof( struct try_block, scope_index ) );
CGDone( CGAssign( name, CGInteger( scope, T_UINT_1 ), T_UINT_1 ) );
}
static void EndFinally()
{
cg_name name;
cg_name func;
LABEL_HANDLE label_handle;
call_handle call_list;
label_handle = BENewLabel();
name = TryFieldAddr( offsetof( struct try_block, unwindflag ) );
name = CGUnary( O_POINTS, name, T_UINT_1 );
name = CGCompare( O_EQ, name, CGInteger( 0, T_UINT_1 ), T_UINT_1 );
CGControl( O_IF_TRUE, name, label_handle );
func = CGFEName( SymFinally, T_CODE_PTR );
call_list = CGInitCall( func, T_INTEGER, SymFinally );
CGDone( CGCall( call_list ) );
CGControl( O_LABEL, NULL, label_handle );
BEFiniLabel( label_handle );
}
static cg_name TryAbnormalTermination()
{
cg_name name;
name = TryFieldAddr( offsetof( struct try_block, unwindflag ) );
name = CGUnary( O_POINTS, name, T_UINT_1 );
return( name );
}
static void CallTryRtn( SYM_HANDLE try_rtn, cg_name parm )
{
call_handle call_list;
call_list = CGInitCall( CGFEName( try_rtn, T_POINTER ),
T_INTEGER, try_rtn );
CGAddParm( call_list, parm, T_POINTER );
CGDone( CGCall( call_list ) );
}
static void CallTryInit( void )
{
CallTryRtn( SymTryInit, CGFEName( TrySymHandle, T_POINTER ) );
}
static void CallTryFini( void )
{
cg_name name;
name = TryFieldAddr( offsetof( struct try_block, next ) );
name = CGUnary( O_POINTS, name, T_POINTER );
CallTryRtn( SymTryFini, name );
}
static void TryUnwind( int scope_index )
{
call_handle call_list;
cg_name parm;
call_list = CGInitCall( CGFEName( SymTryUnwind, T_POINTER ),
T_INTEGER, SymTryUnwind );
parm = CGInteger( scope_index, T_UINT_1 );
CGAddParm( call_list, parm, T_INTEGER );
CGDone( CGCall( call_list ) );
}
#endif
#if _MACHINE == _ALPHA
local void GenVaStart( cg_name op1, cg_name offset )
{
cg_name name;
cg_name baseptr;
baseptr = CGVarargsBasePtr( T_POINTER );
name = CGLVAssign( op1, baseptr, T_POINTER );
name = CGBinary( O_PLUS, name, CGInteger( TARGET_POINTER, T_INTEGER ),
T_POINTER );
name = CGAssign( name, offset, T_INTEGER );
CGDone( name );
}
#elif _MACHINE == _PPC
local void GenVaStart( cg_name op1, cg_name offset )
{
cg_name name;
offset = offset;
name = CGUnary( O_VA_START, op1, T_POINTER );
CGDone( name );
}
#endif
static cg_name PushSym( OPNODE *node )
{
cg_name name;
cg_type dtype;
TYPEPTR typ;
SYM_ENTRY sym;
SymGet( &sym, node->sym_handle );
typ = sym.sym_type;
if( sym.flags & SYM_FUNCTION ){
dtype = CodePtrType( sym.attrib );
}else{
dtype = CGenType( typ );
}
if( sym.flags & SYM_FUNC_RETURN_VAR ) {
name = CGTempName( sym.info.return_var, dtype );
} else {
name = CGFEName( node->sym_handle, dtype );
}
if( node->flags & OPFLAG_UNALIGNED ) {
name = CGAttr( name, CG_SYM_UNALIGNED );
}
if( node->flags & OPFLAG_VOLATILE ) {
name = CGVolatile( name );
} else {
name = ForceVolatileFloat( name, typ );
}
name = CGUnary( O_POINTS, name, dtype );
return( name );
}
static cg_name PushSymAddr( OPNODE *node )
{
cg_name name;
cg_type dtype;
SYM_ENTRY sym;
TYPEPTR typ;
SymGet( &sym, node->sym_handle );
typ = sym.sym_type;
if( sym.flags & SYM_FUNCTION ){
dtype = CodePtrType( sym.attrib );
}else{
dtype = CGenType( typ );
}
if( sym.flags & SYM_FUNC_RETURN_VAR ) {
name = CGTempName( sym.info.return_var, dtype );
} else {
name = CGFEName( node->sym_handle, dtype );
// if( (sym.attrib & FLAG_VOLATILE) ||
// (sym.flags & SYM_USED_IN_PRAGMA) ) {
// name = CGVolatile( name );
// }
if( sym.flags & SYM_USED_IN_PRAGMA ) {
name = CGVolatile( name );
}
}
return( name );
}
static cg_name PushRValue( OPNODE *node, cg_name name )
{
TYPEPTR typ;
if( node->flags & OPFLAG_RVALUE ) {
typ = node->result_type;
if( node->flags & OPFLAG_VOLATILE ) {
name = CGVolatile( name );
} else {
name = ForceVolatileFloat( name, typ );
}
name = CGUnary( O_POINTS, name, CGenType( typ ) );
} else {
// if( node->flags & OPFLAG_VOLATILE ) {
// name = CGVolatile( name );
// }
}
return( name );
}
static cg_name DotOperator( cg_name op1, OPNODE *node, cg_name op2 )
{
TYPEPTR typ;
cg_name name;
// node->result_type is the type of the data
// for the O_PLUS we want a pointer type
name = CGBinary( O_PLUS, op1, op2, DataPointerType( node ) );
typ = node->result_type;
if( typ->decl_type == TYPE_FIELD || typ->decl_type == TYPE_UFIELD ) {
name = CGBitMask( name, typ->u.f.field_start,
typ->u.f.field_width, CGenType( typ ) );
}
if( node->flags & OPFLAG_UNALIGNED ) {
name = CGAttr( name, CG_SYM_UNALIGNED );
}
return( PushRValue( node, name ) );
}
static cg_name ArrowOperator( cg_name op1, OPNODE *node, cg_name op2 )
{
// node->result_type is the type of the data
// for the O_PLUS we want a pointer type
#if _CPU == 386
if( Far16Pointer( node->flags ) ) {
op1 = CGUnary( O_PTR_TO_NATIVE, op1, T_POINTER );
}
#endif
// rvalue has already been done on left side of tree
// op1 = CGUnary( O_POINTS, op1, DataPointerType( node ) );
return( DotOperator( op1, node, op2 ) );
}
static cg_name IndexOperator( cg_name op1, OPNODE *node, cg_name op2 )
{
long element_size;
int index_type;
// node->result_type is the type of the data
// for the O_PLUS we want a pointer type
// op2 needs to be multiplied by the element size of the array
#if _CPU == 386
if( Far16Pointer( node->flags ) ) {
op1 = CGUnary( O_PTR_TO_NATIVE, op1, T_POINTER );
}
#endif
element_size = SizeOfArg( node->result_type );
if( element_size != 1 ) {
index_type = T_INTEGER;
#if _CPU == 8086
if(( node->flags & OPFLAG_HUGEPTR) ||
((TargetSwitches & (BIG_DATA|CHEAP_POINTER))==BIG_DATA &&
(node->flags & (OPFLAG_NEARPTR | OPFLAG_FARPTR))==0)) {
index_type = T_INT_4;
}
#endif
op2 = CGBinary( O_TIMES, op2,
CGInteger( element_size, T_INTEGER ), index_type );
}
op1 = CGBinary( O_PLUS, op1, op2, DataPointerType( node ) );
if( node->flags & OPFLAG_UNALIGNED ) {
op1 = CGAttr( op1, CG_SYM_UNALIGNED );
}
return( PushRValue( node, op1 ) );
}
static cg_name DoAddSub( cg_name op1, OPNODE *node, cg_name op2 )
{
cg_name name;
TYPEPTR typ;
typ = node->result_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
name = CGBinary( CGOperator[node->opr], op1, op2, CGenType( typ ) );
// if( typ->decl_type == TYPE_POINTER ) {
// if( typ->u.p.decl_flags & FLAG_VOLATILE ) {
// name = CGVolatile( name );
// }
// }
return( name );
}
static cg_name PushConstant( OPNODE *node )
{
cg_name name;
cg_type dtype;
FLOATVAL *flt;
#ifdef _LONG_DOUBLE_
double doubleval;
long_double ld;
#endif
auto char buffer[32];
dtype = CGDataType[ node->const_type ];
switch( node->const_type ) {
case TYPE_CHAR:
case TYPE_UCHAR:
case TYPE_SHORT:
case TYPE_USHORT:
case TYPE_INT:
case TYPE_UINT:
case TYPE_LONG:
case TYPE_ULONG:
case TYPE_POINTER:
name = CGInteger( node->ulong_value, dtype );
break;
case TYPE_LONG64:
case TYPE_ULONG64:
name = CGInt64( node->ulong64_value, dtype );
break;
case TYPE_FLOAT:
case TYPE_DOUBLE:
case TYPE_LONG_DOUBLE:
case TYPE_FIMAGINARY:
case TYPE_DIMAGINARY:
case TYPE_LDIMAGINARY:
flt = node->float_value;
if( flt->len != 0 ) { // if still in string form
name = CGFloat( flt->string, dtype );
} else { // else in binary form
#ifdef _LONG_DOUBLE_
ld = flt->ld;
__LDFD( (long_double near *)&ld, (double near *)&doubleval );
ftoa( doubleval, buffer );
#else
ftoa( flt->ld.value, buffer );
#endif
name = CGFloat( buffer, dtype );
}
break;
}
return( name );
}
static cg_name PushString( OPNODE *node )
{
STRING_LITERAL *string;
string = node->string_handle;
Emit1String( string );
return( CGBackName( string->cg_back_handle, T_UINT_1 ) );
}
static cg_name DoIndirection( OPNODE *node, cg_name name )
{
TYPEPTR typ;
// check for special kinds of pointers, eg. call __Far16ToFlat
typ = node->result_type;
#if _CPU == 386
if( Far16Pointer( node->flags ) ) {
// Do NOT convert __far16 function pointers to flat because the
// thunk routine expects 16:16 pointers!
if( ( typ->object != NULL ) &&
( typ->object->decl_type != TYPE_FUNCTION ) )
name = CGUnary( O_PTR_TO_NATIVE, name, T_POINTER );
}
#endif
if( node->flags & OPFLAG_UNALIGNED ) {
name = CGAttr( name, CG_SYM_UNALIGNED );
}
if( node->flags & OPFLAG_RVALUE ) {
if( node->flags & OPFLAG_VOLATILE ) {
name = CGVolatile( name );
}
name = CGUnary( O_POINTS, name, CGenType( typ->object ) );
}
return( name );
}
static cg_name ConvertPointer( OPNODE *node, cg_name name )
{
#if _CPU == 386
if( node->oldptr_class == PTR_FAR16 ) {
name = CGUnary( O_PTR_TO_NATIVE, name, T_POINTER );
} else if( node->newptr_class == PTR_FAR16 ) {
name = CGUnary( O_PTR_TO_FOREIGN, name, T_POINTER );
}
#endif
return( name );
}
static call_handle InitFuncCall( OPNODE *node )
{
cg_name name;
cg_type dtype;
TYPEPTR typ;
SYMPTR sym;
sym = SymGetPtr( node->sym_handle );
typ = sym->sym_type;
dtype = CGenType( typ );
name = CGFEName( node->sym_handle, dtype );
// dtype = FESymType( sym );
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
return( CGInitCall( name, CGenType( typ->object ), node->sym_handle ) );
}
static call_handle InitIndFuncCall( OPNODE *node, cg_name name )
{
TYPEPTR typ;
SYMPTR sym;
sym = SymGetPtr( node->sym_handle );
typ = sym->sym_type;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -