Skip to content

Commit

Permalink
[Compiler] In-progress support for vector float (AVX) (#171)
Browse files Browse the repository at this point in the history
* begin work on vf support

* split reg kind into reg hw kind and class, use class for ireg

* try test

* clang format

* add some more ops and some example functions

* better lvf on statics

* add documentation
  • Loading branch information
water111 authored Dec 30, 2020
1 parent 4d713d5 commit a80b331
Show file tree
Hide file tree
Showing 39 changed files with 1,714 additions and 313 deletions.
2 changes: 1 addition & 1 deletion common/goal_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ constexpr int ARRAY_DATA_OFFSET = 12; // not including type tag
constexpr s32 GOAL_MAX_SYMBOLS = 0x2000;
constexpr s32 SYM_INFO_OFFSET = 0xff34;

enum class RegKind { GPR_64, FLOAT, INT_128, FLOAT_4X, INVALID };
enum class RegClass { GPR_64, FLOAT, INT_128, VECTOR_FLOAT, INVALID };

constexpr u32 GOAL_NEW_METHOD = 0; // method ID of GOAL new
constexpr u32 GOAL_DEL_METHOD = 1; // method ID of GOAL delete
Expand Down
26 changes: 13 additions & 13 deletions common/type_system/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@
#include "Type.h"

namespace {
std::string reg_kind_to_string(RegKind kind) {
std::string reg_kind_to_string(RegClass kind) {
switch (kind) {
case RegKind::GPR_64:
case RegClass::GPR_64:
return "gpr64";
case RegKind::INT_128:
case RegClass::INT_128:
return "int128";
case RegKind::FLOAT:
case RegClass::FLOAT:
return "float";
case RegKind::FLOAT_4X:
case RegClass::VECTOR_FLOAT:
return "float-4x";
default:
throw std::runtime_error("Unsupported RegKind");
throw std::runtime_error("Unsupported HWRegKind");
}
}

Expand Down Expand Up @@ -268,8 +268,8 @@ int NullType::get_size_in_memory() const {
throw std::runtime_error("get_size_in_memory called on NullType");
}

RegKind NullType::get_preferred_reg_kind() const {
throw std::runtime_error("get_preferred_reg_kind called on NullType");
RegClass NullType::get_preferred_reg_class() const {
throw std::runtime_error("get_preferred_reg_class called on NullType");
}

int NullType::get_offset() const {
Expand Down Expand Up @@ -306,7 +306,7 @@ ValueType::ValueType(std::string parent,
bool is_boxed,
int size,
bool sign_extend,
RegKind reg)
RegClass reg)
: Type(std::move(parent), std::move(name), is_boxed),
m_size(size),
m_sign_extend(sign_extend),
Expand Down Expand Up @@ -339,7 +339,7 @@ int ValueType::get_size_in_memory() const {
/*!
* The type of register that this value likes to be loaded into.
*/
RegKind ValueType::get_preferred_reg_kind() const {
RegClass ValueType::get_preferred_reg_class() const {
return m_reg_kind;
}

Expand Down Expand Up @@ -447,8 +447,8 @@ int ReferenceType::get_load_size() const {
/*!
* Pointers go in GPRs
*/
RegKind ReferenceType::get_preferred_reg_kind() const {
return RegKind::GPR_64;
RegClass ReferenceType::get_preferred_reg_class() const {
return RegClass::GPR_64;
}

std::string ReferenceType::print() const {
Expand Down Expand Up @@ -592,7 +592,7 @@ bool BitField::operator==(const BitField& other) const {
}

BitFieldType::BitFieldType(std::string parent, std::string name, int size, bool sign_extend)
: ValueType(std::move(parent), std::move(name), false, size, sign_extend, RegKind::GPR_64) {}
: ValueType(std::move(parent), std::move(name), false, size, sign_extend, RegClass::GPR_64) {}

bool BitFieldType::lookup_field(const std::string& name, BitField* out) const {
for (auto& field : m_fields) {
Expand Down
12 changes: 6 additions & 6 deletions common/type_system/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Type {
virtual int get_size_in_memory() const = 0;

// if we have no other information, what kind of register should we load into?
virtual RegKind get_preferred_reg_kind() const = 0;
virtual RegClass get_preferred_reg_class() const = 0;

// get the "offset" applied to boxed objects
virtual int get_offset() const = 0;
Expand Down Expand Up @@ -106,7 +106,7 @@ class NullType : public Type {
bool get_load_signed() const override;
int get_size_in_memory() const override;
int get_inline_array_alignment() const override;
RegKind get_preferred_reg_kind() const override;
RegClass get_preferred_reg_class() const override;
int get_offset() const override;
int get_in_memory_alignment() const override;
std::string print() const override;
Expand All @@ -125,12 +125,12 @@ class ValueType : public Type {
bool is_boxed,
int size,
bool sign_extend,
RegKind reg);
RegClass reg);
bool is_reference() const override;
int get_load_size() const override;
bool get_load_signed() const override;
int get_size_in_memory() const override;
RegKind get_preferred_reg_kind() const override;
RegClass get_preferred_reg_class() const override;
int get_offset() const override;
int get_in_memory_alignment() const override;
int get_inline_array_alignment() const override;
Expand All @@ -146,7 +146,7 @@ class ValueType : public Type {
int m_size = -1;
int m_offset = 0;
bool m_sign_extend = false;
RegKind m_reg_kind = RegKind::INVALID;
RegClass m_reg_kind = RegClass::INVALID;
};

/*!
Expand All @@ -159,7 +159,7 @@ class ReferenceType : public Type {
bool is_reference() const override;
int get_load_size() const override;
bool get_load_signed() const override;
RegKind get_preferred_reg_kind() const override;
RegClass get_preferred_reg_class() const override;
std::string print() const override;
~ReferenceType() = default;
};
Expand Down
16 changes: 8 additions & 8 deletions common/type_system/TypeSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ DerefInfo TypeSystem::get_deref_info(const TypeSpec& ts) const {
}

// default to GPR
info.reg = RegKind::GPR_64;
info.reg = RegClass::GPR_64;
info.mem_deref = true;

if (typecheck(TypeSpec("float"), ts, "", false, false)) {
info.reg = RegKind::FLOAT;
info.reg = RegClass::FLOAT;
}

if (ts.base_type() == "inline-array") {
Expand Down Expand Up @@ -165,7 +165,7 @@ DerefInfo TypeSystem::get_deref_info(const TypeSpec& ts) const {
// an array of values, which should be loaded in the correct way to the correct register
info.stride = result_type->get_size_in_memory();
info.sign_extend = result_type->get_load_signed();
info.reg = result_type->get_preferred_reg_kind();
info.reg = result_type->get_preferred_reg_class();
info.load_size = result_type->get_load_size();
assert(result_type->get_size_in_memory() == result_type->get_load_size());
}
Expand Down Expand Up @@ -640,7 +640,7 @@ void TypeSystem::add_builtin_types() {

// OBJECT
auto obj_type = add_type(
"object", std::make_unique<ValueType>("object", "object", false, 4, false, RegKind::GPR_64));
"object", std::make_unique<ValueType>("object", "object", false, 4, false, RegClass::GPR_64));

auto structure_type = add_builtin_structure("object", "structure");
auto basic_type = add_builtin_basic("structure", "basic");
Expand All @@ -660,21 +660,21 @@ void TypeSystem::add_builtin_types() {
inline_array_type->set_runtime_type("pointer");

add_builtin_value_type("object", "number", 8); // sign extend?
add_builtin_value_type("number", "float", 4, false, false, RegKind::FLOAT);
add_builtin_value_type("number", "float", 4, false, false, RegClass::FLOAT);
add_builtin_value_type("number", "integer", 8, false, false); // sign extend?
add_builtin_value_type("integer", "binteger", 8, true, false); // sign extend?
add_builtin_value_type("integer", "sinteger", 8, false, true);
add_builtin_value_type("sinteger", "int8", 1, false, true);
add_builtin_value_type("sinteger", "int16", 2, false, true);
add_builtin_value_type("sinteger", "int32", 4, false, true);
add_builtin_value_type("sinteger", "int64", 8, false, true);
add_builtin_value_type("sinteger", "int128", 16, false, true, RegKind::INT_128);
add_builtin_value_type("sinteger", "int128", 16, false, true, RegClass::INT_128);
add_builtin_value_type("integer", "uinteger", 8);
add_builtin_value_type("uinteger", "uint8", 1);
add_builtin_value_type("uinteger", "uint16", 2);
add_builtin_value_type("uinteger", "uint32", 4);
add_builtin_value_type("uinteger", "uint64", 8);
add_builtin_value_type("uinteger", "uint128", 16, false, false, RegKind::INT_128);
add_builtin_value_type("uinteger", "uint128", 16, false, false, RegClass::INT_128);

auto int_type = add_builtin_value_type("integer", "int", 8, false, true);
int_type->disallow_in_runtime();
Expand Down Expand Up @@ -948,7 +948,7 @@ ValueType* TypeSystem::add_builtin_value_type(const std::string& parent,
int size,
bool boxed,
bool sign_extend,
RegKind reg) {
RegClass reg) {
add_type(type_name,
std::make_unique<ValueType>(parent, type_name, boxed, size, sign_extend, reg));
return get_type_of_type<ValueType>(type_name);
Expand Down
8 changes: 4 additions & 4 deletions common/type_system/TypeSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct DerefInfo {
bool can_deref = false;
bool mem_deref = false;
bool sign_extend = false;
RegKind reg = RegKind::INVALID;
RegClass reg = RegClass::INVALID;
int stride = -1;
int load_size = -1;
TypeSpec result_type;
Expand Down Expand Up @@ -68,7 +68,7 @@ struct ReverseDerefInfo {
struct ReverseDerefInputInfo {
int offset = -1;
bool mem_deref = false;
RegKind reg = RegKind::INVALID;
RegClass reg = RegClass::INVALID;
int load_size = -1;
bool sign_extend = false;
TypeSpec input_type;
Expand All @@ -81,7 +81,7 @@ struct DerefKind {
bool is_store = false; // when true, the sign extension shouldn't matter
int size = -1; // how many bytes
bool sign_extend = false; // for loads only (4 bytes and under), do we sign extend?
RegKind reg_kind = RegKind::INVALID;
RegClass reg_kind = RegClass::INVALID;
};

struct FieldReverseLookupInput {
Expand Down Expand Up @@ -239,7 +239,7 @@ class TypeSystem {
int size,
bool boxed = false,
bool sign_extend = false,
RegKind reg = RegKind::GPR_64);
RegClass reg = RegClass::GPR_64);
void builtin_structure_inherit(StructureType* st);

enum ForwardDeclareKind { TYPE, STRUCTURE, BASIC };
Expand Down
2 changes: 1 addition & 1 deletion common/versions.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
namespace versions {
// language version (OpenGOAL)
constexpr s32 GOAL_VERSION_MAJOR = 0;
constexpr s32 GOAL_VERSION_MINOR = 4;
constexpr s32 GOAL_VERSION_MINOR = 5;

// these versions are from the game
constexpr u32 ART_FILE_VERSION = 6;
Expand Down
6 changes: 3 additions & 3 deletions decompiler/IR/IR_TypeAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ bool get_as_reg_offset(const IR* ir, RegOffset* out) {
return false;
}

RegKind get_reg_kind(const Register& r) {
RegClass get_reg_kind(const Register& r) {
switch (r.get_kind()) {
case Reg::GPR:
return RegKind::GPR_64;
return RegClass::GPR_64;
case Reg::FPR:
return RegKind::FLOAT;
return RegClass::FLOAT;
default:
assert(false);
}
Expand Down
Loading

0 comments on commit a80b331

Please sign in to comment.