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 Not( CVector* r, CVector* a );
00380 friend void Le( CVector* r, CVector* a, CVector* b );
00381 friend void Lt( CVector* r, CVector* a, CVector* b );
00382 friend void Ge( CVector* r, CVector* a, CVector* b );
00383 friend void Gt( CVector* r, CVector* a, CVector* b );
00384 friend void Eq( CVector* r, CVector* a, CVector* b );
00385 friend void Ne( CVector* r, CVector* a, CVector* b );
00386 friend void Ceq( CVector* r, CVector* a, CVector* b );
00387 friend void Cne( CVector* r, CVector* a, CVector* b );
00388 friend void Lor( CVector* r, CVector* a, CVector* b );
00389 friend void Land( CVector* r, CVector* a, CVector* b );
00390 friend void Rand( CVector* r, CVector* a );
00391 friend void Ror( CVector* r, CVector* a );
00392 friend void Rnand( CVector* r, CVector* a );
00393 friend void Rnor( CVector* r, CVector* a );
00394 friend void Rxor( CVector* r, CVector* a );
00395 friend void Rxnor( CVector* r, CVector* a );
00396 friend void Hook( CVector* r, CVector* c, CVector* a, CVector* b );
00400 int IsWidthConstant() { return TRUE; }
00401 int IsWidthVolatile() { return FALSE; }
00402 int IsWidthEvaluateable() { return TRUE; }
00403 CNode* GetWidthExp();
00404 virtual NodeType_t GetNodeType( void );
00405 private:
00406 void Adjust( void );
00407 void GrowBuffer( int bytes )
00408 {
00409 if( bytes <= bufferSize ) {
00410 return;
00411 }
00412 if( buffer != NULL ) {
00413 shell_xfree( buffer, bufferSize );
00414 }
00415 bufferSize = bytes * 2;
00416 buffer = (char*) shell_xmalloc( bufferSize );
00417 }
00418 void SetHeap( CObstack* aHeap ) {
00419 aval.SetHeap( aHeap );
00420 bval.SetHeap( aHeap );
00421 }
00428 void* operator new(size_t size, CObstack* heap) {
00429 return heap->Alloc( size );
00430 }
00434 };
00435
00441 inline void Le( CVector* r, double* a, double* b )
00442 {
00443 r->LoadINT32( *a <= *b );
00444 }
00445
00446
00447 inline void Le( CVector* r, INT32 a, INT32 b )
00448 {
00449 r->LoadINT32( a <= b );
00450 }
00451
00452 inline void Lt( CVector* r, double* a, double* b )
00453 {
00454 r->LoadINT32( *a < *b );
00455 }
00456
00457
00458 inline void Lt( CVector* r, INT32 a, INT32 b )
00459 {
00460 r->LoadINT32( a < b );
00461 }
00462
00463 inline void Ge( CVector* r, double* a, double* b )
00464 {
00465 r->LoadINT32( *a >= *b );
00466 }
00467
00468
00469 inline void Ge( CVector* r, INT32 a, INT32 b )
00470 {
00471 r->LoadINT32( a >= b );
00472 }
00473
00474 inline void Gt( CVector* r, double* a, double* b )
00475 {
00476 r->LoadINT32( *a > *b );
00477 }
00478
00479
00480 inline void Gt( CVector* r, INT32 a, INT32 b )
00481 {
00482 r->LoadINT32( a > b );
00483 }
00484
00485
00486 inline void Ne( CVector* r, double* a, double* b )
00487 {
00488 r->LoadINT32( *a != *b );
00489 }
00490
00491 inline void Ne( CVector* r, INT32 a, INT32 b )
00492 {
00493 r->LoadINT32( a != b );
00494 }
00495
00496 inline void Eq( CVector* r, double* a, double* b )
00497 {
00498 r->LoadINT32( *a == *b );
00499 }
00500
00501 inline void Eq( CVector* r, INT32 a, INT32 b )
00502 {
00503 r->LoadINT32( a == b );
00504 }
00505
00506 inline void Cne( CVector*, double*, double* )
00507 {
00508 fatal( NULL, "!== illegal for reals" );
00509 }
00510
00511 inline void Cne( CVector* r, INT32 a, INT32 b )
00512 {
00513 r->LoadINT32( a != b );
00514 }
00515
00516 inline void Ceq( CVector*, double*, double* )
00517 {
00518 fatal( NULL, "=== illegal for reals" );
00519 }
00520
00521 inline void Ceq( CVector* r, INT32 a, INT32 b )
00522 {
00523 r->LoadINT32( a == b );
00524 }
00525
00529 inline void LogicalValue( CVector* dst, CVector* a )
00530 {
00531 CVector zero(a->GetWidth());
00532 Ne( dst, a, &zero );
00533 }
00534
00535 inline void Hook( double* r, CVector* c, double* a, double* b )
00536 {
00537 CVector cond(1);
00538 LogicalValue( &cond, c );
00539 if( cond.HasXZ() ) {
00540 *r = 0;
00541 } else if( cond == 0) {
00542 *r = *b;
00543 } else {
00544 *r = *a;
00545 }
00546 }
00547
00548 inline void Cat( double*, double*, double* )
00549 {
00550 fatal( NULL, "=== illegal for reals" );
00551 }
00556 #endif // CVECTOR_HPP