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)
|
ExpString::ExpString(const char* value)
|
||||||
: value_(strlen(value))
|
: value_(strlen(value))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -692,6 +692,27 @@ class ExpRelation : public ExpBinary {
|
||||||
fun_t fun_;
|
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 {
|
class ExpString : public Expression {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -82,3 +82,33 @@ void ExpNew::dump(ostream&out, int indent) const
|
||||||
out << "New dynamic array size: ";
|
out << "New dynamic array size: ";
|
||||||
size_->dump(out, indent);
|
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;
|
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
|
* When a string appears in a concatenation, then the type of the
|
||||||
* string is an array with the same element type of the concatenation,
|
* 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;
|
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
|
bool ExpString::is_primary(void) const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -216,3 +216,37 @@ bool ExpName::evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const
|
||||||
|
|
||||||
return evaluate(scope, val);
|
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);
|
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
|
void ExpString::write_to_stream(ostream&fd) const
|
||||||
{
|
{
|
||||||
fd << "\"";
|
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
|
sign
|
||||||
: '+'
|
: '+'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue