extern bool ObjEmitMetaReloc( owl_reloc_type type, bool align ) { //*************************************************************** // Emit a reloc to the beginning of code. // Must be a relative reloc. If not, FALSE is returned. if( !IS_RELOC_RELATIVE( type ) ) return( FALSE ); ObjEmitReloc( ASMCODESTART, type, align, TRUE ); return( TRUE ); }
static bool dirFuncValues( directive_t *dir, dir_table_enum parm ) //**************************************************************** { dir_operand *dirop; static int_8 byte; static int_16 half; static int_32 word; static signed_64 quad; static float flt; static double dbl; int_32 rep; uint_8 prev_alignment = 0; int opnum; void *target = NULL; owl_reloc_type rtype = 0; struct { int size; void *ptr; uint_8 alignment; } data_table[] = { { 1, &byte, 0 }, // DT_VAL_INT8 { 8, &dbl, 3 }, // DT_VAL_DOUBLE { 4, &flt, 2 }, // DT_VAL_FLOAT { 2, &half, 1 }, // DT_VAL_INT16 { 4, &word, 2 }, // DT_VAL_INT32 { 8, &quad, 3 }, // DT_VAL_INT64 }; #define TABLE_IDX( x ) ( ( x ) - DT_VAL_FIRST ) #ifdef _STANDALONE_ if( OWLTellSectionType( CurrentSection ) & OWL_SEC_ATTR_BSS ) { Error( INVALID_BSS_DIRECTIVE, SymName( dir->dir_sym ) ); return( TRUE ); } #endif if( autoAlignment ) { prev_alignment = CurrAlignment; CurrAlignment = data_table[TABLE_IDX(parm)].alignment; } dirop = dir->operand_list; opnum = 0; while( dirop ) { rep = 1; switch( parm ) { case DT_VAL_INT8: assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT ); if( dirop->type == DIROP_INTEGER ) { byte = (int_8)NUMBER_INTEGER( dirop ); } else { // repeat rep = REPEAT_COUNT( dirop ); byte = (int_8)REPEAT_INTEGER( dirop ); } break; case DT_VAL_INT64: assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT ); if( dirop->type == DIROP_INTEGER ) { quad.u._32[I64LO32] = NUMBER_INTEGER( dirop ); } else { // repeat rep = REPEAT_COUNT( dirop ); quad.u._32[I64LO32] = REPEAT_INTEGER( dirop ); } break; case DT_VAL_DOUBLE: assert( dirop->type == DIROP_FLOATING || dirop->type == DIROP_REP_FLT ); if( dirop->type == DIROP_FLOATING ) { dbl = NUMBER_FLOAT( dirop ); } else { rep = REPEAT_COUNT( dirop ); dbl = REPEAT_FLOAT( dirop ); } break; case DT_VAL_FLOAT: assert( dirop->type == DIROP_FLOATING || dirop->type == DIROP_REP_FLT ); if( dirop->type == DIROP_FLOATING ) { flt = (float)NUMBER_FLOAT( dirop ); } else { rep = REPEAT_COUNT( dirop ); flt = (float)REPEAT_FLOAT( dirop ); } break; case DT_VAL_INT32: assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT || dirop->type == DIROP_SYMBOL || dirop->type == DIROP_NUMLABEL_REF ); if( dirop->type == DIROP_INTEGER ) { word = NUMBER_INTEGER( dirop ); } else if( dirop->type == DIROP_REP_INT ) { rep = REPEAT_COUNT( dirop ); word = REPEAT_INTEGER( dirop ); } else { // reloc word = SYMBOL_OFFSET( dirop ); if( assignRelocType( &rtype, SYMBOL_RELOC_TYPE( dirop ), parm ) ) { if( dirop->type == DIROP_SYMBOL ) { target = SymName( SYMBOL_HANDLE( dirop ) ); } else { assert( dirop->type == DIROP_NUMLABEL_REF ); target = &SYMBOL_LABEL_REF( dirop ); } } else { Error( IMPROPER_DIROP, opnum ); } } break; case DT_VAL_INT16: assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT || dirop->type == DIROP_SYMBOL || dirop->type == DIROP_NUMLABEL_REF ); if( dirop->type == DIROP_INTEGER ) { half = (int_16)NUMBER_INTEGER( dirop ); } else if( dirop->type == DIROP_REP_INT ) { rep = REPEAT_COUNT( dirop ); half = (int_16)REPEAT_INTEGER( dirop ); } else { // reloc half = (int_16)SYMBOL_OFFSET( dirop ); if( assignRelocType( &rtype, SYMBOL_RELOC_TYPE( dirop ), parm ) ) { if( dirop->type == DIROP_SYMBOL ) { target = SymName( SYMBOL_HANDLE( dirop ) ); } else { assert( dirop->type == DIROP_NUMLABEL_REF ); target = &SYMBOL_LABEL_REF( dirop ); } } else { Error( IMPROPER_DIROP, opnum ); } } break; default: Error( INTERNAL_UNKNOWN_DT_PARM, parm ); return( FALSE ); } if( target != NULL ) { assert( (parm == DT_VAL_INT32 || parm == DT_VAL_INT16) && rep == 1 ); #ifdef _STANDALONE_ // align with data ObjEmitReloc( CurrentSection, target, rtype, ( opnum == 0 ), (dirop->type == DIROP_SYMBOL) ); #else // align with data ObjEmitReloc( target, rtype, ( opnum == 0 ), (dirop->type == DIROP_SYMBOL ) ); #endif target = NULL; } #ifdef _STANDALONE_ // only align for the first data operand ObjEmitData( CurrentSection, data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size, ( opnum == 0 ) ); #else // only align for the first data operand ObjEmitData( data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size, ( opnum == 0 ) ); #endif for( rep--; rep > 0; rep-- ) { #ifdef _STANDALONE_ OWLEmitData( CurrentSection, data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size ); #else ObjDirectEmitData( data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size ); #endif #if 0 printf( "Size=%d\n", data_table[TABLE_IDX(parm)].size ); switch( parm ) { case DT_VAL_INT8: printf( "Out->%d\n", *(int_8 *)(data_table[TABLE_IDX(parm)].ptr) ); break; case DT_VAL_DOUBLE: printf( "Out->%lf\n", *(double *)(data_table[TABLE_IDX(parm)].ptr) ); break; case DT_VAL_FLOAT: printf( "Out->%f\n", *(float *)(data_table[TABLE_IDX(parm)].ptr) ); break; case DT_VAL_INT16: printf( "Out->%d\n", *(int_16 *)(data_table[TABLE_IDX(parm)].ptr) ); break; case DT_VAL_INT32: printf( "Out->%d\n", *(int_32 *)(data_table[TABLE_IDX(parm)].ptr) ); break; case DT_VAL_INT64: printf( "Out->%d\n", ((signed_64 *)(data_table[TABLE_IDX(parm)].ptr))->_32[0] ); break; default: assert( FALSE ); } #endif } opnum++; dirop = dirop->next; } if( autoAlignment ) { CurrAlignment = prev_alignment; } return( TRUE ); }