mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
add IR atomic interface and switch all basic ops to these
This commit is contained in:
parent
d6ad0c0bb5
commit
a9cfa19f92
|
@ -659,7 +659,7 @@ void Function::find_type_defs(LinkedObjectFile& file, DecompilerTypeSystem& dts)
|
|||
}
|
||||
}
|
||||
|
||||
void Function::add_basic_op(std::shared_ptr<IR> op, int start_instr, int end_instr) {
|
||||
void Function::add_basic_op(std::shared_ptr<IR_Atomic> op, int start_instr, int end_instr) {
|
||||
op->is_basic_op = true;
|
||||
assert(end_instr > start_instr);
|
||||
|
||||
|
@ -679,7 +679,7 @@ bool Function::instr_starts_basic_op(int idx) {
|
|||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<IR> Function::get_basic_op_at_instr(int idx) {
|
||||
std::shared_ptr<IR_Atomic> Function::get_basic_op_at_instr(int idx) {
|
||||
return basic_ops.at(instruction_to_basic_op.at(idx));
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
class DecompilerTypeSystem;
|
||||
// Map of what type is in each register.
|
||||
using TypeMap = std::unordered_map<Register, TypeSpec, Register::hash>;
|
||||
class IR_Atomic;
|
||||
class IR;
|
||||
|
||||
struct FunctionName {
|
||||
|
@ -76,11 +77,11 @@ class Function {
|
|||
void find_global_function_defs(LinkedObjectFile& file, DecompilerTypeSystem& dts);
|
||||
void find_method_defs(LinkedObjectFile& file, DecompilerTypeSystem& dts);
|
||||
void find_type_defs(LinkedObjectFile& file, DecompilerTypeSystem& dts);
|
||||
void add_basic_op(std::shared_ptr<IR> op, int start_instr, int end_instr);
|
||||
void add_basic_op(std::shared_ptr<IR_Atomic> op, int start_instr, int end_instr);
|
||||
bool has_basic_ops() { return !basic_ops.empty(); }
|
||||
bool has_typemaps() { return !basic_op_typemaps.empty(); }
|
||||
bool instr_starts_basic_op(int idx);
|
||||
std::shared_ptr<IR> get_basic_op_at_instr(int idx);
|
||||
std::shared_ptr<IR_Atomic> get_basic_op_at_instr(int idx);
|
||||
const TypeMap& get_typemap_by_instr_idx(int idx);
|
||||
int get_basic_op_count();
|
||||
int get_failed_basic_op_count();
|
||||
|
@ -144,7 +145,7 @@ class Function {
|
|||
} prologue;
|
||||
|
||||
bool uses_fp_register = false;
|
||||
std::vector<std::shared_ptr<IR>> basic_ops;
|
||||
std::vector<std::shared_ptr<IR_Atomic>> basic_ops;
|
||||
|
||||
private:
|
||||
void check_epilogue(const LinkedObjectFile& file);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -99,6 +99,41 @@ goos::Object IR_Store::to_form(const LinkedObjectFile& file) const {
|
|||
src->to_form(file));
|
||||
}
|
||||
|
||||
goos::Object IR_Store_Atomic::to_form(const LinkedObjectFile& file) const {
|
||||
std::string store_operator;
|
||||
switch (kind) {
|
||||
case FLOAT:
|
||||
store_operator = "s.f";
|
||||
break;
|
||||
case INTEGER:
|
||||
switch (size) {
|
||||
case 1:
|
||||
store_operator = "s.b";
|
||||
break;
|
||||
case 2:
|
||||
store_operator = "s.h";
|
||||
break;
|
||||
case 4:
|
||||
store_operator = "s.w";
|
||||
break;
|
||||
case 8:
|
||||
store_operator = "s.d";
|
||||
break;
|
||||
case 16:
|
||||
store_operator = "s.q";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return pretty_print::build_list(pretty_print::to_symbol(store_operator), dst->to_form(file),
|
||||
src->to_form(file));
|
||||
}
|
||||
|
||||
goos::Object IR_Symbol::to_form(const LinkedObjectFile& file) const {
|
||||
(void)file;
|
||||
return pretty_print::to_symbol("'" + name);
|
||||
|
|
|
@ -35,14 +35,23 @@ class IR {
|
|||
bool is_basic_op = false;
|
||||
};
|
||||
|
||||
class IR_Failed : public IR {
|
||||
class IR_Atomic : public virtual IR {
|
||||
public:
|
||||
};
|
||||
|
||||
class IR_Failed : public virtual IR {
|
||||
public:
|
||||
IR_Failed() = default;
|
||||
goos::Object to_form(const LinkedObjectFile& file) const override;
|
||||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_Register : public IR {
|
||||
class IR_Failed_Atomic : public IR_Failed, public IR_Atomic {
|
||||
public:
|
||||
IR_Failed_Atomic() = default;
|
||||
};
|
||||
|
||||
class IR_Register : public virtual IR {
|
||||
public:
|
||||
IR_Register(Register _reg, int _instr_idx) : reg(_reg), instr_idx(_instr_idx) {}
|
||||
goos::Object to_form(const LinkedObjectFile& file) const override;
|
||||
|
@ -55,7 +64,7 @@ class IR_Register : public IR {
|
|||
int instr_idx = -1;
|
||||
};
|
||||
|
||||
class IR_Set : public IR {
|
||||
class IR_Set : public virtual IR {
|
||||
public:
|
||||
enum Kind {
|
||||
REG_64,
|
||||
|
@ -79,7 +88,14 @@ class IR_Set : public IR {
|
|||
std::shared_ptr<IR> clobber = nullptr;
|
||||
};
|
||||
|
||||
class IR_Store : public IR_Set {
|
||||
// todo
|
||||
class IR_Set_Atomic : public IR_Set, public IR_Atomic {
|
||||
public:
|
||||
IR_Set_Atomic(IR_Set::Kind _kind, std::shared_ptr<IR> _dst, std::shared_ptr<IR> _src)
|
||||
: IR_Set(_kind, std::move(_dst), std::move(_src)) {}
|
||||
};
|
||||
|
||||
class IR_Store : public virtual IR_Set {
|
||||
public:
|
||||
enum Kind { INTEGER, FLOAT } kind;
|
||||
IR_Store(Kind _kind, std::shared_ptr<IR> _dst, std::shared_ptr<IR> _src, int _size)
|
||||
|
@ -88,7 +104,20 @@ class IR_Store : public IR_Set {
|
|||
goos::Object to_form(const LinkedObjectFile& file) const override;
|
||||
};
|
||||
|
||||
class IR_Symbol : public IR {
|
||||
/*!
|
||||
* Note, IR_Store_Atomic does not appear as a IR_Set_Atomic.
|
||||
* This is to avoid the "diamond problem".
|
||||
*/
|
||||
class IR_Store_Atomic : public IR_Set_Atomic {
|
||||
public:
|
||||
enum Kind { INTEGER, FLOAT } kind;
|
||||
IR_Store_Atomic(Kind _kind, std::shared_ptr<IR> _dst, std::shared_ptr<IR> _src, int _size)
|
||||
: IR_Set_Atomic(IR_Set::LOAD, std::move(_dst), std::move(_src)), kind(_kind), size(_size) {}
|
||||
int size;
|
||||
goos::Object to_form(const LinkedObjectFile& file) const override;
|
||||
};
|
||||
|
||||
class IR_Symbol : public virtual IR {
|
||||
public:
|
||||
explicit IR_Symbol(std::string _name) : name(std::move(_name)) {}
|
||||
std::string name;
|
||||
|
@ -100,7 +129,7 @@ class IR_Symbol : public IR {
|
|||
TypeSpec* out) const override;
|
||||
};
|
||||
|
||||
class IR_SymbolValue : public IR {
|
||||
class IR_SymbolValue : public virtual IR {
|
||||
public:
|
||||
explicit IR_SymbolValue(std::string _name) : name(std::move(_name)) {}
|
||||
std::string name;
|
||||
|
@ -112,7 +141,7 @@ class IR_SymbolValue : public IR {
|
|||
TypeSpec* out) const override;
|
||||
};
|
||||
|
||||
class IR_StaticAddress : public IR {
|
||||
class IR_StaticAddress : public virtual IR {
|
||||
public:
|
||||
explicit IR_StaticAddress(int _label_id) : label_id(_label_id) {}
|
||||
int label_id = -1;
|
||||
|
@ -120,7 +149,7 @@ class IR_StaticAddress : public IR {
|
|||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_Load : public IR {
|
||||
class IR_Load : public virtual IR {
|
||||
public:
|
||||
enum Kind { UNSIGNED, SIGNED, FLOAT } kind;
|
||||
|
||||
|
@ -136,7 +165,7 @@ class IR_Load : public IR {
|
|||
TypeSpec* out) const override;
|
||||
};
|
||||
|
||||
class IR_FloatMath2 : public IR {
|
||||
class IR_FloatMath2 : public virtual IR {
|
||||
public:
|
||||
enum Kind { DIV, MUL, ADD, SUB, MIN, MAX } kind;
|
||||
IR_FloatMath2(Kind _kind, std::shared_ptr<IR> _arg0, std::shared_ptr<IR> _arg1)
|
||||
|
@ -150,7 +179,7 @@ class IR_FloatMath2 : public IR {
|
|||
TypeSpec* out) const override;
|
||||
};
|
||||
|
||||
class IR_FloatMath1 : public IR {
|
||||
class IR_FloatMath1 : public virtual IR {
|
||||
public:
|
||||
enum Kind { FLOAT_TO_INT, INT_TO_FLOAT, ABS, NEG, SQRT } kind;
|
||||
IR_FloatMath1(Kind _kind, std::shared_ptr<IR> _arg) : kind(_kind), arg(std::move(_arg)) {}
|
||||
|
@ -159,7 +188,7 @@ class IR_FloatMath1 : public IR {
|
|||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_IntMath2 : public IR {
|
||||
class IR_IntMath2 : public virtual IR {
|
||||
public:
|
||||
enum Kind {
|
||||
ADD,
|
||||
|
@ -191,7 +220,7 @@ class IR_IntMath2 : public IR {
|
|||
TypeSpec* out) const override;
|
||||
};
|
||||
|
||||
class IR_IntMath1 : public IR {
|
||||
class IR_IntMath1 : public virtual IR {
|
||||
public:
|
||||
enum Kind { NOT, ABS, NEG } kind;
|
||||
IR_IntMath1(Kind _kind, std::shared_ptr<IR> _arg) : kind(_kind), arg(std::move(_arg)) {}
|
||||
|
@ -204,14 +233,20 @@ class IR_IntMath1 : public IR {
|
|||
TypeSpec* out) const override;
|
||||
};
|
||||
|
||||
class IR_Call : public IR {
|
||||
class IR_Call : public virtual IR {
|
||||
public:
|
||||
IR_Call() = default;
|
||||
goos::Object to_form(const LinkedObjectFile& file) const override;
|
||||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_IntegerConstant : public IR {
|
||||
// todo
|
||||
class IR_Call_Atomic : public virtual IR_Call, public IR_Atomic {
|
||||
public:
|
||||
IR_Call_Atomic() = default;
|
||||
};
|
||||
|
||||
class IR_IntegerConstant : public virtual IR {
|
||||
public:
|
||||
int64_t value;
|
||||
explicit IR_IntegerConstant(int64_t _value) : value(_value) {}
|
||||
|
@ -293,7 +328,7 @@ struct Condition {
|
|||
void invert();
|
||||
};
|
||||
|
||||
class IR_Branch : public IR {
|
||||
class IR_Branch : public virtual IR {
|
||||
public:
|
||||
IR_Branch(Condition _condition, int _dest_label_idx, BranchDelay _branch_delay, bool _likely)
|
||||
: condition(std::move(_condition)),
|
||||
|
@ -313,7 +348,17 @@ class IR_Branch : public IR {
|
|||
LinkedObjectFile& file) const;
|
||||
};
|
||||
|
||||
class IR_Compare : public IR {
|
||||
// todo
|
||||
class IR_Branch_Atomic : public virtual IR_Branch, public IR_Atomic {
|
||||
public:
|
||||
IR_Branch_Atomic(Condition _condition,
|
||||
int _dest_label_idx,
|
||||
BranchDelay _branch_delay,
|
||||
bool _likely)
|
||||
: IR_Branch(std::move(_condition), _dest_label_idx, std::move(_branch_delay), _likely) {}
|
||||
};
|
||||
|
||||
class IR_Compare : public virtual IR {
|
||||
public:
|
||||
explicit IR_Compare(Condition _condition) : condition(std::move(_condition)) {}
|
||||
|
||||
|
@ -327,21 +372,26 @@ class IR_Compare : public IR {
|
|||
TypeSpec* out) const override;
|
||||
};
|
||||
|
||||
class IR_Nop : public IR {
|
||||
class IR_Nop : public virtual IR {
|
||||
public:
|
||||
IR_Nop() = default;
|
||||
goos::Object to_form(const LinkedObjectFile& file) const override;
|
||||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_Suspend : public IR {
|
||||
class IR_Nop_Atomic : public IR_Nop, public IR_Atomic {
|
||||
public:
|
||||
IR_Nop_Atomic() = default;
|
||||
};
|
||||
|
||||
class IR_Suspend : public virtual IR, public IR_Atomic {
|
||||
public:
|
||||
IR_Suspend() = default;
|
||||
goos::Object to_form(const LinkedObjectFile& file) const override;
|
||||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_Begin : public IR {
|
||||
class IR_Begin : public virtual IR {
|
||||
public:
|
||||
IR_Begin() = default;
|
||||
explicit IR_Begin(const std::vector<std::shared_ptr<IR>>& _forms) : forms(std::move(_forms)) {}
|
||||
|
@ -350,7 +400,7 @@ class IR_Begin : public IR {
|
|||
std::vector<std::shared_ptr<IR>> forms;
|
||||
};
|
||||
|
||||
class IR_WhileLoop : public IR {
|
||||
class IR_WhileLoop : public virtual IR {
|
||||
public:
|
||||
IR_WhileLoop(std::shared_ptr<IR> _condition, std::shared_ptr<IR> _body)
|
||||
: condition(std::move(_condition)), body(std::move(_body)) {}
|
||||
|
@ -360,7 +410,7 @@ class IR_WhileLoop : public IR {
|
|||
bool cleaned = false;
|
||||
};
|
||||
|
||||
class IR_UntilLoop : public IR {
|
||||
class IR_UntilLoop : public virtual IR {
|
||||
public:
|
||||
IR_UntilLoop(std::shared_ptr<IR> _condition, std::shared_ptr<IR> _body)
|
||||
: condition(std::move(_condition)), body(std::move(_body)) {}
|
||||
|
@ -369,7 +419,7 @@ class IR_UntilLoop : public IR {
|
|||
std::shared_ptr<IR> condition, body;
|
||||
};
|
||||
|
||||
class IR_CondWithElse : public IR {
|
||||
class IR_CondWithElse : public virtual IR {
|
||||
public:
|
||||
struct Entry {
|
||||
std::shared_ptr<IR> condition = nullptr;
|
||||
|
@ -385,7 +435,7 @@ class IR_CondWithElse : public IR {
|
|||
};
|
||||
|
||||
// this one doesn't have an else statement. Will return false if none of the cases are taken.
|
||||
class IR_Cond : public IR {
|
||||
class IR_Cond : public virtual IR {
|
||||
public:
|
||||
struct Entry {
|
||||
std::shared_ptr<IR> condition = nullptr;
|
||||
|
@ -400,7 +450,7 @@ class IR_Cond : public IR {
|
|||
};
|
||||
|
||||
// this will work on pairs, bintegers, or basics
|
||||
class IR_GetRuntimeType : public IR {
|
||||
class IR_GetRuntimeType : public virtual IR {
|
||||
public:
|
||||
std::shared_ptr<IR> object, clobber;
|
||||
IR_GetRuntimeType(std::shared_ptr<IR> _object, std::shared_ptr<IR> _clobber)
|
||||
|
@ -409,7 +459,7 @@ class IR_GetRuntimeType : public IR {
|
|||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_ShortCircuit : public IR {
|
||||
class IR_ShortCircuit : public virtual IR {
|
||||
public:
|
||||
struct Entry {
|
||||
std::shared_ptr<IR> condition = nullptr;
|
||||
|
@ -427,7 +477,7 @@ class IR_ShortCircuit : public IR {
|
|||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_Ash : public IR {
|
||||
class IR_Ash : public virtual IR {
|
||||
public:
|
||||
std::shared_ptr<IR> shift_amount, value, clobber;
|
||||
bool is_signed = true;
|
||||
|
@ -443,7 +493,7 @@ class IR_Ash : public IR {
|
|||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_AsmOp : public IR {
|
||||
class IR_AsmOp : public virtual IR {
|
||||
public:
|
||||
std::shared_ptr<IR> dst = nullptr;
|
||||
std::shared_ptr<IR> src0 = nullptr;
|
||||
|
@ -455,7 +505,12 @@ class IR_AsmOp : public IR {
|
|||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_CMoveF : public IR {
|
||||
class IR_AsmOp_Atomic : public virtual IR_AsmOp, public IR_Atomic {
|
||||
public:
|
||||
IR_AsmOp_Atomic(std::string _name) : IR_AsmOp(std::move(_name)) {}
|
||||
};
|
||||
|
||||
class IR_CMoveF : public virtual IR {
|
||||
public:
|
||||
std::shared_ptr<IR> src = nullptr;
|
||||
bool on_zero = false;
|
||||
|
@ -465,7 +520,7 @@ class IR_CMoveF : public IR {
|
|||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_AsmReg : public IR {
|
||||
class IR_AsmReg : public virtual IR {
|
||||
public:
|
||||
enum Kind { VU_Q, VU_ACC } kind;
|
||||
explicit IR_AsmReg(Kind _kind) : kind(_kind) {}
|
||||
|
@ -473,7 +528,7 @@ class IR_AsmReg : public IR {
|
|||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_Return : public IR {
|
||||
class IR_Return : public virtual IR {
|
||||
public:
|
||||
std::shared_ptr<IR> return_code;
|
||||
std::shared_ptr<IR> dead_code;
|
||||
|
@ -483,7 +538,7 @@ class IR_Return : public IR {
|
|||
void get_children(std::vector<std::shared_ptr<IR>>* output) const override;
|
||||
};
|
||||
|
||||
class IR_Break : public IR {
|
||||
class IR_Break : public virtual IR {
|
||||
public:
|
||||
std::shared_ptr<IR> return_code;
|
||||
std::shared_ptr<IR> dead_code;
|
||||
|
|
Loading…
Reference in a new issue