Skip to content

Commit

Permalink
The power instruction decoding tables are declared as std::map.
Browse files Browse the repository at this point in the history
Currently, we use the [] operator to access entries in the table.
While the tables are mostly read-only, when we encounter instructions
that are not in the table. The [] operator may create new entries
and cause crashes. Therefore, change all accesses from [] operation
to use find() method.
  • Loading branch information
mxz297 committed Oct 16, 2018
1 parent 0777c24 commit e48c167
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 14 deletions.
63 changes: 49 additions & 14 deletions instructionAPI/src/InstructionDecoder-power.C
Expand Up @@ -662,44 +662,76 @@ using namespace boost::assign;
unsigned int xo = field<26, 30>(insn);
if(xo <= 31)
{
return power_entry::extended_op_0[xo];
const power_table::const_iterator entry_it = power_entry::extended_op_0.find(xo);
if (entry_it == power_entry::extended_op_0.end())
return invalid_entry;
return entry_it->second;
}
return power_entry::extended_op_0[field<21, 30>(insn)];
const power_table::const_iterator entry_it = power_entry::extended_op_0.find(field<21, 30>(insn));
if (entry_it == power_entry::extended_op_0.end())
return invalid_entry;
return entry_it->second;
}

const power_entry& InstructionDecoder_power::extended_op_4()
{
return power_entry::extended_op_4[field<26, 30>(insn)];
const power_table::const_iterator entry_it = power_entry::extended_op_4.find(field<26, 30>(insn));
if (entry_it == power_entry::extended_op_4.end())
return invalid_entry;
return entry_it->second;
}
const power_entry& InstructionDecoder_power::extended_op_19()
{
return power_entry::extended_op_19[field<21, 30>(insn)];
const power_table::const_iterator entry_it = power_entry::extended_op_19.find(field<21, 30>(insn));
if (entry_it == power_entry::extended_op_19.end())
return invalid_entry;
return entry_it->second;
}
const power_entry& InstructionDecoder_power::extended_op_30()
{
return power_entry::extended_op_30[field<27, 29>(insn)];
const power_table::const_iterator entry_it = power_entry::extended_op_30.find(field<27, 29>(insn));
if (entry_it == power_entry::extended_op_30.end())
return invalid_entry;
return entry_it->second;
}
const power_entry& InstructionDecoder_power::extended_op_31()
{
// sradi is a special instruction. Its xop is from 21 to 29 and its xop value is 413
if (field<21,29>(insn) == 413) {
return power_entry::extended_op_31[413];
const power_table::const_iterator entry_it = power_entry::extended_op_31.find(413);
if (entry_it == power_entry::extended_op_31.end())
return invalid_entry;
return entry_it->second;
}
const power_entry& xoform_entry = power_entry::extended_op_31[field<22, 30>(insn)];
if(find(xoform_entry.operands.begin(), xoform_entry.operands.end(), &InstructionDecoder_power::OE)
!= xoform_entry.operands.end())
const power_entry* xoform_entry;
const power_table::const_iterator entry_it = power_entry::extended_op_31.find(field<22, 30>(insn));
if (entry_it == power_entry::extended_op_31.end())
xoform_entry = &invalid_entry;
else
xoform_entry = &(entry_it->second);
if(find(xoform_entry->operands.begin(), xoform_entry->operands.end(), &InstructionDecoder_power::OE)
!= xoform_entry->operands.end())
{
return xoform_entry;
return *xoform_entry;
}
return power_entry::extended_op_31[field<21, 30>(insn)];
const power_table::const_iterator entry_it2 = power_entry::extended_op_31.find(field<21, 30>(insn));
if (entry_it2 == power_entry::extended_op_31.end())
return invalid_entry;
return entry_it2->second;
}
const power_entry& InstructionDecoder_power::extended_op_58()
{
return power_entry::extended_op_58[field<30, 31>(insn)];
const power_table::const_iterator entry_it = power_entry::extended_op_58.find(field<30, 31>(insn));
if (entry_it == power_entry::extended_op_58.end())
return invalid_entry;
return entry_it->second;
}
const power_entry& InstructionDecoder_power::extended_op_59()
{
return power_entry::extended_op_59[field<26, 30>(insn)];
const power_table::const_iterator entry_it = power_entry::extended_op_59.find(field<26, 30>(insn));
if (entry_it == power_entry::extended_op_59.end())
return invalid_entry;
return entry_it->second;
}
const power_entry& InstructionDecoder_power::extended_op_63()
{
Expand All @@ -710,7 +742,10 @@ using namespace boost::assign;
if(found != power_entry::extended_op_63.end())
return found->second;
}
return power_entry::extended_op_63[field<21, 30>(insn)];
const power_table::const_iterator entry_it = power_entry::extended_op_63.find(field<21, 30>(insn));
if (entry_it == power_entry::extended_op_63.end())
return invalid_entry;
return entry_it->second;
}

void InstructionDecoder_power::BF()
Expand Down
2 changes: 2 additions & 0 deletions instructionAPI/src/power_opcode_tables.C
Expand Up @@ -39,6 +39,8 @@ power_table power_entry::extended_op_58;
power_table power_entry::extended_op_59;
power_table power_entry::extended_op_63;

power_entry invalid_entry;

void power_entry::buildTables()
{
std::call_once(built_tables, [&]() {
Expand Down

0 comments on commit e48c167

Please sign in to comment.