void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { assert((!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!"); const Triple &T = getContext().getObjectFileInfo()->getTargetTriple(); if (T.isKnownWindowsMSVCEnvironment()) { if (ByteAlignment > 32) report_fatal_error("alignment is limited to 32-bytes"); // Round size up to alignment so that we will honor the alignment request. Size = std::max(Size, static_cast<uint64_t>(ByteAlignment)); } getAssembler().registerSymbol(*Symbol); Symbol->setExternal(true); Symbol->setCommon(Size, ByteAlignment); if (!T.isKnownWindowsMSVCEnvironment() && ByteAlignment > 1) { SmallString<128> Directive; raw_svector_ostream OS(Directive); const MCObjectFileInfo *MFI = getContext().getObjectFileInfo(); OS << " -aligncomm:\"" << Symbol->getName() << "\"," << Log2_32_Ceil(ByteAlignment); PushSection(); SwitchSection(MFI->getDrectveSection()); EmitBytes(Directive); PopSection(); } }
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; } }