[decompiler] Several small fixes (#775)

* fix assorted bugs

* stricter return types

* only look for functions in code files
This commit is contained in:
water111
2021-08-19 20:35:12 -04:00
committed by GitHub
parent 69d0840080
commit 11e11d2c04
48 changed files with 461 additions and 304 deletions
+15
View File
@@ -1121,6 +1121,21 @@ void StoreOp::collect_vars(RegAccessSet& vars) const {
// LoadVarOp
/////////////////////////////
std::string load_kind_to_string(LoadVarOp::Kind kind) {
switch (kind) {
case LoadVarOp::Kind::FLOAT:
return "float";
case LoadVarOp::Kind::VECTOR_FLOAT:
return "vector-float";
case LoadVarOp::Kind::SIGNED:
return "signed";
case LoadVarOp::Kind::UNSIGNED:
return "unsigned";
default:
assert(false);
}
}
LoadVarOp::LoadVarOp(Kind kind, int size, RegisterAccess dst, SimpleExpression src, int my_idx)
: AtomicOp(my_idx), m_kind(kind), m_size(size), m_dst(dst), m_src(std::move(src)) {}
+8 -1
View File
@@ -467,7 +467,7 @@ class StoreOp : public AtomicOp {
*/
class LoadVarOp : public AtomicOp {
public:
enum class Kind { UNSIGNED, SIGNED, FLOAT, VECTOR_FLOAT };
enum class Kind { UNSIGNED, SIGNED, FLOAT, VECTOR_FLOAT, INVALID };
LoadVarOp(Kind kind, int size, RegisterAccess dst, SimpleExpression src, int my_idx);
goos::Object to_form(const std::vector<DecompilerLabel>& labels, const Env& env) const override;
bool operator==(const AtomicOp& other) const override;
@@ -490,6 +490,13 @@ class LoadVarOp : public AtomicOp {
std::optional<TypeSpec> m_type;
};
std::string load_kind_to_string(LoadVarOp::Kind kind);
FormElement* make_label_load(int label_idx,
const Env& env,
FormPool& pool,
int load_size,
LoadVarOp::Kind load_kind);
/*!
* This represents one of the possible instructions that can go in a branch delay slot.
* These will be "absorbed" into higher level structures, but for the purpose of printing AtomicOps,
+85 -68
View File
@@ -476,6 +476,82 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
return pool.alloc_element<StoreElement>(this);
}
FormElement* make_label_load(int label_idx,
const Env& env,
FormPool& pool,
int load_size,
LoadVarOp::Kind load_kind) {
auto label = env.file->labels.at(label_idx);
auto label_name = label.name;
auto hint = env.label_types().find(label_name);
if (hint != env.label_types().end()) {
if (hint->second.is_const) {
if ((load_kind == LoadVarOp::Kind::FLOAT || load_kind == LoadVarOp::Kind::SIGNED) &&
load_size == 4 && hint->second.type_name == "float") {
assert((label.offset % 4) == 0);
auto word = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4);
assert(word.kind == LinkedWord::PLAIN_DATA);
float value;
memcpy(&value, &word.data, 4);
return pool.alloc_element<ConstantFloatElement>(value);
} else if (hint->second.type_name == "uint64" && load_kind != LoadVarOp::Kind::FLOAT &&
load_size == 8) {
assert((label.offset % 8) == 0);
auto word0 = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4);
auto word1 = env.file->words_by_seg.at(label.target_segment).at(1 + (label.offset / 4));
assert(word0.kind == LinkedWord::PLAIN_DATA);
assert(word1.kind == LinkedWord::PLAIN_DATA);
u64 value;
memcpy(&value, &word0.data, 4);
memcpy(((u8*)&value) + 4, &word1.data, 4);
return pool.alloc_element<CastElement>(TypeSpec("uint"),
pool.alloc_single_element_form<SimpleAtomElement>(
nullptr, SimpleAtom::make_int_constant(value)));
}
// is it a constant bitfield?
auto& ts = env.dts->ts;
auto as_bitfield = dynamic_cast<BitFieldType*>(ts.lookup_type(hint->second.type_name));
if (as_bitfield && load_kind != LoadVarOp::Kind::FLOAT && load_size == 8) {
// get the data
assert((label.offset % 8) == 0);
auto word0 = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4);
auto word1 = env.file->words_by_seg.at(label.target_segment).at(1 + (label.offset / 4));
assert(word0.kind == LinkedWord::PLAIN_DATA);
assert(word1.kind == LinkedWord::PLAIN_DATA);
u64 value;
memcpy(&value, &word0.data, 4);
memcpy(((u8*)&value) + 4, &word1.data, 4);
// for some reason, GOAL would use a 64-bit constant for all bitfields, even if they are
// smaller. We should check that the higher bits are all zero.
int bits = as_bitfield->get_size_in_memory() * 8;
assert(bits <= 64);
if (bits < 64) {
assert((value >> bits) == 0);
// technically ub if bits == 64.
}
TypeSpec typespec(hint->second.type_name);
auto defs = decompile_bitfield_from_int(typespec, ts, value);
return pool.alloc_element<BitfieldStaticDefElement>(typespec, defs, pool);
}
}
}
if (load_kind == LoadVarOp::Kind::FLOAT && load_size == 4) {
assert((label.offset % 4) == 0);
const auto& words = env.file->words_by_seg.at(label.target_segment);
if ((int)words.size() > label.offset / 4) {
auto word = words.at(label.offset / 4);
assert(word.kind == LinkedWord::PLAIN_DATA);
float value;
memcpy(&value, &word.data, 4);
return pool.alloc_element<ConstantFloatElement>(value);
}
}
return nullptr;
}
Form* LoadVarOp::get_load_src(FormPool& pool, const Env& env) const {
if (env.has_type_analysis()) {
IR2_RegOffset ro;
@@ -584,6 +660,12 @@ Form* LoadVarOp::get_load_src(FormPool& pool, const Env& env) const {
return pool.alloc_single_element_form<DerefElement>(nullptr, source, rd.addr_of, tokens);
}
if (ro.offset == 0 && input_type.kind == TP_Type::Kind::LABEL_ADDR) {
// we no longer resolve label stuff here because sometimes we need expressions for this
return pool.alloc_single_element_form<LabelDerefElement>(nullptr, input_type.label_id(),
m_size, m_kind, ro.var);
}
if (ro.offset == 0 && (input_type.typespec() == TypeSpec("pointer") ||
input_type.kind == TP_Type::Kind::OBJECT_PLUS_PRODUCT_WITH_CONSTANT)) {
std::string cast_type;
@@ -623,74 +705,9 @@ Form* LoadVarOp::get_load_src(FormPool& pool, const Env& env) const {
}
if (m_src.is_identity() && m_src.get_arg(0).is_label()) {
// try to see if we're loading a constant
auto label = env.file->labels.at(m_src.get_arg(0).label());
auto label_name = label.name;
auto hint = env.label_types().find(label_name);
if (hint != env.label_types().end()) {
if (hint->second.is_const) {
if ((m_kind == Kind::FLOAT || m_kind == Kind::SIGNED) && m_size == 4 &&
hint->second.type_name == "float") {
assert((label.offset % 4) == 0);
auto word = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4);
assert(word.kind == LinkedWord::PLAIN_DATA);
float value;
memcpy(&value, &word.data, 4);
return pool.alloc_single_element_form<ConstantFloatElement>(nullptr, value);
} else if (hint->second.type_name == "uint64" && m_kind != Kind::FLOAT && m_size == 8) {
assert((label.offset % 8) == 0);
auto word0 = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4);
auto word1 = env.file->words_by_seg.at(label.target_segment).at(1 + (label.offset / 4));
assert(word0.kind == LinkedWord::PLAIN_DATA);
assert(word1.kind == LinkedWord::PLAIN_DATA);
u64 value;
memcpy(&value, &word0.data, 4);
memcpy(((u8*)&value) + 4, &word1.data, 4);
return pool.alloc_single_element_form<CastElement>(
nullptr, TypeSpec("uint"),
pool.alloc_single_element_form<SimpleAtomElement>(
nullptr, SimpleAtom::make_int_constant(value)));
}
// is it a constant bitfield?
auto& ts = env.dts->ts;
auto as_bitfield = dynamic_cast<BitFieldType*>(ts.lookup_type(hint->second.type_name));
if (as_bitfield && m_kind != Kind::FLOAT && m_size == 8) {
// get the data
assert((label.offset % 8) == 0);
auto word0 = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4);
auto word1 = env.file->words_by_seg.at(label.target_segment).at(1 + (label.offset / 4));
assert(word0.kind == LinkedWord::PLAIN_DATA);
assert(word1.kind == LinkedWord::PLAIN_DATA);
u64 value;
memcpy(&value, &word0.data, 4);
memcpy(((u8*)&value) + 4, &word1.data, 4);
// for some reason, GOAL would use a 64-bit constant for all bitfields, even if they are
// smaller. We should check that the higher bits are all zero.
int bits = as_bitfield->get_size_in_memory() * 8;
assert(bits <= 64);
if (bits < 64) {
assert((value >> bits) == 0);
// technically ub if bits == 64.
}
TypeSpec typespec(hint->second.type_name);
auto defs = decompile_bitfield_from_int(typespec, ts, value);
return pool.alloc_single_element_form<BitfieldStaticDefElement>(nullptr, typespec, defs,
pool);
}
}
}
if (m_kind == Kind::FLOAT && m_size == 4) {
assert((label.offset % 4) == 0);
const auto& words = env.file->words_by_seg.at(label.target_segment);
if ((int)words.size() > label.offset / 4) {
auto word = words.at(label.offset / 4);
assert(word.kind == LinkedWord::PLAIN_DATA);
float value;
memcpy(&value, &word.data, 4);
return pool.alloc_single_element_form<ConstantFloatElement>(nullptr, value);
}
auto label_load_element = make_label_load(m_src.get_arg(0).label(), env, pool, m_size, m_kind);
if (label_load_element) {
return pool.alloc_single_form(nullptr, label_load_element);
}
}
+1 -1
View File
@@ -137,7 +137,7 @@ TP_Type SimpleAtom::get_type(const TypeState& input,
}
// todo: should we take out this warning?
lg::warn("IR_StaticAddress does not know the type of {}", label.name);
return TP_Type::make_label_addr();
return TP_Type::make_label_addr(m_int);
}
case Kind::INVALID:
default:
+26
View File
@@ -2776,6 +2776,32 @@ void LabelElement::apply_form(const std::function<void(Form*)>&) {}
void LabelElement::collect_vars(RegAccessSet&, bool) const {}
void LabelElement::get_modified_regs(RegSet&) const {}
////////////////////////////////
// LabelDerefElement
///////////////////////////////
LabelDerefElement::LabelDerefElement(int lid,
int size,
LoadVarOp::Kind load_kind,
RegisterAccess var)
: m_lid(lid), m_size(size), m_load_kind(load_kind), m_var(var) {}
goos::Object LabelDerefElement::to_form_internal(const Env& env) const {
return pretty_print::build_list(fmt::format("label-deref {} :label {} :size {} :kind {}",
m_var.to_string(env), env.file->labels.at(m_lid).name,
m_size, load_kind_to_string(m_load_kind)));
}
void LabelDerefElement::apply(const std::function<void(FormElement*)>& f) {
f(this);
}
void LabelDerefElement::apply_form(const std::function<void(Form*)>&) {}
void LabelDerefElement::collect_vars(RegAccessSet& regs, bool) const {
regs.insert(m_var);
}
void LabelDerefElement::get_modified_regs(RegSet&) const {}
////////////////////////////////
// GetSymbolStringPointer
//////////////////////////////
+22
View File
@@ -632,6 +632,7 @@ class ReturnElement : public FormElement {
void collect_vars(RegAccessSet& vars, bool recursive) const override;
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
void get_modified_regs(RegSet& regs) const override;
std::optional<TypeSpec> return_type;
};
/*!
@@ -1549,6 +1550,27 @@ class LabelElement : public FormElement {
int m_lid = -1;
};
class LabelDerefElement : public FormElement {
public:
LabelDerefElement(int lid, int size, LoadVarOp::Kind load_kind, RegisterAccess var);
goos::Object to_form_internal(const Env& env) const override;
void apply(const std::function<void(FormElement*)>& f) override;
void apply_form(const std::function<void(Form*)>& f) override;
void collect_vars(RegAccessSet& vars, bool recursive) const override;
void get_modified_regs(RegSet& regs) const override;
void update_from_stack(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects) override;
private:
int m_lid = -1;
int m_size = -1;
LoadVarOp::Kind m_load_kind = LoadVarOp::Kind::INVALID;
RegisterAccess m_var;
};
class GetSymbolStringPointer : public FormElement {
public:
GetSymbolStringPointer(Form* src);
+68 -21
View File
@@ -3549,6 +3549,24 @@ FormElement* ConditionElement::make_zero_check_generic(const Env& env,
return pool.alloc_element<GenericElement>(GenericOperator::make_compare(m_kind), source_forms);
}
FormElement* try_make_nonzero_logtest(Form* in, FormPool& pool) {
/*
(defmacro logtest? (a b)
"does a have any of the bits in b?"
`(nonzero? (logand ,a ,b))
)
*/
auto logand_matcher = Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::LOGAND),
{Matcher::any(0), Matcher::any(1)});
auto mr_logand = match(logand_matcher, in);
if (mr_logand.matched) {
return pool.alloc_element<GenericElement>(
GenericOperator::make_fixed(FixedOperatorKind::LOGTEST), mr_logand.maps.forms.at(0),
mr_logand.maps.forms.at(1));
}
return nullptr;
}
FormElement* ConditionElement::make_nonzero_check_generic(const Env& env,
FormPool& pool,
const std::vector<Form*>& source_forms,
@@ -3578,19 +3596,9 @@ FormElement* ConditionElement::make_nonzero_check_generic(const Env& env,
std::vector<Form*>{mr.maps.forms.at(0), value_form});
}
/*
(defmacro logtest? (a b)
"does a have any of the bits in b?"
`(nonzero? (logand ,a ,b))
)
*/
auto logand_matcher = Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::LOGAND),
{Matcher::any(0), Matcher::any(1)});
auto mr_logand = match(logand_matcher, source_forms.at(0));
if (mr_logand.matched) {
return pool.alloc_element<GenericElement>(
GenericOperator::make_fixed(FixedOperatorKind::LOGTEST), mr_logand.maps.forms.at(0),
mr_logand.maps.forms.at(1));
auto as_logand = try_make_nonzero_logtest(source_forms.at(0), pool);
if (as_logand) {
return as_logand;
}
return pool.alloc_element<GenericElement>(GenericOperator::make_compare(m_kind), source_forms);
@@ -3967,7 +3975,8 @@ void ReturnElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
return_code->push_back(new_entries.back());
if (var) {
const auto& func_type = env.func->type.last_arg();
if (!env.dts->ts.tc(func_type, env.get_variable_type(*var, false))) {
return_type = env.get_variable_type(*var, false);
if (func_type != return_type) {
auto as_cast = return_code->try_as_element<CastElement>();
if (as_cast) {
return_code->clear();
@@ -4643,13 +4652,25 @@ void ConditionalMoveFalseElement::push_to_stack(const Env& env, FormPool& pool,
stack.push_form_element(this, true);
return;
}
stack.push_value_to_reg(dest,
pool.alloc_single_element_form<GenericElement>(
nullptr,
GenericOperator::make_compare(on_zero ? IR2_Condition::Kind::NONZERO
: IR2_Condition::Kind::ZERO),
std::vector<Form*>{popped.at(1)}),
true, TypeSpec("symbol"));
Form* val = nullptr;
if (!val && on_zero) {
auto as_logtest = try_make_nonzero_logtest(popped.at(1), pool);
if (as_logtest) {
val = pool.alloc_single_form(nullptr, as_logtest);
}
}
if (!val) {
val = pool.alloc_single_element_form<GenericElement>(
nullptr,
GenericOperator::make_compare(on_zero ? IR2_Condition::Kind::NONZERO
: IR2_Condition::Kind::ZERO),
std::vector<Form*>{popped.at(1)});
}
stack.push_value_to_reg(dest, val, true, TypeSpec("symbol"));
}
///////////////////////////
@@ -4951,6 +4972,32 @@ void DefstateElement::update_from_stack(const Env&,
result->push_back(this);
}
void LabelDerefElement::update_from_stack(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects) {
mark_popped();
auto label_var = pop_to_forms({m_var}, env, pool, stack, allow_side_effects).at(0);
auto atom = form_as_atom(label_var);
if (!atom || !atom->is_label()) {
throw std::runtime_error(fmt::format("LabelDerefElement didn't get a label, got {} instead",
label_var->to_string(env)));
}
if (atom->label() != m_lid) {
throw std::runtime_error(
fmt::format("Label ID error in LabelDerefElement: {} vs {}", atom->label(), m_lid));
}
auto as_label = make_label_load(m_lid, env, pool, m_size, m_load_kind);
if (!as_label) {
throw std::runtime_error(
fmt::format("Unable to figure out label load for {}\n", env.file->labels.at(m_lid).name));
}
result->push_back(as_label);
}
void LabelElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
mark_popped();
stack.push_form_element(this, true);
+5 -3
View File
@@ -158,9 +158,11 @@ class ObjectFileDB {
void for_each_function_in_seg(int seg, Func f) {
for_each_obj([&](ObjectFileData& data) {
int fn = 0;
for (size_t j = data.linked_data.functions_by_seg.at(seg).size(); j-- > 0;) {
f(data.linked_data.functions_by_seg.at(seg).at(j), data);
fn++;
if (data.linked_data.segments == 3) {
for (size_t j = data.linked_data.functions_by_seg.at(seg).size(); j-- > 0;) {
f(data.linked_data.functions_by_seg.at(seg).at(j), data);
fn++;
}
}
});
}
+23
View File
@@ -84,8 +84,31 @@ bool convert_to_expressions(
}
}
bool needs_cast = false;
if (!dts.ts.tc(f.type.last_arg(), return_type)) {
// we need to cast the final value.
needs_cast = true;
} else {
bool found_early_return = false;
for (auto e : new_entries) {
e->apply([&](FormElement* elt) {
auto as_ret = dynamic_cast<ReturnElement*>(elt);
if (as_ret) {
found_early_return = true;
}
});
if (found_early_return) {
break;
}
}
if (!found_early_return && f.type.last_arg() != return_type) {
needs_cast = true;
}
}
if (needs_cast) {
auto to_cast = new_entries.back();
auto as_cast = dynamic_cast<CastElement*>(to_cast);
if (as_cast) {
+1 -2
View File
@@ -640,7 +640,6 @@
:bitfield #t
:type uint32
(display-marks 0)
(bit0 0) ;; TODO - nav-enemy::45
(bit1 1)
(bit2 2)
(bit3 3) ;; TODO - nav-enemy::45
@@ -14752,7 +14751,7 @@
(define-extern show-iop-info (function dma-buffer int))
(define-extern show-iop-memory (function dma-buffer int))
(define-extern make-sqrt-table (function int))
(define-extern flava-lookup (function symbol int integer))
(define-extern flava-lookup (function symbol int int))
;; - Symbols
+1 -1
View File
@@ -70,7 +70,7 @@ std::string TP_Type::print() const {
case Kind::PCPYUD_BITFIELD_AND:
return fmt::format("<pcpyud-and {}>", m_ts.print());
case Kind::LABEL_ADDR:
return "<label-addr>";
return fmt::format("<label-{}>", m_int);
case Kind::ENTER_STATE_FUNCTION:
return "<enter-state-func>";
case Kind::INVALID:
+7 -1
View File
@@ -262,9 +262,10 @@ class TP_Type {
return result;
}
static TP_Type make_label_addr() {
static TP_Type make_label_addr(int label_id) {
TP_Type result;
result.kind = Kind::LABEL_ADDR;
result.m_int = label_id;
return result;
}
@@ -342,6 +343,11 @@ class TP_Type {
return m_flipped_order;
}
int label_id() const {
assert(kind == Kind::LABEL_ADDR);
return m_int;
}
private:
TypeSpec m_ts;
TypeSpec m_method_from_type;
+26 -7
View File
@@ -1255,11 +1255,22 @@ std::vector<std::string> decompile_bitfield_enum_from_int(const TypeSpec& type,
return type_info->entries().at(a) < type_info->entries().at(b);
});
for (auto& field_name : bit_sorted_names) {
u64 mask = ((u64)1) << type_info->entries().at(field_name);
for (auto& kv : type_info->entries()) {
u64 mask = ((u64)1) << kv.second;
if (value & mask) {
reconstructed |= mask;
result.push_back(field_name);
result.push_back(kv.first);
}
}
int bit_count = 0;
{
u64 x = value;
while (x) {
if (x & 1) {
bit_count++;
}
x >>= 1;
}
}
@@ -1270,10 +1281,18 @@ std::vector<std::string> decompile_bitfield_enum_from_int(const TypeSpec& type,
type.print(), value, reconstructed));
}
// unordered map will give us these fields in a weird order, let's order them explicitly.
std::sort(result.begin(), result.end(), [&](const std::string& a, const std::string& b) {
return type_info->entries().at(a) < type_info->entries().at(b);
});
if (bit_count == (int)result.size()) {
// unordered map will give us these fields in a weird order, let's order them explicitly.
// because we have exactly one name per bit, we can just order them in bit order.
std::sort(result.begin(), result.end(), [&](const std::string& a, const std::string& b) {
return type_info->entries().at(a) < type_info->entries().at(b);
});
} else {
// we have multiple. Just sort alphabetically and complain.
lg::warn("Enum type {} has multiple entries with the same value.", type_info->get_name());
std::sort(result.begin(), result.end());
}
return result;
}
+1 -1
View File
@@ -561,7 +561,7 @@
(when
(and
(< 8192.0 f28-1)
(nonzero? (logand (-> *camera* master-options) 2))
(logtest? (-> *camera* master-options) 2)
)
(vector-!
(the-as vector (-> s1-0 vector))
+1 -1
View File
@@ -141,5 +141,5 @@
;; definition for method 11 of type vol-control
(defmethod TODO-RENAME-11 vol-control ((obj vol-control))
(and *display-vol-marks* (nonzero? (logand (-> obj flags) 1)))
(and *display-vol-marks* (logtest? (-> obj flags) 1))
)
+2 -4
View File
@@ -1004,9 +1004,7 @@
(+ tex-dest-base-chunk (the-as uint upload-chunk-idx))
)
;; can we possibly use existing data in VRAM?
(set! need-tex
(nonzero? (logand needed-mask (ash 1 upload-chunk-idx)))
)
(set! need-tex (logtest? needed-mask (ash 1 upload-chunk-idx)))
;; look for the start of a run of uploads.
(if (zero? chunks-to-upload-count)
(when (and (!= (-> pool ids current-dest-chunk) page-id) need-tex)
@@ -1579,7 +1577,7 @@
(dotimes (v1-0 32)
(let ((a2-0 (-> obj common-page v1-0)))
(when (and (nonzero? a2-0) ;; known common texture page
(nonzero? (logand (-> obj common-page-mask) (ash 1 v1-0))) ;; in the mask.
(and (nonzero? a2-0) (logtest? (-> obj common-page-mask) (ash 1 v1-0))) ;; in the mask.
)
;; upload it!
(upload-vram-pages obj (-> obj segment-common) a2-0 -2 (bucket-id bucket-65))
+1 -1
View File
@@ -58,7 +58,7 @@
)
(defmethod display-water-marks? water-control ((obj water-control))
(and *display-water-marks* (nonzero? (logand (-> obj flags) 1)))
(and *display-water-marks* (logtest? (-> obj flags) 1))
)
(defmethod new water-control ((allocation symbol) (type-to-make type) (arg0 process) (arg1 int) (arg2 float) (arg3 float) (arg4 float))
+1 -1
View File
@@ -69,7 +69,7 @@
(defmethod get-bit bit-array ((obj bit-array) (idx int))
"Is the bit at idx set or not?"
(let ((v1-2 (-> obj bytes (/ idx 8))))
(nonzero? (logand v1-2 (ash 1 (logand idx 7))))
(logtest? v1-2 (ash 1 (logand idx 7)))
)
)
+1 -2
View File
@@ -9,7 +9,6 @@
:bitfield #t
:type uint32
(display-marks 0)
(bit0 0) ;; TODO - nav-enemy::45
(bit1 1)
(bit2 2)
(bit3 3) ;; TODO - nav-enemy::45
@@ -402,7 +401,7 @@
(defmethod should-display? nav-control ((obj nav-control))
(and
*display-nav-marks*
(nonzero? (logand (-> obj flags) (nav-control-flags bit0 display-marks)))
(logtest? (-> obj flags) (nav-control-flags display-marks))
)
)
+1 -1
View File
@@ -115,7 +115,7 @@
(defmethod should-display? path-control ((obj path-control))
"Should we display path marks?"
(and *display-path-marks*
(nonzero? (logand (-> obj flags) (path-control-flag display)))
(logtest? (-> obj flags) (path-control-flag display))
)
)
+3 -3
View File
@@ -38,7 +38,7 @@
((let ((a0-5 obj))
(and
*display-path-marks*
(nonzero? (logand (-> a0-5 flags) (path-control-flag display)))
(logtest? (-> a0-5 flags) (path-control-flag display))
)
)
(dotimes (s5-1 (-> obj curve num-cverts))
@@ -412,12 +412,12 @@
((let ((a0-5 obj))
(and
*display-path-marks*
(nonzero? (logand (-> a0-5 flags) (path-control-flag display)))
(logtest? (-> a0-5 flags) (path-control-flag display))
)
)
(if
(and
(nonzero? (logand (-> obj flags) (path-control-flag draw-line)))
(logtest? (-> obj flags) (path-control-flag draw-line))
(> (-> obj curve num-cverts) 0)
)
(add-debug-curve2
+1 -1
View File
@@ -826,7 +826,7 @@
(dotimes (i (-> *flava-table* count))
(if (= (-> *flava-table* row i music) music)
(return (-> *flava-table* row i flava n))
(return (the-as int (-> *flava-table* row i flava n)))
)
)
0
+34 -38
View File
@@ -107,50 +107,46 @@
;; INFO: Return type mismatch int vs none.
(defmethod TODO-RENAME-39 nav-enemy ((obj nav-enemy))
(when
(and
(logtest? (-> obj nav-enemy-flags) 256)
(or
(not *target*)
(and
(zero? (logand (-> *target* state-flags) #x80f8))
(>=
(the-as int (- (-> *display* base-frame-counter) (-> obj touch-time)))
15
)
(and
(logtest? (-> obj nav-enemy-flags) 256)
(or
(not *target*)
(and
(zero? (logand (-> *target* state-flags) #x80f8))
(>=
(the-as int (- (-> *display* base-frame-counter) (-> obj touch-time)))
15
)
)
)
)
)
(dummy-54 (-> obj collide-info) 2 1)
(set! (-> obj nav-enemy-flags) (logand -257 (-> obj nav-enemy-flags)))
)
(dummy-54 (-> obj collide-info) 2 1)
(set! (-> obj nav-enemy-flags) (logand -257 (-> obj nav-enemy-flags)))
)
((method-of-object (-> obj draw shadow-ctrl) dummy-14))
(when *target*
(if *target*
(look-at-enemy!
(-> *target* neck)
(the-as vector (-> obj collide-info root-prim prim-core))
(if (logtest? (-> obj nav-enemy-flags) 4)
'attacking
)
obj
)
(if *target*
(look-at-enemy!
(-> *target* neck)
(the-as vector (-> obj collide-info root-prim prim-core))
(if (logtest? (-> obj nav-enemy-flags) 4)
'attacking
)
obj
)
)
(if (and (nonzero? (-> obj neck)) (logtest? (-> obj nav-enemy-flags) #x4000))
(set-target!
(-> obj neck)
(target-pos (-> obj nav-info player-look-at-joint))
)
)
)
(if
(and
(nonzero? (-> obj neck))
(nonzero? (logand (-> obj nav-enemy-flags) #x4000))
)
(set-target!
(-> obj neck)
(target-pos (-> obj nav-info player-look-at-joint))
)
)
)
(when (-> obj nav-info debug-draw-neck)
(if (nonzero? (-> obj neck))
(joint-mod-debug-draw (-> obj neck))
(if (nonzero? (-> obj neck))
(joint-mod-debug-draw (-> obj neck))
)
)
)
(ja-post)
0
(none)
@@ -3168,7 +3164,7 @@ nav-enemy-default-event-handler
)
(logior!
(-> obj nav flags)
(nav-control-flags bit0 display-marks bit3 bit5 bit6 bit7)
(nav-control-flags display-marks bit3 bit5 bit6 bit7)
)
(set! (-> obj nav gap-event) 'jump)
(dummy-26 (-> obj nav))
@@ -557,7 +557,7 @@
(when
(and
(< 8192.0 f28-1)
(nonzero? (logand (-> *camera* master-options) 2))
(logtest? (-> *camera* master-options) 2)
)
(vector-!
(the-as vector (-> s1-0 vector))
+2 -2
View File
@@ -166,13 +166,13 @@
(let ((v1-32 #f))
(set! a0-16 #f)
(when s4-0
(set! v1-32 (nonzero? (logand (shl #x8000 16) (-> s4-0 flags))))
(set! v1-32 (logtest? (shl #x8000 16) (-> s4-0 flags)))
(if (< (-> s4-0 length) (-> s4-0 from-bsp current-leaf-idx))
(set! v1-32 #f)
)
)
(when s3-0
(set! a0-16 (nonzero? (logand (shl #x8000 16) (-> s3-0 flags))))
(set! a0-16 (logtest? (shl #x8000 16) (-> s3-0 flags)))
(if (< (-> s3-0 length) (-> s3-0 from-bsp current-leaf-idx))
(set! a0-16 #f)
)
+1 -1
View File
@@ -1686,7 +1686,7 @@
(logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons right))
(logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons left))
(logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons down))
(nonzero? (logand (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons up)))
(logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons up))
)
(let ((v1-39 (cond
((logtest?
@@ -46,19 +46,19 @@
;; definition for method 12 of type task-cstage
(defmethod closed? task-cstage ((obj task-cstage))
(nonzero? (logand (-> obj flags) (task-flags closed)))
(logtest? (-> obj flags) (task-flags closed))
)
;; definition for method 13 of type task-cstage
(defmethod closed-by-default? task-cstage ((obj task-cstage))
(nonzero? (logand (-> obj flags) (task-flags closed-by-default)))
(logtest? (-> obj flags) (task-flags closed-by-default))
)
;; definition for method 11 of type task-cstage
(defmethod task-available? task-cstage ((obj task-cstage) (arg0 task-control))
(let ((a0-1 obj))
(cond
((nonzero? (logand (-> a0-1 flags) (task-flags closed)))
((logtest? (-> a0-1 flags) (task-flags closed))
#f
)
((>=
@@ -227,11 +227,9 @@
(dotimes (s4-0 (-> obj stage length))
(if (or (= arg0 'game) (let ((a0-4 (-> obj stage s4-0)))
(not
(nonzero?
(logand
(-> a0-4 flags)
(task-flags closed-by-default)
)
(logtest?
(-> a0-4 flags)
(task-flags closed-by-default)
)
)
)
@@ -239,7 +237,7 @@
(open-task! (-> obj stage s4-0))
)
(let ((a0-10 (-> obj stage s4-0)))
(if (nonzero? (logand (-> a0-10 flags) (task-flags closed)))
(if (logtest? (-> a0-10 flags) (task-flags closed))
(close-task! (-> obj stage s4-0))
)
)
@@ -263,7 +261,7 @@
(= arg1 (-> obj stage v1-3 status))
)
(let ((a0-3 (-> obj stage v1-3)))
(return (nonzero? (logand (-> a0-3 flags) (task-flags closed))))
(return (logtest? (-> a0-3 flags) (task-flags closed)))
)
)
)
+1 -1
View File
@@ -173,5 +173,5 @@
;; definition for method 11 of type vol-control
(defmethod TODO-RENAME-11 vol-control ((obj vol-control))
(and *display-vol-marks* (nonzero? (logand (-> obj flags) 1)))
(and *display-vol-marks* (logtest? (-> obj flags) 1))
)
@@ -22,11 +22,9 @@
(v1-4 (logand a0-4 3))
(a0-6 (+ (* a3-0 4) a2-3))
)
(nonzero?
(logand
(-> *ocean-work* trans-camera-masks 0 mask (+ a1-2 (* a0-6 8)))
(ash 1 v1-4)
)
(logtest?
(-> *ocean-work* trans-camera-masks 0 mask (+ a1-2 (* a0-6 8)))
(ash 1 v1-4)
)
)
)
@@ -62,7 +60,7 @@
)
)
(if a0-11
(nonzero? (logand (-> a0-11 1) (ash 1 v1-4)))
(logtest? (-> a0-11 1) (ash 1 v1-4))
#f
)
)
+2 -8
View File
@@ -1213,10 +1213,7 @@
)
(dotimes (upload-chunk-idx chunk-count)
(set! current-dest-chunk (+ tex-dest-base-chunk upload-chunk-idx))
(set!
need-tex
(nonzero? (logand allow-cache-mask (ash 1 upload-chunk-idx)))
)
(set! need-tex (logtest? allow-cache-mask (ash 1 upload-chunk-idx)))
(cond
((zero? chunks-to-upload-count)
(when (and (!= (-> pool ids current-dest-chunk) page-id) need-tex)
@@ -1856,10 +1853,7 @@
(dotimes (v1-0 32)
(let ((a2-0 (-> obj common-page v1-0)))
(when
(and
(nonzero? a2-0)
(nonzero? (logand (-> obj common-page-mask) (ash 1 v1-0)))
)
(and (nonzero? a2-0) (logtest? (-> obj common-page-mask) (ash 1 v1-0)))
(upload-vram-pages
obj
(-> obj segment-common)
+1 -1
View File
@@ -96,7 +96,7 @@
;; definition for method 14 of type water-control
(defmethod display-water-marks? water-control ((obj water-control))
(and *display-water-marks* (nonzero? (logand (-> obj flags) 1)))
(and *display-water-marks* (logtest? (-> obj flags) 1))
)
;; definition for method 0 of type water-control
+1 -1
View File
@@ -62,7 +62,7 @@
;; definition for method 9 of type bit-array
(defmethod get-bit bit-array ((obj bit-array) (arg0 int))
(let ((v1-2 (-> obj bytes (/ arg0 8))))
(nonzero? (logand v1-2 (ash 1 (logand arg0 7))))
(logtest? v1-2 (ash 1 (logand arg0 7)))
)
)
+1 -1
View File
@@ -591,7 +591,7 @@
(defmethod should-display? nav-control ((obj nav-control))
(and
*display-nav-marks*
(nonzero? (logand (-> obj flags) (nav-control-flags display-marks bit0)))
(logtest? (-> obj flags) (nav-control-flags display-marks))
)
)
+1 -1
View File
@@ -135,7 +135,7 @@
(defmethod should-display? path-control ((obj path-control))
(and
*display-path-marks*
(nonzero? (logand (-> obj flags) (path-control-flag display)))
(logtest? (-> obj flags) (path-control-flag display))
)
)
+2 -2
View File
@@ -34,7 +34,7 @@
((let ((a0-5 obj))
(and
*display-path-marks*
(nonzero? (logand (-> a0-5 flags) (path-control-flag display)))
(logtest? (-> a0-5 flags) (path-control-flag display))
)
)
(dotimes (s5-1 (-> obj curve num-cverts))
@@ -404,7 +404,7 @@
((let ((a0-5 obj))
(and
*display-path-marks*
(nonzero? (logand (-> a0-5 flags) (path-control-flag display)))
(logtest? (-> a0-5 flags) (path-control-flag display))
)
)
(if
-1
View File
@@ -1135,7 +1135,6 @@
(set! (-> *flava-table* count) 0)
;; definition for function flava-lookup
;; INFO: Return type mismatch int vs integer.
(defun flava-lookup ((arg0 symbol) (arg1 int))
(dotimes (v1-0 (-> *flava-table* count))
(if (= (-> *flava-table* row v1-0 music) arg0)
+2 -2
View File
@@ -1508,11 +1508,11 @@
(when parent
(let ((child (-> parent 0 child)))
(if (= child proc)
(return (the-as (pointer process-tree) #f))
(return (the-as object #f))
)
(while child
(if (= (-> child 0 brother) proc)
(return child)
(return (the-as object child))
)
(set! child (-> child 0 brother))
)
+1 -1
View File
@@ -65,7 +65,7 @@
((and
(-> obj draw shadow)
(zero? (-> obj draw cur-lod))
(nonzero? (logand (-> obj draw status) 8))
(logtest? (-> obj draw status) 8)
)
(let ((v1-9 (-> obj draw shadow-ctrl)))
(set! (-> v1-9 settings flags) (logand -33 (-> v1-9 settings flags)))
+1 -1
View File
@@ -62,7 +62,7 @@
((and
(-> obj draw shadow)
(zero? (-> obj draw cur-lod))
(nonzero? (logand (-> obj draw status) 8))
(logtest? (-> obj draw status) 8)
)
(let ((v1-9 (-> obj draw shadow-ctrl)))
(set! (-> v1-9 settings flags) (logand -33 (-> v1-9 settings flags)))
+1 -1
View File
@@ -80,7 +80,7 @@
((and
(-> obj draw shadow)
(zero? (-> obj draw cur-lod))
(nonzero? (logand (-> obj draw status) 8))
(logtest? (-> obj draw status) 8)
)
(let ((v1-9 (-> obj draw shadow-ctrl)))
(set! (-> v1-9 settings flags) (logand -33 (-> v1-9 settings flags)))
+19 -29
View File
@@ -131,11 +131,7 @@
obj
)
)
(if
(and
(nonzero? (-> obj neck))
(nonzero? (logand (-> obj nav-enemy-flags) #x4000))
)
(if (and (nonzero? (-> obj neck)) (logtest? (-> obj nav-enemy-flags) #x4000))
(set-target!
(-> obj neck)
(target-pos (-> obj nav-info player-look-at-joint))
@@ -259,10 +255,11 @@
(set! (-> a1-1 mode) arg2)
(set! (-> v1-0 param 1) (the-as uint a1-1))
)
(when (send-event-function arg0 v1-0)
(dummy-54 (-> self collide-info) 2 0)
(logior! (-> self nav-enemy-flags) 256)
#t
(the-as object (when (send-event-function arg0 v1-0)
(dummy-54 (-> self collide-info) 2 0)
(logior! (-> self nav-enemy-flags) 256)
#t
)
)
)
)
@@ -456,7 +453,7 @@ nav-enemy-default-event-handler
(if
(or
(logtest? (-> obj nav-enemy-flags) 128)
(nonzero? (logand #x80000 (-> obj nav flags)))
(logtest? #x80000 (-> obj nav flags))
)
(seek-to-point-toward-point!
(-> obj collide-info)
@@ -487,7 +484,7 @@ nav-enemy-default-event-handler
8192.0
#f
(-> obj nav-info hover-if-no-ground)
(nonzero? (logand (-> obj nav-enemy-flags) #x8000))
(logtest? (-> obj nav-enemy-flags) #x8000)
)
(dummy-58 (-> obj collide-info) (-> obj collide-info transv))
)
@@ -600,7 +597,7 @@ nav-enemy-default-event-handler
;; definition for function nav-enemy-face-player-post
;; INFO: Return type mismatch int vs none.
(defbehavior nav-enemy-face-player-post nav-enemy ()
(if (and *target* (nonzero? (logand (-> self nav-enemy-flags) 16)))
(if (and *target* (logtest? (-> self nav-enemy-flags) 16))
(seek-to-point-toward-point!
(-> self collide-info)
(target-pos 0)
@@ -660,10 +657,7 @@ nav-enemy-default-event-handler
;; INFO: Return type mismatch int vs none.
(defbehavior nav-enemy-neck-control-inactive nav-enemy ()
(when
(and
(nonzero? (-> self neck))
(nonzero? (logand (-> self nav-enemy-flags) #x4000))
)
(and (nonzero? (-> self neck)) (logtest? (-> self nav-enemy-flags) #x4000))
(set! (-> self nav-enemy-flags) (logand -16385 (-> self nav-enemy-flags)))
(shut-down! (-> self neck))
)
@@ -1087,7 +1081,7 @@ nav-enemy-default-event-handler
(nonzero? (-> obj skel))
(!= (-> obj skel root-channel 0) (-> obj skel channel))
)
(and (nonzero? (-> obj draw)) (nonzero? (logand (-> obj draw status) 16)))
(and (nonzero? (-> obj draw)) (logtest? (-> obj draw status) 16))
)
)
)
@@ -1139,7 +1133,7 @@ nav-enemy-default-event-handler
(the-as int (-> self state-timeout))
)
(nonzero? (-> self draw))
(nonzero? (logand (-> self draw status) 8))
(logtest? (-> self draw status) 8)
)
(go-virtual nav-enemy-patrol)
)
@@ -1227,11 +1221,7 @@ nav-enemy-default-event-handler
)
(the-as int (-> self state-timeout))
)
(if
(and
(nonzero? (-> self draw))
(nonzero? (logand (-> self draw status) 8))
)
(if (and (nonzero? (-> self draw)) (logtest? (-> self draw status) 8))
(set! (-> self free-time) (-> *display* base-frame-counter))
)
(if
@@ -1903,7 +1893,7 @@ nav-enemy-default-event-handler
(if
(or
(not (TODO-RENAME-46 self (-> self nav-info stop-chase-distance)))
(nonzero? (logand (-> self nav-enemy-flags) 8192))
(logtest? (-> self nav-enemy-flags) 8192)
)
(go-virtual nav-enemy-stop-chase)
)
@@ -2198,7 +2188,7 @@ nav-enemy-default-event-handler
)
)
)
(nonzero? (logand #x20000 (-> self nav flags)))
(logtest? #x20000 (-> self nav flags))
)
(go-virtual nav-enemy-give-up)
)
@@ -2529,7 +2519,7 @@ nav-enemy-default-event-handler
(logior! (-> self nav-enemy-flags) 1024)
)
)
(when (and arg1 (nonzero? (logand (-> self nav-enemy-flags) 1024)))
(when (and arg1 (logtest? (-> self nav-enemy-flags) 1024))
(set! (-> self nav-enemy-flags) (logand -513 (-> self nav-enemy-flags)))
(set! f30-0 2048.0)
)
@@ -2850,7 +2840,7 @@ nav-enemy-default-event-handler
(if
(or
(logtest? (-> self nav-enemy-flags) 128)
(nonzero? (logand #x80000 (-> self nav flags)))
(logtest? #x80000 (-> self nav flags))
)
(seek-to-point-toward-point!
(-> self collide-info)
@@ -2915,7 +2905,7 @@ nav-enemy-default-event-handler
)
150
)
(nonzero? (logand #x80000 (-> self nav flags)))
(logtest? #x80000 (-> self nav flags))
)
(go-virtual nav-enemy-chase)
)
@@ -3164,7 +3154,7 @@ nav-enemy-default-event-handler
)
(logior!
(-> obj nav flags)
(nav-control-flags display-marks bit0 bit3 bit5 bit6 bit7)
(nav-control-flags display-marks bit3 bit5 bit6 bit7)
)
(set! (-> obj nav gap-event) 'jump)
(dummy-26 (-> obj nav))
+18 -15
View File
@@ -1786,21 +1786,24 @@
:virtual #t
:event
(behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
(case arg2
(('move-to)
(set!
(-> self root trans quad)
(-> (the-as vector (-> arg3 param 0)) quad)
)
(set! (-> self water-height) (-> self root trans y))
(if (nonzero? (-> self sound))
(update-trans! (-> self sound) (-> self root trans))
)
(let ((v0-0 (logclear (-> self mask) (process-mask sleep-code))))
(set! (-> self mask) v0-0)
v0-0
)
)
(let ((v1-0 arg2))
(the-as object (when (= v1-0 'move-to)
(set!
(-> self root trans quad)
(-> (the-as vector (-> arg3 param 0)) quad)
)
(set! (-> self water-height) (-> self root trans y))
(if (nonzero? (-> self sound))
(update-trans! (-> self sound) (-> self root trans))
)
(let
((v0-0 (logclear (-> self mask) (process-mask sleep-code)))
)
(set! (-> self mask) v0-0)
v0-0
)
)
)
)
)
:trans
@@ -129,59 +129,60 @@
(defstate teetertotter-launch (teetertotter)
:event
(behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
(when (= arg2 'touch)
(when
(and
((method-of-type touching-shapes-entry prims-touching?)
(the-as touching-shapes-entry (-> arg3 param 0))
(the-as collide-shape-moving (-> self root))
(the-as uint 1)
)
(-> self rock-is-dangerous)
)
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
(set! (-> a1-2 from) self)
(set! (-> a1-2 num-params) 2)
(set! (-> a1-2 message) 'attack)
(set! (-> a1-2 param 0) (-> arg3 param 0))
(let ((a0-2 (new 'static 'attack-info :mask #x20)))
(set! (-> a0-2 mode) 'deadly)
(set! (-> a1-2 param 1) (the-as uint a0-2))
)
(send-event-function arg0 a1-2)
)
)
(when
(and
((method-of-type touching-shapes-entry prims-touching?)
(the-as touching-shapes-entry (-> arg3 param 0))
(the-as collide-shape-moving (-> self root))
(the-as uint 2)
)
(target-on-end-of-teetertotter? self)
(not (-> self launched-player))
(-> self in-launch-window)
)
(let ((a1-4 (new 'stack-no-clear 'event-message-block)))
(set! (-> a1-4 from) self)
(set! (-> a1-4 num-params) 2)
(set! (-> a1-4 message) 'shove)
(set! (-> a1-4 param 0) (the-as uint #f))
(let ((v1-16 (new 'static 'attack-info :mask #xcc0)))
(set! (-> v1-16 shove-back) 0.0)
(set! (-> v1-16 shove-up) 53248.0)
(set! (-> v1-16 angle) 'jump)
(set! (-> v1-16 control) 1.0)
(set! (-> a1-4 param 1) (the-as uint v1-16))
)
(when (send-event-function arg0 a1-4)
(let ((v0-0 #t))
(set! (-> self launched-player) v0-0)
v0-0
)
)
)
)
(the-as object (when (= arg2 'touch)
(when
(and
((method-of-type touching-shapes-entry prims-touching?)
(the-as touching-shapes-entry (-> arg3 param 0))
(the-as collide-shape-moving (-> self root))
(the-as uint 1)
)
(-> self rock-is-dangerous)
)
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
(set! (-> a1-2 from) self)
(set! (-> a1-2 num-params) 2)
(set! (-> a1-2 message) 'attack)
(set! (-> a1-2 param 0) (-> arg3 param 0))
(let ((a0-2 (new 'static 'attack-info :mask #x20)))
(set! (-> a0-2 mode) 'deadly)
(set! (-> a1-2 param 1) (the-as uint a0-2))
)
(send-event-function arg0 a1-2)
)
)
(when
(and
((method-of-type touching-shapes-entry prims-touching?)
(the-as touching-shapes-entry (-> arg3 param 0))
(the-as collide-shape-moving (-> self root))
(the-as uint 2)
)
(target-on-end-of-teetertotter? self)
(not (-> self launched-player))
(-> self in-launch-window)
)
(let ((a1-4 (new 'stack-no-clear 'event-message-block)))
(set! (-> a1-4 from) self)
(set! (-> a1-4 num-params) 2)
(set! (-> a1-4 message) 'shove)
(set! (-> a1-4 param 0) (the-as uint #f))
(let ((v1-16 (new 'static 'attack-info :mask #xcc0)))
(set! (-> v1-16 shove-back) 0.0)
(set! (-> v1-16 shove-up) 53248.0)
(set! (-> v1-16 angle) 'jump)
(set! (-> v1-16 control) 1.0)
(set! (-> a1-4 param 1) (the-as uint v1-16))
)
(when (send-event-function arg0 a1-4)
(let ((v0-0 #t))
(set! (-> self launched-player) v0-0)
v0-0
)
)
)
)
)
)
)
:code
@@ -283,9 +283,7 @@
(if
(and
(-> obj entity)
(nonzero?
(logand (-> obj entity extra perm status) (entity-perm-status complete))
)
(logtest? (-> obj entity extra perm status) (entity-perm-status complete))
)
(go silostep-rise #t)
(go silostep-idle)
+1 -1
View File
@@ -64,7 +64,7 @@
((and
(-> obj draw shadow)
(zero? (-> obj draw cur-lod))
(nonzero? (logand (-> obj draw status) 8))
(logtest? (-> obj draw status) 8)
)
(let ((v1-9 (-> obj draw shadow-ctrl)))
(set! (-> v1-9 settings flags) (logand -33 (-> v1-9 settings flags)))
+1 -1
View File
@@ -66,7 +66,7 @@
((and
(-> obj draw shadow)
(zero? (-> obj draw cur-lod))
(nonzero? (logand (-> obj draw status) 8))
(logtest? (-> obj draw status) 8)
)
(let ((v1-9 (-> obj draw shadow-ctrl)))
(set! (-> v1-9 settings flags) (logand -33 (-> v1-9 settings flags)))
+2 -2
View File
@@ -2564,7 +2564,7 @@ TEST_F(FormRegressionTest, MoveFalse) {
" daddiu sp, sp, 16\n";
std::string type = "(function int symbol)";
std::string expected = "(nonzero? (logand (+ arg0 12) 1))";
std::string expected = "(logtest? (+ arg0 12) 1)";
test_with_expr(func, type, expected, false, "", {{"L17", "A ~A"}});
}
@@ -2934,7 +2934,7 @@ TEST_F(FormRegressionTest, AshPropagation2) {
std::string type = "(function bit-array int symbol)";
std::string expected =
"(let ((v1-2 (-> arg0 bytes (/ arg1 8))))\n"
" (nonzero? (logand v1-2 (ash 1 (logand arg1 7))))\n"
" (logtest? v1-2 (ash 1 (logand arg1 7)))\n"
" )";
test_with_expr(func, type, expected);
}
@@ -160,6 +160,6 @@ TEST_F(FormRegressionTest, WeirdShortCircuit2) {
" jr ra\n"
" daddu sp, sp, r0";
std::string type = "(function actor-link-info object)";
std::string expected = "(and (-> arg0 prev) (-> arg0 prev extra process))";
std::string expected = "(the-as object (and (-> arg0 prev) (-> arg0 prev extra process)))";
test_with_stack_structures(func, type, expected, "[[16, \"event-message-block\"]]");
}