Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perlmod / Linux-i686 / Bit / Vector / Overload.pm
package Bit::Vector::Overload;
use strict;
use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
use Bit::Vector;
require Exporter;
@ISA = qw(Exporter Bit::Vector);
@EXPORT = qw();
@EXPORT_OK = qw();
$VERSION = '6.4';
package Bit::Vector;
use Carp::Clan '^Bit::Vector\b';
use overload
'""' => '_stringify',
'bool' => '_boolean',
'!' => '_not_boolean',
'~' => '_complement',
'neg' => '_negate',
'abs' => '_absolute',
'.' => '_concat',
'x' => '_xerox',
'<<' => '_shift_left',
'>>' => '_shift_right',
'|' => '_union',
'&' => '_intersection',
'^' => '_exclusive_or',
'+' => '_add',
'-' => '_sub',
'*' => '_mul',
'/' => '_div',
'%' => '_mod',
'**' => '_pow',
'.=' => '_assign_concat',
'x=' => '_assign_xerox',
'<<=' => '_assign_shift_left',
'>>=' => '_assign_shift_right',
'|=' => '_assign_union',
'&=' => '_assign_intersection',
'^=' => '_assign_exclusive_or',
'+=' => '_assign_add',
'-=' => '_assign_sub',
'*=' => '_assign_mul',
'/=' => '_assign_div',
'%=' => '_assign_mod',
'**=' => '_assign_pow',
'++' => '_increment',
'--' => '_decrement',
'cmp' => '_lexicompare', # also enables lt, le, gt, ge, eq, ne
'<=>' => '_compare',
'==' => '_equal',
'!=' => '_not_equal',
'<' => '_less_than',
'<=' => '_less_equal',
'>' => '_greater_than',
'>=' => '_greater_equal',
'=' => '_clone',
'fallback' => undef;
$CONFIG[0] = 0;
$CONFIG[1] = 0;
$CONFIG[2] = 0;
# Configuration:
#
# 0 = Scalar Input: 0 = Bit Index (default)
# 1 = from_Hex
# 2 = from_Bin
# 3 = from_Dec
# 4 = from_Enum
#
# 1 = Operator Semantics: 0 = Set Ops (default)
# 1 = Arithmetic Ops
#
# Affected Operators: "+" "-" "*"
# "<" "<=" ">" ">="
# "abs"
#
# 2 = String Output: 0 = to_Hex() (default)
# 1 = to_Bin()
# 2 = to_Dec()
# 3 = to_Enum()
sub Configuration
{
my(@commands);
my($assignment);
my($which,$value);
my($m0,$m1,$m2,$m3,$m4);
my($result);
my($ok);
if (@_ > 2)
{
croak('Usage: $oldconfig = Bit::Vector->Configuration( [ $newconfig ] );');
}
$result = "Scalar Input = ";
if ($CONFIG[0] == 4) { $result .= "Enumeration"; }
elsif ($CONFIG[0] == 3) { $result .= "Decimal"; }
elsif ($CONFIG[0] == 2) { $result .= "Binary"; }
elsif ($CONFIG[0] == 1) { $result .= "Hexadecimal"; }
else { $result .= "Bit Index"; }
$result .= "\nOperator Semantics = ";
if ($CONFIG[1] == 1) { $result .= "Arithmetic Operators"; }
else { $result .= "Set Operators"; }
$result .= "\nString Output = ";
if ($CONFIG[2] == 3) { $result .= "Enumeration"; }
elsif ($CONFIG[2] == 2) { $result .= "Decimal"; }
elsif ($CONFIG[2] == 1) { $result .= "Binary"; }
else { $result .= "Hexadecimal"; }
shift if (@_ > 0);
if (@_ > 0)
{
$ok = 1;
@commands = split(/[,;:|\/\n&+-]/, $_[0]);
foreach $assignment (@commands)
{
if ($assignment =~ /^\s*$/) { } # ignore empty lines
elsif ($assignment =~ /^([A-Za-z\s]+)=([A-Za-z\s]+)$/)
{
$which = $1;
$value = $2;
$m0 = 0;
$m1 = 0;
$m2 = 0;
if ($which =~ /\bscalar|\binput|\bin\b/i) { $m0 = 1; }
if ($which =~ /\boperator|\bsemantic|\bops\b/i) { $m1 = 1; }
if ($which =~ /\bstring|\boutput|\bout\b/i) { $m2 = 1; }
if ($m0 && !$m1 && !$m2)
{
$m0 = 0;
$m1 = 0;
$m2 = 0;
$m3 = 0;
$m4 = 0;
if ($value =~ /\bbit\b|\bindex|\bindice/i) { $m0 = 1; }
if ($value =~ /\bhex/i) { $m1 = 1; }
if ($value =~ /\bbin/i) { $m2 = 1; }
if ($value =~ /\bdec/i) { $m3 = 1; }
if ($value =~ /\benum/i) { $m4 = 1; }
if ($m0 && !$m1 && !$m2 && !$m3 && !$m4) { $CONFIG[0] = 0; }
elsif (!$m0 && $m1 && !$m2 && !$m3 && !$m4) { $CONFIG[0] = 1; }
elsif (!$m0 && !$m1 && $m2 && !$m3 && !$m4) { $CONFIG[0] = 2; }
elsif (!$m0 && !$m1 && !$m2 && $m3 && !$m4) { $CONFIG[0] = 3; }
elsif (!$m0 && !$m1 && !$m2 && !$m3 && $m4) { $CONFIG[0] = 4; }
else { $ok = 0; last; }
}
elsif (!$m0 && $m1 && !$m2)
{
$m0 = 0;
$m1 = 0;
if ($value =~ /\bset\b/i) { $m0 = 1; }
if ($value =~ /\barithmetic/i) { $m1 = 1; }
if ($m0 && !$m1) { $CONFIG[1] = 0; }
elsif (!$m0 && $m1) { $CONFIG[1] = 1; }
else { $ok = 0; last; }
}
elsif (!$m0 && !$m1 && $m2)
{
$m0 = 0;
$m1 = 0;
$m2 = 0;
$m3 = 0;
if ($value =~ /\bhex/i) { $m0 = 1; }
if ($value =~ /\bbin/i) { $m1 = 1; }
if ($value =~ /\bdec/i) { $m2 = 1; }
if ($value =~ /\benum/i) { $m3 = 1; }
if ($m0 && !$m1 && !$m2 && !$m3) { $CONFIG[2] = 0; }
elsif (!$m0 && $m1 && !$m2 && !$m3) { $CONFIG[2] = 1; }
elsif (!$m0 && !$m1 && $m2 && !$m3) { $CONFIG[2] = 2; }
elsif (!$m0 && !$m1 && !$m2 && $m3) { $CONFIG[2] = 3; }
else { $ok = 0; last; }
}
else { $ok = 0; last; }
}
else { $ok = 0; last; }
}
unless ($ok)
{
croak('configuration string syntax error');
}
}
return($result);
}
sub _error
{
my($name,$code) = @_;
my($text);
if ($code == 0)
{
$text = $@;
$text =~ s!\s+! !g;
$text =~ s!\s+at\s.*$!!;
$text =~ s!^(?:Bit::Vector::)?[a-zA-Z0-9_]+\(\):\s*!!i;
$text =~ s!\s+$!!;
}
elsif ($code == 1) { $text = 'illegal operand type'; }
elsif ($code == 2) { $text = 'illegal reversed operands'; }
else { croak('unexpected internal error - please contact author'); }
$text .= " in overloaded ";
if (length($name) > 5) { $text .= "$name operation"; }
else { $text .= "'$name' operator"; }
croak($text);
}
sub _vectorize_
{
my($vector,$scalar) = @_;
if ($CONFIG[0] == 4) { $vector->from_Enum($scalar); }
elsif ($CONFIG[0] == 3) { $vector->from_Dec ($scalar); }
elsif ($CONFIG[0] == 2) { $vector->from_Bin ($scalar); }
elsif ($CONFIG[0] == 1) { $vector->from_Hex ($scalar); }
else { $vector->Bit_On ($scalar); }
}
sub _scalarize_
{
my($vector) = @_;
if ($CONFIG[2] == 3) { return( $vector->to_Enum() ); }
elsif ($CONFIG[2] == 2) { return( $vector->to_Dec () ); }
elsif ($CONFIG[2] == 1) { return( $vector->to_Bin () ); }
else { return( $vector->to_Hex () ); }
}
sub _fetch_operand
{
my($object,$argument,$flag,$name,$build) = @_;
my($operand);
if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
{
eval
{
if ($build && (defined $flag))
{
$operand = $argument->Clone();
}
else { $operand = $argument; }
};
if ($@) { &_error($name,0); }
}
elsif ((defined $argument) && (!ref($argument)))
{
eval
{
$operand = $object->Shadow();
&_vectorize_($operand,$argument);
};
if ($@) { &_error($name,0); }
}
else { &_error($name,1); }
return($operand);
}
sub _check_operand
{
my($argument,$flag,$name) = @_;
if ((defined $argument) && (!ref($argument)))
{
if ((defined $flag) && $flag) { &_error($name,2); }
}
else { &_error($name,1); }
}
sub _stringify
{
my($vector) = @_;
my($name) = 'string interpolation';
my($result);
eval
{
$result = &_scalarize_($vector);
};
if ($@) { &_error($name,0); }
return($result);
}
sub _boolean
{
my($object) = @_;
my($name) = 'boolean test';
my($result);
eval
{
$result = $object->is_empty();
};
if ($@) { &_error($name,0); }
return(! $result);
}
sub _not_boolean
{
my($object) = @_;
my($name) = 'negated boolean test';
my($result);
eval
{
$result = $object->is_empty();
};
if ($@) { &_error($name,0); }
return($result);
}
sub _complement
{
my($object) = @_;
my($name) = '~';
my($result);
eval
{
$result = $object->Shadow();
$result->Complement($object);
};
if ($@) { &_error($name,0); }
return($result);
}
sub _negate
{
my($object) = @_;
my($name) = 'unary minus';
my($result);
eval
{
$result = $object->Shadow();
$result->Negate($object);
};
if ($@) { &_error($name,0); }
return($result);
}
sub _absolute
{
my($object) = @_;
my($name) = 'abs()';
my($result);
eval
{
if ($CONFIG[1] == 1)
{
$result = $object->Shadow();
$result->Absolute($object);
}
else
{
$result = $object->Norm();
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _concat
{
my($object,$argument,$flag) = @_;
my($name) = '.';
my($result);
$name .= '=' unless (defined $flag);
if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
{
eval
{
if (defined $flag)
{
if ($flag) { $result = $argument->Concat($object); }
else { $result = $object->Concat($argument); }
}
else
{
$object->Interval_Substitute($argument,0,0,0,$argument->Size());
$result = $object;
}
};
if ($@) { &_error($name,0); }
return($result);
}
elsif ((defined $argument) && (!ref($argument)))
{
eval
{
if (defined $flag)
{
if ($flag) { $result = $argument . &_scalarize_($object); }
else { $result = &_scalarize_($object) . $argument; }
}
else
{
if ($CONFIG[0] == 2) { $result = $object->new( length($argument) ); }
elsif ($CONFIG[0] == 1) { $result = $object->new( length($argument) << 2 ); }
else { $result = $object->Shadow(); }
&_vectorize_($result,$argument);
$object->Interval_Substitute($result,0,0,0,$result->Size());
$result = $object;
}
};
if ($@) { &_error($name,0); }
return($result);
}
else { &_error($name,1); }
}
sub _xerox # (in Brazil, a photocopy is called a "xerox")
{
my($object,$argument,$flag) = @_;
my($name) = 'x';
my($result);
my($offset);
my($index);
my($size);
$name .= '=' unless (defined $flag);
&_check_operand($argument,$flag,$name);
eval
{
$size = $object->Size();
if (defined $flag)
{
$result = $object->new($size * $argument);
$offset = 0;
$index = 0;
}
else
{
$result = $object;
$result->Resize($size * $argument);
$offset = $size;
$index = 1;
}
for ( ; $index < $argument; $index++, $offset += $size )
{
$result->Interval_Copy($object,$offset,0,$size);
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _shift_left
{
my($object,$argument,$flag) = @_;
my($name) = '<<';
my($result);
$name .= '=' unless (defined $flag);
&_check_operand($argument,$flag,$name);
eval
{
if (defined $flag)
{
$result = $object->Clone();
$result->Insert(0,$argument);
# $result->Move_Left($argument);
}
else
{
# $object->Move_Left($argument);
$object->Insert(0,$argument);
$result = $object;
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _shift_right
{
my($object,$argument,$flag) = @_;
my($name) = '>>';
my($result);
$name .= '=' unless (defined $flag);
&_check_operand($argument,$flag,$name);
eval
{
if (defined $flag)
{
$result = $object->Clone();
$result->Delete(0,$argument);
# $result->Move_Right($argument);
}
else
{
# $object->Move_Right($argument);
$object->Delete(0,$argument);
$result = $object;
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _union_
{
my($object,$operand,$flag) = @_;
if (defined $flag)
{
$operand->Union($object,$operand);
return($operand);
}
else
{
$object->Union($object,$operand);
return($object);
}
}
sub _union
{
my($object,$argument,$flag) = @_;
my($name) = '|';
my($operand);
$name .= '=' unless (defined $flag);
$operand = &_fetch_operand($object,$argument,$flag,$name,1);
eval
{
$operand = &_union_($object,$operand,$flag);
};
if ($@) { &_error($name,0); }
return($operand);
}
sub _intersection_
{
my($object,$operand,$flag) = @_;
if (defined $flag)
{
$operand->Intersection($object,$operand);
return($operand);
}
else
{
$object->Intersection($object,$operand);
return($object);
}
}
sub _intersection
{
my($object,$argument,$flag) = @_;
my($name) = '&';
my($operand);
$name .= '=' unless (defined $flag);
$operand = &_fetch_operand($object,$argument,$flag,$name,1);
eval
{
$operand = &_intersection_($object,$operand,$flag);
};
if ($@) { &_error($name,0); }
return($operand);
}
sub _exclusive_or
{
my($object,$argument,$flag) = @_;
my($name) = '^';
my($operand);
$name .= '=' unless (defined $flag);
$operand = &_fetch_operand($object,$argument,$flag,$name,1);
eval
{
if (defined $flag)
{
$operand->ExclusiveOr($object,$operand);
}
else
{
$object->ExclusiveOr($object,$operand);
$operand = $object;
}
};
if ($@) { &_error($name,0); }
return($operand);
}
sub _add
{
my($object,$argument,$flag) = @_;
my($name) = '+';
my($operand);
$name .= '=' unless (defined $flag);
$operand = &_fetch_operand($object,$argument,$flag,$name,1);
eval
{
if ($CONFIG[1] == 1)
{
if (defined $flag)
{
$operand->add($object,$operand,0);
}
else
{
$object->add($object,$operand,0);
$operand = $object;
}
}
else
{
$operand = &_union_($object,$operand,$flag);
}
};
if ($@) { &_error($name,0); }
return($operand);
}
sub _sub
{
my($object,$argument,$flag) = @_;
my($name) = '-';
my($operand);
$name .= '=' unless (defined $flag);
$operand = &_fetch_operand($object,$argument,$flag,$name,1);
eval
{
if ($CONFIG[1] == 1)
{
if (defined $flag)
{
if ($flag) { $operand->subtract($operand,$object,0); }
else { $operand->subtract($object,$operand,0); }
}
else
{
$object->subtract($object,$operand,0);
$operand = $object;
}
}
else
{
if (defined $flag)
{
if ($flag) { $operand->Difference($operand,$object); }
else { $operand->Difference($object,$operand); }
}
else
{
$object->Difference($object,$operand);
$operand = $object;
}
}
};
if ($@) { &_error($name,0); }
return($operand);
}
sub _mul
{
my($object,$argument,$flag) = @_;
my($name) = '*';
my($operand);
$name .= '=' unless (defined $flag);
$operand = &_fetch_operand($object,$argument,$flag,$name,1);
eval
{
if ($CONFIG[1] == 1)
{
if (defined $flag)
{
$operand->Multiply($object,$operand);
}
else
{
$object->Multiply($object,$operand);
$operand = $object;
}
}
else
{
$operand = &_intersection_($object,$operand,$flag);
}
};
if ($@) { &_error($name,0); }
return($operand);
}
sub _div
{
my($object,$argument,$flag) = @_;
my($name) = '/';
my($operand);
my($temp);
$name .= '=' unless (defined $flag);
$operand = &_fetch_operand($object,$argument,$flag,$name,1);
eval
{
$temp = $object->Shadow();
if (defined $flag)
{
if ($flag) { $operand->Divide($operand,$object,$temp); }
else { $operand->Divide($object,$operand,$temp); }
}
else
{
$object->Divide($object,$operand,$temp);
$operand = $object;
}
};
if ($@) { &_error($name,0); }
return($operand);
}
sub _mod
{
my($object,$argument,$flag) = @_;
my($name) = '%';
my($operand);
my($temp);
$name .= '=' unless (defined $flag);
$operand = &_fetch_operand($object,$argument,$flag,$name,1);
eval
{
$temp = $object->Shadow();
if (defined $flag)
{
if ($flag) { $temp->Divide($operand,$object,$operand); }
else { $temp->Divide($object,$operand,$operand); }
}
else
{
$temp->Divide($object,$operand,$object);
$operand = $object;
}
};
if ($@) { &_error($name,0); }
return($operand);
}
sub _pow
{
my($object,$argument,$flag) = @_;
my($name) = '**';
my($operand,$result);
$name .= '=' unless (defined $flag);
$operand = &_fetch_operand($object,$argument,$flag,$name,0);
eval
{
if (defined $flag)
{
$result = $object->Shadow();
if ($flag) { $result->Power($operand,$object); }
else { $result->Power($object,$operand); }
}
else
{
$object->Power($object,$operand);
$result = $object;
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _assign_concat
{
my($object,$argument) = @_;
return( &_concat($object,$argument,undef) );
}
sub _assign_xerox
{
my($object,$argument) = @_;
return( &_xerox($object,$argument,undef) );
}
sub _assign_shift_left
{
my($object,$argument) = @_;
return( &_shift_left($object,$argument,undef) );
}
sub _assign_shift_right
{
my($object,$argument) = @_;
return( &_shift_right($object,$argument,undef) );
}
sub _assign_union
{
my($object,$argument) = @_;
return( &_union($object,$argument,undef) );
}
sub _assign_intersection
{
my($object,$argument) = @_;
return( &_intersection($object,$argument,undef) );
}
sub _assign_exclusive_or
{
my($object,$argument) = @_;
return( &_exclusive_or($object,$argument,undef) );
}
sub _assign_add
{
my($object,$argument) = @_;
return( &_add($object,$argument,undef) );
}
sub _assign_sub
{
my($object,$argument) = @_;
return( &_sub($object,$argument,undef) );
}
sub _assign_mul
{
my($object,$argument) = @_;
return( &_mul($object,$argument,undef) );
}
sub _assign_div
{
my($object,$argument) = @_;
return( &_div($object,$argument,undef) );
}
sub _assign_mod
{
my($object,$argument) = @_;
return( &_mod($object,$argument,undef) );
}
sub _assign_pow
{
my($object,$argument) = @_;
return( &_pow($object,$argument,undef) );
}
sub _increment
{
my($object) = @_;
my($name) = '++';
my($result);
eval
{
$result = $object->increment();
};
if ($@) { &_error($name,0); }
return($result);
}
sub _decrement
{
my($object) = @_;
my($name) = '--';
my($result);
eval
{
$result = $object->decrement();
};
if ($@) { &_error($name,0); }
return($result);
}
sub _lexicompare
{
my($object,$argument,$flag) = @_;
my($name) = 'cmp';
my($operand);
my($result);
$operand = &_fetch_operand($object,$argument,$flag,$name,0);
eval
{
if ((defined $flag) && $flag)
{
$result = $operand->Lexicompare($object);
}
else
{
$result = $object->Lexicompare($operand);
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _compare
{
my($object,$argument,$flag) = @_;
my($name) = '<=>';
my($operand);
my($result);
$operand = &_fetch_operand($object,$argument,$flag,$name,0);
eval
{
if ((defined $flag) && $flag)
{
$result = $operand->Compare($object);
}
else
{
$result = $object->Compare($operand);
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _equal
{
my($object,$argument,$flag) = @_;
my($name) = '==';
my($operand);
my($result);
$operand = &_fetch_operand($object,$argument,$flag,$name,0);
eval
{
$result = $object->equal($operand);
};
if ($@) { &_error($name,0); }
return($result);
}
sub _not_equal
{
my($object,$argument,$flag) = @_;
my($name) = '!=';
my($operand);
my($result);
$operand = &_fetch_operand($object,$argument,$flag,$name,0);
eval
{
$result = $object->equal($operand);
};
if ($@) { &_error($name,0); }
return(! $result);
}
sub _less_than
{
my($object,$argument,$flag) = @_;
my($name) = '<';
my($operand);
my($result);
$operand = &_fetch_operand($object,$argument,$flag,$name,0);
eval
{
if ($CONFIG[1] == 1)
{
if ((defined $flag) && $flag)
{
$result = ($operand->Compare($object) < 0);
}
else
{
$result = ($object->Compare($operand) < 0);
}
}
else
{
if ((defined $flag) && $flag)
{
$result = ((!$operand->equal($object)) &&
($operand->subset($object)));
}
else
{
$result = ((!$object->equal($operand)) &&
($object->subset($operand)));
}
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _less_equal
{
my($object,$argument,$flag) = @_;
my($name) = '<=';
my($operand);
my($result);
$operand = &_fetch_operand($object,$argument,$flag,$name,0);
eval
{
if ($CONFIG[1] == 1)
{
if ((defined $flag) && $flag)
{
$result = ($operand->Compare($object) <= 0);
}
else
{
$result = ($object->Compare($operand) <= 0);
}
}
else
{
if ((defined $flag) && $flag)
{
$result = $operand->subset($object);
}
else
{
$result = $object->subset($operand);
}
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _greater_than
{
my($object,$argument,$flag) = @_;
my($name) = '>';
my($operand);
my($result);
$operand = &_fetch_operand($object,$argument,$flag,$name,0);
eval
{
if ($CONFIG[1] == 1)
{
if ((defined $flag) && $flag)
{
$result = ($operand->Compare($object) > 0);
}
else
{
$result = ($object->Compare($operand) > 0);
}
}
else
{
if ((defined $flag) && $flag)
{
$result = ((!$object->equal($operand)) &&
($object->subset($operand)));
}
else
{
$result = ((!$operand->equal($object)) &&
($operand->subset($object)));
}
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _greater_equal
{
my($object,$argument,$flag) = @_;
my($name) = '>=';
my($operand);
my($result);
$operand = &_fetch_operand($object,$argument,$flag,$name,0);
eval
{
if ($CONFIG[1] == 1)
{
if ((defined $flag) && $flag)
{
$result = ($operand->Compare($object) >= 0);
}
else
{
$result = ($object->Compare($operand) >= 0);
}
}
else
{
if ((defined $flag) && $flag)
{
$result = $object->subset($operand);
}
else
{
$result = $operand->subset($object);
}
}
};
if ($@) { &_error($name,0); }
return($result);
}
sub _clone
{
my($object) = @_;
my($name) = 'automatic duplication';
my($result);
eval
{
$result = $object->Clone();
};
if ($@) { &_error($name,0); }
return($result);
}
1;
__END__