mirror of
https://github.com/open-goal/jak-project
synced 2026-06-24 09:51:29 -04:00
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user