[Decompiler] bitfield support and clean up of DMA (#350)

* get to vif

* support basic bitfield access

* make bitfields in dma work

* clean up dma

* fix merge conflict
This commit is contained in:
water111
2021-04-11 16:07:01 -04:00
committed by GitHub
parent 64ae2d6d39
commit e5f0fecf17
39 changed files with 4524 additions and 221 deletions
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#include <optional>
#include "common/util/Range.h"
constexpr int BITS_PER_BYTE = 8;
template <typename T>
std::optional<Range<int>> get_bit_range(T value) {
enum State { INITIAL_ZEROS, ONES, TRAILING_ZEROS } state = INITIAL_ZEROS;
int start_bit = 0;
int end_bit = 0;
int max_bit = BITS_PER_BYTE * sizeof(T);
for (int i = 0; i < max_bit; i++) {
bool bit = (value) & (T(1) << i);
if (state == INITIAL_ZEROS) {
if (bit) {
start_bit = i;
state = ONES;
}
} else if (state == ONES) {
if (!bit) {
end_bit = i;
state = TRAILING_ZEROS;
}
} else if (state == TRAILING_ZEROS) {
if (bit) {
return std::nullopt;
}
}
}
if (state == INITIAL_ZEROS) {
return std::nullopt;
} else if (state == ONES) {
end_bit = max_bit;
}
return Range<int>{start_bit, end_bit};
}
+4
View File
@@ -24,6 +24,10 @@ class Range {
bool contains(T& val) const { return val >= m_start && val < m_end; }
bool empty() const { return m_end <= m_start; }
T size() const { return m_end - m_start; }
bool operator==(const Range<T>& other) const {
return m_start == other.m_start && m_end == other.m_end;
}
bool operator!=(const Range<T>& other) const { return !((*this) == other); }
struct Iterator {
using iterator_category = std::input_iterator_tag;
+1
View File
@@ -36,6 +36,7 @@ add_library(
IR2/AtomicOp.cpp
IR2/AtomicOpForm.cpp
IR2/AtomicOpTypeAnalysis.cpp
IR2/BitfieldForms.cpp
IR2/Env.cpp
IR2/Form.cpp
IR2/FormExpressionAnalysis.cpp
+1 -1
View File
@@ -43,7 +43,7 @@ InstructionParser::InstructionParser() {
InstructionKind::BGTZ, InstructionKind::BLTZL, InstructionKind::BGTZL,
InstructionKind::BGEZL, InstructionKind::MTC1, InstructionKind::MFC1,
InstructionKind::MFLO, InstructionKind::MFHI, InstructionKind::MTLO1,
InstructionKind::MFLO1}) {
InstructionKind::MFLO1, InstructionKind::SYNCL}) {
auto& info = gOpcodeInfo[int(i)];
if (info.defined) {
m_opcode_name_lookup[info.name] = int(i);
+7
View File
@@ -33,6 +33,13 @@ goos::Object RegisterAccess::to_form(const Env& env, Print mode) const {
m_mode == AccessMode::READ ? 'r' : 'w'));
case Print::AS_VARIABLE:
return env.get_variable_name_with_cast(m_reg, m_atomic_idx, m_mode);
case Print::AS_VARIABLE_NO_CAST:
if (env.has_local_vars()) {
return pretty_print::to_symbol(env.get_variable_name(*this));
} else {
return pretty_print::to_symbol(fmt::format("{}-{:03d}-{}", m_reg.to_charp(), m_atomic_idx,
m_mode == AccessMode::READ ? 'r' : 'w'));
}
case Print::AUTOMATIC:
if (env.has_local_vars()) {
return env.get_variable_name_with_cast(m_reg, m_atomic_idx, m_mode);
+5
View File
@@ -310,6 +310,11 @@ class AsmOp : public AtomicOp {
DecompilerTypeSystem& dts) override;
void collect_vars(RegAccessSet& vars) const override;
const Instruction& instruction() const { return m_instr; }
const std::optional<RegisterAccess> dst() const { return m_dst; }
const std::optional<RegisterAccess> src(int i) const {
assert(i < 4);
return m_src[i];
}
private:
Instruction m_instr;
+8 -3
View File
@@ -391,7 +391,8 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
}
std::string cast_type;
if (input_type.typespec() == TypeSpec("pointer") && ro.offset == 0) {
if (ro.offset == 0 && (input_type.typespec() == TypeSpec("pointer") ||
input_type.kind == TP_Type::Kind::OBJECT_PLUS_PRODUCT_WITH_CONSTANT)) {
switch (m_size) {
case 1:
cast_type = "int8";
@@ -419,6 +420,10 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
}
}
if (m_kind == Kind::FLOAT) {
cast_type = "float";
}
auto source = pool.alloc_single_element_form<SimpleExpressionElement>(
nullptr, SimpleAtom::make_var(ro.var).as_expr(), m_my_idx);
auto cast_source = pool.alloc_single_element_form<CastElement>(
@@ -540,8 +545,8 @@ 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 (input_type.typespec() == TypeSpec("pointer") ||
input_type.kind == TP_Type::Kind::OBJECT_PLUS_PRODUCT_WITH_CONSTANT) {
if (ro.offset == 0 && (input_type.typespec() == TypeSpec("pointer") ||
input_type.kind == TP_Type::Kind::OBJECT_PLUS_PRODUCT_WITH_CONSTANT)) {
std::string cast_type;
switch (m_size) {
case 1:
+323
View File
@@ -0,0 +1,323 @@
#include "Form.h"
#include "common/goos/PrettyPrinter.h"
#include "common/util/Range.h"
#include "common/util/BitUtils.h"
namespace decompiler {
////////////////////////////////
// BitfieldStaticDefElement
////////////////////////////////
BitfieldStaticDefElement::BitfieldStaticDefElement(const TypeSpec& type,
const std::vector<BitFieldDef>& field_defs)
: m_type(type), m_field_defs(field_defs) {}
goos::Object BitfieldStaticDefElement::to_form_internal(const Env&) const {
std::vector<goos::Object> result;
result.push_back(pretty_print::to_symbol(fmt::format("new 'static '{}", m_type.print())));
for (auto& def : m_field_defs) {
if (def.is_signed) {
result.push_back(
pretty_print::to_symbol(fmt::format(":{} {}", def.field_name, (s64)def.value)));
} else {
result.push_back(
pretty_print::to_symbol(fmt::format(":{} #x{:x}", def.field_name, def.value)));
}
}
return pretty_print::build_list(result);
}
void BitfieldStaticDefElement::apply(const std::function<void(FormElement*)>& f) {
f(this);
}
void BitfieldStaticDefElement::apply_form(const std::function<void(Form*)>&) {}
void BitfieldStaticDefElement::collect_vars(RegAccessSet&, bool) const {}
void BitfieldStaticDefElement::get_modified_regs(RegSet&) const {}
ModifiedCopyBitfieldElement::ModifiedCopyBitfieldElement(
const TypeSpec& type,
Form* base,
const std::vector<BitfieldFormDef>& field_modifications)
: m_type(type), m_base(base), m_field_modifications(field_modifications) {
m_base->parent_element = this;
}
goos::Object ModifiedCopyBitfieldElement::to_form_internal(const Env& env) const {
std::vector<goos::Object> result = {pretty_print::to_symbol("copy-and-set-bf")};
result.push_back(m_base->to_form(env));
for (auto& def : m_field_modifications) {
result.push_back(pretty_print::to_symbol(fmt::format(":{}", def.field_name)));
result.push_back(def.value->to_form(env));
}
return pretty_print::build_list(result);
}
void ModifiedCopyBitfieldElement::apply(const std::function<void(FormElement*)>& f) {
f(this);
for (auto& mod : m_field_modifications) {
mod.value->apply(f);
}
m_base->apply(f);
}
void ModifiedCopyBitfieldElement::apply_form(const std::function<void(Form*)>& f) {
for (auto& mod : m_field_modifications) {
mod.value->apply_form(f);
}
m_base->apply_form(f);
}
void ModifiedCopyBitfieldElement::collect_vars(RegAccessSet& vars, bool recursive) const {
if (recursive) {
for (auto& mod : m_field_modifications) {
mod.value->collect_vars(vars, recursive);
}
m_base->collect_vars(vars, recursive);
}
}
void ModifiedCopyBitfieldElement::get_modified_regs(RegSet& regs) const {
for (auto& mod : m_field_modifications) {
mod.value->get_modified_regs(regs);
}
m_base->get_modified_regs(regs);
}
////////////////////////////////
// BitfieldReadElement
////////////////////////////////
BitfieldReadElement::BitfieldReadElement(Form* base_value, const TypeSpec& ts)
: m_base(base_value), m_type(ts) {
m_base->parent_element = this;
}
goos::Object BitfieldReadElement::to_form_internal(const Env& env) const {
return pretty_print::build_list("incomplete-bitfield-access", m_base->to_form(env));
}
void BitfieldReadElement::apply(const std::function<void(FormElement*)>& f) {
f(this);
m_base->apply(f);
}
void BitfieldReadElement::apply_form(const std::function<void(Form*)>& f) {
m_base->apply_form(f);
}
void BitfieldReadElement::collect_vars(RegAccessSet& vars, bool recursive) const {
m_base->collect_vars(vars, recursive);
}
void BitfieldReadElement::get_modified_regs(RegSet& regs) const {
m_base->get_modified_regs(regs);
}
namespace {
const BitField& find_field(const TypeSystem& ts,
const BitFieldType* type,
int start_bit,
int size,
std::optional<bool> looking_for_unsigned) {
for (auto& field : type->fields()) {
if (field.size() == size && field.offset() == start_bit) {
bool is_int = ts.tc(TypeSpec("integer"), field.type());
bool is_uint = ts.tc(TypeSpec("uinteger"), field.type());
// allow sign match, or unsigned+not a number.
if (looking_for_unsigned) {
bool want_unsigned = *looking_for_unsigned;
if ((is_int && !want_unsigned) || (is_uint && want_unsigned) ||
(!is_int && !is_uint && want_unsigned)) {
// matched!
return field;
}
} else {
return field;
}
}
}
throw std::runtime_error(
fmt::format("Unmatched field: start bit {}, size {}, signed? {}, type {}", start_bit, size,
!looking_for_unsigned, type->get_name()));
}
std::optional<BitField> find_field_from_mask(const TypeSystem& ts,
const BitFieldType* type,
uint64_t mask) {
// try to find a field that is masked by this:
auto mask_range = get_bit_range(mask);
if (!mask_range) {
// it wasn't even a valid mask...
return {};
}
return find_field(ts, type, mask_range->first(), mask_range->size(), {});
}
template <typename T>
T extract_bitfield(T input, int start_bit, int size) {
int end_bit = start_bit + size;
T left_shifted = input << (64 - end_bit);
return left_shifted >> (64 - size);
}
} // namespace
/*!
* Add a step to the bitfield access. If this completes the access, returns a form representing the
* access
*/
FormElement* BitfieldReadElement::push_step(const BitfieldManip step,
const TypeSystem& ts,
FormPool& pool) {
if (m_steps.empty() && step.kind == BitfieldManip::Kind::LEFT_SHIFT) {
// for left/right shift combo to get a field.
m_steps.push_back(step);
return nullptr;
}
if (m_steps.empty() && step.is_right_shift()) {
// could be a single step right shift to get a field
bool is_unsigned = step.right_shift_unsigned();
int shift_size = step.get_shift_start_bit();
int size = shift_size - step.amount;
int start_bit = shift_size - size;
auto type = ts.lookup_type(m_type);
auto as_bitfield = dynamic_cast<BitFieldType*>(type);
assert(as_bitfield);
auto field = find_field(ts, as_bitfield, start_bit, size, is_unsigned);
return pool.alloc_element<DerefElement>(m_base, false,
DerefToken::make_field_name(field.name()));
}
if (m_steps.size() == 1 && m_steps.at(0).kind == BitfieldManip::Kind::LEFT_SHIFT) {
// second op in left/right shift combo
int end_bit = 64 - m_steps.at(0).amount;
if (!step.is_right_shift()) {
throw std::runtime_error("Unexpected step 1");
}
bool is_unsigned = step.right_shift_unsigned();
int size = 64 - step.amount;
int start_bit = end_bit - size;
assert(start_bit >= 0);
auto type = ts.lookup_type(m_type);
auto as_bitfield = dynamic_cast<BitFieldType*>(type);
assert(as_bitfield);
auto field = find_field(ts, as_bitfield, start_bit, size, is_unsigned);
return pool.alloc_element<DerefElement>(m_base, false,
DerefToken::make_field_name(field.name()));
}
if (m_steps.empty() && step.kind == BitfieldManip::Kind::LOGAND) {
// and with mask
m_steps.push_back(step);
return nullptr;
}
if (m_steps.size() == 1 && m_steps.at(0).kind == BitfieldManip::Kind::LOGAND &&
step.kind == BitfieldManip::Kind::NONZERO_COMPARE) {
auto type = ts.lookup_type(m_type);
auto as_bitfield = dynamic_cast<BitFieldType*>(type);
assert(as_bitfield);
auto field = find_field_from_mask(ts, as_bitfield, m_steps.at(0).amount);
if (field) {
auto get_field = pool.alloc_element<DerefElement>(m_base, false,
DerefToken::make_field_name(field->name()));
get_field->inline_nested();
return pool.alloc_element<GenericElement>(
GenericOperator::make_compare(IR2_Condition::Kind::NONZERO),
pool.alloc_single_form(nullptr, get_field));
}
}
if (m_steps.size() == 1 && m_steps.at(0).kind == BitfieldManip::Kind::LOGAND &&
step.kind == BitfieldManip::Kind::LOGIOR_WITH_CONSTANT_INT) {
// this is setting a bitfield.
// first, let's check that the mask is used properly:
u64 mask = m_steps.at(0).amount;
u64 value = step.amount;
if ((mask & value) != 0) {
throw std::runtime_error(fmt::format(
"Got invalid bitmask set: mask was 0x{:x} and value was 0x{:x}", mask, value));
}
auto type = ts.lookup_type(m_type);
auto as_bitfield = dynamic_cast<BitFieldType*>(type);
assert(as_bitfield);
// use the mask to figure out the field.
auto field = find_field_from_mask(ts, as_bitfield, ~mask);
assert(field);
bool is_signed =
ts.tc(TypeSpec("int"), field->type()) && !ts.tc(TypeSpec("uint"), field->type());
// use the field to figure out what value is being set.
u64 set_value;
if (is_signed) {
set_value = extract_bitfield<s64>(value, field->offset(), field->size());
} else {
set_value = extract_bitfield<u64>(value, field->offset(), field->size());
}
BitfieldFormDef def;
def.field_name = field->name();
def.value = pool.alloc_single_element_form<SimpleAtomElement>(
nullptr, SimpleAtom::make_int_constant(set_value));
return pool.alloc_element<ModifiedCopyBitfieldElement>(m_type, m_base,
std::vector<BitfieldFormDef>{def});
}
throw std::runtime_error("Unknown state in BitfieldReadElement");
}
std::vector<BitFieldDef> decompile_static_bitfield(const TypeSpec& type,
const TypeSystem& ts,
u64 value) {
u64 touched_bits = 0;
std::vector<BitFieldDef> result;
auto type_info = dynamic_cast<BitFieldType*>(ts.lookup_type(type));
assert(type_info);
for (auto& field : type_info->fields()) {
u64 bitfield_value;
bool is_signed = ts.tc(TypeSpec("int"), field.type()) && !ts.tc(TypeSpec("uint"), field.type());
if (is_signed) {
// signed
s64 signed_value = value;
bitfield_value = extract_bitfield<s64>(signed_value, field.offset(), field.size());
} else {
// unsigned
bitfield_value = extract_bitfield<u64>(value, field.offset(), field.size());
}
if (bitfield_value != 0) {
BitFieldDef def;
def.value = bitfield_value;
def.field_name = field.name();
def.is_signed = is_signed;
result.push_back(def);
}
for (int i = field.offset(); i < field.offset() + field.size(); i++) {
touched_bits |= (u64(1) << i);
}
}
u64 untouched_but_set = value & (~touched_bits);
if (untouched_but_set) {
throw std::runtime_error(
fmt::format("Failed to decompile static bitfield of type {}. Original value is 0x{:x} but "
"we didn't touch",
type.print(), value, untouched_but_set));
}
return result;
}
} // namespace decompiler
+7 -1
View File
@@ -2097,7 +2097,9 @@ goos::Object LetElement::to_form_internal(const Env& env) const {
std::vector<goos::Object> def_list;
for (auto& entry : m_entries) {
def_list.push_back(pretty_print::build_list(entry.dest.to_form(env), entry.src->to_form(env)));
def_list.push_back(pretty_print::build_list(
entry.dest.to_form(env, RegisterAccess::Print::AS_VARIABLE_NO_CAST),
entry.src->to_form(env)));
}
outer.push_back(pretty_print::build_list(def_list));
@@ -2288,6 +2290,10 @@ void VectorFloatLoadStoreElement::collect_vf_regs(RegSet& regs) const {
regs.insert(m_vf_reg);
}
////////////////////////////////
// Utilities
////////////////////////////////
std::optional<SimpleAtom> form_as_atom(const Form* f) {
auto as_single = f->try_as_single_element();
auto as_atom = dynamic_cast<SimpleAtomElement*>(as_single);
+134
View File
@@ -156,6 +156,27 @@ class SimpleExpressionElement : public FormElement {
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects);
void update_from_stack_left_shift(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects);
void update_from_stack_right_shift_logic(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects);
void update_from_stack_right_shift_arith(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects);
void update_from_stack_logor_or_logand(const Env& env,
FixedOperatorKind kind,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects);
const SimpleExpression& expr() const { return m_expr; }
@@ -443,6 +464,10 @@ class ConditionElement : public FormElement {
FormPool& pool,
const std::vector<Form*>& source_forms,
const std::vector<TypeSpec>& types);
FormElement* make_nonzero_check_generic(const Env& env,
FormPool& pool,
const std::vector<Form*>& source_forms,
const std::vector<TypeSpec>& types);
FormElement* make_equal_check_generic(const Env& env,
FormPool& pool,
const std::vector<Form*>& source_forms,
@@ -1285,6 +1310,115 @@ class VectorFloatLoadStoreElement : public FormElement {
bool m_is_load = false;
};
struct BitfieldManip {
enum class Kind {
LEFT_SHIFT,
RIGHT_SHIFT_LOGICAL,
RIGHT_SHIFT_LOGICAL_32BIT,
RIGHT_SHIFT_ARITH,
LOGAND,
LOGIOR_WITH_CONSTANT_INT,
NONZERO_COMPARE,
INVALID
} kind = Kind::INVALID;
s64 amount = -1;
bool is_right_shift() const {
return kind == Kind::RIGHT_SHIFT_ARITH || kind == Kind::RIGHT_SHIFT_LOGICAL ||
kind == Kind::RIGHT_SHIFT_LOGICAL_32BIT;
}
bool right_shift_unsigned() const {
assert(is_right_shift());
return kind == Kind::RIGHT_SHIFT_LOGICAL || kind == Kind::RIGHT_SHIFT_LOGICAL_32BIT;
}
bool is_64bit_shift() const {
return kind == Kind::RIGHT_SHIFT_LOGICAL || kind == Kind::RIGHT_SHIFT_ARITH ||
kind == Kind::LEFT_SHIFT;
}
int get_shift_start_bit() const {
if (is_64bit_shift()) {
return 64;
} else {
return 32;
}
}
BitfieldManip(Kind k, s64 imm) : kind(k), amount(imm) {}
};
class BitfieldReadElement : public FormElement {
public:
BitfieldReadElement(Form* base_value, const TypeSpec& ts);
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;
FormElement* push_step(const BitfieldManip step, const TypeSystem& ts, FormPool& pool);
private:
Form* m_base = nullptr;
TypeSpec m_type;
std::vector<BitfieldManip> m_steps;
};
struct BitFieldDef {
bool is_signed = false;
u64 value = -1;
std::string field_name;
};
std::vector<BitFieldDef> decompile_static_bitfield(const TypeSpec& type,
const TypeSystem& ts,
u64 value);
class BitfieldStaticDefElement : public FormElement {
public:
BitfieldStaticDefElement(const TypeSpec& type, const std::vector<BitFieldDef>& field_defs);
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;
private:
TypeSpec m_type;
std::vector<BitFieldDef> m_field_defs;
};
struct BitfieldFormDef {
Form* value;
std::string field_name;
};
/*!
* This represents copying a bitfield object, then modifying the type.
* It's an intermediate step to modifying a bitfield in place and it's not expected to appear
* in the final output.
*/
class ModifiedCopyBitfieldElement : public FormElement {
public:
ModifiedCopyBitfieldElement(const TypeSpec& type,
Form* base,
const std::vector<BitfieldFormDef>& field_modifications);
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;
Form* base() const { return m_base; }
const std::vector<BitfieldFormDef> mods() const { return m_field_modifications; }
private:
TypeSpec m_type;
Form* m_base = nullptr;
std::vector<BitfieldFormDef> m_field_modifications;
};
/*!
* A Form is a wrapper around one or more FormElements.
* This is done for two reasons:
+352 -61
View File
@@ -200,6 +200,32 @@ void pop_helper(const std::vector<RegisterAccess>& vars,
}
}
/*!
* This should be used to generate all casts.
*/
Form* cast_form(Form* in, const TypeSpec& new_type, FormPool& pool, const Env& env) {
auto in_as_cast = dynamic_cast<CastElement*>(in->try_as_single_element());
if (in_as_cast && in_as_cast->type() == new_type) {
return in;
}
auto in_as_atom = form_as_atom(in);
if (in_as_atom && in_as_atom->is_int()) {
auto type_info = env.dts->ts.lookup_type(new_type);
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
if (bitfield_info) {
// GOT BITFIELD:
// fmt::print("Integer constant {} is likely a static bitfield of type {}\n",
// in_as_atom->get_int(), bitfield_info->get_name());
auto fields = decompile_static_bitfield(new_type, env.dts->ts, in_as_atom->get_int());
return pool.alloc_single_element_form<BitfieldStaticDefElement>(nullptr, new_type, fields);
}
}
return pool.alloc_single_element_form<CastElement>(nullptr, new_type, in);
}
/*!
* Pop each variable in the input list into a form. The variables should be given in the order
* they are evaluated in the source. It is safe to put the result of these in the same expression.
@@ -238,7 +264,8 @@ std::vector<Form*> pop_to_forms(const std::vector<RegisterAccess>& vars,
// only cast if we didn't get a var (compacting expressions).
// there is a separate system for casting variables that will do a better job.
if (cast && !is_var) {
forms[i] = pool.alloc_single_element_form<CastElement>(nullptr, *cast, forms[i]);
forms[i] = cast_form(forms[i], *cast, pool, env);
// pool.alloc_single_element_form<CastElement>(nullptr, *cast, forms[i]);
}
}
@@ -338,27 +365,26 @@ void FormElement::update_from_stack(const Env& env,
}
namespace {
Form* make_cast(Form* in, const TypeSpec& in_type, const TypeSpec& out_type, FormPool& pool) {
Form* make_cast_if_needed(Form* in,
const TypeSpec& in_type,
const TypeSpec& out_type,
FormPool& pool,
const Env& env) {
if (in_type == out_type) {
return in;
}
auto in_as_cast = dynamic_cast<CastElement*>(in->try_as_single_element());
if (in_as_cast && in_as_cast->type() == out_type) {
return in;
}
return pool.alloc_single_element_form<CastElement>(nullptr, out_type, in);
return cast_form(in, out_type, pool, env);
}
std::vector<Form*> make_cast(const std::vector<Form*>& in,
const std::vector<TypeSpec>& in_types,
const TypeSpec& out_type,
FormPool& pool) {
std::vector<Form*> make_casts_if_needed(const std::vector<Form*>& in,
const std::vector<TypeSpec>& in_types,
const TypeSpec& out_type,
FormPool& pool,
const Env& env) {
std::vector<Form*> out;
assert(in.size() == in_types.size());
for (size_t i = 0; i < in_types.size(); i++) {
out.push_back(make_cast(in.at(i), in_types.at(i), out_type, pool));
out.push_back(make_cast_if_needed(in.at(i), in_types.at(i), out_type, pool, env));
}
return out;
}
@@ -543,7 +569,8 @@ void SimpleExpressionElement::update_from_stack_si_1(const Env& env,
auto in_type = env.get_types_before_op(m_my_idx).get(m_expr.get_arg(0).var().reg()).typespec();
auto arg = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
result->push_back(pool.alloc_element<GenericElement>(
GenericOperator::make_fixed(kind), make_cast(arg, in_type, TypeSpec("int"), pool)));
GenericOperator::make_fixed(kind),
make_cast_if_needed(arg, in_type, TypeSpec("int"), pool, env)));
}
void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
@@ -855,6 +882,180 @@ void SimpleExpressionElement::update_from_stack_copy_first_int_2(const Env& env,
}
}
void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env,
FixedOperatorKind kind,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects) {
auto arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true);
BitfieldManip::Kind manip_kind;
if (kind == FixedOperatorKind::LOGAND) {
manip_kind = BitfieldManip::Kind::LOGAND;
} else if (kind == FixedOperatorKind::LOGIOR) {
manip_kind = BitfieldManip::Kind::LOGIOR_WITH_CONSTANT_INT;
} else {
assert(false);
}
auto type_info = env.dts->ts.lookup_type(arg0_type);
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
if (bitfield_info && m_expr.get_arg(1).is_int()) {
// andi, bitfield
auto base = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
auto read_elt = dynamic_cast<BitfieldReadElement*>(base->try_as_single_element());
if (!read_elt) {
read_elt = pool.alloc_element<BitfieldReadElement>(base, arg0_type);
}
BitfieldManip step(manip_kind, m_expr.get_arg(1).get_int());
auto other = read_elt->push_step(step, env.dts->ts, pool);
if (other) {
result->push_back(other);
} else {
result->push_back(read_elt);
}
return;
} else if (!m_expr.get_arg(1).is_var()) {
// andi, something else (don't think this can happen?)
update_from_stack_copy_first_int_2(env, kind, pool, stack, result, allow_side_effects);
} else {
// and, two forms
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());
auto arg1_i = is_int_type(env, m_my_idx, m_expr.get_arg(1).var());
auto arg1_u = is_uint_type(env, m_my_idx, m_expr.get_arg(1).var());
auto args = pop_to_forms({m_expr.get_arg(0).var(), m_expr.get_arg(1).var()}, env, pool, stack,
allow_side_effects);
if (bitfield_info) {
// mask didn't fit in imm
auto arg1_atom = form_as_atom(args.at(1));
if (arg1_atom && arg1_atom->is_int()) {
auto read_elt = dynamic_cast<BitfieldReadElement*>(args.at(0)->try_as_single_element());
if (!read_elt) {
read_elt = pool.alloc_element<BitfieldReadElement>(args.at(0), arg0_type);
}
BitfieldManip step(manip_kind, arg1_atom->get_int());
auto other = read_elt->push_step(step, env.dts->ts, pool);
assert(!other); // shouldn't be complete.
result->push_back(read_elt);
return;
}
}
if ((arg0_i && arg1_i) || (arg0_u && arg1_u)) {
// types already good
auto new_form = pool.alloc_element<GenericElement>(GenericOperator::make_fixed(kind),
args.at(0), args.at(1));
result->push_back(new_form);
} else {
// types bad, insert cast.
auto cast = pool.alloc_single_element_form<CastElement>(
nullptr, TypeSpec(arg0_i ? "int" : "uint"), args.at(1));
auto new_form =
pool.alloc_element<GenericElement>(GenericOperator::make_fixed(kind), args.at(0), cast);
result->push_back(new_form);
}
}
}
void SimpleExpressionElement::update_from_stack_left_shift(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects) {
auto arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true);
auto type_info = env.dts->ts.lookup_type(arg0_type);
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
if (bitfield_info && m_expr.get_arg(1).is_int()) {
auto base = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
auto read_elt = pool.alloc_element<BitfieldReadElement>(base, arg0_type);
BitfieldManip step(BitfieldManip::Kind::LEFT_SHIFT, m_expr.get_arg(1).get_int());
auto other = read_elt->push_step(step, env.dts->ts, pool);
assert(!other); // shouldn't be complete.
result->push_back(read_elt);
} else {
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SHL, pool, stack, result,
allow_side_effects);
}
}
void SimpleExpressionElement::update_from_stack_right_shift_logic(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects) {
auto arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true);
auto type_info = env.dts->ts.lookup_type(arg0_type);
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
if (bitfield_info && m_expr.get_arg(1).is_int()) {
auto base = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
auto read_elt = pool.alloc_element<BitfieldReadElement>(base, arg0_type);
BitfieldManip step(BitfieldManip::Kind::RIGHT_SHIFT_LOGICAL, m_expr.get_arg(1).get_int());
auto other = read_elt->push_step(step, env.dts->ts, pool);
assert(other); // should be a high field.
result->push_back(other);
} else {
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 (m_expr.get_arg(1).is_int()) {
auto arg =
pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
auto as_bitfield_access = dynamic_cast<BitfieldReadElement*>(arg->try_as_single_element());
if (as_bitfield_access) {
BitfieldManip step(BitfieldManip::Kind::RIGHT_SHIFT_LOGICAL, m_expr.get_arg(1).get_int());
auto next = as_bitfield_access->push_step(step, env.dts->ts, pool);
if (next) {
result->push_back(next);
} else {
result->push_back(as_bitfield_access);
}
} else {
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)));
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)));
result->push_back(new_form);
}
}
} else {
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SHR, pool, stack, result,
allow_side_effects);
}
}
}
void SimpleExpressionElement::update_from_stack_right_shift_arith(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects) {
auto arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true);
auto type_info = env.dts->ts.lookup_type(arg0_type);
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
if (bitfield_info && m_expr.get_arg(1).is_int()) {
auto base = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
auto read_elt = pool.alloc_element<BitfieldReadElement>(base, arg0_type);
BitfieldManip step(BitfieldManip::Kind::RIGHT_SHIFT_ARITH, m_expr.get_arg(1).get_int());
auto other = read_elt->push_step(step, env.dts->ts, pool);
assert(other); // should be a high field.
result->push_back(other);
} else {
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SAR, pool, stack, result,
allow_side_effects);
}
}
void SimpleExpressionElement::update_from_stack_lognot(const Env& env,
FormPool& pool,
FormStack& stack,
@@ -991,12 +1192,12 @@ void SimpleExpressionElement::update_from_stack(const Env& env,
allow_side_effects, false);
break;
case SimpleExpression::Kind::AND:
update_from_stack_copy_first_int_2(env, FixedOperatorKind::LOGAND, pool, stack, result,
allow_side_effects);
update_from_stack_logor_or_logand(env, FixedOperatorKind::LOGAND, pool, stack, result,
allow_side_effects);
break;
case SimpleExpression::Kind::OR:
update_from_stack_copy_first_int_2(env, FixedOperatorKind::LOGIOR, pool, stack, result,
allow_side_effects);
update_from_stack_logor_or_logand(env, FixedOperatorKind::LOGIOR, pool, stack, result,
allow_side_effects);
break;
case SimpleExpression::Kind::NOR:
update_from_stack_copy_first_int_2(env, FixedOperatorKind::LOGNOR, pool, stack, result,
@@ -1010,16 +1211,13 @@ void SimpleExpressionElement::update_from_stack(const Env& env,
update_from_stack_lognot(env, pool, stack, result, allow_side_effects);
break;
case SimpleExpression::Kind::LEFT_SHIFT:
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SHL, pool, stack, result,
allow_side_effects);
update_from_stack_left_shift(env, pool, stack, result, allow_side_effects);
break;
case SimpleExpression::Kind::RIGHT_SHIFT_LOGIC:
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SHR, pool, stack, result,
allow_side_effects);
update_from_stack_right_shift_logic(env, pool, stack, result, allow_side_effects);
break;
case SimpleExpression::Kind::RIGHT_SHIFT_ARITH:
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SAR, pool, stack, result,
allow_side_effects);
update_from_stack_right_shift_arith(env, pool, stack, result, allow_side_effects);
break;
case SimpleExpression::Kind::MUL_UNSIGNED:
update_from_stack_force_ui_2(env, FixedOperatorKind::MULTIPLICATION, pool, stack, result,
@@ -1115,11 +1313,31 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
}
}
void SetFormFormElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
// todo - is the order here right?
void SetFormFormElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
assert(m_popped);
assert(m_real_push_count == 0);
m_real_push_count++;
// check for bitfield setting:
auto src_as_bf_set = dynamic_cast<ModifiedCopyBitfieldElement*>(m_src->try_as_single_element());
if (src_as_bf_set && src_as_bf_set->mods().size() == 1) {
auto dst_form = m_dst->to_form(env);
auto src_form = src_as_bf_set->base()->to_form(env);
if (dst_form == src_form) {
// success!
auto value = src_as_bf_set->mods().at(0).value;
// make the (-> thing bitfield)
auto field_token = DerefToken::make_field_name(src_as_bf_set->mods().at(0).field_name);
auto loc_elt = pool.alloc_element<DerefElement>(m_dst, false, field_token);
loc_elt->inline_nested();
auto loc = pool.alloc_single_form(nullptr, loc_elt);
m_dst = loc;
m_src = value;
}
}
stack.push_form_element(this, true);
}
@@ -1159,14 +1377,13 @@ void StoreInPairElement::push_to_stack(const Env& env, FormPool& pool, FormStack
}
namespace {
Form* make_optional_cast(const std::optional<TypeSpec>& cast_type, Form* in, FormPool& pool) {
if (cast_type) {
auto in_as_cast = dynamic_cast<CastElement*>(in->try_as_single_element());
if (in_as_cast && in_as_cast->type() == cast_type) {
return in;
}
return pool.alloc_single_element_form<CastElement>(nullptr, *cast_type, in);
Form* make_optional_cast(const std::optional<TypeSpec>& cast_type,
Form* in,
FormPool& pool,
const Env& env) {
if (cast_type) {
return cast_form(in, *cast_type, pool, env);
} else {
return in;
}
@@ -1179,24 +1396,26 @@ void StorePlainDeref::push_to_stack(const Env& env, FormPool& pool, FormStack& s
// this matches the order in Compiler::compile_set
auto vars = std::vector<RegisterAccess>({m_expr.var(), m_base_var});
auto popped = pop_to_forms(vars, env, pool, stack, true);
m_dst->set_base(make_optional_cast(m_dst_cast_type, popped.at(1), pool));
m_dst->set_base(make_optional_cast(m_dst_cast_type, popped.at(1), pool, env));
m_dst->mark_popped();
m_dst->inline_nested();
auto fr = pool.alloc_element<SetFormFormElement>(
pool.alloc_single_form(nullptr, m_dst),
make_optional_cast(m_src_cast_type, popped.at(0), pool));
make_optional_cast(m_src_cast_type, popped.at(0), pool, env));
// so the bitfield set check can run
fr->mark_popped();
stack.push_form_element(fr, true);
fr->push_to_stack(env, pool, stack);
} else {
auto vars = std::vector<RegisterAccess>({m_base_var});
auto popped = pop_to_forms(vars, env, pool, stack, true);
m_dst->set_base(make_optional_cast(m_dst_cast_type, popped.at(0), pool));
m_dst->set_base(make_optional_cast(m_dst_cast_type, popped.at(0), pool, env));
m_dst->mark_popped();
m_dst->inline_nested();
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_expr, m_my_idx);
val->mark_popped();
auto fr = pool.alloc_element<SetFormFormElement>(
pool.alloc_single_form(nullptr, m_dst), make_optional_cast(m_src_cast_type, val, pool));
auto fr =
pool.alloc_element<SetFormFormElement>(pool.alloc_single_form(nullptr, m_dst),
make_optional_cast(m_src_cast_type, val, pool, env));
fr->mark_popped();
stack.push_form_element(fr, true);
}
@@ -1992,6 +2211,27 @@ FormElement* ConditionElement::make_zero_check_generic(const Env&,
}
}
FormElement* ConditionElement::make_nonzero_check_generic(const Env& env,
FormPool& pool,
const std::vector<Form*>& source_forms,
const std::vector<TypeSpec>&) {
// for (nonzero? (-> obj bitfield))
FormElement* bitfield_compare = nullptr;
assert(source_forms.size() == 1);
auto as_bitfield_op =
dynamic_cast<BitfieldReadElement*>(source_forms.at(0)->try_as_single_element());
if (as_bitfield_op) {
bitfield_compare = as_bitfield_op->push_step(
BitfieldManip(BitfieldManip::Kind::NONZERO_COMPARE, 0), env.dts->ts, pool);
}
if (bitfield_compare) {
return bitfield_compare;
} else {
return pool.alloc_element<GenericElement>(GenericOperator::make_compare(m_kind), source_forms);
}
}
FormElement* ConditionElement::make_equal_check_generic(const Env&,
FormPool& pool,
const std::vector<Form*>& source_forms,
@@ -2031,7 +2271,7 @@ FormElement* ConditionElement::make_not_equal_check_generic(const Env&,
}
FormElement* ConditionElement::make_less_than_zero_signed_check_generic(
const Env&,
const Env& env,
FormPool& pool,
const std::vector<Form*>& source_forms,
const std::vector<TypeSpec>& types) {
@@ -2052,7 +2292,7 @@ FormElement* ConditionElement::make_less_than_zero_signed_check_generic(
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::PAIRP),
shift_match.maps.forms.at(0));
} else {
auto casted = make_cast(source_forms, types, TypeSpec("int"), pool);
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));
casted.push_back(zero);
@@ -2062,7 +2302,7 @@ FormElement* ConditionElement::make_less_than_zero_signed_check_generic(
}
FormElement* ConditionElement::make_geq_zero_signed_check_generic(
const Env&,
const Env& env,
FormPool& pool,
const std::vector<Form*>& source_forms,
const std::vector<TypeSpec>& types) {
@@ -2086,7 +2326,7 @@ FormElement* ConditionElement::make_geq_zero_signed_check_generic(
nullptr, GenericOperator::make_fixed(FixedOperatorKind::PAIRP),
shift_match.maps.forms.at(0)));
} else {
auto casted = make_cast(source_forms, types, TypeSpec("int"), pool);
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));
casted.push_back(zero);
@@ -2102,8 +2342,9 @@ FormElement* ConditionElement::make_generic(const Env& env,
switch (m_kind) {
case IR2_Condition::Kind::ZERO:
return make_zero_check_generic(env, pool, source_forms, types);
case IR2_Condition::Kind::TRUTHY:
case IR2_Condition::Kind::NONZERO:
return make_nonzero_check_generic(env, pool, source_forms, types);
case IR2_Condition::Kind::TRUTHY:
case IR2_Condition::Kind::FALSE:
case IR2_Condition::Kind::IS_PAIR:
case IR2_Condition::Kind::IS_NOT_PAIR:
@@ -2122,28 +2363,28 @@ FormElement* ConditionElement::make_generic(const Env& env,
case IR2_Condition::Kind::LESS_THAN_SIGNED:
return pool.alloc_element<GenericElement>(
GenericOperator::make_fixed(FixedOperatorKind::LT),
make_cast(source_forms, types, TypeSpec("int"), pool));
make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env));
case IR2_Condition::Kind::LESS_THAN_UNSIGNED:
return pool.alloc_element<GenericElement>(
GenericOperator::make_fixed(FixedOperatorKind::LT),
make_cast(source_forms, types, TypeSpec("uint"), pool));
make_casts_if_needed(source_forms, types, TypeSpec("uint"), pool, env));
case IR2_Condition::Kind::GEQ_UNSIGNED:
return pool.alloc_element<GenericElement>(
GenericOperator::make_fixed(FixedOperatorKind::GEQ),
make_cast(source_forms, types, TypeSpec("uint"), pool));
make_casts_if_needed(source_forms, types, TypeSpec("uint"), pool, env));
case IR2_Condition::Kind::GEQ_SIGNED:
return pool.alloc_element<GenericElement>(
GenericOperator::make_fixed(FixedOperatorKind::GEQ),
make_cast(source_forms, types, TypeSpec("int"), pool));
make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env));
case IR2_Condition::Kind::LESS_THAN_ZERO_SIGNED: {
return make_less_than_zero_signed_check_generic(env, pool, source_forms, types);
}
case IR2_Condition::Kind::LEQ_ZERO_SIGNED: {
auto casted = make_cast(source_forms, types, TypeSpec("int"), pool);
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));
casted.push_back(zero);
@@ -2156,7 +2397,7 @@ FormElement* ConditionElement::make_generic(const Env& env,
}
case IR2_Condition::Kind::GREATER_THAN_ZERO_UNSIGNED: {
auto casted = make_cast(source_forms, types, TypeSpec("uint"), pool);
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));
casted.push_back(zero);
@@ -2165,7 +2406,7 @@ FormElement* ConditionElement::make_generic(const Env& env,
}
case IR2_Condition::Kind::GREATER_THAN_ZERO_SIGNED: {
auto casted = make_cast(source_forms, types, TypeSpec("int"), pool);
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));
casted.push_back(zero);
@@ -2174,31 +2415,31 @@ FormElement* ConditionElement::make_generic(const Env& env,
}
case IR2_Condition::Kind::FLOAT_NOT_EQUAL: {
auto casted = make_cast(source_forms, types, TypeSpec("float"), pool);
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("float"), pool, env);
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::NEQ),
casted);
}
case IR2_Condition::Kind::FLOAT_EQUAL: {
auto casted = make_cast(source_forms, types, TypeSpec("float"), pool);
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("float"), pool, env);
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::EQ),
casted);
}
case IR2_Condition::Kind::FLOAT_LEQ: {
auto casted = make_cast(source_forms, types, TypeSpec("float"), pool);
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("float"), pool, env);
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::LEQ),
casted);
}
case IR2_Condition::Kind::FLOAT_LESS_THAN: {
auto casted = make_cast(source_forms, types, TypeSpec("float"), pool);
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("float"), pool, env);
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::LT),
casted);
}
case IR2_Condition::Kind::FLOAT_GEQ: {
auto casted = make_cast(source_forms, types, TypeSpec("float"), pool);
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("float"), pool, env);
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::GEQ),
casted);
}
@@ -2322,7 +2563,42 @@ void ReturnElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
stack.push_form_element(this, true);
}
void AtomicOpElement::push_to_stack(const Env& env, FormPool&, FormStack& stack) {
namespace {
void push_asm_srl_to_stack(const AsmOp* op,
FormElement* form_elt,
const Env& env,
FormPool& pool,
FormStack& stack) {
// we will try to convert this into a bitfield operation. If this fails, fall back to assembly.
auto var = op->src(0);
assert(var.has_value()); // srl should always have this.
auto dst = op->dst();
assert(dst.has_value());
auto integer_atom = op->instruction().get_src(1);
assert(integer_atom.is_imm());
auto integer = integer_atom.get_imm();
auto arg0_type = env.get_variable_type(*var, true);
auto type_info = env.dts->ts.lookup_type(arg0_type);
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
if (bitfield_info) {
auto base = pop_to_forms({*var}, env, pool, stack, true).at(0);
auto read_elt = pool.alloc_element<BitfieldReadElement>(base, arg0_type);
BitfieldManip step(BitfieldManip::Kind::RIGHT_SHIFT_LOGICAL_32BIT, integer);
auto other = read_elt->push_step(step, env.dts->ts, pool);
assert(other); // should be a high field.
stack.push_value_to_reg(*dst, pool.alloc_single_form(nullptr, other), true,
env.get_variable_type(*dst, true));
} else {
stack.push_form_element(form_elt, true);
}
}
} // namespace
void AtomicOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
mark_popped();
auto as_end = dynamic_cast<const FunctionEndOp*>(m_op);
if (as_end) {
@@ -2343,15 +2619,30 @@ void AtomicOpElement::push_to_stack(const Env& env, FormPool&, FormStack& stack)
auto as_asm = dynamic_cast<const AsmOp*>(m_op);
if (as_asm) {
stack.push_form_element(this, true);
switch (as_asm->instruction().kind) {
case InstructionKind::SRL:
push_asm_srl_to_stack(as_asm, this, env, pool, stack);
break;
default:
stack.push_form_element(this, true);
break;
}
return;
}
throw std::runtime_error("Can't push atomic op to stack: " + m_op->to_string(env));
}
void AsmOpElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
void AsmOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
mark_popped();
stack.push_form_element(this, true);
switch (m_op->instruction().kind) {
case InstructionKind::SRL:
push_asm_srl_to_stack(m_op, this, env, pool, stack);
break;
default:
stack.push_form_element(this, true);
break;
}
}
void GenericElement::update_from_stack(const Env& env,
+5 -4
View File
@@ -64,10 +64,11 @@ class RegisterAccess {
RegisterAccess(AccessMode mode, Register reg, int atomic_idx, bool allow_all = false);
enum class Print {
AS_REG, // print as a PS2 register name
FULL, // print as a register name, plus an index, plus read or write
AS_VARIABLE, // print local variable name, error if impossible
AUTOMATIC, // print as variable, but if that's not possible print as reg.
AS_REG, // print as a PS2 register name
FULL, // print as a register name, plus an index, plus read or write
AS_VARIABLE, // print local variable name, error if impossible
AS_VARIABLE_NO_CAST, // same as above, but no cast
AUTOMATIC, // print as variable, but if that's not possible print as reg.
};
goos::Object to_form(const Env& env, Print mode = Print::AUTOMATIC) const;
+14 -10
View File
@@ -1665,11 +1665,9 @@
;(define-extern sound-rpc-set-falloff-curve object) ;; unknown type
;;(define-extern *sound-bank-2* object) ;; unknown type
;;(define-extern sound-rpc-reload-info object) ;; unknown type
;;(define-extern sound-rpc-stop-sound object) ;; unknown type
;;(define-extern sound-rpc-list-sounds object) ;; unknown type
;;(define-extern *current-sound-id* object) ;; unknown type
;;(define-extern sound-bank-id object) ;; unknown type
;;(define-extern sound-rpc-get-irx-version object) ;; unknown type
;;(define-extern sound-rpc-load-music object) ;; unknown type
@@ -1688,6 +1686,8 @@
:flag-assert #xa00000004
)
(define-extern *current-sound-id* sound-id)
(deftype sound-bank-id (uint32)
()
:flag-assert #x900000004
@@ -1701,7 +1701,8 @@
;;(define-extern sound-rpc-load-bank object) ;; unknown type
;;(define-extern sound-rpc-set-master-volume object) ;; unknown type
;;(define-extern sound-rpc-set-param object) ;; unknown type
;;(define-extern *sound-bank-1* object) ;; unknown type
(define-extern *sound-bank-1* symbol)
(define-extern *sound-bank-2* symbol)
;;(define-extern sound-rpc-stop-group object) ;; unknown type
;;(define-extern sound-rpc-play object) ;; unknown type
;;(define-extern sound-rpc-cmd object) ;; unknown type
@@ -2203,7 +2204,7 @@
(deftype vif-bank (structure)
((stat uint32 :offset-assert 0)
(fbrst uint32 :offset 16)
(err uint32 :offset 32)
(err vif-err :offset 32)
(mark uint32 :offset 48)
(cycle uint32 :offset 64)
(mode uint32 :offset 80)
@@ -2353,18 +2354,18 @@
)
;; dma-h
(deftype vif-tag (uint32)
((imm uint16 :offset 0 :size 16)
(num uint8 :offset 16 :size 8)
(cmd uint8 :offset 24 :size 8)
(cmd uint8 :offset 24 :size 7)
(msk uint8 :offset 28 :size 1)
(irq uint8 :offset 31 :size 1) ;;?
(msk uint8 :offset 15 :size 1)
)
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
(deftype dma-enable (uint32)
()
:flag-assert #x900000004
@@ -2479,6 +2480,9 @@
:flag-assert #x900000014
)
(define-extern *vu1-enable-user-menu* int)
(define-extern *vu1-enable-user* int)
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2536,10 +2540,10 @@
(define-extern *video-parms* video-parms) ;; unknown type
;;(define-extern video-parms object) ;; unknown type
;;(define-extern generic-bucket-state object) ;; unknown type
;;(define-extern *vu1-enable-user-menu* object) ;; unknown type
;; unknown type
(define-extern dma-foreground-sink type)
(define-extern dma-foreground-sink-group type)
;;(define-extern *vu1-enable-user* object) ;; unknown type
;; ;; unknown type
(define-extern generic-dma-foreground-sink type)
@@ -3243,7 +3247,7 @@
(define-extern vector-vector-distance-squared (function vector vector float))
(define-extern vector-vector-xz-distance (function vector vector float))
(define-extern vector-vector-xz-distance-squared (function vector vector float))
(define-extern vector-normalize! (function vector vector vector))
(define-extern vector-normalize! (function vector float vector))
(define-extern vector-normalize-ret-len! (function vector float float))
(define-extern vector-normalize-copy! (function vector vector float vector))
(define-extern vector-xz-normalize! (function vector float vector))
@@ -108,6 +108,12 @@
["L136", "float", true]
],
"timer": [["L20", "float", true]],
"dma": [["L56", "uint64", true]],
"video-h": [["L1", "video-parms", true]],
"pad": [
["L44", "float", true],
["L42", "float", true],
@@ -40,7 +40,7 @@
[132, "gp", "(array int8)"], // bug in game
[150, "gp", "(array int16)"],
[168, "gp", "(array uint16)"],
[190, "gp", "(array uint128)"],
[191, "gp", "(array uint128)"],
[207, "gp", "(array int32)"],
[226, "gp", "(array float)"],
[243, "gp", "(array basic)"]
@@ -49,9 +49,7 @@
// GKERNEL-H
"(method 2 handle)": [
[10, "a2", "(pointer process)"],
[11, "a3", "process"],
[12, "v1", "int"],
[16, "gp", "int"]
[11, "a3", "process"]
],
// GKERNEL
@@ -120,6 +118,33 @@
"vector-y-quaternion!": [[10, "v1", "(pointer uint128)"]],
"vector-z-quaternion!": [[10, "v1", "(pointer uint128)"]],
// Matrix
//"eul->matrix": [[[110, 228], "gp", "(pointer float)"]],
// DMA
"dma-send-to-spr": [[[0, 32], "s5", "dma-bank-spr"]],
"dma-send-to-spr-no-flush": [[[0, 32], "s5", "dma-bank-spr"]],
"dma-send-from-spr": [[[0, 32], "s5", "dma-bank-spr"]],
"dma-send-from-spr-no-flush": [[[0, 32], "s5", "dma-bank-spr"]],
"dma-initialize": [
[1, "v1", "vif-bank"],
[8, "v1", "vif-bank"],
[6, "a0", "vif-bank"],
[13, "a0", "vif-bank"]
],
"clear-vu1-mem": [[[0, 11], "v1", "(pointer uint32)"]],
"clear-vu0-mem": [[[0, 11], "v1", "(pointer uint32)"]],
"dump-vu1-mem": [[[0, 49], "gp", "(pointer uint32)"]],
"dump-vu1-range": [[[0, 54], "s4", "(pointer uint32)"]],
"ultimate-memcpy": [
[[0, 54], "s4", "dma-bank-spr"],
[[0, 54], "s3", "dma-bank-spr"]
],
// LEVEL
"lookup-level-info": [
[3, "a1", "symbol"],
@@ -578,14 +578,18 @@
"args": ["tf", "dst-mat"]
},
"quaternion-axis-angle!":{
"quaternion-axis-angle!": {
"args": ["quat", "x", "y", "z", "angle"]
},
"quaternion-vector-angle!":{
"quaternion-vector-angle!": {
"args": ["quat", "axis", "angle"]
},
"vector-flatten!": {
"args": ["dst", "src", "plane-normal"]
},
"deg-seek": {
"args": ["in", "target", "max-diff"],
"vars": {
+26 -10
View File
@@ -10,14 +10,17 @@
;; The PS2 supports several types of DMA, including simple chunk transfer and more complicated
;; "chain" transfers, where the hardware can follow a linked data-structure.
;; In OpenGOAL, "DMA" will be instant. By default, DMA syncs will be disabled by this flag.
;; In OpenGOAL, "DMA" will be instant, meaning the game code will stop, wait until the
;; DMA is finished, and then continue. As a result, there is no need for DMA synchronization.
;; When this flag is set, all DMA syncs will be instantaneous.
(defglobalconstant INSTANT_DMA #t)
;; count returned by dma-sync-with-count
;; when instant dma is enabled.
;; Some DMA sync functions return a count for how long it took.
;; When INSTANT_DMA is enabled, these functions will return this value.
(defglobalconstant INSTANT_DMA_COUNT 123)
;; DMA Channel Control Register. This starts the DMA and can be checked to see if it done.
;; There is one CHCR per DMA channel.
(deftype dma-chcr (uint32)
((dir uint8 :offset 0 :size 1) ;; 1 - from memory
(mod uint8 :offset 2 :size 2) ;; normal, chain, interleave
@@ -43,7 +46,8 @@
obj
)
;; Most basic DMA register layout
;; Each DMA Channel has a bank of registers with the following layout.
;; Some channels have more advanced features, but all support at least these three.
(deftype dma-bank (structure)
((chcr dma-chcr :offset 0) ;; control register
(madr uint32 :offset 16) ;; memory address
@@ -84,6 +88,8 @@
:flag-assert #x900000084
)
;; These addresses are the location of DMA banks for each channel.
;; These do not exist in OpenGOAL.
(defconstant VIF0_DMA_BANK (the dma-bank-vif #x10008000))
(defconstant VIF1_DMA_BANK (the dma-bank-vif #x10009000))
(defconstant GIF_DMA_BANK (the dma-bank #x1000a000))
@@ -91,7 +97,14 @@
(defconstant SPR_FROM_BANK (the dma-bank-spr #x1000d000))
(defconstant SPR_TO_BANK (the dma-bank-spr #x1000d400))
;; D_CTRL, master DMA control register, shraed for all channels.
(defconstant VU0_DATA_MEM_MAP (the (pointer uint32) #x11004000))
(defconstant VU1_DATA_MEM_MAP (the (pointer uint32) #x1100c000))
;; The DMA system also has some shared control registers that
;; apply to all channels.
;; D_CTRL, master DMA control register, shared for all channels.
(deftype dma-ctrl (uint32)
()
:method-count-assert 9
@@ -202,9 +215,9 @@
(deftype vif-tag (uint32)
((imm uint16 :offset 0 :size 16)
(num uint8 :offset 16 :size 8)
(cmd uint8 :offset 24 :size 8)
(cmd uint8 :offset 24 :size 7)
(msk uint8 :offset 28 :size 1)
(irq uint8 :offset 31 :size 1) ;;?
(msk uint8 :offset 15 :size 1)
)
:method-count-assert 9
:size-assert #x4
@@ -252,7 +265,8 @@
Makes sure any ongoing transfer on the channel is done
Flushes the cache. Sets dir to 0, so I don't expect
this to be used for VIF1 transfers.
Madr should not be a scratchpad address."
Madr should not be a scratchpad address.
This function is unused."
((inline dma-sync-fast) bank)
(flush-cache 0)
;; (.sync.l)
@@ -272,7 +286,8 @@
(count (pointer int32)))
"Wait for DMA to finish, incrementing count.
This doesn't seem like a very accurate way
to find out how long it takes..."
to find out how long it takes...
This function is unused."
(#cond
(INSTANT_DMA
(set! (-> count) INSTANT_DMA_COUNT)
@@ -294,7 +309,8 @@
(defun dma-count-until-done ((bank dma-bank)
(count (pointer int32)))
"Like the previous one, kinda"
"Like the previous one, kinda.
This function is unused."
(#cond
(INSTANT_DMA
(set! (-> count) INSTANT_DMA_COUNT)
+59 -84
View File
@@ -17,14 +17,12 @@
;; these functions are just here for completeness and won't work properly on PC.
;; DMA sync functions will succeed and return instantly, so it's safe to leave those in.
(defconstant SPR_FROM_BANK (the dma-bank-spr #x100D000))
(defconstant SPR_TO_BANK (the dma-bank-spr #x1000D400))
(defun dma-sync-hang ((bank dma-bank))
"Hang here until the dma transfer is completed.
This is worse than the dma-sync-fast because it ends
up spamming the DMA bank register more often, and reduces
the speed of the DMA transfer."
the speed of the DMA transfer.
This function is unused."
(#cond
(INSTANT_DMA
0)
@@ -38,59 +36,68 @@
)
(defun dma-sync-crash ((arg0 dma-bank))
"Try to sync DMA for a bit, then crash if we can't"
(local-vars (count int))
(#when INSTANT_DMA
(return 0)
"Wait for DMA to finish for a while, then crash if we can't.
This function is unused."
(#cond
(INSTANT_DMA
(return 0)
)
)
(set! count 5000000)
;; checking str
(while (nonzero? (logand (the-as int (-> arg0 chcr)) 256))
(if (zero? count)
(segfault)
(set! count (+ count -1))
)
(let ((v1-0 5000000))
(while (nonzero? (-> arg0 chcr str))
(if (zero? v1-0)
(crash!)
(+! v1-0 -1)
)
)
(none)
)
(none)
)
(defmacro make-madr-addr (addr)
"Convert an address to one suitable for MADR.
This works with Main RAM (all mappings) and for spad"
`(let ((int-addr (the-as int ,addr)))
(logior (logand #xfffffff int-addr) ;; mask off spad/mapping bits
(if (= (logand #x70000000 int-addr) #x70000000)
#x80000000 ;; if we're in spad, set high bit.
0 ;; otherwise nothing.
)
)
)
)
(defun dma-send ((arg0 dma-bank) (madr uint) (qwc uint))
"Send DMA! madr can be a scratchpad address.
Like dma-send-no-scratch, this sets chcr to zero, which may be undesirable."
"Send DMA given an address and a quadword count.
The madr can be in main memory or scratchpad.
This is appropriate for VIF0/GIF transfers.
It can be used for VIF1, but will do VIF -> madr, which is probably
not what you want."
(dma-sync (the-as pointer arg0) 0 0)
(flush-cache 0)
(.sync.l)
(set! (-> arg0 madr)
(logior (logand #xfffffff (the-as int madr)) ;; lower 28 bits are untouched
;; if we are transferring to the scratchpad (at 70000000)
;; we should set bit 31 in madr, per the manual.
(if (= (logand #x70000000 (the-as int madr)) #x70000000)
(shl #x8000 16) ;; set bit 31
0)
)
)
(set! (-> arg0 madr) (make-madr-addr madr))
(set! (-> arg0 qwc) qwc)
(.sync.l)
;; set str!
;; begin DMA!
(set! (-> arg0 chcr) (new 'static 'dma-chcr :str 1))
(.sync.l)
(none)
)
(defun dma-send-chain ((arg0 dma-bank-source) (tadr uint))
"Send DMA! tadr should be a tag address, possibly in spad ram."
"Send DMA! tadr should be a tag address, possibly in spad ram.
This is useful for sending to VIF.
Tag transfer is enabled, and DIR is set so a VIF1 transfer
goes from tadr -> VIF."
(dma-sync (the-as pointer arg0) 0 0)
(flush-cache 0)
(.sync.l)
(set! (-> arg0 qwc) 0)
;; adjust address
(set! (-> arg0 tadr)
(logior (logand #xfffffff (the-as int tadr))
(if (= (logand #x70000000 (the-as int tadr)) #x70000000)
(shl #x8000 16)
0)
)
)
(set! (-> arg0 tadr) (make-madr-addr tadr))
(.sync.l)
;;(set! (-> arg0 chcr) 325)
(set! (-> arg0 chcr)
@@ -105,21 +112,13 @@
)
(defun dma-send-chain-no-tte ((arg0 dma-bank-source) (arg1 uint))
"Send DMA chain! TTE bit is not set, don't transfer tags."
"Send DMA chain! TTE bit is not set, don't transfer tags.
This is never used."
(dma-sync (the-as pointer arg0) 0 0)
(flush-cache 0)
(.sync.l)
(set! (-> arg0 qwc) 0)
(set!
(-> arg0 tadr)
(logior
(logand #xfffffff (the-as int arg1))
(the-as
uint
(if (= (logand #x70000000 (the-as int arg1)) #x70000000) (shl #x8000 16) 0)
)
)
)
(set! (-> arg0 tadr) (make-madr-addr arg1))
(.sync.l)
(set! (-> arg0 chcr)
(new 'static 'dma-chcr
@@ -138,16 +137,7 @@
(dma-sync (the-as pointer arg0) 0 0)
(.sync.l)
(set! (-> arg0 qwc) 0)
(set!
(-> arg0 tadr)
(logior
(logand #xfffffff (the-as int arg1))
(the-as
uint
(if (= (logand #x70000000 (the-as int arg1)) #x70000000) (shl #x8000 16) 0)
)
)
)
(set! (-> arg0 tadr) arg1)
(.sync.l)
;;(set! (-> arg0 chcr) 325)
(set! (-> arg0 chcr)
@@ -158,7 +148,6 @@
:str 1)
)
(.sync.l)
(set! v0-1 0)
(none)
)
@@ -232,49 +221,35 @@
(defun dma-initialize ()
"Due to a bug in the PS2 hardware, you must always disable the DMAtag mismatch
error. This is done here."
;; (declare (print-asm))
(#when PC_PORT
(format 0 "[dma.gc] skipping dma-initialize for PC port~%")
(return 0)
)
(set! (-> VIF0_BANK err)
(logior (logand (-> VIF0_BANK err) (the-as uint -3)) 2)
)
(set! (-> (the vif-bank #x10003c00) err)
(logior (logand (-> VIF1_BANK err) (the-as uint -3)) 2)
)
(set! (-> (the-as vif-bank #x10003800) err me0) 1)
(set! (-> (the-as vif-bank #x10003c00) err me0) 1)
(none)
)
(defun clear-vu0-mem ()
"Clear the data memory of VU0, filling it with abadbeef
This uses the slow memory mapping of VU0's data memory at 0x11004000"
(local-vars
(v1-0 (pointer uint32))
(a0-0 int)
)
(set! v1-0 (the (pointer uint32) #x11004000))
(set! a0-0 0)
(while (< a0-0 1024)
"Set the vu0 data memory to 0xabadbeef. This uses the slow EE mapping of VU memory."
(let ((v1-0 VU0_DATA_MEM_MAP))
(dotimes (a0-0 1024)
(set! (-> v1-0 a0-0) #xabadbeef)
(set! a0-0 (+ a0-0 1))
)
)
(none)
)
(defun clear-vu1-mem ()
"Clear the data memory of VU1, filling it with abadbeef
This uses the slow memory mapping of VU1's data memory at 0x1100C000"
(local-vars
(v1-0 (pointer uint32))
(a0-0 int)
)
(set! v1-0 (the (pointer uint32) #x1100c000))
(set! a0-0 0)
(while (< a0-0 4096)
"Set the vu1 data memory to 0xabadbeef. This uses the slow EE mapping of VU memory."
(let ((v1-0 VU1_DATA_MEM_MAP))
(dotimes (a0-0 4096)
(set! (-> v1-0 a0-0) #xabadbeef)
(set! a0-0 (+ a0-0 1))
)
)
(none)
)
+2
View File
@@ -10,6 +10,8 @@
(define EulNext (new 'static 'boxed-array int32 4 1 2 0 1))
;; just uses the same xyzw and data array as vector.
;; the w stores a float that should be an integer that seems to have
;; bitfields for... something? Like maybe the order?
(deftype euler-angles (vector)
()
:method-count-assert 9
+249
View File
@@ -5,3 +5,252 @@
;; name in dgo: euler
;; dgos: GAME, ENGINE
;; In general, the euler angle stuff is really inefficient. I don't think it's really used outside of
;; a few camera debugging functions.
(defun set-eul! ((arg0 euler-angles) (arg1 float) (arg2 float) (arg3 float) (arg4 int))
"Set the euler angles. The 4th argument is for flags."
(set! (-> arg0 data 0) arg1)
(set! (-> arg0 data 1) arg2)
(set! (-> arg0 data 2) arg3)
(set! (-> arg0 data 3) (the float arg4))
arg0
)
(defun eul->matrix ((arg0 matrix) (arg1 euler-angles))
"Convert euler angles to rotation matrix."
(matrix-identity! arg0)
(let ((s5-0 (new 'stack 'vector)))
;; copy to temp storage.
(set! (-> s5-0 quad) (-> arg1 quad))
(if (= (logand (the int (-> s5-0 data 3)) 1) 1)
(let ((f0-2 (-> s5-0 data 0)))
(set! (-> s5-0 data 0) (-> s5-0 data 2))
(set! (-> s5-0 data 2) f0-2)
)
)
(when (= (logand (sar (the int (-> s5-0 data 3)) 2) 1) 1)
(set! (-> s5-0 data 0) (- (-> s5-0 data 0)))
(set! (-> s5-0 data 1) (- (-> s5-0 data 1)))
(set! (-> s5-0 data 2) (- (-> s5-0 data 2)))
)
(let* ((f26-0 (cos (-> s5-0 data 0)))
(f30-0 (cos (-> s5-0 data 1)))
(f22-0 (cos (-> s5-0 data 2)))
(f24-0 (sin (-> s5-0 data 0)))
(f28-0 (sin (-> s5-0 data 1)))
(f4-0 (sin (-> s5-0 data 2)))
(f0-17 (* f26-0 f22-0))
(f1-1 (* f26-0 f4-0))
(f2-0 (* f24-0 f22-0))
(f3-0 (* f24-0 f4-0))
)
(let* ((v1-12 (logand (sar (the int (-> s5-0 data 3)) 2) 1))
(a1-2 (-> EulSafe (logand (sar (the int (-> s5-0 data 3)) 3) 3)))
(a0-21 (-> EulNext (+ a1-2 v1-12)))
(v1-17 (-> EulNext (+ (- 1 v1-12) a1-2)))
)
(cond
((= (logand (sar (the int (-> s5-0 data 3)) 1) 1) 1)
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl a1-2 2)) (the-as int arg0))))
f30-0
)
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl a0-21 2)) (the-as int arg0))))
(* f28-0 f24-0)
)
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl v1-17 2)) (the-as int arg0))))
(* f28-0 f26-0)
)
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl a1-2 2)) (the-as int arg0))))
(* f28-0 f4-0)
)
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl a0-21 2)) (the-as int arg0))))
(- f0-17 (* f30-0 f3-0))
)
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl v1-17 2)) (the-as int arg0))))
(- (- f2-0) (* f30-0 f1-1))
)
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl a1-2 2)) (the-as int arg0))))
(- (* f28-0 f22-0))
)
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl a0-21 2)) (the-as int arg0))))
(+ f1-1 (* f30-0 f2-0))
)
(let ((f0-19 (+ (- f3-0) (* f30-0 f0-17))))
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl v1-17 2)) (the-as int arg0))))
f0-19
)
)
)
(else
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl a1-2 2)) (the-as int arg0))))
(* f30-0 f22-0)
)
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl a0-21 2)) (the-as int arg0))))
(+ (- f1-1) (* f28-0 f2-0))
)
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl v1-17 2)) (the-as int arg0))))
(+ f3-0 (* f28-0 f0-17))
)
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl a1-2 2)) (the-as int arg0))))
(* f30-0 f4-0)
)
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl a0-21 2)) (the-as int arg0))))
(+ f0-17 (* f28-0 f3-0))
)
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl v1-17 2)) (the-as int arg0))))
(+ (- f2-0) (* f28-0 f1-1))
)
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl a1-2 2)) (the-as int arg0))))
(- f28-0)
)
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl a0-21 2)) (the-as int arg0))))
(* f30-0 f24-0)
)
(let ((f0-25 (* f30-0 f26-0)))
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl v1-17 2)) (the-as int arg0))))
f0-25
)
)
)
)
)
)
)
arg0
)
(defun matrix->eul ((arg0 euler-angles) (arg1 matrix) (arg2 int))
"Conver matrix to euler angles. Takes some weird flag for what kind of euler angles"
(let* ((v1-4 (logand (sar arg2 2) 1))
(s3-0 (-> EulSafe (logand (sar arg2 3) 3)))
(s2-0 (-> EulNext (+ s3-0 v1-4)))
(s1-0 (-> EulNext (+ (- 1 v1-4) s3-0)))
)
(if (= (logand (sar arg2 1) 1) 1)
(let* ((f0-0 (-> (the-as (pointer float) (+ (+ (shl s2-0 2) (shl s3-0 4)) (the-as int arg1)))))
(f0-2 (* f0-0 f0-0))
(f1-0 (-> (the-as (pointer float) (+ (+ (shl s1-0 2) (shl s3-0 4)) (the-as int arg1)))))
(f30-0 (sqrtf (+ f0-2 (* f1-0 f1-0))))
)
(cond
((< 0.00001 f30-0)
(set! (-> arg0 data 0)
(atan (-> (the-as (pointer float) (+ (+ (shl s2-0 2) (shl s3-0 4)) (the-as int arg1))))
(-> (the-as (pointer float) (+ (+ (shl s1-0 2) (shl s3-0 4)) (the-as int arg1))))
)
)
(set! (-> arg0 data 1)
(atan f30-0 (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1)))))
)
(let ((f0-13 (atan
(-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1))))
(- (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1)))))
)
)
)
(set! (-> arg0 data 2) f0-13)
)
)
(else
(set! (-> arg0 data 0)
(atan (- (-> (the-as (pointer float) (+ (+ (shl s1-0 2) (shl s2-0 4)) (the-as int arg1)))))
(-> (the-as (pointer float) (+ (+ (shl s2-0 2) (shl s2-0 4)) (the-as int arg1))))
)
)
(set! (-> arg0 data 1)
(atan
f30-0
(-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))))
)
)
(let ((f0-20 0.0))
(set! (-> arg0 data 2) f0-20)
)
)
)
)
(let* ((f0-21 (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1)))))
(f0-23 (* f0-21 f0-21))
(f1-3 (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1)))))
(f30-1 (sqrtf (+ f0-23 (* f1-3 f1-3))))
)
(cond
((< 0.00001 f30-1)
(set! (-> arg0 data 0)
(atan
(-> (the-as (pointer float) (+ (+ (shl s2-0 2) (shl s1-0 4)) (the-as int arg1))))
(-> (the-as (pointer float) (+ (+ (shl s1-0 2) (shl s1-0 4)) (the-as int arg1))))
)
)
(set! (-> arg0 data 1)
(atan
(- (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1)))))
f30-1
)
)
(let ((f0-34 (atan
(-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1))))
(-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))))
)
)
)
(set! (-> arg0 data 2) f0-34)
)
)
(else
(set! (-> arg0 data 0)
(atan
(- (-> (the-as (pointer float) (+ (+ (shl s1-0 2) (shl s2-0 4)) (the-as int arg1)))))
(-> (the-as (pointer float) (+ (+ (shl s2-0 2) (shl s2-0 4)) (the-as int arg1))))
)
)
(set! (-> arg0 data 1)
(atan
(- (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1)))))
f30-1
)
)
(let ((f0-42 0.0))
(set! (-> arg0 data 2) f0-42)
)
)
)
)
)
)
(when (= (logand (sar arg2 2) 1) 1)
(set! (-> arg0 data 0) (- (-> arg0 data 0)))
(set! (-> arg0 data 1) (- (-> arg0 data 1)))
(let ((f0-48 (- (-> arg0 data 2))))
(set! (-> arg0 data 2) f0-48)
)
)
(if (= (logand arg2 1) 1)
(let ((f0-49 (-> arg0 data 0)))
(set! (-> arg0 data 0) (-> arg0 data 2))
(set! (-> arg0 data 2) f0-49)
)
)
(set! (-> arg0 data 3) (the float arg2))
arg0
)
(defun eul->quat ((arg0 quaternion) (arg1 euler-angles))
"Convert euler angles to quaternion"
(let ((s5-0 (new 'stack 'matrix)))
(eul->matrix s5-0 arg1)
(matrix->quaternion arg0 s5-0)
)
arg0
)
(defun quat->eul ((arg0 euler-angles) (arg1 quaternion) (arg2 int))
"Convert quaternion to euler angles. The last argument is euler flags"
(let ((s5-0 (new 'stack 'matrix)))
(quaternion->matrix s5-0 arg1)
(matrix->eul arg0 s5-0 arg2)
)
arg0
)
+3
View File
@@ -686,3 +686,6 @@
(define-extern vector-length (function vector float))
(define-extern vector-xz-normalize! (function vector float vector))
(define-extern vector-xz-length (function vector float))
(defun-extern vector+float*! vector vector vector float vector)
(defun-extern vector-normalize! vector float vector)
(defun-extern vector-float*! vector vector float vector)
-26
View File
@@ -464,32 +464,6 @@
;; (.svf a0-0 vf1)
;; (ret-value v0-0)))
(defun vector-normalize! ((arg0 vector) (arg1 vector))
"TODO"
(local-vars (v1-0 vector))
(rlet ((acc :class vf)
(Q :class vf)
(vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
(vf3 :class vf))
(.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0))
(.lvf vf1 arg0)
(.mul.vf vf2 vf1 vf1 :mask #b1110)
(set! v1-0 arg1)
(.mov vf3 v1-0)
(.mul.x.vf acc vf0 vf2 :mask #b1)
(.add.mul.y.vf acc vf0 vf2 acc :mask #b1)
(.add.mul.z.vf vf2 vf0 vf2 acc :mask #b1)
(.isqrt.vf Q vf3 vf2 :ftf #b0 :fsf #b11)
(.wait.vf)
(.mul.vf vf1 vf1 Q :mask #b1110)
(.nop.vf)
(.nop.vf)
(.nop.vf)
(.svf arg0 vf1)
arg0))
(defun vector-vector-xz-distance-squared ((arg0 vector) (arg1 vector))
"TODO"
(local-vars (v0-0 int))
+1 -1
View File
@@ -68,7 +68,7 @@
(deftype vif-bank (structure)
((stat uint32 :offset-assert 0)
(fbrst uint32 :offset 16)
(err uint32 :offset 32)
(err vif-err :offset 32)
(mark uint32 :offset 48)
(cycle uint32 :offset 64)
(mode uint32 :offset 80)
+5
View File
@@ -177,6 +177,11 @@
`(/ 0 0)
)
(defmacro crash! ()
"Cause a crash by attempting to deference 0x0"
`(-> (the (pointer uint8) 0))
)
;;;;;;;;;;;;;;;;;;;
;; GOAL Syntax
;;;;;;;;;;;;;;;;;;;
@@ -118,6 +118,9 @@
(define-extern quaternion-from-two-vectors-max-angle! (function quaternion vector vector float quaternion))
(define-extern vector-xz-length (function vector float))
(defmacro .sync.l ()
`(none))
;; display-h
(deftype display-env (structure)
((pmode uint64 :offset-assert 0)
@@ -216,4 +219,4 @@
)
)
(define-extern *display* display)
(define-extern *display* display)
+312
View File
@@ -0,0 +1,312 @@
;;-*-Lisp-*-
(in-package goal)
;; definition of type dma-chcr
(deftype dma-chcr (uint32)
((dir uint8 :offset 0 :size 1)
(mod uint8 :offset 2 :size 2)
(asp uint8 :offset 4 :size 2)
(tte uint8 :offset 6 :size 1)
(tie uint8 :offset 7 :size 1)
(str uint8 :offset 8 :size 1)
(tag uint16 :offset 16 :size 16)
)
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition for method 3 of type dma-chcr
(defmethod inspect dma-chcr ((obj dma-chcr))
(format #t "[~8x] ~A~%" obj 'dma-chcr)
(format #t "~Tdir: ~D~%" (-> obj dir))
(format #t "~Tmod: ~D~%" (-> obj mod))
(format #t "~Tasp: ~D~%" (-> obj asp))
(format #t "~Ttte: ~D~%" (-> obj tte))
(format #t "~Ttie: ~D~%" (-> obj tie))
(format #t "~Tstr: ~D~%" (-> obj str))
(format #t "~Ttag: #x~X~%" (-> obj tag))
obj
)
;; definition of type dma-bank
(deftype dma-bank (structure)
((chcr dma-chcr :offset 0)
(madr uint32 :offset 16)
(qwc uint32 :offset 32)
)
:method-count-assert 9
:size-assert #x24
:flag-assert #x900000024
)
;; definition for method 3 of type dma-bank
(defmethod inspect dma-bank ((obj dma-bank))
(format #t "[~8x] ~A~%" obj 'dma-bank)
(format #t "~Tchcr: #x~X~%" (-> obj chcr))
(format #t "~Tmadr: #x~X~%" (-> obj madr))
(format #t "~Tqwc: #x~X~%" (-> obj qwc))
obj
)
;; definition of type dma-bank-source
(deftype dma-bank-source (dma-bank)
((tadr uint32 :offset 48)
)
:method-count-assert 9
:size-assert #x34
:flag-assert #x900000034
)
;; definition for method 3 of type dma-bank-source
(defmethod inspect dma-bank-source ((obj dma-bank-source))
(format #t "[~8x] ~A~%" obj 'dma-bank-source)
(format #t "~Tchcr: #x~X~%" (-> obj chcr))
(format #t "~Tmadr: #x~X~%" (-> obj madr))
(format #t "~Tqwc: #x~X~%" (-> obj qwc))
(format #t "~Ttadr: #x~X~%" (-> obj tadr))
obj
)
;; definition of type dma-bank-vif
(deftype dma-bank-vif (dma-bank-source)
((as0 uint32 :offset 64)
(as1 uint32 :offset 80)
)
:method-count-assert 9
:size-assert #x54
:flag-assert #x900000054
)
;; definition for method 3 of type dma-bank-vif
(defmethod inspect dma-bank-vif ((obj dma-bank-vif))
(format #t "[~8x] ~A~%" obj 'dma-bank-vif)
(format #t "~Tchcr: #x~X~%" (-> obj chcr))
(format #t "~Tmadr: #x~X~%" (-> obj madr))
(format #t "~Tqwc: #x~X~%" (-> obj qwc))
(format #t "~Ttadr: #x~X~%" (-> obj tadr))
(format #t "~Tas0: #x~X~%" (-> obj as0))
(format #t "~Tas1: #x~X~%" (-> obj as1))
obj
)
;; definition of type dma-bank-spr
(deftype dma-bank-spr (dma-bank-source)
((sadr uint32 :offset 128)
)
:method-count-assert 9
:size-assert #x84
:flag-assert #x900000084
)
;; definition for method 3 of type dma-bank-spr
(defmethod inspect dma-bank-spr ((obj dma-bank-spr))
(format #t "[~8x] ~A~%" obj 'dma-bank-spr)
(format #t "~Tchcr: #x~X~%" (-> obj chcr))
(format #t "~Tmadr: #x~X~%" (-> obj madr))
(format #t "~Tqwc: #x~X~%" (-> obj qwc))
(format #t "~Ttadr: #x~X~%" (-> obj tadr))
(format #t "~Tsadr: #x~X~%" (-> obj sadr))
obj
)
;; definition of type dma-ctrl
(deftype dma-ctrl (uint32)
()
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition of type dma-enable
(deftype dma-enable (uint32)
()
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition of type dma-sqwc
(deftype dma-sqwc (uint32)
()
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition of type dma-bank-control
(deftype dma-bank-control (structure)
((ctrl dma-ctrl :offset 0)
(stat uint32 :offset 16)
(pcr uint32 :offset 32)
(sqwc dma-sqwc :offset 48)
(rbsr uint32 :offset 64)
(rbor uint32 :offset 80)
(stadr uint32 :offset 96)
(enabler uint32 :offset 5408)
(enablew uint32 :offset 5520)
)
:method-count-assert 9
:size-assert #x1594
:flag-assert #x900001594
)
;; definition for method 3 of type dma-bank-control
(defmethod inspect dma-bank-control ((obj dma-bank-control))
(format #t "[~8x] ~A~%" obj 'dma-bank-control)
(format #t "~Tctrl: #x~X~%" (-> obj ctrl))
(format #t "~Tstat: #x~X~%" (-> obj stat))
(format #t "~Tpcr: #x~X~%" (-> obj pcr))
(format #t "~Tsqwc: #x~X~%" (-> obj sqwc))
(format #t "~Trbsr: #x~X~%" (-> obj rbsr))
(format #t "~Trbor: #x~X~%" (-> obj rbor))
(format #t "~Tstadr: #x~X~%" (-> obj stadr))
(format #t "~Tenabler: ~D~%" (-> obj enabler))
(format #t "~Tenablew: ~D~%" (-> obj enablew))
obj
)
;; definition of type vu-code-block
(deftype vu-code-block (basic)
((name basic :offset-assert 4)
(code uint32 :offset-assert 8)
(size int32 :offset-assert 12)
(dest-address uint32 :offset-assert 16)
)
:method-count-assert 9
:size-assert #x14
:flag-assert #x900000014
)
;; definition for method 3 of type vu-code-block
(defmethod inspect vu-code-block ((obj vu-code-block))
(format #t "[~8x] ~A~%" obj (-> obj type))
(format #t "~Tname: ~A~%" (-> obj name))
(format #t "~Tcode: #x~X~%" (-> obj code))
(format #t "~Tsize: ~D~%" (-> obj size))
(format #t "~Tdest-address: ~D~%" (-> obj dest-address))
obj
)
;; definition of type vu-stat
(deftype vu-stat (uint64)
()
:method-count-assert 9
:size-assert #x8
:flag-assert #x900000008
)
;; definition of type dma-tag
(deftype dma-tag (uint64)
((qwc uint16 :offset 0 :size 16)
(pce uint8 :offset 26 :size 2)
(id uint8 :offset 28 :size 3)
(irq uint8 :offset 31 :size 1)
(addr uint32 :offset 32 :size 31)
(spr uint8 :offset 63 :size 1)
)
:method-count-assert 9
:size-assert #x8
:flag-assert #x900000008
)
;; definition for method 3 of type dma-tag
(defmethod inspect dma-tag ((obj dma-tag))
(format #t "[~8x] ~A~%" obj 'dma-tag)
(format #t "~Tqwc: ~D~%" (-> obj qwc))
(format #t "~Tpce: ~D~%" (-> obj pce))
(format #t "~Tid: ~D~%" (-> obj id))
(format #t "~Tirq: ~D~%" (-> obj irq))
(format #t "~Taddr: #x~X~%" (-> obj addr))
(format #t "~Tspr: ~D~%" (-> obj spr))
obj
)
;; definition of type dma-bucket
(deftype dma-bucket (structure)
((tag dma-tag :offset-assert 0)
(last (pointer uint64) :offset-assert 8)
(dummy uint32 :offset-assert 12)
(next uint32 :offset 4)
)
:method-count-assert 9
:size-assert #x10
:flag-assert #x900000010
)
;; definition for method 3 of type dma-bucket
(defmethod inspect dma-bucket ((obj dma-bucket))
(format #t "[~8x] ~A~%" obj 'dma-bucket)
(format #t "~Ttag: ~D~%" (-> obj tag))
(format #t "~Tlast: #x~X~%" (-> obj last))
(format #t "~Tdummy: ~D~%" (-> obj dummy))
(format #t "~Tnext: #x~X~%" (-> obj next))
obj
)
;; definition of type vif-mask
(deftype vif-mask (uint32)
()
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition of type vif-stcycl-imm
(deftype vif-stcycl-imm (uint16)
()
:method-count-assert 9
:size-assert #x2
:flag-assert #x900000002
)
;; definition of type vif-unpack-imm
(deftype vif-unpack-imm (uint16)
()
:method-count-assert 9
:size-assert #x2
:flag-assert #x900000002
)
;; definition of type vif-tag
(deftype vif-tag (uint32)
((imm uint16 :offset 0 :size 16)
(num uint8 :offset 16 :size 8)
(cmd uint8 :offset 24 :size 7)
(msk uint8 :offset 28 :size 1)
(irq uint8 :offset 31 :size 1)
)
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition for method 3 of type vif-tag
(defmethod inspect vif-tag ((obj vif-tag))
(format #t "[~8x] ~A~%" obj 'vif-tag)
(format #t "~Timm: #x~X~%" (-> obj imm))
(format #t "~Tnum: ~D~%" (-> obj num))
(format #t "~Tcmd: #x~X~%" (-> obj cmd))
(format #t "~Tmsk: ~D~%" (-> obj msk))
(format #t "~Tirq: ~D~%" (-> obj irq))
obj
)
;; definition for function dma-sync-fast
;; ERROR: function was not converted to expressions. Cannot decompile.
;; definition for function dma-send-no-scratch
;; ERROR: function was not converted to expressions. Cannot decompile.
;; definition for function dma-sync-with-count
;; ERROR: function was not converted to expressions. Cannot decompile.
;; definition for function dma-count-until-done
;; ERROR: function was not converted to expressions. Cannot decompile.
;; failed to figure out what this is:
(none)
+419
View File
@@ -0,0 +1,419 @@
;;-*-Lisp-*-
(in-package goal)
;; definition for function dma-sync-hang
;; ERROR: function was not converted to expressions. Cannot decompile.
;; definition for function dma-sync-crash
;; INFO: Return type mismatch int vs none.
(defun dma-sync-crash ((arg0 dma-bank))
(let ((v1-0 #x4c4b40))
(while (nonzero? (-> arg0 chcr str))
(cond
((zero? v1-0)
(crash!)
(let ((a1-0 0))
)
)
(else
(+! v1-0 -1)
)
)
)
)
(let ((v0-0 0))
)
(none)
)
;; definition for function dma-send
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun dma-send ((arg0 dma-bank) (arg1 uint) (arg2 uint))
(dma-sync (the-as pointer arg0) 0 0)
(flush-cache 0)
(.sync.l)
(set!
(-> arg0 madr)
(logior
(logand #xfffffff (the-as int arg1))
(the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)
(shl #x8000 16)
0
)
)
)
)
(set! (-> arg0 qwc) arg2)
(.sync.l)
(set! (-> arg0 chcr) (new 'static 'dma-chcr :str #x1))
(.sync.l)
(let ((v0-1 0))
)
(none)
)
;; definition for function dma-send-chain
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun dma-send-chain ((arg0 dma-bank-source) (arg1 uint))
(dma-sync (the-as pointer arg0) 0 0)
(flush-cache 0)
(.sync.l)
(set! (-> arg0 qwc) (the-as uint 0))
(set!
(-> arg0 tadr)
(logior
(logand #xfffffff (the-as int arg1))
(the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)
(shl #x8000 16)
0
)
)
)
)
(.sync.l)
(set!
(-> arg0 chcr)
(new 'static 'dma-chcr :dir #x1 :mod #x1 :tte #x1 :str #x1)
)
(.sync.l)
(let ((v0-1 0))
)
(none)
)
;; definition for function dma-send-chain-no-tte
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun dma-send-chain-no-tte ((arg0 dma-bank-source) (arg1 uint))
(dma-sync (the-as pointer arg0) 0 0)
(flush-cache 0)
(.sync.l)
(set! (-> arg0 qwc) (the-as uint 0))
(set!
(-> arg0 tadr)
(logior
(logand #xfffffff (the-as int arg1))
(the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)
(shl #x8000 16)
0
)
)
)
)
(.sync.l)
(set! (-> arg0 chcr) (new 'static 'dma-chcr :dir #x1 :mod #x1 :str #x1))
(.sync.l)
(let ((v0-1 0))
)
(none)
)
;; definition for function dma-send-chain-no-flush
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun dma-send-chain-no-flush ((arg0 dma-bank-source) (arg1 uint))
(dma-sync (the-as pointer arg0) 0 0)
(.sync.l)
(set! (-> arg0 qwc) (the-as uint 0))
(set!
(-> arg0 tadr)
(logior
(logand #xfffffff (the-as int arg1))
(the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)
(shl #x8000 16)
0
)
)
)
)
(.sync.l)
(set!
(-> arg0 chcr)
(new 'static 'dma-chcr :dir #x1 :mod #x1 :tte #x1 :str #x1)
)
(.sync.l)
(let ((v0-1 0))
)
(none)
)
;; definition for function dma-send-to-spr
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun dma-send-to-spr ((sadr uint) (madr uint) (qwc uint) (sync symbol))
(let ((s5-0 (the-as dma-bank-spr #x1000d400)))
(dma-sync (the-as pointer s5-0) 0 0)
(flush-cache 0)
(.sync.l)
(set! (-> s5-0 madr) (logand #xfffffff (the-as int madr)))
(set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr)))
(set! (-> s5-0 qwc) qwc)
(.sync.l)
(set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1))
(.sync.l)
(if sync
(dma-sync (the-as pointer s5-0) 0 0)
)
)
(let ((v0-2 0))
)
(none)
)
;; definition for function dma-send-to-spr-no-flush
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun
dma-send-to-spr-no-flush
((sadr uint) (madr uint) (qwc uint) (sync symbol))
(let ((s5-0 (the-as dma-bank-spr #x1000d400)))
(dma-sync (the-as pointer s5-0) 0 0)
(.sync.l)
(set! (-> s5-0 madr) (logand #xfffffff (the-as int madr)))
(set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr)))
(set! (-> s5-0 qwc) qwc)
(.sync.l)
(set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1))
(.sync.l)
(if sync
(dma-sync (the-as pointer s5-0) 0 0)
)
)
(let ((v0-2 0))
)
(none)
)
;; definition for function dma-send-from-spr
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun dma-send-from-spr ((madr uint) (sadr uint) (qwc uint) (sync symbol))
(let ((s5-0 (the-as dma-bank-spr #x1000d000)))
(dma-sync (the-as pointer s5-0) 0 0)
(flush-cache 0)
(.sync.l)
(set! (-> s5-0 madr) (logand #xfffffff (the-as int madr)))
(set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr)))
(set! (-> s5-0 qwc) qwc)
(.sync.l)
(set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1))
(.sync.l)
(if sync
(dma-sync (the-as pointer s5-0) 0 0)
)
)
(let ((v0-2 0))
)
(none)
)
;; definition for function dma-send-from-spr-no-flush
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun
dma-send-from-spr-no-flush
((madr uint) (sadr uint) (qwc uint) (sync symbol))
(let ((s5-0 (the-as dma-bank-spr #x1000d000)))
(dma-sync (the-as pointer s5-0) 0 0)
(.sync.l)
(set! (-> s5-0 madr) (logand #xfffffff (the-as int madr)))
(set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr)))
(set! (-> s5-0 qwc) qwc)
(.sync.l)
(set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1))
(.sync.l)
(if sync
(dma-sync (the-as pointer s5-0) 0 0)
)
)
(let ((v0-2 0))
)
(none)
)
;; definition for function dma-initialize
;; INFO: Return type mismatch int vs none.
(defun dma-initialize ()
(set! (-> (the-as vif-bank #x10003800) err me0) 1)
(set! (-> (the-as vif-bank #x10003c00) err me0) 1)
(let ((v0-0 0))
)
(none)
)
;; definition for function clear-vu0-mem
;; INFO: Return type mismatch int vs none.
(defun clear-vu0-mem ()
(let ((v1-0 (the-as (pointer uint32) #x11004000)))
(dotimes (a0-0 1024)
(set! (-> v1-0 a0-0) #xabadbeef)
)
)
(let ((v0-0 0))
)
(none)
)
;; definition for function clear-vu1-mem
;; INFO: Return type mismatch int vs none.
(defun clear-vu1-mem ()
(let ((v1-0 (the-as (pointer uint32) #x1100c000)))
(dotimes (a0-0 4096)
(set! (-> v1-0 a0-0) #xabadbeef)
)
)
(let ((v0-0 0))
)
(none)
)
;; definition for function dump-vu1-mem
;; INFO: Return type mismatch symbol vs none.
(defun dump-vu1-mem ()
(let ((gp-0 (the-as (pointer uint32) #x1100c000)))
(dotimes (s5-0 1024)
(format
0
"~4,'0X: ~8,'0X ~8,'0X ~8,'0X ~8,'0X"
s5-0
(-> gp-0 (shl s5-0 2))
(-> gp-0 (+ (shl s5-0 2) 1))
(-> gp-0 (+ (shl s5-0 2) 2))
(-> gp-0 (+ (shl s5-0 2) 3))
)
(format
0
" ~F ~F ~F ~F ~%"
(-> gp-0 (shl s5-0 2))
(-> gp-0 (+ (shl s5-0 2) 1))
(-> gp-0 (+ (shl s5-0 2) 2))
(-> gp-0 (+ (shl s5-0 2) 3))
)
)
)
(none)
)
;; definition for function dump-vu1-range
(defun dump-vu1-range ((start uint) (total-count uint))
(let ((s4-0 (the-as (pointer uint32) #x1100c000)))
(dotimes (s3-0 (the-as int total-count))
(let ((s2-0 (+ s3-0 (the-as int start))))
(format
0
"~4,'0X: ~8x ~8x ~8x ~8x"
s2-0
(-> s4-0 (shl s2-0 2))
(-> s4-0 (+ (shl s2-0 2) 1))
(-> s4-0 (+ (shl s2-0 2) 2))
(-> s4-0 (+ (shl s2-0 2) 3))
)
(format
0
" ~F ~F ~F ~F ~%"
(-> s4-0 (shl s2-0 2))
(-> s4-0 (+ (shl s2-0 2) 1))
(-> s4-0 (+ (shl s2-0 2) 2))
(-> s4-0 (+ (shl s2-0 2) 3))
)
)
)
)
#f
)
;; definition for symbol *video-reset-parm*, type int
(define *video-reset-parm* 2)
;; definition for function reset-vif1-path
;; INFO: Return type mismatch int vs none.
(defun reset-vif1-path ()
((method-of-type dma-bank-vif inspect) (the-as dma-bank-vif #x10009000))
((method-of-type vif-bank inspect) (the-as vif-bank #x10003c00))
(reset-path)
(reset-graph 1 1 *video-reset-parm* 1)
(format 0 "gkernel: vif1 path reset!~%")
(let ((v0-3 0))
)
(none)
)
;; definition for function ultimate-memcpy
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun ultimate-memcpy ((dst pointer) (src pointer) (size-bytes uint))
(let ((spr-to-bank (the-as dma-bank-spr #x1000d400))
(spr-from-bank (the-as dma-bank-spr #x1000d000))
(qwc-remaining (shr size-bytes 4))
)
(flush-cache 0)
(dma-sync (the-as pointer spr-to-bank) 0 0)
(dma-sync (the-as pointer spr-from-bank) 0 0)
(while (> qwc-remaining 0)
(let ((qwc-transferred-now (the-as int qwc-remaining)))
(if (< (the-as uint 1024) (the-as uint qwc-transferred-now))
(set! qwc-transferred-now 1024)
)
(set! qwc-remaining (- qwc-remaining (the-as uint qwc-transferred-now)))
(.sync.l)
(set! (-> spr-to-bank madr) (the-as uint src))
(set! (-> spr-to-bank sadr) (the-as uint 0))
(set! (-> spr-to-bank qwc) (the-as uint qwc-transferred-now))
(.sync.l)
(set! (-> spr-to-bank chcr) (new 'static 'dma-chcr :str #x1))
(.sync.l)
(dma-sync (the-as pointer spr-to-bank) 0 0)
(&+! src (shl qwc-transferred-now 4))
(set! (-> spr-from-bank madr) (the-as uint dst))
(set! (-> spr-from-bank sadr) (the-as uint 0))
(set! (-> spr-from-bank qwc) (the-as uint qwc-transferred-now))
(.sync.l)
(set! (-> spr-from-bank chcr) (new 'static 'dma-chcr :str #x1))
(.sync.l)
(dma-sync (the-as pointer spr-from-bank) 0 0)
(&+! dst (shl qwc-transferred-now 4))
)
)
)
(let ((v0-4 0))
)
(none)
)
;; definition for function symlink2
;; ERROR: function was not converted to expressions. Cannot decompile.
;; definition for function symlink3
;; ERROR: function was not converted to expressions. Cannot decompile.
;; failed to figure out what this is:
(dma-initialize)
;; failed to figure out what this is:
(none)
+516
View File
@@ -0,0 +1,516 @@
;;-*-Lisp-*-
(in-package goal)
;; definition for function set-eul!
(defun
set-eul!
((arg0 euler-angles) (arg1 float) (arg2 float) (arg3 float) (arg4 int))
(set! (-> arg0 data 0) arg1)
(set! (-> arg0 data 1) arg2)
(set! (-> arg0 data 2) arg3)
(set! (-> arg0 data 3) (the float arg4))
arg0
)
;; definition for function eul->matrix
;; Used lq/sq
(defun eul->matrix ((arg0 matrix) (arg1 euler-angles))
(matrix-identity! arg0)
(let ((s5-0 (new 'stack 'vector)))
(set! (-> s5-0 quad) (-> arg1 quad))
(if (= (logand (the int (-> s5-0 data 3)) 1) 1)
(let ((f0-2 (-> s5-0 data 0)))
(set! (-> s5-0 data 0) (-> s5-0 data 2))
(set! (-> s5-0 data 2) f0-2)
)
)
(when (= (logand (sar (the int (-> s5-0 data 3)) 2) 1) 1)
(set! (-> s5-0 data 0) (- (-> s5-0 data 0)))
(set! (-> s5-0 data 1) (- (-> s5-0 data 1)))
(let ((f0-10 (- (-> s5-0 data 2))))
(set! (-> s5-0 data 2) f0-10)
)
)
(let* ((f26-0 (cos (-> s5-0 data 0)))
(f30-0 (cos (-> s5-0 data 1)))
(f22-0 (cos (-> s5-0 data 2)))
(f24-0 (sin (-> s5-0 data 0)))
(f28-0 (sin (-> s5-0 data 1)))
(f4-0 (sin (-> s5-0 data 2)))
(f0-17 (* f26-0 f22-0))
(f1-1 (* f26-0 f4-0))
(f2-0 (* f24-0 f22-0))
(f3-0 (* f24-0 f4-0))
)
(let ((v1-7 0))
)
(let ((v1-8 0))
)
(let ((v1-9 0))
)
(let* ((v1-12 (logand (sar (the int (-> s5-0 data 3)) 2) 1))
(a1-2 (-> EulSafe (logand (sar (the int (-> s5-0 data 3)) 3) 3)))
(a0-21 (-> EulNext (+ a1-2 v1-12)))
(v1-17 (-> EulNext (+ (- 1 v1-12) a1-2)))
)
(cond
((= (logand (sar (the int (-> s5-0 data 3)) 1) 1) 1)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a1-2 4) (shl a1-2 2)) (the-as int arg0))
)
)
f30-0
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a1-2 4) (shl a0-21 2)) (the-as int arg0))
)
)
(* f28-0 f24-0)
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a1-2 4) (shl v1-17 2)) (the-as int arg0))
)
)
(* f28-0 f26-0)
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a0-21 4) (shl a1-2 2)) (the-as int arg0))
)
)
(* f28-0 f4-0)
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a0-21 4) (shl a0-21 2)) (the-as int arg0))
)
)
(- f0-17 (* f30-0 f3-0))
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a0-21 4) (shl v1-17 2)) (the-as int arg0))
)
)
(- (- f2-0) (* f30-0 f1-1))
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl v1-17 4) (shl a1-2 2)) (the-as int arg0))
)
)
(- (* f28-0 f22-0))
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl v1-17 4) (shl a0-21 2)) (the-as int arg0))
)
)
(+ f1-1 (* f30-0 f2-0))
)
(let ((f0-19 (+ (- f3-0) (* f30-0 f0-17))))
(set!
(->
(the-as
(pointer float)
(+ (+ (shl v1-17 4) (shl v1-17 2)) (the-as int arg0))
)
)
f0-19
)
)
)
(else
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a1-2 4) (shl a1-2 2)) (the-as int arg0))
)
)
(* f30-0 f22-0)
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a1-2 4) (shl a0-21 2)) (the-as int arg0))
)
)
(+ (- f1-1) (* f28-0 f2-0))
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a1-2 4) (shl v1-17 2)) (the-as int arg0))
)
)
(+ f3-0 (* f28-0 f0-17))
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a0-21 4) (shl a1-2 2)) (the-as int arg0))
)
)
(* f30-0 f4-0)
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a0-21 4) (shl a0-21 2)) (the-as int arg0))
)
)
(+ f0-17 (* f28-0 f3-0))
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl a0-21 4) (shl v1-17 2)) (the-as int arg0))
)
)
(+ (- f2-0) (* f28-0 f1-1))
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl v1-17 4) (shl a1-2 2)) (the-as int arg0))
)
)
(- f28-0)
)
(set!
(->
(the-as
(pointer float)
(+ (+ (shl v1-17 4) (shl a0-21 2)) (the-as int arg0))
)
)
(* f30-0 f24-0)
)
(let ((f0-25 (* f30-0 f26-0)))
(set!
(->
(the-as
(pointer float)
(+ (+ (shl v1-17 4) (shl v1-17 2)) (the-as int arg0))
)
)
f0-25
)
)
)
)
)
)
)
arg0
)
;; definition for function matrix->eul
(defun matrix->eul ((arg0 euler-angles) (arg1 matrix) (arg2 int))
(let ((v1-0 0))
)
(let ((v1-1 0))
)
(let ((v1-2 0))
)
(let* ((v1-4 (logand (sar arg2 2) 1))
(s3-0 (-> EulSafe (logand (sar arg2 3) 3)))
(s2-0 (-> EulNext (+ s3-0 v1-4)))
(s1-0 (-> EulNext (+ (- 1 v1-4) s3-0)))
)
(if (= (logand (sar arg2 1) 1) 1)
(let*
((f0-0
(->
(the-as
(pointer float)
(+ (+ (shl s2-0 2) (shl s3-0 4)) (the-as int arg1))
)
)
)
(f0-2 (* f0-0 f0-0))
(f1-0
(->
(the-as
(pointer float)
(+ (+ (shl s1-0 2) (shl s3-0 4)) (the-as int arg1))
)
)
)
(f30-0 (sqrtf (+ f0-2 (* f1-0 f1-0))))
)
(cond
((< 0.00001 f30-0)
(set!
(-> arg0 data 0)
(atan
(->
(the-as
(pointer float)
(+ (+ (shl s2-0 2) (shl s3-0 4)) (the-as int arg1))
)
)
(->
(the-as
(pointer float)
(+ (+ (shl s1-0 2) (shl s3-0 4)) (the-as int arg1))
)
)
)
)
(set!
(-> arg0 data 1)
(atan
f30-0
(->
(the-as
(pointer float)
(+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))
)
)
)
)
(let
((f0-13
(atan
(->
(the-as
(pointer float)
(+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1))
)
)
(-
(->
(the-as
(pointer float)
(+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1))
)
)
)
)
)
)
(set! (-> arg0 data 2) f0-13)
)
)
(else
(set!
(-> arg0 data 0)
(atan
(-
(->
(the-as
(pointer float)
(+ (+ (shl s1-0 2) (shl s2-0 4)) (the-as int arg1))
)
)
)
(->
(the-as
(pointer float)
(+ (+ (shl s2-0 2) (shl s2-0 4)) (the-as int arg1))
)
)
)
)
(set!
(-> arg0 data 1)
(atan
f30-0
(->
(the-as
(pointer float)
(+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))
)
)
)
)
(let ((f0-20 0.0))
(set! (-> arg0 data 2) f0-20)
)
)
)
)
(let*
((f0-21
(->
(the-as
(pointer float)
(+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))
)
)
)
(f0-23 (* f0-21 f0-21))
(f1-3
(->
(the-as
(pointer float)
(+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1))
)
)
)
(f30-1 (sqrtf (+ f0-23 (* f1-3 f1-3))))
)
(cond
((< 0.00001 f30-1)
(set!
(-> arg0 data 0)
(atan
(->
(the-as
(pointer float)
(+ (+ (shl s2-0 2) (shl s1-0 4)) (the-as int arg1))
)
)
(->
(the-as
(pointer float)
(+ (+ (shl s1-0 2) (shl s1-0 4)) (the-as int arg1))
)
)
)
)
(set!
(-> arg0 data 1)
(atan
(-
(->
(the-as
(pointer float)
(+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1))
)
)
)
f30-1
)
)
(let
((f0-34
(atan
(->
(the-as
(pointer float)
(+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1))
)
)
(->
(the-as
(pointer float)
(+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))
)
)
)
)
)
(set! (-> arg0 data 2) f0-34)
)
)
(else
(set!
(-> arg0 data 0)
(atan
(-
(->
(the-as
(pointer float)
(+ (+ (shl s1-0 2) (shl s2-0 4)) (the-as int arg1))
)
)
)
(->
(the-as
(pointer float)
(+ (+ (shl s2-0 2) (shl s2-0 4)) (the-as int arg1))
)
)
)
)
(set!
(-> arg0 data 1)
(atan
(-
(->
(the-as
(pointer float)
(+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1))
)
)
)
f30-1
)
)
(let ((f0-42 0.0))
(set! (-> arg0 data 2) f0-42)
)
)
)
)
)
)
(when (= (logand (sar arg2 2) 1) 1)
(set! (-> arg0 data 0) (- (-> arg0 data 0)))
(set! (-> arg0 data 1) (- (-> arg0 data 1)))
(let ((f0-48 (- (-> arg0 data 2))))
(set! (-> arg0 data 2) f0-48)
)
)
(if (= (logand arg2 1) 1)
(let ((f0-49 (-> arg0 data 0)))
(set! (-> arg0 data 0) (-> arg0 data 2))
(set! (-> arg0 data 2) f0-49)
)
)
(set! (-> arg0 data 3) (the float arg2))
arg0
)
;; definition for function eul->quat
(defun eul->quat ((arg0 quaternion) (arg1 euler-angles))
(let ((s5-0 (new 'stack 'matrix)))
(eul->matrix s5-0 arg1)
(matrix->quaternion arg0 s5-0)
)
arg0
)
;; definition for function quat->eul
(defun quat->eul ((arg0 euler-angles) (arg1 quaternion) (arg2 int))
(let ((s5-0 (new 'stack 'matrix)))
(quaternion->matrix s5-0 arg1)
(matrix->eul arg0 s5-0 arg2)
)
arg0
)
;; failed to figure out what this is:
(none)
+1 -1
View File
@@ -816,7 +816,7 @@
#t
"~T [~D] #x~X~%"
s5-8
(-> (the-as (pointer uint128) (+ (shl s5-8 4) (the-as int obj))))
(-> (the-as (array uint128) obj) s5-8)
)
)
)
+6 -6
View File
@@ -279,8 +279,8 @@
;; definition for method 3 of type handle
(defmethod inspect handle ((obj handle))
(format #t "[~8x] ~A~%" obj 'handle)
(format #t "~Tprocess: #x~X~%" (shr (shl (the-as int obj) 32) 32))
(format #t "~Tpid: ~D~%" (sar (the-as int obj) 32))
(format #t "~Tprocess: #x~X~%" (-> obj process))
(format #t "~Tpid: ~D~%" (-> obj pid))
obj
)
@@ -295,17 +295,17 @@
(a1-0 "#<handle :process ~A :pid ~D>")
(v1-0 obj)
)
(.subu a2-0 (the-as handle v1-0) s7-0)
(.subu a2-0 v1-0 s7-0)
(t9-0 a0-1 a1-0 (and (nonzero? a2-0) (begin
(.sllv a2-2 (the-as handle v1-0) r0-0)
(.sllv a2-2 v1-0 r0-0)
(let ((a3-0 (-> a2-2 0)))
(if (= (sar v1-0 32) (-> a3-0 pid))
(if (= (-> v1-0 pid) (-> a3-0 pid))
a3-0
)
)
)
)
(sar (the-as int obj) 32)
(-> obj pid)
)
)
(format #t "#<handle :process 0 :pid 0>")
+796
View File
@@ -0,0 +1,796 @@
;;-*-Lisp-*-
(in-package goal)
;; definition of type sound-id
(deftype sound-id (uint32)
()
:method-count-assert 10
:size-assert #x4
:flag-assert #xa00000004
(:methods
(dummy-9 () none 9)
)
)
;; definition of type sound-bank-id
(deftype sound-bank-id (uint32)
()
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition of type sound-name
(deftype sound-name (uint128)
()
:method-count-assert 9
:size-assert #x10
:flag-assert #x900000010
)
;; definition of type sound-rpc-cmd
(deftype sound-rpc-cmd (structure)
((rsvd1 uint16 :offset-assert 0)
(command uint16 :offset-assert 2)
)
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition for method 3 of type sound-rpc-cmd
(defmethod inspect sound-rpc-cmd ((obj sound-rpc-cmd))
(format #t "[~8x] ~A~%" obj 'sound-rpc-cmd)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
obj
)
;; definition of type sound-play-parms
(deftype sound-play-parms (structure)
((mask uint16 :offset-assert 0)
(pitch-mod int16 :offset-assert 2)
(bend int16 :offset-assert 4)
(fo-min int16 :offset-assert 6)
(fo-max int16 :offset-assert 8)
(fo-curve int8 :offset-assert 10)
(priority int8 :offset-assert 11)
(volume int32 :offset-assert 12)
(trans float 3 :offset-assert 16)
(group uint8 :offset-assert 28)
)
:pack-me
:method-count-assert 9
:size-assert #x1d
:flag-assert #x90000001d
)
;; definition for method 3 of type sound-play-parms
(defmethod inspect sound-play-parms ((obj sound-play-parms))
(format #t "[~8x] ~A~%" obj 'sound-play-parms)
(format #t "~Tmask: ~D~%" (-> obj mask))
(format #t "~Tpitch-mod: ~D~%" (-> obj pitch-mod))
(format #t "~Tbend: ~D~%" (-> obj bend))
(format #t "~Tfo-min: ~D~%" (-> obj fo-min))
(format #t "~Tfo-max: ~D~%" (-> obj fo-max))
(format #t "~Tfo-curve: ~D~%" (-> obj fo-curve))
(format #t "~Tpriority: ~D~%" (-> obj priority))
(format #t "~Tvolume: ~D~%" (-> obj volume))
(format #t "~Ttrans[3] @ #x~X~%" (-> obj trans))
(format #t "~Tgroup: ~D~%" (-> obj group))
obj
)
;; definition of type sound-rpc-bank-cmd
(deftype sound-rpc-bank-cmd (sound-rpc-cmd)
((bank-name uint128 :offset-assert 16)
)
:method-count-assert 9
:size-assert #x20
:flag-assert #x900000020
)
;; definition for method 3 of type sound-rpc-bank-cmd
;; Used lq/sq
(defmethod inspect sound-rpc-bank-cmd ((obj sound-rpc-bank-cmd))
(format #t "[~8x] ~A~%" obj 'sound-rpc-bank-cmd)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tbank-name: ~D~%" (-> obj bank-name))
obj
)
;; definition of type sound-rpc-sound-cmd
(deftype sound-rpc-sound-cmd (sound-rpc-cmd)
((id uint32 :offset-assert 4)
)
:method-count-assert 9
:size-assert #x8
:flag-assert #x900000008
)
;; definition for method 3 of type sound-rpc-sound-cmd
(defmethod inspect sound-rpc-sound-cmd ((obj sound-rpc-sound-cmd))
(format #t "[~8x] ~A~%" obj 'sound-rpc-sound-cmd)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tid: ~D~%" (-> obj id))
obj
)
;; definition of type sound-rpc-group-cmd
(deftype sound-rpc-group-cmd (sound-rpc-cmd)
((group uint8 :offset-assert 4)
)
:method-count-assert 9
:size-assert #x5
:flag-assert #x900000005
)
;; definition for method 3 of type sound-rpc-group-cmd
(defmethod inspect sound-rpc-group-cmd ((obj sound-rpc-group-cmd))
(format #t "[~8x] ~A~%" obj 'sound-rpc-group-cmd)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tgroup: ~D~%" (-> obj group))
obj
)
;; definition of type sound-rpc-load-bank
(deftype sound-rpc-load-bank (sound-rpc-bank-cmd)
()
:method-count-assert 9
:size-assert #x20
:flag-assert #x900000020
)
;; definition for method 3 of type sound-rpc-load-bank
;; Used lq/sq
(defmethod inspect sound-rpc-load-bank ((obj sound-rpc-load-bank))
(format #t "[~8x] ~A~%" obj 'sound-rpc-load-bank)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tbank-name: ~D~%" (-> obj bank-name))
obj
)
;; definition of type sound-rpc-load-music
(deftype sound-rpc-load-music (sound-rpc-bank-cmd)
()
:method-count-assert 9
:size-assert #x20
:flag-assert #x900000020
)
;; definition for method 3 of type sound-rpc-load-music
;; Used lq/sq
(defmethod inspect sound-rpc-load-music ((obj sound-rpc-load-music))
(format #t "[~8x] ~A~%" obj 'sound-rpc-load-music)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tbank-name: ~D~%" (-> obj bank-name))
obj
)
;; definition of type sound-rpc-unload-bank
(deftype sound-rpc-unload-bank (sound-rpc-bank-cmd)
()
:method-count-assert 9
:size-assert #x20
:flag-assert #x900000020
)
;; definition for method 3 of type sound-rpc-unload-bank
;; Used lq/sq
(defmethod inspect sound-rpc-unload-bank ((obj sound-rpc-unload-bank))
(format #t "[~8x] ~A~%" obj 'sound-rpc-unload-bank)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tbank-name: ~D~%" (-> obj bank-name))
obj
)
;; definition of type sound-rpc-play
(deftype sound-rpc-play (sound-rpc-sound-cmd)
((name uint128 :offset-assert 16)
(parms sound-play-parms :inline :offset-assert 32)
)
:method-count-assert 9
:size-assert #x3d
:flag-assert #x90000003d
)
;; definition for method 3 of type sound-rpc-play
;; Used lq/sq
(defmethod inspect sound-rpc-play ((obj sound-rpc-play))
(format #t "[~8x] ~A~%" obj 'sound-rpc-play)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tid: ~D~%" (-> obj id))
(format #t "~Tname: ~D~%" (-> obj name))
(format #t "~Tparms: #<sound-play-parms @ #x~X>~%" (-> obj parms))
obj
)
;; definition of type sound-rpc-pause-sound
(deftype sound-rpc-pause-sound (sound-rpc-sound-cmd)
()
:method-count-assert 9
:size-assert #x8
:flag-assert #x900000008
)
;; definition for method 3 of type sound-rpc-pause-sound
(defmethod inspect sound-rpc-pause-sound ((obj sound-rpc-pause-sound))
(format #t "[~8x] ~A~%" obj 'sound-rpc-pause-sound)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tid: ~D~%" (-> obj id))
obj
)
;; definition of type sound-rpc-stop-sound
(deftype sound-rpc-stop-sound (sound-rpc-sound-cmd)
()
:method-count-assert 9
:size-assert #x8
:flag-assert #x900000008
)
;; definition for method 3 of type sound-rpc-stop-sound
(defmethod inspect sound-rpc-stop-sound ((obj sound-rpc-stop-sound))
(format #t "[~8x] ~A~%" obj 'sound-rpc-stop-sound)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tid: ~D~%" (-> obj id))
obj
)
;; definition of type sound-rpc-continue-sound
(deftype sound-rpc-continue-sound (sound-rpc-sound-cmd)
()
:method-count-assert 9
:size-assert #x8
:flag-assert #x900000008
)
;; definition for method 3 of type sound-rpc-continue-sound
(defmethod inspect sound-rpc-continue-sound ((obj sound-rpc-continue-sound))
(format #t "[~8x] ~A~%" obj 'sound-rpc-continue-sound)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tid: ~D~%" (-> obj id))
obj
)
;; definition of type sound-rpc-set-param
(deftype sound-rpc-set-param (sound-rpc-sound-cmd)
((parms sound-play-parms :inline :offset-assert 8)
(auto-time int32 :offset-assert 40)
(auto-from int32 :offset-assert 44)
)
:method-count-assert 9
:size-assert #x30
:flag-assert #x900000030
)
;; definition for method 3 of type sound-rpc-set-param
(defmethod inspect sound-rpc-set-param ((obj sound-rpc-set-param))
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-param)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tid: ~D~%" (-> obj id))
(format #t "~Tparms: #<sound-play-parms @ #x~X>~%" (-> obj parms))
(format #t "~Tauto-time: ~D~%" (-> obj auto-time))
(format #t "~Tauto-from: ~D~%" (-> obj auto-from))
obj
)
;; definition of type sound-rpc-set-master-volume
(deftype sound-rpc-set-master-volume (sound-rpc-group-cmd)
((volume int32 :offset-assert 8)
)
:method-count-assert 9
:size-assert #xc
:flag-assert #x90000000c
)
;; definition for method 3 of type sound-rpc-set-master-volume
(defmethod
inspect
sound-rpc-set-master-volume
((obj sound-rpc-set-master-volume))
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-master-volume)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tgroup: ~D~%" (-> obj group))
(format #t "~Tvolume: ~D~%" (-> obj volume))
obj
)
;; definition of type sound-rpc-pause-group
(deftype sound-rpc-pause-group (sound-rpc-group-cmd)
()
:method-count-assert 9
:size-assert #x5
:flag-assert #x900000005
)
;; definition for method 3 of type sound-rpc-pause-group
(defmethod inspect sound-rpc-pause-group ((obj sound-rpc-pause-group))
(format #t "[~8x] ~A~%" obj 'sound-rpc-pause-group)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tgroup: ~D~%" (-> obj group))
obj
)
;; definition of type sound-rpc-stop-group
(deftype sound-rpc-stop-group (sound-rpc-group-cmd)
()
:method-count-assert 9
:size-assert #x5
:flag-assert #x900000005
)
;; definition for method 3 of type sound-rpc-stop-group
(defmethod inspect sound-rpc-stop-group ((obj sound-rpc-stop-group))
(format #t "[~8x] ~A~%" obj 'sound-rpc-stop-group)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tgroup: ~D~%" (-> obj group))
obj
)
;; definition of type sound-rpc-continue-group
(deftype sound-rpc-continue-group (sound-rpc-group-cmd)
()
:method-count-assert 9
:size-assert #x5
:flag-assert #x900000005
)
;; definition for method 3 of type sound-rpc-continue-group
(defmethod inspect sound-rpc-continue-group ((obj sound-rpc-continue-group))
(format #t "[~8x] ~A~%" obj 'sound-rpc-continue-group)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tgroup: ~D~%" (-> obj group))
obj
)
;; definition of type sound-rpc-get-irx-version
(deftype sound-rpc-get-irx-version (sound-rpc-cmd)
((major uint32 :offset-assert 4)
(minor uint32 :offset-assert 8)
(ee-addr uint32 :offset-assert 12)
)
:method-count-assert 9
:size-assert #x10
:flag-assert #x900000010
)
;; definition for method 3 of type sound-rpc-get-irx-version
(defmethod inspect sound-rpc-get-irx-version ((obj sound-rpc-get-irx-version))
(format #t "[~8x] ~A~%" obj 'sound-rpc-get-irx-version)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tmajor: ~D~%" (-> obj major))
(format #t "~Tminor: ~D~%" (-> obj minor))
(format #t "~Tee-addr: ~D~%" (-> obj ee-addr))
obj
)
;; definition of type sound-rpc-set-language
(deftype sound-rpc-set-language (sound-rpc-cmd)
((lang uint32 :offset-assert 4)
)
:method-count-assert 9
:size-assert #x8
:flag-assert #x900000008
)
;; definition for method 3 of type sound-rpc-set-language
(defmethod inspect sound-rpc-set-language ((obj sound-rpc-set-language))
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-language)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tlang: ~D~%" (-> obj lang))
obj
)
;; definition of type sound-rpc-set-falloff-curve
(deftype sound-rpc-set-falloff-curve (sound-rpc-cmd)
((curve int32 :offset-assert 4)
(falloff int32 :offset-assert 8)
(ease int32 :offset-assert 12)
)
:method-count-assert 9
:size-assert #x10
:flag-assert #x900000010
)
;; definition for method 3 of type sound-rpc-set-falloff-curve
(defmethod
inspect
sound-rpc-set-falloff-curve
((obj sound-rpc-set-falloff-curve))
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-falloff-curve)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tcurve: ~D~%" (-> obj curve))
(format #t "~Tfalloff: ~D~%" (-> obj falloff))
(format #t "~Tease: ~D~%" (-> obj ease))
obj
)
;; definition of type sound-rpc-set-sound-falloff
(deftype sound-rpc-set-sound-falloff (sound-rpc-cmd)
((name uint128 :offset-assert 16)
(curve int32 :offset-assert 32)
(min int32 :offset-assert 36)
(max int32 :offset-assert 40)
)
:method-count-assert 9
:size-assert #x2c
:flag-assert #x90000002c
)
;; definition for method 3 of type sound-rpc-set-sound-falloff
;; Used lq/sq
(defmethod
inspect
sound-rpc-set-sound-falloff
((obj sound-rpc-set-sound-falloff))
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-sound-falloff)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tname: ~D~%" (-> obj name))
(format #t "~Tcurve: ~D~%" (-> obj curve))
(format #t "~Tmin: ~D~%" (-> obj min))
(format #t "~Tmax: ~D~%" (-> obj max))
obj
)
;; definition of type sound-rpc-reload-info
(deftype sound-rpc-reload-info (sound-rpc-cmd)
()
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition for method 3 of type sound-rpc-reload-info
(defmethod inspect sound-rpc-reload-info ((obj sound-rpc-reload-info))
(format #t "[~8x] ~A~%" obj 'sound-rpc-reload-info)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
obj
)
;; definition of type sound-rpc-set-reverb
(deftype sound-rpc-set-reverb (sound-rpc-cmd)
((core uint8 :offset-assert 4)
(reverb int32 :offset-assert 8)
(left uint32 :offset-assert 12)
(right uint32 :offset-assert 16)
)
:method-count-assert 9
:size-assert #x14
:flag-assert #x900000014
)
;; definition for method 3 of type sound-rpc-set-reverb
(defmethod inspect sound-rpc-set-reverb ((obj sound-rpc-set-reverb))
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-reverb)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tcore: ~D~%" (-> obj core))
(format #t "~Treverb: ~D~%" (-> obj reverb))
(format #t "~Tleft: ~D~%" (-> obj left))
(format #t "~Tright: ~D~%" (-> obj right))
obj
)
;; definition of type sound-rpc-set-ear-trans
(deftype sound-rpc-set-ear-trans (sound-rpc-cmd)
((ear-trans float 3 :offset-assert 4)
(cam-trans float 3 :offset-assert 16)
(cam-angle int32 :offset-assert 28)
)
:method-count-assert 9
:size-assert #x20
:flag-assert #x900000020
)
;; definition for method 3 of type sound-rpc-set-ear-trans
(defmethod inspect sound-rpc-set-ear-trans ((obj sound-rpc-set-ear-trans))
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-ear-trans)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tear-trans[3] @ #x~X~%" (-> obj ear-trans))
(format #t "~Tcam-trans[3] @ #x~X~%" (-> obj cam-trans))
(format #t "~Tcam-angle: ~D~%" (-> obj cam-angle))
obj
)
;; definition of type sound-rpc-set-flava
(deftype sound-rpc-set-flava (sound-rpc-cmd)
((flava uint8 :offset-assert 4)
)
:method-count-assert 9
:size-assert #x5
:flag-assert #x900000005
)
;; definition for method 3 of type sound-rpc-set-flava
(defmethod inspect sound-rpc-set-flava ((obj sound-rpc-set-flava))
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-flava)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
(format #t "~Tflava: ~D~%" (-> obj flava))
obj
)
;; definition of type sound-rpc-shutdown
(deftype sound-rpc-shutdown (sound-rpc-cmd)
()
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition for method 3 of type sound-rpc-shutdown
(defmethod inspect sound-rpc-shutdown ((obj sound-rpc-shutdown))
(format #t "[~8x] ~A~%" obj 'sound-rpc-shutdown)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
obj
)
;; definition of type sound-rpc-list-sounds
(deftype sound-rpc-list-sounds (sound-rpc-cmd)
()
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition for method 3 of type sound-rpc-list-sounds
(defmethod inspect sound-rpc-list-sounds ((obj sound-rpc-list-sounds))
(format #t "[~8x] ~A~%" obj 'sound-rpc-list-sounds)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
obj
)
;; definition of type sound-rpc-unload-music
(deftype sound-rpc-unload-music (sound-rpc-cmd)
()
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition for method 3 of type sound-rpc-unload-music
(defmethod inspect sound-rpc-unload-music ((obj sound-rpc-unload-music))
(format #t "[~8x] ~A~%" obj 'sound-rpc-unload-music)
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
(format #t "~Tcommand: ~D~%" (-> obj command))
obj
)
;; definition of type sound-rpc-union
(deftype sound-rpc-union (structure)
((data uint32 20 :offset-assert 0)
(load-bank sound-rpc-load-bank :offset 0)
(unload-bank sound-rpc-unload-bank :offset 0)
(play sound-rpc-play :offset 0)
(pause-sound sound-rpc-pause-sound :offset 0)
(stop-sound sound-rpc-stop-sound :offset 0)
(continue-sound sound-rpc-continue-sound :offset 0)
(set-param sound-rpc-set-param :offset 0)
(set-master-volume sound-rpc-set-master-volume :offset 0)
(pause-group sound-rpc-pause-group :offset 0)
(stop-group sound-rpc-stop-group :offset 0)
(continue-group sound-rpc-continue-group :offset 0)
(get-irx-version sound-rpc-get-irx-version :offset 0)
(set-falloff-curve sound-rpc-set-falloff-curve :offset 0)
(set-sound-falloff sound-rpc-set-sound-falloff :offset 0)
(reload-info sound-rpc-reload-info :offset 0)
(set-language sound-rpc-set-language :offset 0)
(set-reverb sound-rpc-set-reverb :offset 0)
(set-ear-trans sound-rpc-set-ear-trans :offset 0)
(set-flava sound-rpc-set-flava :offset 0)
(shutdown sound-rpc-shutdown :offset 0)
(list-sounds sound-rpc-list-sounds :offset 0)
(unload-music sound-rpc-unload-music :offset 0)
)
:method-count-assert 9
:size-assert #x50
:flag-assert #x900000050
)
;; definition for method 3 of type sound-rpc-union
(defmethod inspect sound-rpc-union ((obj sound-rpc-union))
(format #t "[~8x] ~A~%" obj 'sound-rpc-union)
(format #t "~Tdata[20] @ #x~X~%" (-> obj data))
(format #t "~Tload-bank: #<sound-rpc-load-bank @ #x~X>~%" (-> obj data 0))
(format #t "~Tunload-bank: #<sound-rpc-unload-bank @ #x~X>~%" (-> obj data 0))
(format #t "~Tplay: #<sound-rpc-play @ #x~X>~%" (-> obj data 0))
(format #t "~Tpause-sound: #<sound-rpc-pause-sound @ #x~X>~%" (-> obj data 0))
(format #t "~Tstop-sound: #<sound-rpc-stop-sound @ #x~X>~%" (-> obj data 0))
(format
#t
"~Tcontinue-sound: #<sound-rpc-continue-sound @ #x~X>~%"
(-> obj data 0)
)
(format #t "~Tset-param: #<sound-rpc-set-param @ #x~X>~%" (-> obj data 0))
(format
#t
"~Tset-master-volume: #<sound-rpc-set-master-volume @ #x~X>~%"
(-> obj data 0)
)
(format #t "~Tpause-group: #<sound-rpc-pause-group @ #x~X>~%" (-> obj data 0))
(format #t "~Tstop-group: #<sound-rpc-stop-group @ #x~X>~%" (-> obj data 0))
(format
#t
"~Tcontinue-group: #<sound-rpc-continue-group @ #x~X>~%"
(-> obj data 0)
)
(format
#t
"~Tget-irx-version: #<sound-rpc-get-irx-version @ #x~X>~%"
(-> obj data 0)
)
(format
#t
"~Tset-falloff-curve: #<sound-rpc-set-falloff-curve @ #x~X>~%"
(-> obj data 0)
)
(format
#t
"~Tset-sound-falloff: #<sound-rpc-set-sound-falloff @ #x~X>~%"
(-> obj data 0)
)
(format #t "~Treload-info: #<sound-rpc-reload-info @ #x~X>~%" (-> obj data 0))
(format
#t
"~Tset-language: #<sound-rpc-set-language @ #x~X>~%"
(-> obj data 0)
)
(format #t "~Tset-reverb: #<sound-rpc-set-reverb @ #x~X>~%" (-> obj data 0))
(format
#t
"~Tset-ear-trans: #<sound-rpc-set-ear-trans @ #x~X>~%"
(-> obj data 0)
)
(format #t "~Tset-flava: #<sound-rpc-set-flava @ #x~X>~%" (-> obj data 0))
(format #t "~Tshutdown: #<sound-rpc-shutdown @ #x~X>~%" (-> obj data 0))
(format #t "~Tlist-sounds: #<sound-rpc-list-sounds @ #x~X>~%" (-> obj data 0))
(format
#t
"~Tunload-music: #<sound-rpc-unload-music @ #x~X>~%"
(-> obj data 0)
)
obj
)
;; definition of type sound-spec
(deftype sound-spec (basic)
((mask uint16 :offset-assert 4)
(num float :offset-assert 8)
(group uint8 :offset-assert 12)
(sound-name-char uint8 16 :offset 16)
(sound-name uint128 :offset 16)
(trans float 4 :offset-assert 32)
(volume int32 :offset-assert 48)
(pitch-mod int32 :offset-assert 52)
(bend int32 :offset-assert 56)
(fo-min int16 :offset-assert 60)
(fo-max int16 :offset-assert 62)
(fo-curve int8 :offset-assert 64)
(priority int8 :offset-assert 65)
(auto-time int32 :offset-assert 68)
(auto-from int32 :offset-assert 72)
)
:method-count-assert 9
:size-assert #x4c
:flag-assert #x90000004c
)
;; definition for method 3 of type sound-spec
;; Used lq/sq
(defmethod inspect sound-spec ((obj sound-spec))
(format #t "[~8x] ~A~%" obj (-> obj type))
(format #t "~Tmask: ~D~%" (-> obj mask))
(format #t "~Tnum: ~f~%" (-> obj num))
(format #t "~Tgroup: ~D~%" (-> obj group))
(format #t "~Tsound-name-char[16] @ #x~X~%" (-> obj sound-name-char))
(format #t "~Tsound-name: ~D~%" (-> obj sound-name))
(format #t "~Ttrans[4] @ #x~X~%" (-> obj trans))
(format #t "~Tvolume: ~D~%" (-> obj volume))
(format #t "~Tpitch-mod: ~D~%" (-> obj pitch-mod))
(format #t "~Tbend: ~D~%" (-> obj bend))
(format #t "~Tfo-min: ~D~%" (-> obj fo-min))
(format #t "~Tfo-max: ~D~%" (-> obj fo-max))
(format #t "~Tfo-curve: ~D~%" (-> obj fo-curve))
(format #t "~Tpriority: ~D~%" (-> obj priority))
(format #t "~Tauto-time: ~D~%" (-> obj auto-time))
(format #t "~Tauto-from: ~D~%" (-> obj auto-from))
obj
)
;; definition for symbol *current-sound-id*, type sound-id
(define *current-sound-id* (the-as sound-id #x10000))
;; definition of type ambient-sound
(deftype ambient-sound (basic)
((spec basic :offset-assert 4)
(playing-id uint32 :offset-assert 8)
(trans vector :inline :offset-assert 16)
(name uint128 :offset-assert 32)
(play-time uint64 :offset-assert 48)
(time-base uint64 :offset-assert 56)
(time-random uint64 :offset-assert 64)
(volume int32 :offset-assert 72)
(pitch int32 :offset-assert 76)
(falloff-near int32 :offset-assert 80)
(falloff-far int32 :offset-assert 84)
(falloff-mode int32 :offset-assert 88)
(params uint32 :offset-assert 92)
(param-count int32 :offset-assert 96)
(entity basic :offset-assert 100)
(sound-count int32 :offset-assert 104)
)
:method-count-assert 14
:size-assert #x6c
:flag-assert #xe0000006c
(:methods
(dummy-9 () none 9)
(dummy-10 () none 10)
(dummy-11 () none 11)
(dummy-12 () none 12)
(dummy-13 () none 13)
)
)
;; definition for method 3 of type ambient-sound
;; Used lq/sq
(defmethod inspect ambient-sound ((obj ambient-sound))
(format #t "[~8x] ~A~%" obj (-> obj type))
(format #t "~Tspec: ~A~%" (-> obj spec))
(format #t "~Tplaying-id: ~D~%" (-> obj playing-id))
(format #t "~Ttrans: ~`vector`P~%" (-> obj trans))
(format #t "~Tname: ~D~%" (-> obj name))
(format #t "~Tplay-time: ~D~%" (-> obj play-time))
(format #t "~Ttime-base: ~D~%" (-> obj time-base))
(format #t "~Ttime-random: ~D~%" (-> obj time-random))
(format #t "~Tvolume: ~D~%" (-> obj volume))
(format #t "~Tpitch: ~D~%" (-> obj pitch))
(format #t "~Tfalloff-near: ~D~%" (-> obj falloff-near))
(format #t "~Tfalloff-far: ~D~%" (-> obj falloff-far))
(format #t "~Tfalloff-mode: ~D~%" (-> obj falloff-mode))
(format #t "~Tparams: #x~X~%" (-> obj params))
(format #t "~Tparam-count: ~D~%" (-> obj param-count))
(format #t "~Tentity: ~A~%" (-> obj entity))
(format #t "~Tsound-count: ~D~%" (-> obj sound-count))
obj
)
;; definition for symbol *sound-bank-1*, type symbol
(define *sound-bank-1* #f)
;; definition for symbol *sound-bank-2*, type symbol
(define *sound-bank-2* #f)
;; failed to figure out what this is:
(let ((v0-34 0))
)
;; failed to figure out what this is:
(none)
+175
View File
@@ -0,0 +1,175 @@
;;-*-Lisp-*-
(in-package goal)
;; definition of type timer-mode
(deftype timer-mode (uint32)
((clks uint8 :offset 0 :size 2)
(gate uint8 :offset 2 :size 1)
(gats uint8 :offset 3 :size 1)
(gatm uint8 :offset 4 :size 2)
(zret uint8 :offset 6 :size 1)
(cue uint8 :offset 7 :size 1)
(cmpe uint8 :offset 8 :size 1)
(ovfe uint8 :offset 9 :size 1)
(equf uint8 :offset 10 :size 1)
(ovff uint8 :offset 11 :size 1)
)
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition of type timer-bank
(deftype timer-bank (structure)
((count uint32 :offset-assert 0)
(mode timer-mode :offset 16)
(comp uint32 :offset 32)
)
:method-count-assert 9
:size-assert #x24
:flag-assert #x900000024
)
;; definition for method 3 of type timer-bank
(defmethod inspect timer-bank ((obj timer-bank))
(format #t "[~8x] ~A~%" obj 'timer-bank)
(format #t "~Tcount: #x~X~%" (-> obj count))
(format #t "~Tmode: #x~X~%" (-> obj mode))
(format #t "~Tcomp: #x~X~%" (-> obj comp))
obj
)
;; definition of type timer-hold-bank
(deftype timer-hold-bank (timer-bank)
((hold uint32 :offset 48)
)
:method-count-assert 9
:size-assert #x34
:flag-assert #x900000034
)
;; definition for method 3 of type timer-hold-bank
(defmethod inspect timer-hold-bank ((obj timer-hold-bank))
(format #t "[~8x] ~A~%" obj 'timer-hold-bank)
(format #t "~Tcount: #x~X~%" (-> obj count))
(format #t "~Tmode: #x~X~%" (-> obj mode))
(format #t "~Tcomp: #x~X~%" (-> obj comp))
(format #t "~Thold: #x~X~%" (-> obj hold))
obj
)
;; definition of type stopwatch
(deftype stopwatch (basic)
((prev-time-elapsed uint64 :offset-assert 8)
(start-time uint64 :offset-assert 16)
(begin-level int32 :offset-assert 24)
)
:method-count-assert 9
:size-assert #x1c
:flag-assert #x90000001c
)
;; definition for method 3 of type stopwatch
(defmethod inspect stopwatch ((obj stopwatch))
(format #t "[~8x] ~A~%" obj (-> obj type))
(format #t "~Tprev-time-elapsed: ~D~%" (-> obj prev-time-elapsed))
(format #t "~Tstart-time: ~D~%" (-> obj start-time))
(format #t "~Tbegin-level: ~D~%" (-> obj begin-level))
obj
)
;; definition for symbol *ticks-per-frame*, type int
(define *ticks-per-frame* 9765)
;; definition for function timer-init
(defun timer-init ((arg0 timer-bank) (arg1 timer-mode))
(set! (-> arg0 mode) arg1)
(set! (-> arg0 count) (the-as uint 0))
0
)
;; failed to figure out what this is:
(timer-init (the-as timer-bank #x10000800) (the-as timer-mode 130))
;; definition of type profile-frame
(deftype profile-frame (structure)
((name basic :offset-assert 0)
(time-stamp uint32 :offset-assert 4)
(color uint32 :offset-assert 8)
(r uint8 :offset 8)
(g uint8 :offset 9)
(b uint8 :offset 10)
)
:method-count-assert 9
:size-assert #xc
:flag-assert #x90000000c
)
;; definition for method 3 of type profile-frame
;; INFO: this function exists in multiple non-identical object files
(defmethod inspect profile-frame ((obj profile-frame))
(format #t "[~8x] ~A~%" obj 'profile-frame)
(format #t "~Tname: ~A~%" (-> obj name))
(format #t "~Ttime-stamp: ~D~%" (-> obj time-stamp))
(format #t "~Tcolor: ~D~%" (-> obj color))
obj
)
;; definition for method 3 of type profile-frame
;; INFO: this function exists in multiple non-identical object files
(defmethod inspect profile-frame ((obj profile-frame))
(format #t "[~8x] profile-frame~%" obj)
(format #t "~Tname: ~A~%" (-> obj name))
(format #t "~Ttime-stamp: ~D~%" (-> obj time-stamp))
(format
#t
"~Tcolor: ~D ~D ~D~%"
(shr (shl (-> obj color) 56) 56)
(shr (shl (-> obj color) 48) 56)
(shr (shl (-> obj color) 40) 56)
)
obj
)
;; definition of type profile-bar
(deftype profile-bar (basic)
((profile-frame-count int32 :offset-assert 4)
(cache-time uint64 :offset-assert 8)
(data profile-frame 1024 :inline :offset-assert 16)
)
:method-count-assert 14
:size-assert #x4010
:flag-assert #xe00004010
(:methods
(get-last-frame-time-stamp (profile-bar) uint 9)
(dummy-10 () none 10)
(dummy-11 () none 11)
(dummy-12 () none 12)
(dummy-13 () none 13)
)
)
;; definition for method 3 of type profile-bar
(defmethod inspect profile-bar ((obj profile-bar))
(format #t "[~8x] ~A~%" obj (-> obj type))
(format #t "~Tprofile-frame-count: ~D~%" (-> obj profile-frame-count))
(format #t "~Tcache-time: ~D~%" (-> obj cache-time))
(format #t "~Tdata[1024] @ #x~X~%" (-> obj data))
obj
)
;; definition for method 9 of type profile-bar
(defmethod get-last-frame-time-stamp profile-bar ((obj profile-bar))
(-> obj data (+ (-> obj profile-frame-count) -2) time-stamp)
)
;; failed to figure out what this is:
(let ((v0-7 0))
)
;; failed to figure out what this is:
(none)
+179
View File
@@ -0,0 +1,179 @@
;;-*-Lisp-*-
(in-package goal)
;; definition for function timer-reset
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun timer-reset ((arg0 timer-bank))
(.sync.l)
(set! (-> arg0 count) (the-as uint 0))
(.sync.l)
(let ((v0-0 0))
)
(none)
)
;; definition for function timer-count
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun timer-count ((arg0 timer-bank))
(.sync.l)
(let ((v0-0 (-> arg0 count)))
(.sync.l)
v0-0
)
)
;; definition for function disable-irq
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v0, Status]
;; WARN: Unsupported inline assembly instruction kind - [mtc0 Status, v0]
;; WARN: Unsupported inline assembly instruction kind - [sync.p]
(defun disable-irq ()
(local-vars (v0-0 int))
(let ((v1-0 (l.d L21)))
(.mfc0 v0-0 Status)
(let ((v0-1 (logand v0-0 (the-as int v1-0))))
(.mtc0 Status v0-1)
)
)
(.sync.p)
(let ((v0-2 0))
)
(none)
)
;; definition for function enable-irq
;; INFO: Return type mismatch int vs none.
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v0, Status]
;; WARN: Unsupported inline assembly instruction kind - [mtc0 Status, v0]
;; WARN: Unsupported inline assembly instruction kind - [sync.p]
(defun enable-irq ()
(local-vars (v0-0 int))
(.mfc0 v0-0 Status)
(let ((v0-1 (logior v0-0 1)))
(.mtc0 Status v0-1)
)
(.sync.p)
(let ((v0-2 0))
)
(none)
)
;; definition for function stopwatch-init
(defun stopwatch-init ((arg0 stopwatch))
(set! (-> arg0 begin-level) 0)
(set! (-> arg0 prev-time-elapsed) (the-as uint 0))
0
)
;; definition for function stopwatch-reset
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
(defun stopwatch-reset ((arg0 stopwatch))
(local-vars (v1-3 int))
(set! (-> arg0 prev-time-elapsed) (the-as uint 0))
(when (> (-> arg0 begin-level) 0)
(let ((v1-2 0))
)
(.mfc0 v1-3 Count)
(set! (-> arg0 start-time) (the-as uint v1-3))
)
0
)
;; definition for function stopwatch-start
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
(defun stopwatch-start ((arg0 stopwatch))
(local-vars (v1-4 int))
(when (zero? (-> arg0 begin-level))
(set! (-> arg0 begin-level) 1)
(let ((v1-3 0))
)
(.mfc0 v1-4 Count)
(set! (-> arg0 start-time) (the-as uint v1-4))
)
0
)
;; definition for function stopwatch-stop
;; INFO: Return type mismatch int vs uint.
;; WARN: Unsupported inline assembly instruction kind - [mfc0 a1, Count]
(defun stopwatch-stop ((arg0 stopwatch))
(local-vars (a1-0 int))
(when (> (-> arg0 begin-level) 0)
(set! (-> arg0 begin-level) 0)
(let ((v1-2 0))
)
(.mfc0 a1-0 Count)
(set!
(-> arg0 prev-time-elapsed)
(+
(-> arg0 prev-time-elapsed)
(the-as uint (- a1-0 (the-as int (-> arg0 start-time))))
)
)
)
(the-as uint 0)
)
;; definition for function stopwatch-begin
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
(defun stopwatch-begin ((arg0 stopwatch))
(local-vars (v1-3 int))
(when (zero? (-> arg0 begin-level))
(let ((v1-2 0))
)
(.mfc0 v1-3 Count)
(set! (-> arg0 start-time) (the-as uint v1-3))
)
(set! (-> arg0 begin-level) (+ (-> arg0 begin-level) 1))
0
)
;; definition for function stopwatch-end
;; INFO: Return type mismatch int vs uint.
;; WARN: Unsupported inline assembly instruction kind - [mfc0 a1, Count]
(defun stopwatch-end ((arg0 stopwatch))
(local-vars (a1-0 int))
(set! (-> arg0 begin-level) (+ (-> arg0 begin-level) -1))
(when (zero? (-> arg0 begin-level))
(let ((v1-4 0))
)
(.mfc0 a1-0 Count)
(set!
(-> arg0 prev-time-elapsed)
(+
(-> arg0 prev-time-elapsed)
(the-as uint (- a1-0 (the-as int (-> arg0 start-time))))
)
)
)
(the-as uint 0)
)
;; definition for function stopwatch-elapsed-ticks
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
(defun stopwatch-elapsed-ticks ((arg0 stopwatch))
(local-vars (v1-3 int))
(let ((v0-0 (-> arg0 prev-time-elapsed)))
(when (> (-> arg0 begin-level) 0)
(let ((v1-2 0))
)
(.mfc0 v1-3 Count)
(+! v0-0 (the-as uint (- v1-3 (the-as int (-> arg0 start-time)))))
)
v0-0
)
)
;; definition for function stopwatch-elapsed-seconds
(defun stopwatch-elapsed-seconds ((arg0 stopwatch))
(let ((v1-0 (stopwatch-elapsed-ticks arg0)))
(* 0.0000000033333334 (the float v1-0))
)
)
;; failed to figure out what this is:
(none)
+84
View File
@@ -0,0 +1,84 @@
;;-*-Lisp-*-
(in-package goal)
;; definition of type video-parms
(deftype video-parms (structure)
((set-video-mode basic :offset-assert 0)
(reset-video-mode basic :offset-assert 4)
(screen-sy int32 :offset-assert 8)
(screen-hy int32 :offset-assert 12)
(screen-miny int32 :offset-assert 16)
(screen-maxy int32 :offset-assert 20)
(screen-masky int32 :offset-assert 24)
(display-dx int32 :offset-assert 28)
(display-dy int32 :offset-assert 32)
(screen-pages-high int32 :offset-assert 36)
(_pad int64 :offset-assert 40)
(relative-x-scale float :offset-assert 48)
(relative-y-scale float :offset-assert 52)
(_pad2 int64 :offset-assert 56)
(relative-x-scale-reciprical float :offset-assert 64)
(relative-y-scale-reciprical float :offset-assert 68)
)
:method-count-assert 9
:size-assert #x48
:flag-assert #x900000048
)
;; definition for method 3 of type video-parms
(defmethod inspect video-parms ((obj video-parms))
(format #t "[~8x] ~A~%" obj 'video-parms)
(format #t "~Tset-video-mode: ~A~%" (-> obj set-video-mode))
(format #t "~Treset-video-mode: ~A~%" (-> obj reset-video-mode))
(format #t "~Tscreen-sy: ~D~%" (-> obj screen-sy))
(format #t "~Tscreen-hy: ~D~%" (-> obj screen-hy))
(format #t "~Tscreen-miny: ~D~%" (-> obj screen-miny))
(format #t "~Tscreen-maxy: ~D~%" (-> obj screen-maxy))
(format #t "~Tscreen-masky: ~D~%" (-> obj screen-masky))
(format #t "~Tdisplay-dx: ~D~%" (-> obj display-dx))
(format #t "~Tdisplay-dy: ~D~%" (-> obj display-dy))
(format #t "~Tscreen-pages-high: ~D~%" (-> obj screen-pages-high))
(format #t "~Trelative-x-scale: ~f~%" (-> obj relative-x-scale))
(format #t "~Trelative-y-scale: ~f~%" (-> obj relative-y-scale))
(format
#t
"~Trelative-x-scale-reciprical: ~f~%"
(-> obj relative-x-scale-reciprical)
)
(format
#t
"~Trelative-y-scale-reciprical: ~f~%"
(-> obj relative-y-scale-reciprical)
)
obj
)
;; definition for symbol *video-parms*, type video-parms
(define
*video-parms*
(new 'static 'video-parms
:set-video-mode #f
:reset-video-mode #f
:screen-sy #xe0
:screen-hy #x70
:screen-miny #x720
:screen-maxy #x8e0
:screen-masky #xdf
:display-dy 8
:screen-pages-high 7
:relative-x-scale 1.0
:relative-y-scale 1.0
:relative-x-scale-reciprical 1.0
)
)
;; failed to figure out what this is:
(let ((v0-1 0))
)
;; failed to figure out what this is:
(none)
+128
View File
@@ -0,0 +1,128 @@
;;-*-Lisp-*-
(in-package goal)
;; definition of type vif-stat
(deftype vif-stat (uint32)
((vps uint8 :offset 0 :size 2)
(vew uint8 :offset 2 :size 1)
(mrk uint8 :offset 6 :size 1)
(vss uint8 :offset 8 :size 1)
(vfs uint8 :offset 9 :size 1)
(vis uint8 :offset 10 :size 1)
(int uint8 :offset 11 :size 1)
(er0 uint8 :offset 12 :size 1)
(er1 uint8 :offset 13 :size 1)
(fqc uint8 :offset 24 :size 4)
)
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition for method 3 of type vif-stat
(defmethod inspect vif-stat ((obj vif-stat))
(format #t "[~8x] ~A~%" obj 'vif-stat)
(format #t "~Tvps: ~D~%" (-> obj vps))
(format #t "~Tvew: ~D~%" (-> obj vew))
(format #t "~Tmrk: ~D~%" (-> obj mrk))
(format #t "~Tvss: ~D~%" (-> obj vss))
(format #t "~Tvfs: ~D~%" (-> obj vfs))
(format #t "~Tvis: ~D~%" (-> obj vis))
(format #t "~Tint: ~D~%" (-> obj int))
(format #t "~Ter0: ~D~%" (-> obj er0))
(format #t "~Ter1: ~D~%" (-> obj er1))
(format #t "~Tfqc: ~D~%" (-> obj fqc))
obj
)
;; definition of type vif-fbrst
(deftype vif-fbrst (uint32)
((rst uint8 :offset 0 :size 1)
(fbk uint8 :offset 1 :size 1)
(stp uint8 :offset 2 :size 1)
(stc uint8 :offset 3 :size 1)
)
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition of type vif-err
(deftype vif-err (uint32)
((mii uint8 :offset 0 :size 1)
(me0 uint8 :offset 1 :size 1)
(me1 uint8 :offset 2 :size 1)
)
:method-count-assert 9
:size-assert #x4
:flag-assert #x900000004
)
;; definition of type vif-bank
(deftype vif-bank (structure)
((stat uint32 :offset-assert 0)
(fbrst uint32 :offset 16)
(err vif-err :offset 32)
(mark uint32 :offset 48)
(cycle uint32 :offset 64)
(mode uint32 :offset 80)
(num uint32 :offset 96)
(mask uint32 :offset 112)
(code uint32 :offset 128)
(itops uint32 :offset 144)
(base uint32 :offset 160)
(offset uint32 :offset 176)
(tops uint32 :offset 192)
(itop uint32 :offset 208)
(top uint32 :offset 224)
(r0 uint32 :offset 256)
(r1 uint32 :offset 272)
(r2 uint32 :offset 288)
(r3 uint32 :offset 304)
(c0 uint32 :offset 320)
(c1 uint32 :offset 336)
(c2 uint32 :offset 352)
(c3 uint32 :offset 368)
)
:method-count-assert 9
:size-assert #x174
:flag-assert #x900000174
)
;; definition for method 3 of type vif-bank
(defmethod inspect vif-bank ((obj vif-bank))
(format #t "[~8x] ~A~%" obj 'vif-bank)
(format #t "~Tstat: #x~X~%" (-> obj stat))
(format #t "~Tfbrst: #x~X~%" (-> obj fbrst))
(format #t "~Terr: #x~X~%" (-> obj err))
(format #t "~Tmark: #x~X~%" (-> obj mark))
(format #t "~Tcycle: #x~X~%" (-> obj cycle))
(format #t "~Tmode: #x~X~%" (-> obj mode))
(format #t "~Tnum: #x~X~%" (-> obj num))
(format #t "~Tmask: #x~X~%" (-> obj mask))
(format #t "~Tcode: #x~X~%" (-> obj code))
(format #t "~Titops: #x~X~%" (-> obj itops))
(format #t "~Tbase: #x~X~%" (-> obj base))
(format #t "~Toffset: #x~X~%" (-> obj offset))
(format #t "~Ttops: #x~X~%" (-> obj tops))
(format #t "~Titop: #x~X~%" (-> obj itop))
(format #t "~Ttop: #x~X~%" (-> obj top))
(format #t "~Tr0: #x~X~%" (-> obj r0))
(format #t "~Tr1: #x~X~%" (-> obj r1))
(format #t "~Tr2: #x~X~%" (-> obj r2))
(format #t "~Tr3: #x~X~%" (-> obj r3))
(format #t "~Tc0: #x~X~%" (-> obj c0))
(format #t "~Tc1: #x~X~%" (-> obj c1))
(format #t "~Tc2: #x~X~%" (-> obj c2))
(format #t "~Tc3: #x~X~%" (-> obj c3))
obj
)
;; failed to figure out what this is:
(let ((v0-4 0))
)
;; failed to figure out what this is:
(none)
+121
View File
@@ -0,0 +1,121 @@
;;-*-Lisp-*-
(in-package goal)
;; definition for symbol *vu1-enable-user-menu*, type int
(define *vu1-enable-user-menu* #x1ffff8)
;; definition for symbol *vu1-enable-user*, type int
(define *vu1-enable-user* 0)
;; definition of type dma-foreground-sink
(deftype dma-foreground-sink (basic)
((bucket int32 :offset-assert 4)
(foreground-texture-page int8 :offset-assert 8)
(foreground-texture-level int8 :offset-assert 9)
(foreground-output-bucket int8 :offset-assert 10)
)
:method-count-assert 9
:size-assert #xb
:flag-assert #x90000000b
)
;; definition for method 3 of type dma-foreground-sink
(defmethod inspect dma-foreground-sink ((obj dma-foreground-sink))
(format #t "[~8x] ~A~%" obj (-> obj type))
(format #t "~Tbucket: ~D~%" (-> obj bucket))
(format #t "~Tforeground-texture-page: ~D~%" (-> obj foreground-texture-page))
(format
#t
"~Tforeground-texture-level: ~D~%"
(-> obj foreground-texture-level)
)
(format
#t
"~Tforeground-output-bucket: ~D~%"
(-> obj foreground-output-bucket)
)
obj
)
;; definition of type generic-bucket-state
(deftype generic-bucket-state (structure)
((gifbuf-adr uint32 :offset-assert 0)
(inbuf-adr uint32 :offset-assert 4)
)
:pack-me
:method-count-assert 9
:size-assert #x8
:flag-assert #x900000008
)
;; definition for method 3 of type generic-bucket-state
(defmethod inspect generic-bucket-state ((obj generic-bucket-state))
(format #t "[~8x] ~A~%" obj 'generic-bucket-state)
(format #t "~Tgifbuf-adr: ~D~%" (-> obj gifbuf-adr))
(format #t "~Tinbuf-adr: ~D~%" (-> obj inbuf-adr))
obj
)
;; definition of type generic-dma-foreground-sink
(deftype generic-dma-foreground-sink (dma-foreground-sink)
((state generic-bucket-state :inline :offset-assert 12)
)
:method-count-assert 9
:size-assert #x14
:flag-assert #x900000014
)
;; definition for method 3 of type generic-dma-foreground-sink
(defmethod
inspect
generic-dma-foreground-sink
((obj generic-dma-foreground-sink))
(format #t "[~8x] ~A~%" obj (-> obj type))
(format #t "~Tbucket: ~D~%" (-> obj bucket))
(format #t "~Tforeground-texture-page: ~D~%" (-> obj foreground-texture-page))
(format
#t
"~Tforeground-texture-level: ~D~%"
(-> obj foreground-texture-level)
)
(format
#t
"~Tforeground-output-bucket: ~D~%"
(-> obj foreground-output-bucket)
)
(format #t "~Tstate: #<generic-bucket-state @ #x~X>~%" (-> obj state))
obj
)
;; definition of type dma-foreground-sink-group
(deftype dma-foreground-sink-group (basic)
((sink dma-foreground-sink 3 :offset-assert 4)
(merc-sink dma-foreground-sink :offset 4)
(generic-sink generic-dma-foreground-sink :offset 8)
(level basic :offset-assert 16)
)
:method-count-assert 9
:size-assert #x14
:flag-assert #x900000014
)
;; definition for method 3 of type dma-foreground-sink-group
(defmethod inspect dma-foreground-sink-group ((obj dma-foreground-sink-group))
(format #t "[~8x] ~A~%" obj (-> obj type))
(format #t "~Tsink[3] @ #x~X~%" (-> obj sink))
(format #t "~Tmerc-sink: ~A~%" (-> obj sink 0))
(format #t "~Tgeneric-sink: ~A~%" (-> obj sink 1))
(format #t "~Tlevel: ~A~%" (-> obj level))
obj
)
;; failed to figure out what this is:
(let ((v0-4 0))
)
;; failed to figure out what this is:
(none)
@@ -325,4 +325,467 @@ TEST_F(FormRegressionTest, IterateProcessTree) {
" s4-0\n"
" )";
test_with_stack_vars(func, type, expected, "[]");
}
TEST_F(FormRegressionTest, InspectVifStatBitfield) {
std::string func =
"sll r0, r0, 0\n"
" daddiu sp, sp, -32\n"
" sd ra, 0(sp)\n"
" sd fp, 8(sp)\n"
" or fp, t9, r0\n"
" sq gp, 16(sp)\n"
" or gp, a0, r0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L37\n"
" or a2, gp, r0\n"
" daddiu a3, s7, vif-stat\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L36\n"
" dsll32 v1, gp, 30\n"
" dsrl32 a2, v1, 30\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L35\n"
" dsll32 v1, gp, 29\n"
" dsrl32 a2, v1, 31\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L34\n"
" dsll32 v1, gp, 25\n"
" dsrl32 a2, v1, 31\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L33\n"
" dsll32 v1, gp, 23\n"
" dsrl32 a2, v1, 31\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L32\n"
" dsll32 v1, gp, 22\n"
" dsrl32 a2, v1, 31\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L31\n"
" dsll32 v1, gp, 21\n"
" dsrl32 a2, v1, 31\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L30\n"
" dsll32 v1, gp, 20\n"
" dsrl32 a2, v1, 31\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L29\n"
" dsll32 v1, gp, 19\n"
" dsrl32 a2, v1, 31\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L28\n"
" dsll32 v1, gp, 18\n"
" dsrl32 a2, v1, 31\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L27\n"
" dsll32 v1, gp, 4\n"
" dsrl32 a2, v1, 28\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" or v0, gp, r0\n"
" ld ra, 0(sp)\n"
" ld fp, 8(sp)\n"
" lq gp, 16(sp)\n"
" jr ra\n"
" daddiu sp, sp, 32";
std::string type = "(function vif-stat vif-stat)";
std::string expected =
"(begin\n"
" (format #t \"[~8x] ~A~%\" arg0 (quote vif-stat))\n"
" (format #t \"~T ~D~%\" (-> arg0 vps))\n"
" (format #t \"~T ~D~%\" (-> arg0 vew))\n"
" (format #t \"~T ~D~%\" (-> arg0 mrk))\n"
" (format #t \"~T ~D~%\" (-> arg0 vss))\n"
" (format #t \"~T ~D~%\" (-> arg0 vfs))\n"
" (format #t \"~T ~D~%\" (-> arg0 vis))\n"
" (format #t \"~T ~D~%\" (-> arg0 int))\n"
" (format #t \"~T ~D~%\" (-> arg0 er0))\n"
" (format #t \"~T ~D~%\" (-> arg0 er1))\n"
" (format #t \"~T ~D~%\" (-> arg0 fqc))\n"
" arg0\n"
" )";
test_with_expr(func, type, expected, false, "",
{{"L37", "[~8x] ~A~%"},
{"L36", "~T ~D~%"},
{"L35", "~T ~D~%"},
{"L34", "~T ~D~%"},
{"L33", "~T ~D~%"},
{"L32", "~T ~D~%"},
{"L31", "~T ~D~%"},
{"L30", "~T ~D~%"},
{"L29", "~T ~D~%"},
{"L28", "~T ~D~%"},
{"L27", "~T ~D~%"}});
}
TEST_F(FormRegressionTest, InspectHandleBitfield) {
std::string func =
"sll r0, r0, 0\n"
" daddiu sp, sp, -32\n"
" sd ra, 0(sp)\n"
" sd fp, 8(sp)\n"
" or fp, t9, r0\n"
" sq gp, 16(sp)\n"
" or gp, a0, r0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L79\n"
" or a2, gp, r0\n"
" daddiu a3, s7, handle\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L32\n"
" dsll32 v1, gp, 0\n"
" dsrl32 a2, v1, 0\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L31\n"
" dsra32 a2, gp, 0\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" or v0, gp, r0\n"
" ld ra, 0(sp)\n"
" ld fp, 8(sp)\n"
" lq gp, 16(sp)\n"
" jr ra\n"
" daddiu sp, sp, 32";
std::string type = "(function handle handle)";
std::string expected =
"(begin\n"
" (format #t \"[~8x] ~A~%\" arg0 (quote handle))\n"
" (format #t \"~Tprocess: #x~X~%\" (-> arg0 process))\n"
" (format #t \"~Tpid: ~D~%\" (-> arg0 pid))\n"
" arg0\n"
" )";
test_with_expr(func, type, expected, false, "",
{{"L79", "[~8x] ~A~%"}, {"L32", "~Tprocess: #x~X~%"}, {"L31", "~Tpid: ~D~%"}});
}
TEST_F(FormRegressionTest, InspectDmaTagBitfield) {
std::string func =
"sll r0, r0, 0\n"
" daddiu sp, sp, -32\n"
" sd ra, 0(sp)\n"
" sd fp, 8(sp)\n"
" or fp, t9, r0\n"
" sq gp, 16(sp)\n"
" or gp, a0, r0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L65\n"
" or a2, gp, r0\n"
" daddiu a3, s7, dma-tag\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L37\n"
" dsll32 v1, gp, 16\n"
" dsrl32 a2, v1, 16\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L36\n"
" dsll32 v1, gp, 4\n"
" dsrl32 a2, v1, 30\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L35\n"
" dsll32 v1, gp, 1\n"
" dsrl32 a2, v1, 29\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L34\n"
" srl a2, gp, 31\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L33\n"
" dsll v1, gp, 1\n"
" dsrl32 a2, v1, 1\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L32\n"
" dsrl32 a2, gp, 31\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" or v0, gp, r0\n"
" ld ra, 0(sp)\n"
" ld fp, 8(sp)\n"
" lq gp, 16(sp)\n"
" jr ra\n"
" daddiu sp, sp, 32";
std::string type = "(function dma-tag dma-tag)";
std::string expected =
"(begin\n"
" (format #t \"[~8x] ~A~%\" arg0 (quote dma-tag))\n"
" (format #t \"~Ta: ~D~%\" (-> arg0 qwc))\n"
" (format #t \"~Ta: ~D~%\" (-> arg0 pce))\n"
" (format #t \"~Ta: ~D~%\" (-> arg0 id))\n"
" (format #t \"~Ta: ~D~%\" (-> arg0 irq))\n"
" (format #t \"~Ta: ~D~%\" (-> arg0 addr))\n"
" (format #t \"~Ta: ~D~%\" (-> arg0 spr))\n"
" arg0\n"
" )";
test_with_expr(func, type, expected, false, "",
{
{"L65", "[~8x] ~A~%"},
{"L37", "~Ta: ~D~%"},
{"L36", "~Ta: ~D~%"},
{"L35", "~Ta: ~D~%"},
{"L34", "~Ta: ~D~%"},
{"L33", "~Ta: ~D~%"},
{"L32", "~Ta: ~D~%"},
});
}
// Tests nonzero-check on bitfield
TEST_F(FormRegressionTest, DmaSyncCrash) {
std::string func =
"sll r0, r0, 0\n"
"L46:\n"
" lui v1, 76\n"
" ori v1, v1, 19264\n"
" beq r0, r0, L49\n"
" sll r0, r0, 0\n"
"L47:\n"
" bne v1, r0, L48\n"
" sll r0, r0, 0\n"
" sd r0, 2(r0)\n"
" or a1, r0, r0\n"
" beq r0, r0, L49\n"
" sll r0, r0, 0\n"
"L48:\n"
" daddiu v1, v1, -1\n"
" or a1, v1, r0\n"
"L49:\n"
" lwu a1, 0(a0)\n"
" andi a1, a1, 256\n"
" bne a1, r0, L47\n"
" sll r0, r0, 0\n"
" or v1, s7, r0\n"
" or v0, r0, r0\n"
" jr ra\n"
" daddu sp, sp, r0";
std::string type = "(function dma-bank int)";
std::string expected =
"(begin\n"
" (let ((v1-0 #x4c4b40))\n"
" (while (nonzero? (-> arg0 chcr str))\n"
" (cond\n"
" ((zero? v1-0)\n"
" (crash!)\n"
" (let ((a1-0 0))\n"
" )\n"
" )\n"
" (else\n"
" (+! v1-0 -1)\n"
" )\n"
" )\n"
" )\n"
" )\n"
" 0\n"
" )";
test_with_expr(func, type, expected);
}
TEST_F(FormRegressionTest, DmaSend) {
std::string func =
"sll r0, r0, 0\n"
" daddiu sp, sp, -64\n"
" sd ra, 0(sp)\n"
" sq s4, 16(sp)\n"
" sq s5, 32(sp)\n"
" sq gp, 48(sp)\n"
" or gp, a0, r0\n"
" or s4, a1, r0\n"
" or s5, a2, r0\n"
" lw t9, dma-sync(s7)\n"
" or a0, gp, r0\n"
" addiu a1, r0, 0\n"
" addiu a2, r0, 0\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" lw t9, flush-cache(s7)\n"
" addiu a0, r0, 0\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" sync.l\n"
" lui v1, 4095\n"
" ori v1, v1, 65535\n"
" and v1, v1, s4\n"
" lui a0, 28672\n"
" lui a1, 28672\n"
" and a1, a1, s4\n"
" bne a1, a0, L44\n"
" sll r0, r0, 0\n"
" ori a0, r0, 32768\n"
" dsll a0, a0, 16\n"
" beq r0, r0, L45\n"
" sll r0, r0, 0\n"
"L44:\n"
" addiu a0, r0, 0\n"
"L45:\n"
" or v1, v1, a0\n"
" sw v1, 16(gp)\n"
" sw s5, 32(gp)\n"
" sync.l\n"
" addiu v1, r0, 256\n"
" sw v1, 0(gp)\n"
" sync.l\n"
" or v0, r0, r0\n"
" ld ra, 0(sp)\n"
" lq gp, 48(sp)\n"
" lq s5, 32(sp)\n"
" lq s4, 16(sp)\n"
" jr ra\n"
" daddiu sp, sp, 64";
std::string type = "(function dma-bank uint uint int)";
std::string expected =
"(begin\n"
" (dma-sync (the-as pointer arg0) 0 0)\n"
" (flush-cache 0)\n"
" (.sync.l)\n"
" (set!\n"
" (-> arg0 madr)\n"
" (logior\n"
" (logand #xfffffff (the-as int arg1))\n"
" (the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)\n"
" (shl #x8000 16)\n" // note: maybe this should be #x80000000? Not sure.
" 0\n"
" )\n"
" )\n"
" )\n"
" )\n"
" (set! (-> arg0 qwc) arg2)\n"
" (.sync.l)\n"
" (set! (-> arg0 chcr) (new 'static 'dma-chcr :str 1))\n"
" (.sync.l)\n"
" 0\n"
" )";
test_with_expr(func, type, expected);
}
TEST_F(FormRegressionTest, DmaInitialize) {
std::string func =
"sll r0, r0, 0\n"
" lui v1, 4096\n"
" ori v1, v1, 14336\n"
" lwu v1, 32(v1)\n"
" addiu a0, r0, -3\n"
" and v1, v1, a0\n"
" ori v1, v1, 2\n"
" lui a0, 4096\n"
" ori a0, a0, 14336\n"
" sw v1, 32(a0)\n"
" lui v1, 4096\n"
" ori v1, v1, 15360\n"
" lwu v1, 32(v1)\n"
" addiu a0, r0, -3\n"
" and v1, v1, a0\n"
" ori v1, v1, 2\n"
" lui a0, 4096\n"
" ori a0, a0, 15360\n"
" sw v1, 32(a0)\n"
" or v0, r0, r0\n"
" jr ra\n"
" daddu sp, sp, r0";
std::string type = "(function int)";
std::string expected =
"(begin\n"
" (set! (-> (the-as vif-bank #x10003800) err me0) 1)\n"
" (set! (-> (the-as vif-bank #x10003c00) err me0) 1)\n"
" 0\n"
" )";
test_with_expr(func, type, expected, false, "", {},
"[[1, \"v1\", \"vif-bank\"], [8, \"v1\", \"vif-bank\"], [6, \"a0\", "
"\"vif-bank\"], [13, \"a0\", \"vif-bank\"]]");
}
+12 -4
View File
@@ -15,6 +15,8 @@ const std::unordered_set<std::string> g_object_files_to_decompile = {
/*"pskernel",*/ "gstring", "dgo-h", "gstate", "types-h", "vu1-macros", "math", "vector-h",
"bounding-box-h", "matrix-h", "quaternion-h", "euler-h", "transform-h", "geometry-h",
"trigonometry-h", /* transformq-h */ "matrix", "transform", "quaternion",
"euler", /* geometry, trigonometry, */
"gsound-h", "timer-h", "timer", "vif-h", "dma-h", "video-h", "vu1-user-h", "dma",
/* gap */
"bounding-box",
/* gap */
@@ -27,9 +29,9 @@ const std::vector<std::string> g_object_files_to_check_against_reference = {
"math", "vector-h", "bounding-box-h", "matrix-h", "quaternion-h", "euler-h", "transform-h",
"geometry-h", "trigonometry-h",
/* transformq-h, */
"matrix", "transform", "quaternion",
/* gap */
"bounding-box",
"matrix", "transform", "quaternion", "euler", /* geometry, trigonometry */
"gsound-h", "timer-h", /* timer, */ "vif-h", "dma-h", "video-h", "vu1-user-h", "dma",
/* gap */ "bounding-box",
/* gap */
"sync-info-h", "sync-info"};
@@ -62,6 +64,11 @@ const std::unordered_set<std::string> expected_skip_in_decompiler = {
// matrix
"(method 9 matrix)", // handwritten asm loop
"matrix-axis-sin-cos!", "matrix-axis-sin-cos-vu!",
// dma-h
"dma-count-until-done", // dma asm loop
"dma-sync-with-count", "dma-send-no-scratch", "dma-sync-fast",
// dma
"symlink2", "symlink3", "dma-sync-hang", // handwritten asm
// sync-info
"(method 15 sync-info)", // needs *res-static-buf*
"(method 15 sync-info-eased)", // needs *res-static-buf*
@@ -106,11 +113,12 @@ const std::unordered_set<std::string> skip_in_compiling = {
"matrix-with-scale->quaternion", // fpu acc
"quaternion-delta-y", // fpu acc
"(method 3 profile-frame)", // double definition.
// sync-info
"(method 15 sync-info)", // needs display stuff first
"(method 15 sync-info-eased)", // needs display stuff first
"(method 15 sync-info-paused)", // needs display stuff first
};
// default location for the data. It can be changed with a command line argument.
+19 -2
View File
@@ -1,11 +1,14 @@
#include <string>
#include <vector>
#include "common/util/FileUtil.h"
#include "common/util/Trie.h"
#include "common/util/BitUtils.h"
#include "gtest/gtest.h"
#include "test/all_jak1_symbols.h"
#include "common/util/json_util.h"
#include "common/util/Range.h"
#include <string>
#include <vector>
#include "third-party/fmt/core.h"
TEST(CommonUtil, get_file_path) {
std::vector<std::string> test = {"cabbage", "banana", "apple"};
@@ -77,4 +80,18 @@ TEST(CommonUtil, RangeIterator) {
EXPECT_FALSE(Range<int>(3, 4).empty());
EXPECT_EQ(1, Range<int>(3, 4).size());
EXPECT_EQ(4, Range<int>(4, 8).size());
}
TEST(CommonUtil, BitRange) {
for (int x : {0, 0b1001, 0b1010, 0b01110001, 0b000100110}) {
EXPECT_EQ(get_bit_range(x), std::nullopt); // invalids
}
EXPECT_EQ(get_bit_range(0b1), Range<int>(0, 1));
EXPECT_EQ(get_bit_range(0b10), Range<int>(1, 2));
EXPECT_EQ(get_bit_range(0b11), Range<int>(0, 2));
EXPECT_EQ(get_bit_range(0b110), Range<int>(1, 3));
EXPECT_EQ(get_bit_range(UINT64_MAX), Range<int>(0, 64));
EXPECT_EQ(get_bit_range(UINT64_MAX - 1), Range<int>(1, 64));
EXPECT_EQ(get_bit_range(UINT64_MAX / 2), Range<int>(0, 63));
}