vhdlpp: Support for shift operators (SRL, SRR, SRA, SLA).
To be done: ROR & ROL.
This commit is contained in:
parent
49b6ddf93c
commit
763c6fe3c9
|
|
@ -494,6 +494,11 @@ ExpRelation::~ExpRelation()
|
|||
{
|
||||
}
|
||||
|
||||
ExpShift::ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2)
|
||||
: ExpBinary(op1, op2), shift_(op)
|
||||
{
|
||||
}
|
||||
|
||||
ExpString::ExpString(const char* value)
|
||||
: value_(strlen(value))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -692,6 +692,27 @@ class ExpRelation : public ExpBinary {
|
|||
fun_t fun_;
|
||||
};
|
||||
|
||||
class ExpShift : public ExpBinary {
|
||||
public:
|
||||
enum shift_t { SRL, SLL, SRA, SLA, ROL, ROR };
|
||||
|
||||
public:
|
||||
ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2);
|
||||
|
||||
Expression*clone() const {
|
||||
return new ExpShift(shift_, peek_operand1()->clone(), peek_operand2()->clone());
|
||||
}
|
||||
|
||||
int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
|
||||
void write_to_stream(std::ostream&fd) const;
|
||||
int emit(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
virtual bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
shift_t shift_;
|
||||
};
|
||||
|
||||
class ExpString : public Expression {
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -82,3 +82,33 @@ void ExpNew::dump(ostream&out, int indent) const
|
|||
out << "New dynamic array size: ";
|
||||
size_->dump(out, indent);
|
||||
}
|
||||
|
||||
void ExpShift::dump(ostream&out, int indent) const
|
||||
{
|
||||
const char*fun_name = "?";
|
||||
switch (shift_) {
|
||||
case SRL:
|
||||
fun_name = "srl";
|
||||
break;
|
||||
case SLL:
|
||||
fun_name = "sll";
|
||||
break;
|
||||
case SLA:
|
||||
fun_name = "sla";
|
||||
break;
|
||||
case SRA:
|
||||
fun_name = "sra";
|
||||
break;
|
||||
case ROR:
|
||||
fun_name = "ror";
|
||||
break;
|
||||
case ROL:
|
||||
fun_name = "rol";
|
||||
break;
|
||||
}
|
||||
|
||||
out << setw(indent) << "" << "Shift " << fun_name
|
||||
<< " at " << get_fileline() << endl;
|
||||
dump_operands(out, indent+4);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -961,6 +961,19 @@ int ExpRelation::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
|
|||
return errors;
|
||||
}
|
||||
|
||||
int ExpShift::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
if (ltype == 0) {
|
||||
ltype = probe_type(ent, scope);
|
||||
}
|
||||
|
||||
ivl_assert(*this, ltype != 0);
|
||||
errors += elaborate_exprs(ent, scope, ltype);
|
||||
return errors;
|
||||
}
|
||||
|
||||
/*
|
||||
* When a string appears in a concatenation, then the type of the
|
||||
* string is an array with the same element type of the concatenation,
|
||||
|
|
|
|||
|
|
@ -766,6 +766,36 @@ int ExpRelation::emit(ostream&out, Entity*ent, ScopeBase*scope)
|
|||
return errors;
|
||||
}
|
||||
|
||||
int ExpShift::emit(ostream&out, Entity*ent, ScopeBase*scope)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
errors += emit_operand1(out, ent, scope);
|
||||
|
||||
switch (shift_) {
|
||||
case SRL:
|
||||
out << " >> ";
|
||||
break;
|
||||
case SLL:
|
||||
out << " << ";
|
||||
break;
|
||||
case SRA:
|
||||
out << " >>> ";
|
||||
break;
|
||||
case SLA:
|
||||
out << " <<< ";
|
||||
break;
|
||||
case ROR:
|
||||
case ROL:
|
||||
out << " /* ?ror/rol? */ ";
|
||||
break;
|
||||
}
|
||||
|
||||
errors += emit_operand2(out, ent, scope);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
bool ExpString::is_primary(void) const
|
||||
{
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -216,3 +216,37 @@ bool ExpName::evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const
|
|||
|
||||
return evaluate(scope, val);
|
||||
}
|
||||
|
||||
bool ExpShift::evaluate(ScopeBase*scope, int64_t&val) const
|
||||
{
|
||||
int64_t val1, val2;
|
||||
bool rc;
|
||||
|
||||
rc = eval_operand1(scope, val1);
|
||||
if (rc == false)
|
||||
return false;
|
||||
|
||||
rc = eval_operand2(scope, val2);
|
||||
if (rc == false)
|
||||
return false;
|
||||
|
||||
switch (shift_) {
|
||||
case SRL:
|
||||
val = (uint64_t)val1 >> (uint64_t)val2;
|
||||
break;
|
||||
case SLL:
|
||||
val = (uint64_t)val1 << (uint64_t)val2;
|
||||
break;
|
||||
case SRA:
|
||||
val = (int64_t)val1 >> (int64_t)val2;
|
||||
break;
|
||||
case SLA:
|
||||
val = (int64_t)val1 << (int64_t)val2;
|
||||
break;
|
||||
case ROR:
|
||||
case ROL:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -236,6 +236,39 @@ void ExpRelation::write_to_stream(ostream&fd) const
|
|||
peek_operand2()->write_to_stream(fd);
|
||||
}
|
||||
|
||||
void ExpShift::write_to_stream(ostream&out) const
|
||||
{
|
||||
out << "(";
|
||||
write_to_stream_operand1(out);
|
||||
out << ")";
|
||||
|
||||
switch (shift_) {
|
||||
case SRL:
|
||||
out << "srl";
|
||||
break;
|
||||
case SLL:
|
||||
out << "sll";
|
||||
break;
|
||||
case SLA:
|
||||
out << "sla";
|
||||
break;
|
||||
case SRA:
|
||||
out << "sra";
|
||||
break;
|
||||
case ROR:
|
||||
out << "ror";
|
||||
break;
|
||||
case ROL:
|
||||
out << "rol";
|
||||
break;
|
||||
}
|
||||
|
||||
out << "(";
|
||||
write_to_stream_operand2(out);
|
||||
out << ")";
|
||||
}
|
||||
|
||||
|
||||
void ExpString::write_to_stream(ostream&fd) const
|
||||
{
|
||||
fd << "\"";
|
||||
|
|
|
|||
|
|
@ -2139,7 +2139,41 @@ sequential_statement
|
|||
}
|
||||
;
|
||||
|
||||
shift_expression : simple_expression { $$ = $1; } ;
|
||||
shift_expression
|
||||
: simple_expression
|
||||
| simple_expression K_srl simple_expression
|
||||
{ ExpShift*tmp = new ExpShift(ExpShift::SRL, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| simple_expression K_sll simple_expression
|
||||
{ ExpShift*tmp = new ExpShift(ExpShift::SLL, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| simple_expression K_sra simple_expression
|
||||
{ ExpShift*tmp = new ExpShift(ExpShift::SRA, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| simple_expression K_sla simple_expression
|
||||
{ ExpShift*tmp = new ExpShift(ExpShift::SLA, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| simple_expression K_ror simple_expression
|
||||
{ sorrymsg(@2, "ROR is not supported.\n");
|
||||
ExpShift*tmp = new ExpShift(ExpShift::ROR, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| simple_expression K_rol simple_expression
|
||||
{ sorrymsg(@2, "ROL is not supported.\n");
|
||||
ExpShift*tmp = new ExpShift(ExpShift::ROL, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
sign
|
||||
: '+'
|
||||
|
|
|
|||
Loading…
Reference in New Issue