[decompiler] decomp jak2 static-attack-info (#2992)

Fixes #2993
This commit is contained in:
ManDude
2023-09-15 19:32:57 +01:00
committed by GitHub
parent a03413d4ca
commit 87be9ebd14
208 changed files with 4472 additions and 6706 deletions
+147 -82
View File
@@ -316,7 +316,6 @@ FormElement* rewrite_as_send_event(LetElement* in,
// (let ((block-var (new 'stack-no-clear 'event-message-block))
auto block_var = in->entries().at(0).dest;
const auto& block_var_reg = block_var.reg();
auto block_var_name = env.get_variable_name(block_var);
auto block_src = in->entries().at(0).src->try_as_element<StackStructureDefElement>();
if (!block_src) {
return nullptr;
@@ -1148,13 +1147,13 @@ FormElement* rewrite_as_case_with_else(LetElement* in, const Env& env, FormPool&
return pool.alloc_element<CaseElement>(in->entries().at(0).src, entries, cond->else_ir);
}
bool var_name_equal(const Env& env, const std::string& a, std::optional<RegisterAccess> b) {
bool var_equal(const Env& env, const RegisterAccess& a, std::optional<RegisterAccess> b) {
ASSERT(b);
return env.get_variable_name(*b) == a;
return env.get_variable_name_name_only(*b) == env.get_variable_name_name_only(a);
}
Form* match_ja_set(const Env& env,
const std::string& ch_var_name,
const RegisterAccess& ch_var,
const std::string& field_name,
int arr_idx,
Form* in,
@@ -1179,9 +1178,9 @@ Form* match_ja_set(const Env& env,
return nullptr;
}
if (!var_name_equal(env, ch_var_name, mr.maps.regs.at(0))) {
lg::error("[{}] JA MACRO ERROR channel var not {} in set {} {}", env.func->name(), ch_var_name,
field_name, arr_idx);
if (!var_equal(env, ch_var, mr.maps.regs.at(0))) {
lg::error("[{}] JA MACRO ERROR channel var not {} in set {} {}", env.func->name(),
env.get_variable_name(ch_var), field_name, arr_idx);
*bad = true;
return nullptr;
}
@@ -1226,8 +1225,7 @@ FormElement* rewrite_joint_macro(LetElement* in, const Env& env, FormPool& pool)
// look for setting a var to (-> self skel root-channel ,channel).
// yes, channel is actually not always just 0!
auto ra = in->entries().at(0).dest;
auto var = env.get_variable_name(ra);
auto chan = in->entries().at(0).dest;
auto mr_chan = match(
Matcher::deref(Matcher::s6(), false,
{DerefTokenMatcher::string("skel"), DerefTokenMatcher::string("root-channel"),
@@ -1242,13 +1240,13 @@ FormElement* rewrite_joint_macro(LetElement* in, const Env& env, FormPool& pool)
// there is just a LOT to match. and then to write!
bool bad = false;
int idx = 0;
auto set_fi = match_ja_set(env, var, "frame-interp", -1, in->body(), &idx, &bad);
auto set_dist = match_ja_set(env, var, "dist", -1, in->body(), &idx, &bad);
auto set_fg = match_ja_set(env, var, "frame-group", -1, in->body(), &idx, &bad);
auto set_p0 = match_ja_set(env, var, "param", 0, in->body(), &idx, &bad);
auto set_p1 = match_ja_set(env, var, "param", 1, in->body(), &idx, &bad);
auto set_nf = match_ja_set(env, var, "num-func", -1, in->body(), &idx, &bad);
auto set_fn = match_ja_set(env, var, "frame-num", -1, in->body(), &idx, &bad);
auto set_fi = match_ja_set(env, chan, "frame-interp", -1, in->body(), &idx, &bad);
auto set_dist = match_ja_set(env, chan, "dist", -1, in->body(), &idx, &bad);
auto set_fg = match_ja_set(env, chan, "frame-group", -1, in->body(), &idx, &bad);
auto set_p0 = match_ja_set(env, chan, "param", 0, in->body(), &idx, &bad);
auto set_p1 = match_ja_set(env, chan, "param", 1, in->body(), &idx, &bad);
auto set_nf = match_ja_set(env, chan, "num-func", -1, in->body(), &idx, &bad);
auto set_fn = match_ja_set(env, chan, "frame-num", -1, in->body(), &idx, &bad);
// lastly, match the function call.
enum { NO_FUNC, EVAL, NO_EVAL } func_status = NO_FUNC;
@@ -1261,7 +1259,7 @@ FormElement* rewrite_joint_macro(LetElement* in, const Env& env, FormPool& pool)
in->body()->at(idx));
if (mr_func.matched) {
// NOTE : it's actually fine for there to be no func. we just forgo setting the num! param.
if (!var_name_equal(env, var, mr_func.maps.regs.at(0))) {
if (!var_equal(env, chan, mr_func.maps.regs.at(0))) {
return nullptr;
}
@@ -1293,7 +1291,7 @@ FormElement* rewrite_joint_macro(LetElement* in, const Env& env, FormPool& pool)
}
// PSYCHE! there may actually be a second frame-num set. for some reason. sigh...
auto set_fn2 = match_ja_set(env, var, "frame-num", -1, in->body(), &idx, &bad);
auto set_fn2 = match_ja_set(env, chan, "frame-num", -1, in->body(), &idx, &bad);
if (bad) {
// an error occurred
@@ -1378,7 +1376,7 @@ FormElement* rewrite_joint_macro(LetElement* in, const Env& env, FormPool& pool)
auto mr = match(matcher_max_num, set_fn2);
if (mr.matched &&
((form_fg && mr.maps.forms.at(1)->to_form(env) == form_fg->to_form(env)) ||
(!form_fg && var_name_equal(env, var, mr.maps.regs.at(0))))) {
(!form_fg && var_equal(env, chan, mr.maps.regs.at(0))))) {
num_form = pool.form<ConstantTokenElement>("max");
} else {
num_form = pool.form<GenericElement>(
@@ -1398,7 +1396,7 @@ FormElement* rewrite_joint_macro(LetElement* in, const Env& env, FormPool& pool)
auto mr = match(matcher_max_num, set_p0);
if (mr.matched &&
((form_fg && mr.maps.forms.at(1)->to_form(env) == form_fg->to_form(env)) ||
(!form_fg && var_name_equal(env, var, mr.maps.regs.at(0))))) {
(!form_fg && var_equal(env, chan, mr.maps.regs.at(0))))) {
num_form = pool.form<GenericElement>(
GenericOperator::make_function(pool.form<ConstantTokenElement>(prelim_num)),
pool.form<ConstantTokenElement>("max"));
@@ -1432,7 +1430,7 @@ FormElement* rewrite_joint_macro(LetElement* in, const Env& env, FormPool& pool)
// (the float (1- (-> ja-ch frame-group data 0 length)))
auto mr = match(matcher_max_num, set_p0);
if (!mr.matched || (form_fg && mr.maps.forms.at(1)->to_form(env) != form_fg->to_form(env)) ||
(!form_fg && !var_name_equal(env, var, mr.maps.regs.at(0)))) {
(!form_fg && !var_equal(env, chan, mr.maps.regs.at(0)))) {
// did not match default
seek_args.push_back(set_p0);
}
@@ -1466,7 +1464,7 @@ FormElement* rewrite_joint_macro(LetElement* in, const Env& env, FormPool& pool)
if (set_fn) {
auto mr = match(matcher_max_num, set_fn);
if (mr.matched && ((form_fg && mr.maps.forms.at(1)->to_form(env) == form_fg->to_form(env)) ||
(!form_fg && var_name_equal(env, var, mr.maps.regs.at(0))))) {
(!form_fg && var_equal(env, chan, mr.maps.regs.at(0))))) {
set_fn = pool.form<ConstantTokenElement>("max");
}
}
@@ -1510,11 +1508,8 @@ FormElement* rewrite_proc_new(LetElement* in, const Env& env, FormPool& pool) {
return nullptr;
}
auto test = in->to_form(env).print();
// look for setting a var to (get-process *default-dead-pool* logo-slave #x4000)
auto ra = in->entries().at(0).dest;
auto var = env.get_variable_name(ra);
auto mr_get_proc = match(
Matcher::func("get-process", {Matcher::any(0), Matcher::any_symbol(1), Matcher::any(2)}),
in->entries().at(0).src);
@@ -1690,8 +1685,6 @@ FormElement* rewrite_attack_info(LetElement* in, const Env& env, FormPool& pool)
return nullptr;
}
auto test = in->to_form(env).print();
// (let ((block-var (new 'static 'attack-info))
auto block_src = in->entries().at(0).src->try_as_element<DecompiledDataElement>();
if (!block_src) {
@@ -1705,34 +1698,109 @@ FormElement* rewrite_attack_info(LetElement* in, const Env& env, FormPool& pool)
const auto& label = block_src->label();
const auto& words = env.file->words_by_seg.at(label.target_segment);
u32 mask = words.at((label.offset + 64) / 4).data;
// offset of `mask` field in `attack-info`
int mask_field_offset = 64;
if (env.version == GameVersion::Jak2) {
mask_field_offset = 88;
}
u32 mask = words.at((label.offset + mask_field_offset) / 4).data;
u32 mask_implicit = 0;
auto block_var = in->entries().at(0).dest;
const auto& block_var_reg = block_var.reg();
auto block_var_name = env.get_variable_name(block_var);
const static std::map<std::string, std::pair<int, bool>> possible_args = {
{"vector", {1, true}}, {"mode", {5, false}}, {"shove-back", {6, false}},
{"shove-up", {7, false}}, {"control", {10, false}}, {"angle", {11, false}}};
enum AttackInfoFieldKind { DEFAULT, VECTOR, METERS, DEGREES };
const static std::map<std::string, std::pair<int, AttackInfoFieldKind>> possible_args_jak1 = {
{"vector", {1, VECTOR}}, {"mode", {5, DEFAULT}}, {"shove-back", {6, DEFAULT}},
{"shove-up", {7, DEFAULT}}, {"control", {10, DEFAULT}}, {"angle", {11, DEFAULT}},
};
const static std::map<std::string, std::pair<int, AttackInfoFieldKind>> possible_args_jak2 = {
{"vector", {1, VECTOR}},
{"intersection", {2, VECTOR}},
{"attacker", {3, DEFAULT}},
{"invinc-time", {5, DEFAULT}},
{"mode", {6, DEFAULT}},
{"shove-back", {7, DEFAULT}},
{"shove-up", {8, DEFAULT}},
{"speed", {9, DEFAULT}},
{"control", {11, DEFAULT}},
{"angle", {12, DEFAULT}},
{"id", {15, DEFAULT}},
{"count", {16, DEFAULT}},
{"penetrate-using", {17, DEFAULT}},
{"attacker-velocity", {18, VECTOR}},
{"damage", {19, DEFAULT}},
{"shield-damage", {20, DEFAULT}},
{"knock", {21, DEFAULT}},
{"test", {22, DEFAULT}},
};
const auto& possible_args =
env.version == GameVersion::Jak1 ? possible_args_jak1 : possible_args_jak2;
std::vector<std::pair<std::string, Form*>> args_in_info;
for (int i = 0; i < in->body()->size() - 1; ++i) {
auto s_elt = dynamic_cast<SetFormFormElement*>(in->body()->at(i));
// v--v
// (set! (-> v1-2 mode) arg2)
Form* s_src = nullptr; // the source form. we use a separate variable since we might want to
// change this (e.g. into (new-attack-id))
if (!s_elt) {
lg::error("attack info err elt {} not a set!: {}", i, in->body()->at(i)->to_string(env));
return nullptr;
// lg::error("attack info err elt {} not a set!: {}", i, in->body()->at(i)->to_string(env));
// lg::error("checking if (new-attack-id)...");
auto l_elt = dynamic_cast<LetElement*>(in->body()->at(i));
if (l_elt) {
const auto match_let_for_new_attack_id = Matcher::let(
false, {LetEntryMatcher::any(Matcher::symbol("*game-info*"), 0)},
{Matcher::let(
false,
{LetEntryMatcher::any(
Matcher::op_fixed(FixedOperatorKind::ADDITION,
{Matcher::deref(Matcher::same_var(0), false,
{DerefTokenMatcher::string("attack-id")}),
Matcher::integer(1)}),
1)},
{Matcher::set(Matcher::deref(Matcher::same_var(0), false,
{DerefTokenMatcher::string("attack-id")}),
Matcher::same_var(1)),
Matcher::set(Matcher::deref(Matcher::reg(block_var_reg), false,
{DerefTokenMatcher::string("id")}),
Matcher::same_var(1))})});
auto mr_let = match(match_let_for_new_attack_id, l_elt, &env);
if (mr_let.matched) {
s_src = pool.form<GenericElement>(
GenericOperator::make_function(pool.form<ConstantTokenElement>("new-attack-id")));
s_elt = dynamic_cast<SetFormFormElement*>(
dynamic_cast<LetElement*>(l_elt->body()->at(0))->body()->at(1));
}
}
if (!s_src) {
lg::error("attack info err elt {} not a set! or (new-attack-id): {}", i,
in->body()->at(i)->to_string(env));
return nullptr;
}
} else {
s_src = s_elt->src();
}
auto d_elt = s_elt->dst()->try_as_element<DerefElement>();
// (set! (-> v1-2 mode) arg2)
// ^------------^
if (!d_elt) {
lg::error("attack info err elt {} dst not a deref: {}", i, s_elt->dst()->to_string(env));
return nullptr;
}
// (set! (-> v1-2 mode) arg2)
// ^--^ ^--^
if (d_elt->tokens().size() != 1 && d_elt->tokens().size() != 2) {
lg::error("attack info err elt {} invalid token len: {}", i, d_elt->to_string(env));
return nullptr;
}
// (set! (-> v1-2 mode) arg2)
// ^--^
if (d_elt->tokens().at(0).kind() != DerefToken::Kind::FIELD_NAME) {
lg::error("attack info err elt {} invalid token kind: {}", i, d_elt->to_string(env));
return nullptr;
@@ -1740,7 +1808,8 @@ FormElement* rewrite_attack_info(LetElement* in, const Env& env, FormPool& pool)
const auto& field_name = d_elt->tokens().at(0).field_name();
auto arg_it = possible_args.find(field_name);
if (arg_it == possible_args.end()) {
lg::error("attack info unknown field {}", field_name);
lg::error("attack info unknown field `{}`, static-attack-info could not be generated",
field_name);
return nullptr;
}
if (arg_it->second.second &&
@@ -1753,25 +1822,25 @@ FormElement* rewrite_attack_info(LetElement* in, const Env& env, FormPool& pool)
}
if (arg_it->second.second) {
auto d_src = s_elt->src()->try_as_element<DerefElement>();
auto d_src = s_src->try_as_element<DerefElement>();
if (d_src) {
if (d_src->tokens().size() == 1 && d_src->tokens().at(0).is_field_name("quad")) {
args_in_info.push_back({field_name, d_src->base()});
} else {
d_src->tokens().pop_back();
args_in_info.push_back({field_name, s_elt->src()});
args_in_info.push_back({field_name, s_src});
}
}
} else {
if ((field_name == "shove-back" || field_name == "shove-up") &&
s_elt->src()->to_form(env).is_float()) {
s_src->to_form(env).is_float()) {
args_in_info.push_back(
{field_name, pool.form<GenericElement>(GenericOperator::make_function(
pool.form<ConstantTokenElement>("meters")),
pool.form<ConstantTokenElement>(meters_to_string(
s_elt->src()->to_form(env).as_float())))});
s_src->to_form(env).as_float())))});
} else {
args_in_info.push_back({field_name, s_elt->src()});
args_in_info.push_back({field_name, s_src});
}
}
mask_implicit |= 1 << arg_it->second.first;
@@ -2110,16 +2179,15 @@ FormElement* rewrite_with_dma_buf_add_bucket(LetElement* in, const Env& env, For
}
// dma buffer part can be anything, really.
auto buf_reg = in->entries().at(0).dest;
auto buf_dst = env.get_variable_name(buf_reg);
auto bucket_dst = env.get_variable_name(in->entries().at(1).dest);
auto buf_dst = in->entries().at(0).dest;
auto bucket_dst = in->entries().at(1).dest;
auto buf_src = in->entries().at(0).src;
// check for (-> buf_dst base) now
auto mr_buf_base = match(dma_buf_base_matcher, in->entries().at(1).src);
if (!mr_buf_base.matched) {
return nullptr;
}
if (!var_name_equal(env, buf_dst, mr_buf_base.maps.regs.at(0))) {
if (!var_equal(env, buf_dst, mr_buf_base.maps.regs.at(0))) {
lg::print("dma buf bad name\n");
return nullptr;
}
@@ -2141,7 +2209,7 @@ FormElement* rewrite_with_dma_buf_add_bucket(LetElement* in, const Env& env, For
if (last_part->entries().size() != 1 || last_part->body()->size() != 2) {
return nullptr;
}
auto buf_end_dst = env.get_variable_name(last_part->entries().at(0).dest);
auto buf_end_dst = last_part->entries().at(0).dest;
auto dmatag_let = dynamic_cast<LetElement*>(last_part->body()->at(0));
@@ -2149,7 +2217,7 @@ FormElement* rewrite_with_dma_buf_add_bucket(LetElement* in, const Env& env, For
return nullptr;
}
auto dmatag_dst = env.get_variable_name(dmatag_let->entries().at(0).dest);
auto dmatag_dst = dmatag_let->entries().at(0).dest;
auto mr_last_part = match(dma_buf_base_matcher, last_part->entries().at(0).src);
auto mr_dmatag = match(dma_buf_base_matcher, dmatag_let->entries().at(0).src);
@@ -2157,8 +2225,8 @@ FormElement* rewrite_with_dma_buf_add_bucket(LetElement* in, const Env& env, For
lg::print("dma buf bad match 2\n");
return nullptr;
}
if (!var_name_equal(env, buf_dst, mr_last_part.maps.regs.at(0)) ||
!var_name_equal(env, buf_dst, mr_dmatag.maps.regs.at(0))) {
if (!var_equal(env, buf_dst, mr_last_part.maps.regs.at(0)) ||
!var_equal(env, buf_dst, mr_dmatag.maps.regs.at(0))) {
lg::print("dma buf bad name 2\n");
return nullptr;
}
@@ -2178,7 +2246,7 @@ FormElement* rewrite_with_dma_buf_add_bucket(LetElement* in, const Env& env, For
Matcher::set(Matcher::deref(Matcher::cast("(pointer int64)", Matcher::any_reg(0)), false, {}),
Matcher::integer(0x20000000)),
set_dmatag_hdr);
if (!mr_dmatag_hdr.matched || !var_name_equal(env, dmatag_dst, mr_dmatag_hdr.maps.regs.at(0))) {
if (!mr_dmatag_hdr.matched || !var_equal(env, dmatag_dst, mr_dmatag_hdr.maps.regs.at(0))) {
return nullptr;
}
@@ -2186,7 +2254,7 @@ FormElement* rewrite_with_dma_buf_add_bucket(LetElement* in, const Env& env, For
set_dmatag_w1->op()->store_size() != 4 || !set_dmatag_w1->op()->value().is_int(0) ||
set_dmatag_w1->op()->addr().kind() != SimpleExpression::Kind::ADD ||
set_dmatag_w1->op()->addr().args() != 2 || !set_dmatag_w1->op()->addr().get_arg(0).is_var() ||
!var_name_equal(env, dmatag_dst, set_dmatag_w1->op()->addr().get_arg(0).var()) ||
!var_equal(env, dmatag_dst, set_dmatag_w1->op()->addr().get_arg(0).var()) ||
!set_dmatag_w1->op()->addr().get_arg(1).is_int(8)) {
return nullptr;
}
@@ -2194,7 +2262,7 @@ FormElement* rewrite_with_dma_buf_add_bucket(LetElement* in, const Env& env, For
set_dmatag_w2->op()->store_size() != 4 || !set_dmatag_w2->op()->value().is_int(0) ||
set_dmatag_w2->op()->addr().kind() != SimpleExpression::Kind::ADD ||
set_dmatag_w2->op()->addr().args() != 2 || !set_dmatag_w2->op()->addr().get_arg(0).is_var() ||
!var_name_equal(env, dmatag_dst, set_dmatag_w2->op()->addr().get_arg(0).var()) ||
!var_equal(env, dmatag_dst, set_dmatag_w2->op()->addr().get_arg(0).var()) ||
!set_dmatag_w2->op()->addr().get_arg(1).is_int(12)) {
return nullptr;
}
@@ -2204,8 +2272,8 @@ FormElement* rewrite_with_dma_buf_add_bucket(LetElement* in, const Env& env, For
Matcher::op_fixed(FixedOperatorKind::ADDITION_PTR,
{Matcher::any_reg(0), Matcher::integer(16)})),
set_dmatag_push);
if (!mr_dmatag_push.matched || !var_name_equal(env, dmatag_dst, mr_dmatag_push.maps.regs.at(0)) ||
!var_name_equal(env, buf_dst, mr_dmatag_push.maps.regs.at(1))) {
if (!mr_dmatag_push.matched || !var_equal(env, dmatag_dst, mr_dmatag_push.maps.regs.at(0)) ||
!var_equal(env, buf_dst, mr_dmatag_push.maps.regs.at(1))) {
return nullptr;
}
@@ -2219,8 +2287,8 @@ FormElement* rewrite_with_dma_buf_add_bucket(LetElement* in, const Env& env, For
Matcher::cast("(pointer dma-tag)", Matcher::any_reg(3))}),
last_part->body()->at(1));
if (!mr_bucket_add_tag_func.matched ||
!var_name_equal(env, bucket_dst, mr_bucket_add_tag_func.maps.regs.at(2)) ||
!var_name_equal(env, buf_end_dst, mr_bucket_add_tag_func.maps.regs.at(3))) {
!var_equal(env, bucket_dst, mr_bucket_add_tag_func.maps.regs.at(2)) ||
!var_equal(env, buf_end_dst, mr_bucket_add_tag_func.maps.regs.at(3))) {
return nullptr;
}
auto mr_submatch = match(
@@ -2241,7 +2309,7 @@ FormElement* rewrite_with_dma_buf_add_bucket(LetElement* in, const Env& env, For
}
auto elt = pool.alloc_element<WithDmaBufferAddBucketElement>(
buf_reg, buf_src, mr_bucket_add_tag_func.maps.forms.at(1),
buf_dst, buf_src, mr_bucket_add_tag_func.maps.forms.at(1),
pool.alloc_sequence_form(nullptr, body));
elt->parent_form = in->parent_form;
return elt;
@@ -2270,7 +2338,7 @@ FormElement* rewrite_launch_particles(LetElement* in, const Env& env, FormPool&
return nullptr;
}
auto func = in->entries().at(0);
auto& func = in->entries().at(0);
if (func.src->elts().at(0)->to_string(env) != "sp-launch-particles-var") {
return nullptr;
}
@@ -2285,7 +2353,7 @@ FormElement* rewrite_launch_particles(LetElement* in, const Env& env, FormPool&
return nullptr;
}
auto part_system = in->entries().at(1);
auto& part_system = in->entries().at(1);
auto system = part_system.src->at(0)->to_string(env);
if (system != "*sp-particle-system-2d*" && system != "*sp-particle-system-3d*") {
return nullptr;
@@ -2302,7 +2370,7 @@ FormElement* rewrite_launch_particles(LetElement* in, const Env& env, FormPool&
return nullptr;
}
auto launch_matrix = in->entries().at(3);
auto& launch_matrix = in->entries().at(3);
if (launch_matrix.src->at(0)->to_string(env) != "*launch-matrix*") {
return nullptr;
}
@@ -2440,28 +2508,27 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
// (set! (-> v1-0 base) (&+ a0-2 16))
u16 dma_qwc = 0;
bool flusha = false;
auto check_vifcode_set = [&](StoreElement* store, const std::string& varname, int size,
int addr) {
auto check_vifcode_set = [&](StoreElement* store, const RegisterAccess& var, int size, int addr) {
return store->op()->kind() == StoreOp::Kind::INTEGER && store->op()->store_size() == size &&
// store->op()->value().is_int(0) &&
store->op()->addr().kind() == SimpleExpression::Kind::ADD &&
store->op()->addr().args() == 2 && store->op()->addr().get_arg(0).is_var() &&
store->op()->addr().get_arg(1).is_int(addr) &&
var_name_equal(env, varname, store->op()->addr().get_arg(0).var());
var_equal(env, var, store->op()->addr().get_arg(0).var());
};
const auto match_buf_push = [&env](FormElement* elt, const std::string& reg_buf,
const std::string& reg_base, int amt) {
const auto match_buf_push = [&env](FormElement* elt, const RegisterAccess& reg_buf,
const RegisterAccess& reg_base, int amt) {
auto mr = match(Matcher::set(Matcher::deref(Matcher::any_reg(0), false,
{DerefTokenMatcher::string("base")}),
Matcher::op_fixed(FixedOperatorKind::ADDITION_PTR,
{Matcher::any_reg(1), Matcher::integer(amt)})),
elt);
return mr.matched && var_name_equal(env, reg_buf, mr.maps.regs.at(0)) &&
var_name_equal(env, reg_base, mr.maps.regs.at(1));
return mr.matched && var_equal(env, reg_buf, mr.maps.regs.at(0)) &&
var_equal(env, reg_base, mr.maps.regs.at(1));
};
{
auto dmatag_buf = env.get_variable_name(let0->entries().at(0).dest);
auto dmatag_ptr = env.get_variable_name(let0->entries().at(1).dest);
auto dmatag_buf = let0->entries().at(0).dest;
auto dmatag_ptr = let0->entries().at(1).dest;
auto set_dmatag_hdr = dynamic_cast<SetFormFormElement*>(let0->body()->at(0));
auto set_dmatag_vif0 = dynamic_cast<StoreElement*>(let0->body()->at(1));
auto let_dmatag_vif0 = dynamic_cast<LetElement*>(let0->body()->at(1));
@@ -2506,7 +2573,7 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
Matcher::deref(Matcher::cast("(pointer int64)", Matcher::any_reg(0)), false, {}),
Matcher::any_integer(1)),
set_dmatag_hdr);
if (!mr_dmatag_hdr.matched || !var_name_equal(env, dmatag_ptr, mr_dmatag_hdr.maps.regs.at(0))) {
if (!mr_dmatag_hdr.matched || !var_equal(env, dmatag_ptr, mr_dmatag_hdr.maps.regs.at(0))) {
lg::error("rewrite_dma_buffer_add_gs_set: bad dmatag set");
return nullptr;
}
@@ -2553,8 +2620,8 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
// (set! (-> v1-1 base) (&+ a0-4 16))
// )
{
auto giftag_buf = env.get_variable_name(let1->entries().at(0).dest);
auto giftag_ptr = env.get_variable_name(let1->entries().at(1).dest);
auto giftag_buf = let1->entries().at(0).dest;
auto giftag_ptr = let1->entries().at(1).dest;
auto set_giftag_hdr = dynamic_cast<SetFormFormElement*>(let1->body()->at(0));
auto let_giftag_regs = dynamic_cast<LetElement*>(let1->body()->at(1));
auto set_giftag_push = dynamic_cast<SetFormFormElement*>(let1->body()->at(2));
@@ -2576,7 +2643,7 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
set_giftag_hdr);
if (!mr_giftag_hdr.matched || (mr_giftag_hdr.maps.ints.at(1) & 0x0fffffffffffffff) != 0x8001 ||
((mr_giftag_hdr.maps.ints.at(1) >> 60) & 0xf) != dma_qwc - 1 ||
!var_name_equal(env, giftag_ptr, mr_giftag_hdr.maps.regs.at(0))) {
!var_equal(env, giftag_ptr, mr_giftag_hdr.maps.regs.at(0))) {
return nullptr;
}
auto giftag_regs_elt = let_giftag_regs->entries().at(0).src->try_as_element<CastElement>();
@@ -2635,8 +2702,8 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
// (set! (-> v1-2 base) (&+ a0-6 96))
// )
{
auto gsregs_buf = env.get_variable_name(let2->entries().at(0).dest);
auto gsregs_ptr = env.get_variable_name(let2->entries().at(1).dest);
auto gsregs_buf = let2->entries().at(0).dest;
auto gsregs_ptr = let2->entries().at(1).dest;
auto set_gsregs_push =
dynamic_cast<SetFormFormElement*>(let2->body()->at(let2->body()->size() - 1));
// check dma buffer base set
@@ -2646,7 +2713,7 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
return nullptr;
}
bool error = false;
auto get_int_from_form = [&](FormElement* elt, const std::string& ptr_name, int offset) {
auto get_int_from_form = [&](FormElement* elt, const RegisterAccess& ptr_name, int offset) {
auto as_set = dynamic_cast<SetFormFormElement*>(elt);
if (as_set) {
auto mr_set = match(
@@ -2657,7 +2724,7 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
false, {}),
Matcher::any_integer(1)),
as_set);
if (!mr_set.matched || !var_name_equal(env, gsregs_ptr, mr_set.maps.regs.at(0))) {
if (!mr_set.matched || !var_equal(env, gsregs_ptr, mr_set.maps.regs.at(0))) {
error = true;
return (s64)0;
}
@@ -2681,8 +2748,7 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
auto store_in_let = dynamic_cast<StoreElement*>(as_let->body()->at(0));
if (!store_in_let || !check_vifcode_set(store_in_let, ptr_name, 8, offset) ||
!store_in_let->op()->value().is_var() ||
!var_name_equal(env, env.get_variable_name(as_let->entries().at(0).dest),
store_in_let->op()->value().var())) {
!var_equal(env, as_let->entries().at(0).dest, store_in_let->op()->value().var())) {
error = true;
return (s64)0;
}
@@ -2707,7 +2773,7 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
error = true;
return (s64)0;
};
auto get_src_form = [&](FormPool& pool, FormElement* elt, const std::string& ptr_name,
auto get_src_form = [&](FormPool& pool, FormElement* elt, const RegisterAccess& ptr_name,
int offset) -> Form* {
auto as_set = dynamic_cast<SetFormFormElement*>(elt);
if (as_set) {
@@ -2719,7 +2785,7 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
false, {}),
Matcher::any()),
as_set);
if (!mr_set.matched || !var_name_equal(env, gsregs_ptr, mr_set.maps.regs.at(0))) {
if (!mr_set.matched || !var_equal(env, gsregs_ptr, mr_set.maps.regs.at(0))) {
return nullptr;
}
return as_set->src();
@@ -2739,8 +2805,7 @@ FormElement* rewrite_dma_buffer_add_gs_set(const std::vector<LetElement*>& in,
auto store_in_let = dynamic_cast<StoreElement*>(as_let->body()->at(0));
if (!store_in_let || !check_vifcode_set(store_in_let, ptr_name, 8, offset) ||
!store_in_let->op()->value().is_var() ||
!var_name_equal(env, env.get_variable_name(as_let->entries().at(0).dest),
store_in_let->op()->value().var())) {
!var_equal(env, as_let->entries().at(0).dest, store_in_let->op()->value().var())) {
return nullptr;
}
return as_let->entries().at(0).src;