static void dataGenPtrSym( // GENERATE POINTER FOR A SYMBOL + OFFSET SYMBOL sym, // - the symbol target_size_t offset, // - the offset cg_type type ) // - codegen type of pointer { if( sym == NULL ) { DbgVerify( offset == 0, "dataGenPtrSym -- NULL symbol with offset <> 0" ); DGInteger( 0, type ); } else { DGFEPtr( (cg_sym_handle)sym, type, offset ); if( type == TY_CODE_PTR && SymIsThunk( sym ) ) { CgioThunkAddrTaken( sym ); } } }
static void EmitDQuad( DATA_QUAD *dq ) { cg_type data_type; int size_of_item; unsigned long amount; auto SYM_ENTRY sym; static int segment; static unsigned long size = 0; if( dq->flags & Q_NEAR_POINTER ) { data_type = T_NEAR_POINTER; size_of_item = TARGET_NEAR_POINTER; } else if( dq->flags & Q_FAR_POINTER ) { data_type = T_LONG_POINTER; size_of_item = TARGET_FAR_POINTER; } else if( dq->flags & Q_CODE_POINTER ) { data_type = T_CODE_PTR; size_of_item = TARGET_POINTER; #if _CPU == 8086 if( TargetSwitches & BIG_CODE ) { size_of_item = TARGET_FAR_POINTER; } #endif } else { data_type = T_POINTER; size_of_item = TARGET_POINTER; #if _CPU == 8086 if( TargetSwitches & BIG_DATA ) { size_of_item = TARGET_FAR_POINTER; } #endif } #if _CPU == 8086 if( size >= 0x10000 ) { if( segment != SEG_CONST && segment != SEG_DATA ) { ++segment; BESetSeg( segment ); size -= 0x10000; } } #endif switch( dq->type ) { case QDT_STATIC: SymGet( &sym, dq->u.var.sym_handle ); segment = sym.u.var.segment; BESetSeg( segment ); AlignIt( sym.sym_type ); DGLabel( FEBack( dq->u.var.sym_handle ) ); size = 0; break; case QDT_CHAR: case QDT_UCHAR: case QDT_BOOL: DGInteger( dq->u.long_values[0], T_UINT_1 ); size += sizeof( char ); if( dq->flags & Q_2_INTS_IN_ONE ) { DGInteger( dq->u.long_values[1], T_UINT_1 ); size += sizeof( char ); } break; case QDT_SHORT: case QDT_USHORT: DGInteger( dq->u.long_values[0], T_UINT_2 ); size += sizeof( target_short ); if( dq->flags & Q_2_INTS_IN_ONE ) { DGInteger( dq->u.long_values[1], T_UINT_2 ); size += sizeof( target_short ); } break; case QDT_INT: case QDT_UINT: DGInteger( dq->u.long_values[0], T_INTEGER ); size += sizeof( target_int ); if( dq->flags & Q_2_INTS_IN_ONE ) { DGInteger( dq->u.long_values[1], T_INTEGER ); size += sizeof( target_int ); } break; case QDT_LONG: case QDT_ULONG: DGInteger( dq->u.long_values[0], T_UINT_4 ); size += sizeof( target_long ); if( dq->flags & Q_2_INTS_IN_ONE ) { DGInteger( dq->u.long_values[1], T_UINT_4 ); size += sizeof( target_long ); } break; case QDT_LONG64: case QDT_ULONG64: DGInteger64( dq->u.long64, T_UINT_8 ); size += sizeof( int64 ); break; case QDT_FLOAT: case QDT_FIMAGINARY: // ftoa( dq->u.double_value, Buffer ); // DGFloat( Buffer, T_SINGLE ); { DATA_QUAD local_dq; float float_value; // dq->u.double_value may not have proper alignment on Alpha // so copy pieces to local copy on stack which will have // proper alignment local_dq.u.long_values[0] = dq->u.long_values[0]; local_dq.u.long_values[1] = dq->u.long_values[1]; float_value = (float)local_dq.u.double_value; DGBytes( sizeof(float), (char *)&float_value ); } size += sizeof( float ); break; case QDT_DOUBLE: case QDT_DIMAGINARY: // ftoa( dq->u.double_value, Buffer ); // DGFloat( Buffer, TY_DOUBLE ); DGBytes( sizeof(double), (char *)&dq->u.double_value ); size += sizeof( double ); break; case QDT_LONG_DOUBLE: case QDT_LDIMAGINARY: DGBytes( sizeof(long_double), (char *)&dq->u.long_double_value ); size += sizeof( long_double ); break; case QDT_STRING: EmitStrPtr( dq->u.string_leaf, data_type ); size += size_of_item; break; case QDT_POINTER: case QDT_ID: if( dq->u.var.sym_handle == 0 ) { DGInteger( dq->u.var.offset, data_type ); } else { DGFEPtr( dq->u.var.sym_handle, data_type, dq->u.var.offset ); } size += size_of_item; break; case QDT_CONST: /* array of characters */ size += EmitBytes( dq->u.string_leaf ); break; case QDT_CONSTANT: #if _CPU == 8086 for( amount = dq->u.long_values[0]; amount != 0; ) { if( amount + size >= 0x00010000 ) { EmitZeros( 0x10000 - size ); amount -= ( 0x10000 - size ); size = 0; if( segment != SEG_CONST && segment != SEG_DATA ) { ++segment; BESetSeg( segment ); } } else { EmitZeros( amount ); size += amount; amount = 0; } } #else amount = dq->u.long_values[0]; EmitZeros( amount ); size += amount; #endif break; } }