00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef CVECTOR_HPP
00032 #define CVECTOR_HPP
00033
00034 #include <stdio.h>
00035 #include <math.h>
00036 #include "glue.h"
00037 #include "cuint.h"
00038 #include "cdecl.h"
00039
00040
00058 class CVector
00059 {
00060 private:
00061 CUInt aval;
00062 CUInt bval;
00063 CUInt hook;
00064 INT32 width;
00065 int sized;
00066
00067 int based;
00068
00069 int preferredBase;
00070
00071 int _signed;
00072 int overflowed;
00073
00074 static int bufferSize;
00075 static char* buffer;
00076 public:
00083 static CVector* AllocFromHeap( CObstack* aHeap, int width ) {
00084 CVector* v = new(aHeap) CVector( width );
00085 v->SetHeap( aHeap );
00086 return v;
00087 }
00088
00093 CVector( INT32 aWidth );
00097 ~CVector();
00104 unsigned Hash();
00109 int HasXZ() { return bval != 0; }
00114 int HasZ( void ) { return (~aval & bval) != 0; }
00119 int IsNegative()
00120 { return _signed && ((aval>>(width-1)) & 1) != 0 && !HasXZ(); }
00125 void SetPreferredBase( int base ) { preferredBase = base; }
00130 int GetPreferredBase() { return preferredBase; }
00136 int Sized() { return sized; }
00142 void Sized( int sized ) { this->sized = sized; }
00148 int Based() { return based; }
00154 void Based( int based ) { this->based = based; }
00159 int Signed() const { return _signed; }
00164 void Signed( int _signed ) { this->_signed = _signed; }
00170 int Overflowed() { return overflowed; }
00175 INT32 GetWidth( void );
00183 void SetWidth( INT32 newWidth );
00187 void SetToX();
00192 const CVector& operator=( const CVector& v );
00197 UINT32 operator=( UINT32 v );
00202 int LoadDecimal( const char* string );
00207 int LoadBinary( const char* string );
00212 int LoadOctal( const char* string );
00217 int LoadHex( const char* string );
00222 int LoadString( const char* string );
00229 char* GetVString( void );
00236 char* GetDecimal( void );
00243 char* GetBinary( void );
00250 char* GetOctal( void );
00257 char* GetHex( void );
00265 char* GetString( void );
00271 int operator==( CVector& v );
00277 int operator==( UINT32 i );
00283 int operator!=( CVector& v ) { return !(*this == v); }
00289 int operator!=( UINT32 i ) { return !(*this == i); }
00295 INT32 GetINT32( void )
00296 {
00297 if( IsNegative() ) {
00298 CVector n(GetWidth());
00299 n.Signed(1);
00300 Neg( &n, this );
00301 return -(INT32)n.aval.GetUINT32();
00302 }
00303
00304 return aval.GetUINT32();
00305 }
00311 INT64 GetINT64( void )
00312 {
00313 if( IsNegative() ) {
00314 CVector n(GetWidth());
00315 n.Signed(1);
00316 Neg( &n, this );
00317 return -(INT64)n.aval.GetUINT64();
00318 }
00319
00320 return aval.GetUINT64();
00321 }
00326 void LoadINT32( INT32 v )
00327 {
00328 aval = (unsigned int)v;
00329 bval = 0;
00330 }
00335 void LoadReal( double d );
00340 double GetReal();
00345 void GetAval( CVector& v ) {
00346 v.aval = aval;
00347 bval = 0;
00348 }
00353 void GetBval( CVector& v ) {
00354 v.aval = bval;
00355 bval = 0;
00356 }
00357
00361 friend void Add( CVector* r, CVector* a, CVector* b );
00362 friend void Sub( CVector* r, CVector* a, CVector* b );
00363 friend void Mul( CVector* r, CVector* a, CVector* b );
00364 friend void Div( CVector* r, CVector* a, CVector* b );
00365 friend void Pow( CVector* r, CVector* a, CVector* b );
00366 friend void Lsha( CVector* r, CVector* a, CVector* b );
00367 friend void Rsha( CVector* r, CVector* a, CVector* b );
00368 friend void Lsh( CVector* r, CVector* a, CVector* b );
00369 friend void Rsh( CVector* r, CVector* a, CVector* b );
00370 friend void Cat( CVector* r, CVector* a, CVector* b );
00371 friend void Rep( CVector* r, CVector* a, CVector* b );
00372 friend void Mod( CVector* r, CVector* a, CVector* b );
00373 friend void And( CVector* r, CVector* a, CVector* b );
00374 friend void Or( CVector* r, CVector* a, CVector* b );
00375 friend void Xor( CVector* r, CVector* a, CVector* b );
00376 friend void Xnor( CVector* r, CVector* a, CVector* b );
00377 friend void Com( CVector* r, CVector* a );
00378 friend void Neg( CVector* r, CVector* a );
00379 friend void Plus( CVector* r, CVector* a );
00380 friend void Not( CVector* r, CVector* a );
00381 friend void Le( CVector* r, CVector* a, CVector* b );
00382 friend void Lt( CVector* r, CVector* a, CVector* b );
00383 friend void Ge( CVector* r, CVector* a, CVector* b );
00384 friend void Gt( CVector* r, CVector* a, CVector* b );
00385 friend void Eq( CVector* r, CVector* a, CVector* b );
00386 friend void Ne( CVector* r, CVector* a, CVector* b );
00387 friend void Ceq( CVector* r, CVector* a, CVector* b );
00388 friend void Cne( CVector* r, CVector* a, CVector* b );
00389 friend void Lor( CVector* r, CVector* a, CVector* b );
00390 friend void Land( CVector* r, CVector* a, CVector* b );
00391 friend void Rand( CVector* r, CVector* a );
00392 friend void Ror( CVector* r, CVector* a );
00393 friend void Rnand( CVector* r, CVector* a );
00394 friend void Rnor( CVector* r, CVector* a );
00395 friend void Rxor( CVector* r, CVector* a );
00396 friend void Rxnor( CVector* r, CVector* a );
00397 friend void Hook( CVector* r, CVector* c, CVector* a, CVector* b );
00401 int IsWidthConstant() { return TRUE; }
00402 int IsWidthVolatile() { return FALSE; }
00403 int IsWidthEvaluateable() { return TRUE; }
00404 CNode* GetWidthExp();
00405 virtual NodeType_t GetNodeType( void );
00406 private:
00407 void Adjust( void );
00408 void GrowBuffer( int bytes )
00409 {
00410 if( bytes <= bufferSize ) {
00411 return;
00412 }
00413 if( buffer != NULL ) {
00414 shell_xfree( buffer, bufferSize );
00415 }
00416 bufferSize = bytes * 2;
00417 buffer = (char*) shell_xmalloc( bufferSize );
00418 }
00419 void SetHeap( CObstack* aHeap ) {
00420 aval.SetHeap( aHeap );
00421 bval.SetHeap( aHeap );
00422 }
00429 void* operator new(size_t size, CObstack* heap) {
00430 return heap->Alloc( size );
00431 }
00435 };
00436
00442 inline void Le( CVector* r, double* a, double* b )
00443 {
00444 r->LoadINT32( *a <= *b );
00445 }
00446
00447
00448 inline void Le( CVector* r, INT32 a, INT32 b )
00449 {
00450 r->LoadINT32( a <= b );
00451 }
00452
00453 inline void Lt( CVector* r, double* a, double* b )
00454 {
00455 r->LoadINT32( *a < *b );
00456 }
00457
00458
00459 inline void Lt( CVector* r, INT32 a, INT32 b )
00460 {
00461 r->LoadINT32( a < b );
00462 }
00463
00464 inline void Ge( CVector* r, double* a, double* b )
00465 {
00466 r->LoadINT32( *a >= *b );
00467 }
00468
00469
00470 inline void Ge( CVector* r, INT32 a, INT32 b )
00471 {
00472 r->LoadINT32( a >= b );
00473 }
00474
00475 inline void Gt( CVector* r, double* a, double* b )
00476 {
00477 r->LoadINT32( *a > *b );
00478 }
00479
00480
00481 inline void Gt( CVector* r, INT32 a, INT32 b )
00482 {
00483 r->LoadINT32( a > b );
00484 }
00485
00486
00487 inline void Ne( CVector* r, double* a, double* b )
00488 {
00489 r->LoadINT32( *a != *b );
00490 }
00491
00492 inline void Ne( CVector* r, INT32 a, INT32 b )
00493 {
00494 r->LoadINT32( a != b );
00495 }
00496
00497 inline void Eq( CVector* r, double* a, double* b )
00498 {
00499 r->LoadINT32( *a == *b );
00500 }
00501
00502 inline void Eq( CVector* r, INT32 a, INT32 b )
00503 {
00504 r->LoadINT32( a == b );
00505 }
00506
00507 inline void Cne( CVector*, double*, double* )
00508 {
00509 fatal( NULL, "!== illegal for reals" );
00510 }
00511
00512 inline void Cne( CVector* r, INT32 a, INT32 b )
00513 {
00514 r->LoadINT32( a != b );
00515 }
00516
00517 inline void Ceq( CVector*, double*, double* )
00518 {
00519 fatal( NULL, "=== illegal for reals" );
00520 }
00521
00522 inline void Ceq( CVector* r, INT32 a, INT32 b )
00523 {
00524 r->LoadINT32( a == b );
00525 }
00526
00530 inline void LogicalValue( CVector* dst, CVector* a )
00531 {
00532 CVector zero(a->GetWidth());
00533 Ne( dst, a, &zero );
00534 }
00535
00536 inline void Hook( double* r, CVector* c, double* a, double* b )
00537 {
00538 CVector cond(1);
00539 LogicalValue( &cond, c );
00540 if( cond.HasXZ() ) {
00541 *r = 0;
00542 } else if( cond == 0) {
00543 *r = *b;
00544 } else {
00545 *r = *a;
00546 }
00547 }
00548
00549 inline void Cat( double*, double*, double* )
00550 {
00551 fatal( NULL, "=== illegal for reals" );
00552 }
00557 #endif // CVECTOR_HPP