mirror of
https://github.com/open-goal/jak-project
synced 2026-07-09 14:55:51 -04:00
[Decompile] pad and gs (#389)
* update stuff * gs reference added * update config
This commit is contained in:
@@ -216,6 +216,24 @@ std::optional<BitFieldDef> get_bitfield_initial_set(Form* form,
|
||||
return def;
|
||||
}
|
||||
|
||||
// also possible to omit the shr if it would be zero:
|
||||
auto matcher_no_shr = Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::SHL),
|
||||
{Matcher::any(0), Matcher::any_integer(1)});
|
||||
auto mr_no_shr = match(matcher_no_shr, strip_int_or_uint_cast(form));
|
||||
if (mr_no_shr.matched) {
|
||||
auto value = mr_no_shr.maps.forms.at(0);
|
||||
int left = mr_no_shr.maps.ints.at(1);
|
||||
int right = 0;
|
||||
int size = 64 - left;
|
||||
int offset = left - right;
|
||||
auto& f = find_field(ts, type, offset, size, {});
|
||||
BitFieldDef def;
|
||||
def.value = value;
|
||||
def.field_name = f.name();
|
||||
def.is_signed = false; // we don't know.
|
||||
return def;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -228,7 +246,7 @@ std::optional<BitFieldDef> get_bitfield_initial_set(Form* form,
|
||||
FormElement* BitfieldAccessElement::push_step(const BitfieldManip step,
|
||||
const TypeSystem& ts,
|
||||
FormPool& pool,
|
||||
const Env& env) {
|
||||
const Env&) {
|
||||
if (m_steps.empty() && step.kind == BitfieldManip::Kind::LEFT_SHIFT) {
|
||||
// for left/right shift combo to get a field.
|
||||
m_steps.push_back(step);
|
||||
@@ -354,6 +372,12 @@ FormElement* BitfieldAccessElement::push_step(const BitfieldManip step,
|
||||
std::vector<BitFieldDef>{*val});
|
||||
}
|
||||
|
||||
lg::error("Invalid state in BitfieldReadElement. Previous steps:");
|
||||
for (auto& old_step : m_steps) {
|
||||
lg::error(" {}", old_step.print());
|
||||
}
|
||||
lg::error("Current: {}\n", step.print());
|
||||
|
||||
throw std::runtime_error("Unknown state in BitfieldReadElement");
|
||||
}
|
||||
|
||||
@@ -409,8 +433,14 @@ BitFieldDef BitFieldDef::from_constant(const BitFieldConstantDef& constant, Form
|
||||
BitFieldDef bfd;
|
||||
bfd.field_name = constant.field_name;
|
||||
bfd.is_signed = constant.is_signed;
|
||||
bfd.value = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(constant.value));
|
||||
if (constant.enum_constant) {
|
||||
bfd.value =
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, *constant.enum_constant);
|
||||
} else {
|
||||
bfd.value = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(constant.value));
|
||||
}
|
||||
|
||||
return bfd;
|
||||
}
|
||||
|
||||
@@ -426,7 +456,7 @@ Form* cast_to_bitfield(const BitFieldType* type_info,
|
||||
in = strip_int_or_uint_cast(in);
|
||||
// check if it's just a constant:
|
||||
auto in_as_atom = form_as_atom(in);
|
||||
if (in_as_atom) {
|
||||
if (in_as_atom && in_as_atom->is_int()) {
|
||||
auto fields = decompile_bitfield_from_int(typespec, env.dts->ts, in_as_atom->get_int());
|
||||
return pool.alloc_single_element_form<BitfieldStaticDefElement>(nullptr, typespec, fields,
|
||||
pool);
|
||||
@@ -458,7 +488,8 @@ Form* cast_to_bitfield(const BitFieldType* type_info,
|
||||
|
||||
// now variables
|
||||
for (auto& arg : args) {
|
||||
auto maybe_field = get_bitfield_initial_set(arg, type_info, env.dts->ts);
|
||||
auto maybe_field =
|
||||
get_bitfield_initial_set(strip_int_or_uint_cast(arg), type_info, env.dts->ts);
|
||||
if (!maybe_field) {
|
||||
// failed, just return cast.
|
||||
return pool.alloc_single_element_form<CastElement>(nullptr, typespec, in);
|
||||
@@ -503,16 +534,19 @@ Form* cast_to_int_enum(const EnumType* type_info,
|
||||
assert(!type_info->is_bitfield());
|
||||
auto integer = get_goal_integer_constant(strip_int_or_uint_cast(in), env);
|
||||
if (integer) {
|
||||
auto entry =
|
||||
decompile_int_enum_from_int(TypeSpec(type_info->get_name()), env.dts->ts, *integer);
|
||||
auto oper = GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, type_info->get_name()));
|
||||
return pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, oper, pool.alloc_single_element_form<ConstantTokenElement>(nullptr, entry));
|
||||
return cast_to_int_enum(type_info, pool, env, *integer);
|
||||
} else {
|
||||
// all failed, just return whatever.
|
||||
return pool.alloc_single_element_form<CastElement>(nullptr, typespec, in);
|
||||
}
|
||||
}
|
||||
|
||||
Form* cast_to_int_enum(const EnumType* type_info, FormPool& pool, const Env& env, s64 in) {
|
||||
auto entry = decompile_int_enum_from_int(TypeSpec(type_info->get_name()), env.dts->ts, in);
|
||||
auto oper = GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, type_info->get_name()));
|
||||
return pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, oper, pool.alloc_single_element_form<ConstantTokenElement>(nullptr, entry));
|
||||
}
|
||||
|
||||
} // namespace decompiler
|
||||
Reference in New Issue
Block a user