BOOL StrToU64( char *str, unsigned_64 *u64, BOOL neg ) { unsigned_64 r64; unsigned_64 v64; int value; int radix; str = eatSpace( str ); U32ToU64( 0, u64 ); if( neg == TRUE ) { if( *str == '-') { str++; } else { if( *str == '+' ) { str++; neg = FALSE; } } } str = eatSpace( str ); switch( *str ){ case '\0': return( FALSE ); case '0': str++; if( tolower(*str) == 'x' ) { radix = 16; str++; } else { radix = 8; } break; default: radix = 10; } U32ToU64( radix, &r64 ); while( *str != '\0' ) { if( isdigit( *str ) ) { value = *str - '0'; } else { value = 10 + tolower( *str ) - 'a'; } if( value < 0 || value >= radix ) { return ( FALSE ); } U32ToU64( value, &v64 ); U64Mul( u64, &r64, u64 ); U64Add( &v64, u64, u64 ); str++; } if( neg == TRUE) { U64Neg( u64, u64 ); } return( TRUE ); }
OVL_EXTERN bool ConvU8( stack_entry *entry, conv_class from ) { unsigned_64 tmp; switch( from ) { case U1: case U2: case U4: case U8: tmp = entry->v.uint; break; case I1: case I2: case I4: case I8: tmp = entry->v.sint; break; case F4: case F8: case F10: //NYI: 64-bit support I32ToI64( LDToD( &entry->v.real ), &tmp ); break; case C8: case C16: case C20: I32ToI64( LDToD( &entry->v.cmplx.re ), &tmp ); break; case NP2: case NP4: //NYI: 64-bit offsets U32ToU64( entry->v.addr.mach.offset, &tmp ); break; case FP4: case HP4: U32ToU64( entry->v.addr.mach.offset + ((long) entry->v.addr.mach.segment << 16), &tmp ); break; case FP6: U32ToU64( entry->v.addr.mach.offset, &tmp ); break; default: return( FALSE ); } entry->v.uint = tmp; return( TRUE ); }
static bool GetNum( unsigned base ) { bool ok; unsigned_64 num; unsigned_64 big_base; unsigned_64 big_dig; int dig; ok = FALSE; U32ToU64( base, &big_base ); U64Clear( num ); for( ; ; ) { dig = GetDig( base ); if( dig < 0 ) break; U32ToU64( dig, &big_dig ); U64Mul( &num, &big_base, &num ); U64Add( &num, &big_dig, &num ); ++ScanPtr; ok = TRUE; } TokenVal.int_val = num; return( ok ); }
static char ScanNumber( void ) { rad_str *pref; bool ret; char *hold_scan; ret = FALSE; hold_scan = ScanPtr; if( ScanCCharNum && (*ScanPtr == '\'') ) { if( ScanPtr[ 1 ] != NULLCHAR && ScanPtr[ 2 ] == '\'' ) { U32ToU64( ScanPtr[1], &TokenVal.int_val ); ScanPtr += 3; CurrToken = T_INT_NUM; return( TRUE ); } } else { CurrToken = T_BAD_NUM; /* assume we'll find a bad number */ pref = RadStrs; while( pref != NULL ) { if( memicmp( ScanPtr, &pref->radstr[1], pref->radstr[0] ) == 0 ) { ret = TRUE; ScanPtr += pref->radstr[0]; hold_scan = ScanPtr; if( GetNum( pref->radval ) ) { CurrToken = T_INT_NUM; return( TRUE ); } ScanPtr -= pref->radstr[0]; } pref = pref->next; } if( isdigit( *ScanPtr ) && GetNum( CurrRadix ) ) { CurrToken = T_INT_NUM; return( TRUE ); } } ScanPtr = hold_scan; return( ret ); }
local void StoreInt64( TYPEPTR typ ) { TREEPTR tree; DATA_QUAD dq; dq.type = typ->decl_type; dq.flags = Q_DATA; U32ToU64( 0, &dq.u.long64 ); if( CurToken != T_RIGHT_BRACE ) { tree = SingleExpr(); tree = InitAsgn( typ, tree ); // as if we are assigning if( tree->op.opr == OPR_PUSHINT || tree->op.opr == OPR_PUSHFLOAT ) { CastConstValue( tree, typ->decl_type ); dq.u.long64 = tree->op.ulong64_value; } else { CErr1( ERR_NOT_A_CONSTANT_EXPR ); } FreeExprTree( tree ); CompFlags.non_zero_data = 1; } GenDataQuad( &dq, sizeof( int64 ) ); }
TYPEPTR EnumDecl( int flags ) { TYPEPTR typ; TAGPTR tag; flags = flags; NextToken(); if( CurToken == T_ID ) { /* could be: (1) "enum" <id> ";" (2) "enum" <id> <variable_name> ";" (3) "enum" <id> "{" <enum_const_decl> ... "}" */ tag = TagLookup(); NextToken(); if( CurToken != T_LEFT_BRACE ) { typ = tag->sym_type; if( typ == NULL ) { CErr1( ERR_INCOMPLETE_ENUM_DECL ); typ = TypeDefault(); } else { if( typ->decl_type != TYPE_ENUM ) { /* 18-jan-89 */ CErr2p( ERR_DUPLICATE_TAG, tag->name ); } typ->u.tag = tag; } return( typ ); } tag = VfyNewTag( tag, TYPE_ENUM ); } else { tag = NullTag(); } typ = TypeNode( TYPE_ENUM, GetType( TYPE_INT ) ); typ->u.tag = tag; tag->sym_type = typ; tag->size = TARGET_INT; tag->u.enum_list = NULL; if( CurToken == T_LEFT_BRACE ) { const_val val; enum enum_rng index; enum enum_rng const_index; enum enum_rng start_index; enum enum_rng step; enum enum_rng error; uint64 n; uint64 Inc; bool minus; bool has_sign; ENUMPTR *prev_lnk; ENUMPTR esym; source_loc error_loc; char buff[50]; if( CompFlags.make_enums_an_int ) { start_index = ENUM_INT; } else { start_index = ENUM_S8; } const_index = ENUM_UNDEF; NextToken(); if( CurToken == T_RIGHT_BRACE ) { CErr1( ERR_EMPTY_ENUM_LIST ); } U32ToU64( 1, &Inc ); U64Clear( n ); minus = FALSE; has_sign = FALSE; step = 1; prev_lnk = &esym; esym = NULL; while( CurToken == T_ID ) { esym = EnumLkAdd( tag ); *prev_lnk = esym; prev_lnk = &esym->thread; error_loc = TokenLoc; NextToken(); if( CurToken == T_EQUAL ) { NextToken(); error_loc = TokenLoc; ConstExprAndType( &val ); switch( val.type ){ case TYPE_ULONG: case TYPE_UINT: case TYPE_ULONG64: minus = FALSE; break; default: if( val.value.u.sign.v ) { minus = TRUE; step = 2; } else { minus = FALSE; } break; } n = val.value; } else if( has_sign ) { if( n.u.sign.v ) { minus = TRUE; } else { minus = FALSE; } } for( index = start_index; index < ENUM_SIZE; index += step ) { if( minus ) { if( I64Cmp( &n, &( RangeTable[ index ][LOW] ) ) >= 0 ) break; } else { if( U64Cmp( &n, &( RangeTable[ index ][HIGH]) ) <= 0 ) break; } } error = ENUM_UNDEF; if( !CompFlags.extensions_enabled && ( index > ENUM_INT )) { error = ENUM_INT; } if( index >= ENUM_SIZE ) { // overflow signed maximum range if( error == ENUM_UNDEF ) { error = const_index; } } else if(( const_index == ENUM_SIZE - 1 ) && minus ) { // overflow unsigned maximum range by any negative signed value if( error == ENUM_UNDEF ) error = const_index; step = 1; } else { if( !has_sign && minus) { has_sign = TRUE; if( index < const_index ) { // round up to signed index = ( const_index + 1 ) & ~1; } } if( index > const_index ) { const_index = index; typ->object = GetType( ItypeTable[const_index].decl_type ); tag->size = ItypeTable[const_index].size; } } if( error != ENUM_UNDEF ) { SetErrLoc( &error_loc ); get_msg_range( buff, error ); CErr2p( ERR_ENUM_CONSTANT_OUT_OF_RANGE, buff ); InitErrLoc(); } esym->value = n; EnumTable[ esym->hash ] = esym; /* 08-nov-94 */ if( CurToken == T_RIGHT_BRACE ) break; U64Add( &n, &Inc, &n ); MustRecog( T_COMMA ); if( !CompFlags.extensions_enabled && !CompFlags.c99_extensions && ( CurToken == T_RIGHT_BRACE )) { ExpectIdentifier(); /* 13-may-91 */ } } MustRecog( T_RIGHT_BRACE ); } return( typ ); }
local FIELDPTR InitBitField( FIELDPTR field ) { TYPEPTR typ; unsigned long value; unsigned long size; uint64 value64; unsigned long bit_value; unsigned long offset; TOKEN token; int is64bit; token = CurToken; if( CurToken == T_LEFT_BRACE ) NextToken(); typ = field->field_type; size = SizeOfArg( typ ); is64bit = ( typ->u.f.field_type == TYPE_LONG64 ) || ( typ->u.f.field_type == TYPE_ULONG64 ); if( is64bit ) U32ToU64( 0, &value64 ); offset = field->offset; value = 0; while( typ->decl_type == TYPE_FIELD || typ->decl_type == TYPE_UFIELD ) { bit_value = 0; if( CurToken != T_RIGHT_BRACE ) bit_value = ConstExpr(); if( typ->u.f.field_type == TYPE_BOOL ) { if( bit_value != 0 ) { bit_value = 1; } } else { ChkConstant( bit_value, BitMask[typ->u.f.field_width - 1] ); bit_value &= BitMask[typ->u.f.field_width - 1]; } if( is64bit ) { uint64 tmp; U32ToU64( bit_value, &tmp ); U64ShiftL( &tmp, typ->u.f.field_start, &tmp ); value64.u._32[L] |= tmp.u._32[L]; value64.u._32[H] |= tmp.u._32[H]; } else { value |= bit_value << typ->u.f.field_start; } field = field->next_field; if( field == NULL ) break; if( field->offset != offset ) break; /* bit field done */ typ = field->field_type; if( CurToken == T_EOF ) break; if( CurToken != T_RIGHT_BRACE ) { MustRecog( T_COMMA ); } } if( is64bit ) { StoreIValue64( typ->u.f.field_type, value64 ); } else { StoreIValue( typ->u.f.field_type, value, size ); } if( token == T_LEFT_BRACE ) { if( CurToken == T_COMMA ) NextToken(); MustRecog( T_RIGHT_BRACE ); } return( field ); }
/* * ConvertTo -- convert 'entry' to the given 'class'. * 'entry' should be an rvalue. */ void ConvertTo( stack_entry *entry, type_kind k, type_modifier m, unsigned s ) { conv_class from; char *dest; if( s == 0 && k == TK_INTEGER ) { s = DefaultSize( DK_INT ); } if( entry->info.kind == k && entry->info.modifier == m && entry->info.size == s ) return; from = ConvIdx( &entry->info ); switch( from ) { case U1: U32ToU64( U8FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case U2: U32ToU64( U16FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case U4: U32ToU64( U32FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I1: I32ToI64( I8FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I2: I32ToI64( I16FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I4: I32ToI64( I32FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case F4: DToLD( (float)LDToD( &entry->v.real ), &entry->v.real ); break; case F8: DToLD( (double)LDToD( &entry->v.real ), &entry->v.real ); break; case C8: DToLD( (float)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re ); DToLD( (float)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im ); break; case C16: DToLD( (double)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re ); DToLD( (double)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im ); break; case NP2: case FP4: entry->v.addr.mach.offset &= 0xffff; break; case STR: if( k != TK_STRING ) { Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) ); } if( s > entry->info.size ) { /* have to expand string */ _ChkAlloc( dest, s, LIT( ERR_NO_MEMORY_FOR_EXPR ) ); memcpy( dest, entry->v.string.loc.e[0].u.p, entry->info.size ); memset( &dest[entry->info.size], ' ', s - entry->info.size ); if( AllocatedString( entry ) ) { _Free( entry->v.string.allocated ); } entry->v.string.allocated = dest; LocationCreate( &entry->v.string.loc, LT_INTERNAL, dest ); } break; default: break; } entry->info.kind = k; entry->info.modifier = m; entry->info.size = s; if( !ConvFunc[ ConvIdx( &entry->info ) ]( entry, from ) ) { Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) ); } entry->th = NULL; }
OVL_EXTERN bool ConvU4( stack_entry *entry, conv_class from ) { if( !ConvU8( entry, from ) ) return( FALSE ); U32ToU64( (unsigned_32)U32FetchTrunc( entry->v.uint ), &entry->v.uint ); return( TRUE ); }
OVL_EXTERN bool ConvU2( stack_entry *entry, conv_class from ) { if( !ConvU8( entry, from ) ) return( false ); U32ToU64( (unsigned_16)U32FetchTrunc( entry->v.uint ), &entry->v.uint ); return( true ); }