mirror of
https://github.com/open-goal/jak-project
synced 2026-07-11 15:28:58 -04:00
[decomp] better handling of animation code and art files (#1352)
* update refs * [decompiler] read and process art groups * finish decompiler art group selection & detect in `ja-group?` * make art stuff work on offline tests! * [decompiler] detect `ja-group!` (primitive) * corrections. * more * use new feature on skel groups! * find `loop!` as well * fully fledged `ja` macro & decomp + `loop` detect * fancy fixed point printing! * update source * `:num! max` (i knew i should've done this) * Update jak1_ntsc_black_label.jsonc * hi imports * make compiling the game work * fix `defskelgroup` * clang * update refs * fix chan * fix seek and finalboss * fix tests * delete unused function * track let rewrite stats * reorder `rewrite_let` * Update .gitattributes * fix bug with `:num! max` * Update robotboss-part.gc * Update goal-lib.gc * document `ja` * get rid of pc fixes thing * use std::abs
This commit is contained in:
@@ -100,11 +100,9 @@ Form* try_cast_simplify(Form* in,
|
||||
if (fc) {
|
||||
double div = (double)*fc / METER_LENGTH; // GOOS will use doubles here
|
||||
if (div * METER_LENGTH == *fc) {
|
||||
return pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr,
|
||||
GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "meters")),
|
||||
pool.alloc_single_element_form<ConstantFloatElement>(nullptr, div));
|
||||
return pool.form<GenericElement>(
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("meters")),
|
||||
pool.form<ConstantFloatElement>(div));
|
||||
} else {
|
||||
lg::error("Floating point value {} could not be converted to meters.", *fc);
|
||||
}
|
||||
@@ -114,11 +112,9 @@ Form* try_cast_simplify(Form* in,
|
||||
if (fc) {
|
||||
double div = (double)*fc / DEGREES_LENGTH; // GOOS will use doubles here
|
||||
if (div * DEGREES_LENGTH == *fc) {
|
||||
return pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr,
|
||||
GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "degrees")),
|
||||
pool.alloc_single_element_form<ConstantFloatElement>(nullptr, div));
|
||||
return pool.form<GenericElement>(
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("degrees")),
|
||||
pool.form<ConstantFloatElement>(div));
|
||||
} else {
|
||||
lg::error("Floating point value {} could not be converted to degrees.", *fc);
|
||||
}
|
||||
@@ -142,21 +138,11 @@ Form* try_cast_simplify(Form* in,
|
||||
// if they used a 1 as a time-frame, they likely just want to literally remove 1
|
||||
// instead of (seconds 0.0034) or whatever the result would be.
|
||||
// also 0 is decompiled as just 0.
|
||||
return pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(value));
|
||||
return pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(value));
|
||||
}
|
||||
|
||||
// only rewrite if exact.
|
||||
s64 seconds_int = value / (s64)TICKS_PER_SECOND;
|
||||
if (seconds_int * (s64)TICKS_PER_SECOND == value) {
|
||||
return pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, fmt::format("(seconds {})", seconds_int));
|
||||
}
|
||||
double seconds = (double)value / TICKS_PER_SECOND;
|
||||
if (seconds * TICKS_PER_SECOND == value) {
|
||||
return pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, fmt::format("(seconds {})", float_to_string(seconds, false)));
|
||||
}
|
||||
return pool.form<ConstantTokenElement>(
|
||||
fmt::format("(seconds {})", fixed_point_to_string(value, TICKS_PER_SECOND)));
|
||||
} else {
|
||||
// not a constant like (seconds 2), probably an expression or function call. we pretend that a
|
||||
// cast to int happened instead.
|
||||
@@ -217,7 +203,7 @@ Form* try_cast_simplify(Form* in,
|
||||
if (as_atom && as_atom->is_var()) {
|
||||
if (env.get_variable_type(as_atom->var(), true) == new_type) {
|
||||
// we are a variable with the right type.
|
||||
return pool.alloc_single_element_form<SimpleAtomElement>(nullptr, *as_atom, true);
|
||||
return pool.form<SimpleAtomElement>(*as_atom, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,7 +285,7 @@ Form* repop_passthrough_arg(Form* in,
|
||||
* Create a form which represents a variable.
|
||||
*/
|
||||
Form* var_to_form(const RegisterAccess& var, FormPool& pool) {
|
||||
return pool.alloc_single_element_form<SimpleAtomElement>(nullptr, SimpleAtom::make_var(var));
|
||||
return pool.form<SimpleAtomElement>(SimpleAtom::make_var(var));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -429,7 +415,7 @@ Form* cast_form(Form* in,
|
||||
return result;
|
||||
}
|
||||
|
||||
return pool.alloc_single_element_form<CastElement>(nullptr, new_type, in);
|
||||
return pool.form<CastElement>(new_type, in);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -471,7 +457,7 @@ std::vector<Form*> pop_to_forms(const std::vector<RegisterAccess>& vars,
|
||||
// there is a separate system for casting variables that will do a better job.
|
||||
if (cast && !is_var) {
|
||||
forms[i] = cast_form(forms[i], *cast, pool, env);
|
||||
// pool.alloc_single_element_form<CastElement>(nullptr, *cast, forms[i]);
|
||||
// pool.form<CastElement>(*cast, forms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -941,7 +927,7 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
|
||||
allow_side_effects);
|
||||
} else {
|
||||
args = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects);
|
||||
args.push_back(pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
args.push_back(pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
}
|
||||
|
||||
bool arg0_ptr = is_ptr_or_child(env, m_my_idx, m_expr.get_arg(0).var(), true);
|
||||
@@ -1251,11 +1237,11 @@ void SimpleExpressionElement::update_from_stack_mult_si(const Env& env,
|
||||
allow_side_effects);
|
||||
|
||||
if (!arg0_i) {
|
||||
args.at(0) = pool.alloc_single_element_form<CastElement>(nullptr, TypeSpec("int"), args.at(0));
|
||||
args.at(0) = pool.form<CastElement>(TypeSpec("int"), args.at(0));
|
||||
}
|
||||
|
||||
if (!arg1_i) {
|
||||
args.at(1) = pool.alloc_single_element_form<CastElement>(nullptr, TypeSpec("int"), args.at(1));
|
||||
args.at(1) = pool.form<CastElement>(TypeSpec("int"), args.at(1));
|
||||
}
|
||||
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
@@ -1299,7 +1285,7 @@ void SimpleExpressionElement::update_from_stack_force_si_2(const Env& env,
|
||||
|
||||
} else {
|
||||
args = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects);
|
||||
args.push_back(pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
args.push_back(pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
@@ -1350,15 +1336,15 @@ void SimpleExpressionElement::update_from_stack_force_ui_2(const Env& env,
|
||||
allow_side_effects);
|
||||
} else {
|
||||
args = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects);
|
||||
args.push_back(pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
args.push_back(pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
}
|
||||
|
||||
if (!arg0_u) {
|
||||
args.at(0) = pool.alloc_single_element_form<CastElement>(nullptr, TypeSpec("uint"), args.at(0));
|
||||
args.at(0) = pool.form<CastElement>(TypeSpec("uint"), args.at(0));
|
||||
}
|
||||
|
||||
if (!arg1_u) {
|
||||
args.at(1) = pool.alloc_single_element_form<CastElement>(nullptr, TypeSpec("uint"), args.at(1));
|
||||
args.at(1) = pool.form<CastElement>(TypeSpec("uint"), args.at(1));
|
||||
}
|
||||
|
||||
auto new_form =
|
||||
@@ -1386,8 +1372,7 @@ void SimpleExpressionElement::update_from_stack_pcypld(const Env& env,
|
||||
args.push_back(popped_args.at(ras_idx));
|
||||
ras_idx++;
|
||||
} else {
|
||||
args.push_back(
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(arg_idx)));
|
||||
args.push_back(pool.form<SimpleAtomElement>(m_expr.get_arg(arg_idx)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1505,20 +1490,18 @@ void SimpleExpressionElement::update_from_stack_copy_first_int_2(const Env& env,
|
||||
if (bti) {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(kind), args.at(0),
|
||||
cast_form(pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)),
|
||||
arg0_type, pool, env));
|
||||
cast_form(pool.form<SimpleAtomElement>(m_expr.get_arg(1)), arg0_type, pool, env));
|
||||
result->push_back(new_form);
|
||||
} else {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(kind),
|
||||
pool.alloc_single_element_form<CastElement>(nullptr, TypeSpec("int"), args.at(0)),
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
GenericOperator::make_fixed(kind), pool.form<CastElement>(TypeSpec("int"), args.at(0)),
|
||||
pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
result->push_back(new_form);
|
||||
}
|
||||
} else {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(kind), args.at(0),
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
auto new_form =
|
||||
pool.alloc_element<GenericElement>(GenericOperator::make_fixed(kind), args.at(0),
|
||||
pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
result->push_back(new_form);
|
||||
}
|
||||
|
||||
@@ -1543,8 +1526,7 @@ void SimpleExpressionElement::update_from_stack_copy_first_int_2(const Env& env,
|
||||
args.at(0), args.at(1));
|
||||
result->push_back(new_form);
|
||||
} else {
|
||||
auto cast = pool.alloc_single_element_form<CastElement>(
|
||||
nullptr, TypeSpec(arg0_i ? "int" : "uint"), args.at(1));
|
||||
auto cast = pool.form<CastElement>(TypeSpec(arg0_i ? "int" : "uint"), args.at(1));
|
||||
if (kind == FixedOperatorKind::SUBTRACTION &&
|
||||
is_pointer_type(env, m_my_idx, m_expr.get_arg(0).var())) {
|
||||
kind = FixedOperatorKind::SUBTRACTION_PTR;
|
||||
@@ -1720,17 +1702,15 @@ FormElement* SimpleExpressionElement::update_from_stack_logor_or_logand_helper(
|
||||
if (integer && ((s64)*integer) < 0) {
|
||||
// clearing a bitfield.
|
||||
auto elts = decompile_bitfield_enum_from_int(arg1_type, env.dts->ts, ~*integer);
|
||||
auto oper =
|
||||
GenericOperator::make_function(pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, arg1_type.base_type()));
|
||||
auto oper = GenericOperator::make_function(
|
||||
pool.form<ConstantTokenElement>(arg1_type.base_type()));
|
||||
std::vector<Form*> form_elts;
|
||||
for (auto& x : elts) {
|
||||
form_elts.push_back(pool.alloc_single_element_form<ConstantTokenElement>(nullptr, x));
|
||||
form_elts.push_back(pool.form<ConstantTokenElement>(x));
|
||||
}
|
||||
auto inverted =
|
||||
pool.alloc_single_element_form<GenericElement>(nullptr, oper, form_elts);
|
||||
auto normal = pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::LOGNOT), inverted);
|
||||
auto inverted = pool.form<GenericElement>(oper, form_elts);
|
||||
auto normal = pool.form<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::LOGNOT), inverted);
|
||||
auto new_form = pool.alloc_element<GenericElement>(GenericOperator::make_fixed(kind),
|
||||
normal, args.at(1));
|
||||
return new_form;
|
||||
@@ -1757,8 +1737,7 @@ FormElement* SimpleExpressionElement::update_from_stack_logor_or_logand_helper(
|
||||
}
|
||||
}
|
||||
// types bad, insert cast.
|
||||
auto cast = pool.alloc_single_element_form<CastElement>(
|
||||
nullptr, TypeSpec(arg0_i ? "int" : "uint"), args.at(1));
|
||||
auto cast = pool.form<CastElement>(TypeSpec(arg0_i ? "int" : "uint"), args.at(1));
|
||||
auto new_form =
|
||||
pool.alloc_element<GenericElement>(GenericOperator::make_fixed(kind), args.at(0), cast);
|
||||
return new_form;
|
||||
@@ -1889,8 +1868,7 @@ void SimpleExpressionElement::update_from_stack_left_shift(const Env& env,
|
||||
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::MULTIPLICATION), args.at(0),
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(multiplier)));
|
||||
pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(multiplier)));
|
||||
result->push_back(new_form);
|
||||
return;
|
||||
}
|
||||
@@ -1898,15 +1876,15 @@ void SimpleExpressionElement::update_from_stack_left_shift(const Env& env,
|
||||
auto arg0_i = is_int_type(env, m_my_idx, m_expr.get_arg(0).var());
|
||||
auto arg0_u = is_uint_type(env, m_my_idx, m_expr.get_arg(0).var());
|
||||
if (!arg0_i && !arg0_u) {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::SHL),
|
||||
pool.alloc_single_element_form<CastElement>(nullptr, TypeSpec("int"), args.at(0)),
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
auto new_form =
|
||||
pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::SHL),
|
||||
pool.form<CastElement>(TypeSpec("int"), args.at(0)),
|
||||
pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
result->push_back(new_form);
|
||||
} else {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::SHL), args.at(0),
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
result->push_back(new_form);
|
||||
}
|
||||
|
||||
@@ -1970,13 +1948,13 @@ void SimpleExpressionElement::update_from_stack_right_shift_logic(const Env& env
|
||||
if (!arg0_i && !arg0_u) {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::SHR),
|
||||
pool.alloc_single_element_form<CastElement>(nullptr, TypeSpec("int"), arg),
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
pool.form<CastElement>(TypeSpec("int"), arg),
|
||||
pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
result->push_back(new_form);
|
||||
} else {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::SHR), arg,
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
result->push_back(new_form);
|
||||
}
|
||||
}
|
||||
@@ -2017,8 +1995,7 @@ void SimpleExpressionElement::update_from_stack_right_shift_arith(const Env& env
|
||||
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::DIVISION), arg,
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(multiplier)));
|
||||
pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(multiplier)));
|
||||
result->push_back(new_form);
|
||||
return;
|
||||
}
|
||||
@@ -2037,15 +2014,15 @@ void SimpleExpressionElement::update_from_stack_right_shift_arith(const Env& env
|
||||
}
|
||||
|
||||
if (!arg0_i && !arg0_u) {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::SAR),
|
||||
pool.alloc_single_element_form<CastElement>(nullptr, TypeSpec("int"), args.at(0)),
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
auto new_form =
|
||||
pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::SAR),
|
||||
pool.form<CastElement>(TypeSpec("int"), args.at(0)),
|
||||
pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
result->push_back(new_form);
|
||||
} else {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::SAR), args.at(0),
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
pool.form<SimpleAtomElement>(m_expr.get_arg(1)));
|
||||
result->push_back(new_form);
|
||||
}
|
||||
|
||||
@@ -2350,9 +2327,8 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||
m_dst.reg().get_kind() == Reg::FPR && src_as_se->expr().get_arg(0).is_int() &&
|
||||
src_as_se->expr().get_arg(0).get_int() == 0) {
|
||||
// not sure this is the best place for this.
|
||||
stack.push_value_to_reg(m_dst,
|
||||
pool.alloc_single_element_form<ConstantFloatElement>(nullptr, 0.0),
|
||||
true, m_src_type, m_var_info);
|
||||
stack.push_value_to_reg(m_dst, pool.form<ConstantFloatElement>(0.0), true, m_src_type,
|
||||
m_var_info);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2414,7 +2390,7 @@ void SetFormFormElement::push_to_stack(const Env& env, FormPool& pool, FormStack
|
||||
loc->parent_element = this;
|
||||
m_dst = loc;
|
||||
auto zero = SimpleAtom::make_int_constant(0);
|
||||
auto zero_form = pool.alloc_single_element_form<SimpleAtomElement>(nullptr, zero);
|
||||
auto zero_form = pool.form<SimpleAtomElement>(zero);
|
||||
m_src = zero_form;
|
||||
}
|
||||
}
|
||||
@@ -2453,16 +2429,13 @@ void SetFormFormElement::push_to_stack(const Env& env, FormPool& pool, FormStack
|
||||
|
||||
if (dst_form == src_form_in_func) {
|
||||
auto new_func_op = GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr,
|
||||
call_info.inplace_name));
|
||||
pool.form<ConstantTokenElement>(call_info.inplace_name));
|
||||
GenericElement* inplace_call = nullptr;
|
||||
|
||||
if (funcname == "seek" || funcname == "seekl") {
|
||||
inplace_call = pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, new_func_op,
|
||||
std::vector<Form*>{m_dst, src_as_generic->elts().at(1),
|
||||
src_as_generic->elts().at(2)})
|
||||
->try_as_element<GenericElement>();
|
||||
inplace_call = pool.alloc_element<GenericElement>(
|
||||
new_func_op, std::vector<Form*>{m_dst, src_as_generic->elts().at(1),
|
||||
src_as_generic->elts().at(2)});
|
||||
}
|
||||
ASSERT_MSG(
|
||||
inplace_call,
|
||||
@@ -2495,9 +2468,9 @@ void SetFormFormElement::push_to_stack(const Env& env, FormPool& pool, FormStack
|
||||
}
|
||||
|
||||
void StoreInSymbolElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||
auto sym = pool.alloc_single_element_form<SimpleExpressionElement>(
|
||||
nullptr, SimpleAtom::make_sym_val(m_sym_name).as_expr(), m_my_idx);
|
||||
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_value, m_my_idx);
|
||||
auto sym =
|
||||
pool.form<SimpleExpressionElement>(SimpleAtom::make_sym_val(m_sym_name).as_expr(), m_my_idx);
|
||||
auto val = pool.form<SimpleExpressionElement>(m_value, m_my_idx);
|
||||
val->update_children_from_stack(env, pool, stack, true);
|
||||
|
||||
if (m_cast_for_set) {
|
||||
@@ -2523,18 +2496,16 @@ void StoreInPairElement::push_to_stack(const Env& env, FormPool& pool, FormStack
|
||||
if (m_value.is_var()) {
|
||||
auto vars = std::vector<RegisterAccess>({m_value.var(), m_pair});
|
||||
auto popped = pop_to_forms(vars, env, pool, stack, true);
|
||||
auto addr = pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_fixed(op), popped.at(1));
|
||||
auto addr = pool.form<GenericElement>(GenericOperator::make_fixed(op), popped.at(1));
|
||||
addr->mark_popped();
|
||||
auto fr = pool.alloc_element<SetFormFormElement>(addr, popped.at(0));
|
||||
fr->mark_popped();
|
||||
stack.push_form_element(fr, true);
|
||||
} else {
|
||||
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_value, m_my_idx);
|
||||
auto val = pool.form<SimpleExpressionElement>(m_value, m_my_idx);
|
||||
val->mark_popped();
|
||||
auto addr = pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_fixed(op),
|
||||
pop_to_forms({m_pair}, env, pool, stack, true).at(0));
|
||||
auto addr = pool.form<GenericElement>(GenericOperator::make_fixed(op),
|
||||
pop_to_forms({m_pair}, env, pool, stack, true).at(0));
|
||||
addr->mark_popped();
|
||||
auto fr = pool.alloc_element<SetFormFormElement>(addr, val);
|
||||
fr->mark_popped();
|
||||
@@ -2612,10 +2583,8 @@ bool try_to_rewrite_vector_inline_ctor(const Env& env,
|
||||
|
||||
stack.push_value_to_reg(
|
||||
*matrix_entries->at(0).destination,
|
||||
pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr,
|
||||
GenericOperator::make_function(pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, fmt::format("new-stack-{}0", type_name)))),
|
||||
pool.form<GenericElement>(GenericOperator::make_function(
|
||||
pool.form<ConstantTokenElement>(fmt::format("new-stack-{}0", type_name)))),
|
||||
true, TypeSpec(type_name));
|
||||
return true;
|
||||
}
|
||||
@@ -2673,10 +2642,8 @@ bool try_to_rewrite_matrix_inline_ctor(const Env& env, FormPool& pool, FormStack
|
||||
stack.pop(5);
|
||||
|
||||
stack.push_value_to_reg(*matrix_entries->at(0).destination,
|
||||
pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, "new-stack-matrix0"))),
|
||||
pool.form<GenericElement>(GenericOperator::make_function(
|
||||
pool.form<ConstantTokenElement>("new-stack-matrix0"))),
|
||||
true, TypeSpec("matrix"));
|
||||
return true;
|
||||
}
|
||||
@@ -2715,7 +2682,7 @@ void StorePlainDeref::push_to_stack(const Env& env, FormPool& pool, FormStack& s
|
||||
make_optional_cast(m_dst_cast_type, popped.at(0), pool, env));
|
||||
m_dst->mark_popped();
|
||||
m_dst->try_as_element<DerefElement>()->inline_nested();
|
||||
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_expr, m_my_idx);
|
||||
auto val = pool.form<SimpleExpressionElement>(m_expr, m_my_idx);
|
||||
val->mark_popped();
|
||||
auto fr = pool.alloc_element<SetFormFormElement>(
|
||||
m_dst, make_optional_cast(m_src_cast_type, val, pool, env));
|
||||
@@ -2744,7 +2711,7 @@ void StoreArrayAccess::push_to_stack(const Env& env, FormPool& pool, FormStack&
|
||||
auto vars = std::vector<RegisterAccess>({m_base_var});
|
||||
auto popped = pop_to_forms(vars, env, pool, stack, true);
|
||||
m_dst->mark_popped();
|
||||
expr_form = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_expr, m_my_idx);
|
||||
expr_form = pool.form<SimpleExpressionElement>(m_expr, m_my_idx);
|
||||
array_form = popped.at(0);
|
||||
}
|
||||
|
||||
@@ -2961,21 +2928,17 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
{Matcher::any(0), Matcher::any_constant_token(1)});
|
||||
auto virtual_go_mr = match(virtual_go_state_matcher, go_next_state);
|
||||
if (virtual_go_mr.matched && virtual_go_mr.maps.forms.at(0)->to_string(env) == "self") {
|
||||
arg_forms.insert(arg_forms.begin(), pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, virtual_go_mr.maps.strings.at(1)));
|
||||
arg_forms.insert(arg_forms.begin(),
|
||||
pool.form<ConstantTokenElement>(virtual_go_mr.maps.strings.at(1)));
|
||||
auto go_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "go-virtual")),
|
||||
arg_forms);
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("go-virtual")), arg_forms);
|
||||
result->push_back(go_form);
|
||||
return;
|
||||
}
|
||||
|
||||
arg_forms.insert(arg_forms.begin(), go_next_state);
|
||||
auto go_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "go")),
|
||||
arg_forms);
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("go")), arg_forms);
|
||||
result->push_back(go_form);
|
||||
return;
|
||||
}
|
||||
@@ -3059,8 +3022,7 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
auto& var = all_pop_vars.at(i + 1); // 0 is the function itself.
|
||||
auto arg_type = env.get_types_before_op(var.idx()).get(var.reg()).typespec();
|
||||
if (!env.dts->ts.tc(expected_arg_types.at(i), arg_type)) {
|
||||
new_args.at(i) = pool.alloc_single_element_form<CastElement>(
|
||||
nullptr, expected_arg_types.at(i), new_args.at(i));
|
||||
new_args.at(i) = pool.form<CastElement>(expected_arg_types.at(i), new_args.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3101,8 +3063,7 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
type_2 = "boxed-array";
|
||||
}
|
||||
|
||||
auto quoted_type = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_sym_ptr(type_2));
|
||||
auto quoted_type = pool.form<SimpleAtomElement>(SimpleAtom::make_sym_ptr(type_2));
|
||||
|
||||
if (alloc == "global" && type_1 == "pair") {
|
||||
// cons!
|
||||
@@ -3194,7 +3155,7 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
":final in the deftype to disable virtual method calls",
|
||||
tp_type.method_from_type().print(), tp_type.method_id()));
|
||||
}
|
||||
auto method_op = pool.alloc_single_element_form<ConstantTokenElement>(nullptr, name);
|
||||
auto method_op = pool.form<ConstantTokenElement>(name);
|
||||
auto gop = GenericOperator::make_function(method_op);
|
||||
|
||||
result->push_back(pool.alloc_element<GenericElement>(gop, arg_forms));
|
||||
@@ -3227,10 +3188,9 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
|
||||
if (got_stack_new) {
|
||||
std::vector<Form*> stack_new_args;
|
||||
stack_new_args.push_back(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "'stack"));
|
||||
stack_new_args.push_back(pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, fmt::format("'{}", type_source_form->to_string(env))));
|
||||
stack_new_args.push_back(pool.form<ConstantTokenElement>("'stack"));
|
||||
stack_new_args.push_back(pool.form<ConstantTokenElement>(
|
||||
fmt::format("'{}", type_source_form->to_string(env))));
|
||||
for (size_t i = 2; i < arg_forms.size(); i++) {
|
||||
stack_new_args.push_back(arg_forms.at(i));
|
||||
}
|
||||
@@ -3241,8 +3201,7 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
}
|
||||
}
|
||||
|
||||
auto method_op =
|
||||
pool.alloc_single_element_form<GetMethodElement>(nullptr, type_source_form, name, false);
|
||||
auto method_op = pool.form<GetMethodElement>(type_source_form, name, false);
|
||||
auto gop = GenericOperator::make_function(method_op);
|
||||
|
||||
result->push_back(pool.alloc_element<GenericElement>(gop, arg_forms));
|
||||
@@ -3265,6 +3224,26 @@ void FunctionCallElement::push_to_stack(const Env& env, FormPool& pool, FormStac
|
||||
///////////////////
|
||||
// DerefElement
|
||||
///////////////////
|
||||
ConstantTokenElement* DerefElement::try_as_art_const(const Env& env, FormPool& pool) {
|
||||
auto mr = match(
|
||||
Matcher::deref(Matcher::s6(), false,
|
||||
{DerefTokenMatcher::string("draw"), DerefTokenMatcher::string("art-group"),
|
||||
DerefTokenMatcher::string("data"), DerefTokenMatcher::any_integer(0)}),
|
||||
this);
|
||||
|
||||
if (mr.matched) {
|
||||
auto elt_name = env.get_art_elt_name(mr.maps.ints.at(0));
|
||||
if (elt_name) {
|
||||
return pool.alloc_element<ConstantTokenElement>(*elt_name);
|
||||
} else {
|
||||
lg::error("function {}: did not find art element {} in {}", env.func->name(),
|
||||
mr.maps.ints.at(0), env.art_group());
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DerefElement::update_from_stack(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
@@ -3285,6 +3264,12 @@ void DerefElement::update_from_stack(const Env& env,
|
||||
// merge nested ->'s
|
||||
inline_nested();
|
||||
|
||||
auto as_art = try_as_art_const(env, pool);
|
||||
if (as_art) {
|
||||
result->push_back(as_art);
|
||||
return;
|
||||
}
|
||||
|
||||
result->push_back(this);
|
||||
}
|
||||
|
||||
@@ -3422,8 +3407,8 @@ Form* try_rewrite_as_process_to_ppointer(CondNoElseElement* value,
|
||||
}
|
||||
}
|
||||
|
||||
return pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::PROCESS_TO_PPOINTER), repopped);
|
||||
return pool.form<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::PROCESS_TO_PPOINTER), repopped);
|
||||
}
|
||||
|
||||
// (if x (-> x 0 self)) -> (ppointer->process x)
|
||||
@@ -3472,8 +3457,59 @@ Form* try_rewrite_as_pppointer_to_process(CondNoElseElement* value,
|
||||
repopped = var_to_form(condition_var, pool);
|
||||
}
|
||||
|
||||
return pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::PPOINTER_TO_PROCESS), repopped);
|
||||
return pool.form<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::PPOINTER_TO_PROCESS), repopped);
|
||||
}
|
||||
|
||||
// (if (> (-> self skel active-channels) 0)
|
||||
// (-> self skel root-channel 0 frame-group)
|
||||
// )
|
||||
// (ja-group :chan 0)
|
||||
Form* try_rewrite_as_ja_group(CondNoElseElement* value,
|
||||
FormStack& stack,
|
||||
FormPool& pool,
|
||||
const Env& env) {
|
||||
if (value->entries.size() != 1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto condition = value->entries.at(0).condition;
|
||||
auto body = value->entries[0].body;
|
||||
|
||||
// safe to look for a reg directly here.
|
||||
auto condition_matcher = Matcher::fixed_op(
|
||||
FixedOperatorKind::GT, {Matcher::deref(Matcher::s6(), false,
|
||||
{DerefTokenMatcher::string("skel"),
|
||||
DerefTokenMatcher::string("active-channels")}),
|
||||
Matcher::any(0)});
|
||||
auto condition_mr = match(condition_matcher, condition);
|
||||
if (!condition_mr.matched) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto body_matcher = Matcher::deref(
|
||||
Matcher::s6(), false,
|
||||
{DerefTokenMatcher::string("skel"), DerefTokenMatcher::string("root-channel"),
|
||||
DerefTokenMatcher::any_expr_or_int(0), DerefTokenMatcher::string("frame-group")});
|
||||
auto body_mr = match(body_matcher, body);
|
||||
|
||||
if (!body_mr.matched) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto chan = body_mr.int_or_form_to_form(pool, 0);
|
||||
auto obj_chan = chan->to_form(env);
|
||||
if (condition_mr.maps.forms.at(0)->to_form(env) == obj_chan) {
|
||||
auto func = GenericOperator::make_function(pool.form<ConstantTokenElement>("ja-group"));
|
||||
if (obj_chan.is_int(0)) {
|
||||
return pool.form<GenericElement>(func);
|
||||
} else {
|
||||
return pool.form<GenericElement>(func, pool.form<ConstantTokenElement>(":chan"),
|
||||
condition_mr.maps.forms.at(0));
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -3542,11 +3578,17 @@ void CondNoElseElement::push_to_stack(const Env& env, FormPool& pool, FormStack&
|
||||
stack.push_value_to_reg(write_as_value, as_ppointer_to_process, true,
|
||||
env.get_variable_type(final_destination, false));
|
||||
} else {
|
||||
// fmt::print("func {} final destination {} type {}\n", env.func->name(),
|
||||
// final_destination.to_string(env),
|
||||
// env.get_variable_type(final_destination, false).print());
|
||||
stack.push_value_to_reg(write_as_value, pool.alloc_single_form(nullptr, this), true,
|
||||
env.get_variable_type(final_destination, false));
|
||||
auto as_ja_group = try_rewrite_as_ja_group(this, stack, pool, env);
|
||||
if (as_ja_group) {
|
||||
stack.push_value_to_reg(write_as_value, as_ja_group, true,
|
||||
env.get_variable_type(final_destination, false));
|
||||
} else {
|
||||
// fmt::print("func {} final destination {} type {}\n", env.func->name(),
|
||||
// final_destination.to_string(env),
|
||||
// env.get_variable_type(final_destination, false).print());
|
||||
stack.push_value_to_reg(write_as_value, pool.alloc_single_form(nullptr, this), true,
|
||||
env.get_variable_type(final_destination, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3724,8 +3766,7 @@ void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStac
|
||||
|
||||
Form* result_value = pool.alloc_single_form(nullptr, this);
|
||||
if (!env.dts->ts.tc(expected_type, result_type)) {
|
||||
result_value =
|
||||
pool.alloc_single_element_form<CastElement>(nullptr, expected_type, result_value);
|
||||
result_value = pool.form<CastElement>(expected_type, result_value);
|
||||
}
|
||||
// fmt::print("{}\n", result_value->to_string(env));
|
||||
|
||||
@@ -3944,8 +3985,7 @@ FormElement* ConditionElement::make_zero_check_generic(const Env& env,
|
||||
source_forms.at(0));
|
||||
if (mr.matched) {
|
||||
s64 value = -mr.maps.ints.at(1);
|
||||
auto value_form = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(value));
|
||||
auto value_form = pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(value));
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::EQ),
|
||||
std::vector<Form*>{mr.maps.forms.at(0), value_form});
|
||||
@@ -4018,12 +4058,7 @@ FormElement* try_make_logtest_cpad_macro(Form* in, FormPool& pool) {
|
||||
if (logtest_elt != nullptr) {
|
||||
auto buttons_form = logtest_elt->elts().at(1);
|
||||
std::vector<Form*> v;
|
||||
if (mr.maps.forms.find(0) != mr.maps.forms.end()) {
|
||||
v.push_back(mr.maps.forms.at(0));
|
||||
} else {
|
||||
v.push_back(
|
||||
pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(mr.maps.ints.at(0))));
|
||||
}
|
||||
v.push_back(mr.int_or_form_to_form(pool, 0));
|
||||
GenericElement* butts =
|
||||
dynamic_cast<GenericElement*>(buttons_form->at(0)); // the form with the buttons itself
|
||||
if (butts) {
|
||||
@@ -4063,8 +4098,7 @@ FormElement* ConditionElement::make_nonzero_check_generic(const Env& env,
|
||||
source_forms.at(0));
|
||||
if (mr.matched) {
|
||||
s64 value = -mr.maps.ints.at(1);
|
||||
auto value_form = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(value));
|
||||
auto value_form = pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(value));
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::NEQ),
|
||||
std::vector<Form*>{mr.maps.forms.at(0), value_form});
|
||||
}
|
||||
@@ -4103,6 +4137,29 @@ FormElement* ConditionElement::make_equal_check_generic(const Env& env,
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::EQ),
|
||||
forms_with_cast);
|
||||
} else {
|
||||
{
|
||||
// (= (ja-group)
|
||||
// (-> self draw art-group data 7)
|
||||
// )
|
||||
// actually (ja-group? (-> self draw art-group data 7) :channel channel)
|
||||
auto mr =
|
||||
match(Matcher::op(GenericOpMatcher::func(Matcher::constant_token("ja-group")), {}),
|
||||
source_forms.at(0));
|
||||
// check if both things matched
|
||||
if (mr.matched) {
|
||||
// grab args from the ja-group and pass them on
|
||||
std::vector<Form*> macro_args;
|
||||
macro_args.push_back(source_forms.at(1));
|
||||
|
||||
auto jagroup = source_forms.at(0)->try_as_element<GenericElement>();
|
||||
for (int i = 1; i < jagroup->elts().size(); ++i) {
|
||||
macro_args.push_back(jagroup->elts().at(i));
|
||||
}
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("ja-group?")),
|
||||
macro_args);
|
||||
}
|
||||
}
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::EQ),
|
||||
cast_to_64_bit(source_forms, source_types, pool, env));
|
||||
@@ -4123,8 +4180,8 @@ FormElement* ConditionElement::make_not_equal_check_generic(
|
||||
// null?
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_compare(IR2_Condition::Kind::FALSE),
|
||||
pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::NULLP), source_forms.at(0)));
|
||||
pool.form<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::NULLP),
|
||||
source_forms.at(0)));
|
||||
} else {
|
||||
auto nice_constant =
|
||||
try_make_constant_for_compare(source_forms.at(1), source_types.at(0), pool, env);
|
||||
@@ -4164,8 +4221,7 @@ FormElement* ConditionElement::make_less_than_zero_signed_check_generic(
|
||||
shift_match.maps.forms.at(0));
|
||||
} else {
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(nullptr,
|
||||
SimpleAtom::make_int_constant(0));
|
||||
auto zero = pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::LT),
|
||||
casted);
|
||||
@@ -4193,13 +4249,11 @@ FormElement* ConditionElement::make_geq_zero_signed_check_generic(
|
||||
if (shift_match.matched) {
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_compare(IR2_Condition::Kind::FALSE),
|
||||
pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::PAIRP),
|
||||
shift_match.maps.forms.at(0)));
|
||||
pool.form<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::PAIRP),
|
||||
shift_match.maps.forms.at(0)));
|
||||
} else {
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(nullptr,
|
||||
SimpleAtom::make_int_constant(0));
|
||||
auto zero = pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::GEQ),
|
||||
casted);
|
||||
@@ -4225,8 +4279,7 @@ FormElement* ConditionElement::make_geq_zero_unsigned_check_generic(
|
||||
source_forms.at(0));
|
||||
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("uint"), pool, env);
|
||||
auto zero =
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, SimpleAtom::make_int_constant(0));
|
||||
auto zero = pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::GEQ),
|
||||
casted);
|
||||
@@ -4280,8 +4333,7 @@ FormElement* ConditionElement::make_generic(const Env& env,
|
||||
|
||||
case IR2_Condition::Kind::LESS_THAN_ZERO_UNSIGNED: {
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("uint"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(0));
|
||||
auto zero = pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::LT),
|
||||
casted);
|
||||
@@ -4289,8 +4341,7 @@ FormElement* ConditionElement::make_generic(const Env& env,
|
||||
|
||||
case IR2_Condition::Kind::LEQ_ZERO_SIGNED: {
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(0));
|
||||
auto zero = pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::LEQ),
|
||||
casted);
|
||||
@@ -4306,8 +4357,7 @@ FormElement* ConditionElement::make_generic(const Env& env,
|
||||
|
||||
case IR2_Condition::Kind::GREATER_THAN_ZERO_UNSIGNED: {
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("uint"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(0));
|
||||
auto zero = pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::GT),
|
||||
casted);
|
||||
@@ -4315,8 +4365,7 @@ FormElement* ConditionElement::make_generic(const Env& env,
|
||||
|
||||
case IR2_Condition::Kind::GREATER_THAN_ZERO_SIGNED: {
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(0));
|
||||
auto zero = pool.form<SimpleAtomElement>(SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::GT),
|
||||
casted);
|
||||
@@ -4405,7 +4454,7 @@ void ConditionElement::push_to_stack(const Env& env, FormPool& pool, FormStack&
|
||||
if (m_src[i]->is_var()) {
|
||||
source_forms.push_back(popped_forms.at(popped_counter++));
|
||||
} else {
|
||||
source_forms.push_back(pool.alloc_single_element_form<SimpleAtomElement>(nullptr, *m_src[i]));
|
||||
source_forms.push_back(pool.form<SimpleAtomElement>(*m_src[i]));
|
||||
}
|
||||
}
|
||||
ASSERT(popped_counter == int(popped_forms.size()));
|
||||
@@ -4458,7 +4507,7 @@ void ConditionElement::update_from_stack(const Env& env,
|
||||
if (m_src[i]->is_var()) {
|
||||
source_forms.push_back(popped_forms.at(popped_counter++));
|
||||
} else {
|
||||
source_forms.push_back(pool.alloc_single_element_form<SimpleAtomElement>(nullptr, *m_src[i]));
|
||||
source_forms.push_back(pool.form<SimpleAtomElement>(*m_src[i]));
|
||||
}
|
||||
}
|
||||
ASSERT(popped_counter == int(popped_forms.size()));
|
||||
@@ -4591,8 +4640,8 @@ void push_asm_sllv_to_stack(const AsmOp* op,
|
||||
// these are lazily converted at the destination.
|
||||
stack.push_value_to_reg(
|
||||
*dst,
|
||||
pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::ASM_SLLV_R0), src_var),
|
||||
pool.form<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::ASM_SLLV_R0),
|
||||
src_var),
|
||||
true, env.get_variable_type(*dst, true));
|
||||
}
|
||||
}
|
||||
@@ -4750,7 +4799,7 @@ void AtomicOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& s
|
||||
auto delay = as_branch->branch_delay();
|
||||
ASSERT(delay);
|
||||
// this might not be enough - we may need to back up to the cfg builder and do something there.
|
||||
auto del = pool.alloc_single_element_form<AtomicOpElement>(nullptr, delay);
|
||||
auto del = pool.form<AtomicOpElement>(delay);
|
||||
auto be = pool.alloc_element<AsmBranchElement>(as_branch, del, false);
|
||||
be->push_to_stack(env, pool, stack);
|
||||
return;
|
||||
@@ -4832,27 +4881,22 @@ void BranchElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||
auto src = m_op->branch_delay().var(1);
|
||||
auto dst = m_op->branch_delay().var(0);
|
||||
|
||||
auto src_form =
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, SimpleAtom::make_var(src));
|
||||
auto src_form = pool.form<SimpleAtomElement>(SimpleAtom::make_var(src));
|
||||
|
||||
branch_delay = pool.alloc_single_element_form<SetVarElement>(
|
||||
nullptr, dst, src_form, true, env.get_variable_type(src, true));
|
||||
branch_delay =
|
||||
pool.form<SetVarElement>(dst, src_form, true, env.get_variable_type(src, true));
|
||||
} break;
|
||||
case IR2_BranchDelay::Kind::SET_REG_FALSE: {
|
||||
auto dst = m_op->branch_delay().var(0);
|
||||
auto src_form = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_sym_val("#f"));
|
||||
auto src_form = pool.form<SimpleAtomElement>(SimpleAtom::make_sym_val("#f"));
|
||||
|
||||
branch_delay = pool.alloc_single_element_form<SetVarElement>(nullptr, dst, src_form, true,
|
||||
TypeSpec("symbol"));
|
||||
branch_delay = pool.form<SetVarElement>(dst, src_form, true, TypeSpec("symbol"));
|
||||
} break;
|
||||
case IR2_BranchDelay::Kind::SET_REG_TRUE: {
|
||||
auto dst = m_op->branch_delay().var(0);
|
||||
auto src_form = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_sym_val("#t"));
|
||||
auto src_form = pool.form<SimpleAtomElement>(SimpleAtom::make_sym_val("#t"));
|
||||
|
||||
branch_delay = pool.alloc_single_element_form<SetVarElement>(nullptr, dst, src_form, true,
|
||||
TypeSpec("symbol"));
|
||||
branch_delay = pool.form<SetVarElement>(dst, src_form, true, TypeSpec("symbol"));
|
||||
} break;
|
||||
default:
|
||||
throw std::runtime_error("Unhandled branch delay in BranchElement::push_to_stack: " +
|
||||
@@ -5241,8 +5285,7 @@ void ConditionalMoveFalseElement::push_to_stack(const Env& env, FormPool& pool,
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
val = pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr,
|
||||
val = pool.form<GenericElement>(
|
||||
GenericOperator::make_compare(on_zero ? IR2_Condition::Kind::NONZERO
|
||||
: IR2_Condition::Kind::ZERO),
|
||||
std::vector<Form*>{popped.at(1)});
|
||||
@@ -5260,11 +5303,10 @@ void StackSpillStoreElement::push_to_stack(const Env& env, FormPool& pool, FormS
|
||||
if (m_value.is_var()) {
|
||||
src = pop_to_forms({m_value.var()}, env, pool, stack, true).at(0);
|
||||
} else {
|
||||
src = pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_value);
|
||||
src = pool.form<SimpleAtomElement>(m_value);
|
||||
}
|
||||
|
||||
auto dst = pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, env.get_spill_slot_var_name(m_stack_offset));
|
||||
auto dst = pool.form<ConstantTokenElement>(env.get_spill_slot_var_name(m_stack_offset));
|
||||
if (m_cast_type) {
|
||||
src = cast_form(src, *m_cast_type, pool, env);
|
||||
}
|
||||
@@ -5365,10 +5407,8 @@ bool try_vector_reset_inline(const Env& env,
|
||||
store = repop_passthrough_arg(store, stack, env, &orig, &got_orig);
|
||||
|
||||
// create the actual form
|
||||
Form* new_thing = pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr,
|
||||
GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "vector-reset!")),
|
||||
Form* new_thing = pool.form<GenericElement>(
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("vector-reset!")),
|
||||
std::vector<Form*>{store});
|
||||
|
||||
if (got_orig) {
|
||||
@@ -5440,24 +5480,21 @@ void MethodOfTypeElement::update_from_stack(const Env& env,
|
||||
type_as_deref->tokens().pop_back();
|
||||
result->push_back(pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::METHOD_OF_OBJECT),
|
||||
std::vector<Form*>{type, pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, m_method_info.name)}));
|
||||
std::vector<Form*>{type, pool.form<ConstantTokenElement>(m_method_info.name)}));
|
||||
return;
|
||||
} else if (type_as_deref->tokens().size() == 1 &&
|
||||
type_as_deref->tokens().back().is_field_name("type")) {
|
||||
result->push_back(pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::METHOD_OF_OBJECT),
|
||||
std::vector<Form*>{
|
||||
type_as_deref->base(),
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, m_method_info.name)}));
|
||||
std::vector<Form*>{type_as_deref->base(),
|
||||
pool.form<ConstantTokenElement>(m_method_info.name)}));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
result->push_back(pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::METHOD_OF_TYPE),
|
||||
std::vector<Form*>{type, pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, m_method_info.name)}));
|
||||
std::vector<Form*>{type, pool.form<ConstantTokenElement>(m_method_info.name)}));
|
||||
}
|
||||
|
||||
void SimpleAtomElement::update_from_stack(const Env&,
|
||||
|
||||
Reference in New Issue
Block a user