Forward declare IR::Opcode and IR::Type where possible
This commit is contained in:
parent
6c9b4f0114
commit
f378d2ef1b
13 changed files with 112 additions and 57 deletions
|
@ -119,6 +119,8 @@ add_library(dynarmic
|
||||||
frontend/ir/opcodes.h
|
frontend/ir/opcodes.h
|
||||||
frontend/ir/opcodes.inc
|
frontend/ir/opcodes.inc
|
||||||
frontend/ir/terminal.h
|
frontend/ir/terminal.h
|
||||||
|
frontend/ir/type.cpp
|
||||||
|
frontend/ir/type.h
|
||||||
frontend/ir/value.cpp
|
frontend/ir/value.cpp
|
||||||
frontend/ir/value.h
|
frontend/ir/value.h
|
||||||
ir_opt/a32_constant_memory_reads_pass.cpp
|
ir_opt/a32_constant_memory_reads_pass.cpp
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "frontend/ir/microinstruction.h"
|
#include "frontend/ir/microinstruction.h"
|
||||||
|
#include "frontend/ir/opcodes.h"
|
||||||
|
#include "frontend/ir/type.h"
|
||||||
|
|
||||||
namespace Dynarmic::IR {
|
namespace Dynarmic::IR {
|
||||||
|
|
||||||
|
@ -349,6 +351,10 @@ Type Inst::GetType() const {
|
||||||
return GetTypeOf(op);
|
return GetTypeOf(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Inst::NumArgs() const {
|
||||||
|
return GetNumArgsOf(op);
|
||||||
|
}
|
||||||
|
|
||||||
Value Inst::GetArg(size_t index) const {
|
Value Inst::GetArg(size_t index) const {
|
||||||
ASSERT(index < GetNumArgsOf(op));
|
ASSERT(index < GetNumArgsOf(op));
|
||||||
ASSERT(!args[index].IsEmpty());
|
ASSERT(!args[index].IsEmpty());
|
||||||
|
|
|
@ -10,11 +10,13 @@
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/intrusive_list.h"
|
#include "common/intrusive_list.h"
|
||||||
#include "frontend/ir/opcodes.h"
|
|
||||||
#include "frontend/ir/value.h"
|
#include "frontend/ir/value.h"
|
||||||
|
|
||||||
namespace Dynarmic::IR {
|
namespace Dynarmic::IR {
|
||||||
|
|
||||||
|
enum class Opcode;
|
||||||
|
enum class Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of a microinstruction. A single ARM/Thumb instruction may be
|
* A representation of a microinstruction. A single ARM/Thumb instruction may be
|
||||||
* converted into zero or more microinstructions.
|
* converted into zero or more microinstructions.
|
||||||
|
@ -98,7 +100,7 @@ public:
|
||||||
/// Get the type this instruction returns.
|
/// Get the type this instruction returns.
|
||||||
Type GetType() const;
|
Type GetType() const;
|
||||||
/// Get the number of arguments this instruction has.
|
/// Get the number of arguments this instruction has.
|
||||||
size_t NumArgs() const { return GetNumArgsOf(op); }
|
size_t NumArgs() const;
|
||||||
|
|
||||||
Value GetArg(size_t index) const;
|
Value GetArg(size_t index) const;
|
||||||
void SetArg(size_t index, Value value);
|
void SetArg(size_t index, Value value);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
|
|
||||||
#include "frontend/ir/opcodes.h"
|
#include "frontend/ir/opcodes.h"
|
||||||
|
#include "frontend/ir/type.h"
|
||||||
|
|
||||||
namespace Dynarmic::IR {
|
namespace Dynarmic::IR {
|
||||||
|
|
||||||
|
@ -59,26 +60,8 @@ std::string GetNameOf(Opcode op) {
|
||||||
return OpcodeInfo::opcode_info.at(op).name;
|
return OpcodeInfo::opcode_info.at(op).name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetNameOf(Type type) {
|
|
||||||
static const std::array<const char*, 16> names = {
|
|
||||||
"Void", "A32Reg", "A32ExtReg", "A64Reg", "A64Vec", "Opaque", "U1", "U8", "U16", "U32", "U64", "F32", "F64", "CoprocInfo", "NZCVFlags", "Cond"
|
|
||||||
};
|
|
||||||
const size_t index = static_cast<size_t>(type);
|
|
||||||
if (index > names.size())
|
|
||||||
return fmt::format("Unknown Type {}", index);
|
|
||||||
return names.at(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AreTypesCompatible(Type t1, Type t2) {
|
|
||||||
return t1 == t2 || t1 == Type::Opaque || t2 == Type::Opaque;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& o, Opcode opcode) {
|
std::ostream& operator<<(std::ostream& o, Opcode opcode) {
|
||||||
return o << GetNameOf(opcode);
|
return o << GetNameOf(opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& o, Type type) {
|
|
||||||
return o << GetNameOf(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Dynarmic::IR
|
} // namespace Dynarmic::IR
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
namespace Dynarmic::IR {
|
namespace Dynarmic::IR {
|
||||||
|
|
||||||
|
enum class Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Opcodes of our intermediate representation.
|
* The Opcodes of our intermediate representation.
|
||||||
* Type signatures for each opcode can be found in opcodes.inc
|
* Type signatures for each opcode can be found in opcodes.inc
|
||||||
|
@ -30,35 +32,6 @@ enum class Opcode {
|
||||||
|
|
||||||
constexpr size_t OpcodeCount = static_cast<size_t>(Opcode::NUM_OPCODE);
|
constexpr size_t OpcodeCount = static_cast<size_t>(Opcode::NUM_OPCODE);
|
||||||
|
|
||||||
/**
|
|
||||||
* The intermediate representation is typed. These are the used by our IR.
|
|
||||||
*/
|
|
||||||
enum class Type {
|
|
||||||
Void = 0,
|
|
||||||
A32Reg = 1 << 0,
|
|
||||||
A32ExtReg = 1 << 1,
|
|
||||||
A64Reg = 1 << 2,
|
|
||||||
A64Vec = 1 << 3,
|
|
||||||
Opaque = 1 << 4,
|
|
||||||
U1 = 1 << 5,
|
|
||||||
U8 = 1 << 6,
|
|
||||||
U16 = 1 << 7,
|
|
||||||
U32 = 1 << 8,
|
|
||||||
U64 = 1 << 9,
|
|
||||||
U128 = 1 << 10,
|
|
||||||
CoprocInfo = 1 << 11,
|
|
||||||
NZCVFlags = 1 << 12,
|
|
||||||
Cond = 1 << 13,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr Type operator|(Type a, Type b) {
|
|
||||||
return static_cast<Type>(static_cast<size_t>(a) | static_cast<size_t>(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr Type operator&(Type a, Type b) {
|
|
||||||
return static_cast<Type>(static_cast<size_t>(a) & static_cast<size_t>(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get return type of an opcode
|
/// Get return type of an opcode
|
||||||
Type GetTypeOf(Opcode op);
|
Type GetTypeOf(Opcode op);
|
||||||
|
|
||||||
|
@ -71,13 +44,6 @@ Type GetArgTypeOf(Opcode op, size_t arg_index);
|
||||||
/// Get the name of an opcode.
|
/// Get the name of an opcode.
|
||||||
std::string GetNameOf(Opcode op);
|
std::string GetNameOf(Opcode op);
|
||||||
|
|
||||||
/// Get the name of a type.
|
|
||||||
std::string GetNameOf(Type type);
|
|
||||||
|
|
||||||
/// @returns true if t1 and t2 are compatible types
|
|
||||||
bool AreTypesCompatible(Type t1, Type t2);
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& o, Opcode opcode);
|
std::ostream& operator<<(std::ostream& o, Opcode opcode);
|
||||||
std::ostream& operator<<(std::ostream& o, Type type);
|
|
||||||
|
|
||||||
} // namespace Dynarmic::IR
|
} // namespace Dynarmic::IR
|
||||||
|
|
36
src/frontend/ir/type.cpp
Normal file
36
src/frontend/ir/type.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/* This file is part of the dynarmic project.
|
||||||
|
* Copyright (c) 2016 MerryMage
|
||||||
|
* This software may be used and distributed according to the terms of the GNU
|
||||||
|
* General Public License version 2 or any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ostream.h>
|
||||||
|
|
||||||
|
#include "frontend/ir/type.h"
|
||||||
|
|
||||||
|
namespace Dynarmic::IR {
|
||||||
|
|
||||||
|
std::string GetNameOf(Type type) {
|
||||||
|
static const std::array<const char*, 16> names = {
|
||||||
|
"Void", "A32Reg", "A32ExtReg", "A64Reg", "A64Vec", "Opaque", "U1", "U8", "U16", "U32", "U64", "F32", "F64", "CoprocInfo", "NZCVFlags", "Cond"
|
||||||
|
};
|
||||||
|
const size_t index = static_cast<size_t>(type);
|
||||||
|
if (index > names.size())
|
||||||
|
return fmt::format("Unknown Type {}", index);
|
||||||
|
return names.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AreTypesCompatible(Type t1, Type t2) {
|
||||||
|
return t1 == t2 || t1 == Type::Opaque || t2 == Type::Opaque;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& o, Type type) {
|
||||||
|
return o << GetNameOf(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Dynarmic::IR
|
53
src/frontend/ir/type.h
Normal file
53
src/frontend/ir/type.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* This file is part of the dynarmic project.
|
||||||
|
* Copyright (c) 2016 MerryMage
|
||||||
|
* This software may be used and distributed according to the terms of the GNU
|
||||||
|
* General Public License version 2 or any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace Dynarmic::IR {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The intermediate representation is typed. These are the used by our IR.
|
||||||
|
*/
|
||||||
|
enum class Type {
|
||||||
|
Void = 0,
|
||||||
|
A32Reg = 1 << 0,
|
||||||
|
A32ExtReg = 1 << 1,
|
||||||
|
A64Reg = 1 << 2,
|
||||||
|
A64Vec = 1 << 3,
|
||||||
|
Opaque = 1 << 4,
|
||||||
|
U1 = 1 << 5,
|
||||||
|
U8 = 1 << 6,
|
||||||
|
U16 = 1 << 7,
|
||||||
|
U32 = 1 << 8,
|
||||||
|
U64 = 1 << 9,
|
||||||
|
U128 = 1 << 10,
|
||||||
|
CoprocInfo = 1 << 11,
|
||||||
|
NZCVFlags = 1 << 12,
|
||||||
|
Cond = 1 << 13,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr Type operator|(Type a, Type b) {
|
||||||
|
return static_cast<Type>(static_cast<size_t>(a) | static_cast<size_t>(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Type operator&(Type a, Type b) {
|
||||||
|
return static_cast<Type>(static_cast<size_t>(a) & static_cast<size_t>(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the name of a type.
|
||||||
|
std::string GetNameOf(Type type);
|
||||||
|
|
||||||
|
/// @returns true if t1 and t2 are compatible types
|
||||||
|
bool AreTypesCompatible(Type t1, Type t2);
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& o, Type type);
|
||||||
|
|
||||||
|
} // namespace Dynarmic::IR
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "frontend/ir/microinstruction.h"
|
#include "frontend/ir/microinstruction.h"
|
||||||
|
#include "frontend/ir/opcodes.h"
|
||||||
|
#include "frontend/ir/type.h"
|
||||||
#include "frontend/ir/value.h"
|
#include "frontend/ir/value.h"
|
||||||
|
|
||||||
namespace Dynarmic::IR {
|
namespace Dynarmic::IR {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "frontend/A32/types.h"
|
#include "frontend/A32/types.h"
|
||||||
#include "frontend/A64/types.h"
|
#include "frontend/A64/types.h"
|
||||||
#include "frontend/ir/cond.h"
|
#include "frontend/ir/cond.h"
|
||||||
#include "frontend/ir/opcodes.h"
|
#include "frontend/ir/type.h"
|
||||||
|
|
||||||
namespace Dynarmic::IR {
|
namespace Dynarmic::IR {
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "frontend/ir/basic_block.h"
|
#include "frontend/ir/basic_block.h"
|
||||||
|
#include "frontend/ir/opcodes.h"
|
||||||
#include "frontend/ir/value.h"
|
#include "frontend/ir/value.h"
|
||||||
#include "ir_opt/passes.h"
|
#include "ir_opt/passes.h"
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "frontend/ir/basic_block.h"
|
#include "frontend/ir/basic_block.h"
|
||||||
#include "frontend/ir/ir_emitter.h"
|
#include "frontend/ir/ir_emitter.h"
|
||||||
|
#include "frontend/ir/opcodes.h"
|
||||||
#include "frontend/ir/value.h"
|
#include "frontend/ir/value.h"
|
||||||
#include "ir_opt/passes.h"
|
#include "ir_opt/passes.h"
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "frontend/ir/basic_block.h"
|
#include "frontend/ir/basic_block.h"
|
||||||
#include "frontend/ir/microinstruction.h"
|
#include "frontend/ir/microinstruction.h"
|
||||||
|
#include "frontend/ir/opcodes.h"
|
||||||
|
#include "frontend/ir/type.h"
|
||||||
#include "ir_opt/passes.h"
|
#include "ir_opt/passes.h"
|
||||||
|
|
||||||
namespace Dynarmic::Optimization {
|
namespace Dynarmic::Optimization {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "frontend/A64/location_descriptor.h"
|
#include "frontend/A64/location_descriptor.h"
|
||||||
#include "frontend/A64/translate/translate.h"
|
#include "frontend/A64/translate/translate.h"
|
||||||
#include "frontend/ir/basic_block.h"
|
#include "frontend/ir/basic_block.h"
|
||||||
|
#include "frontend/ir/opcodes.h"
|
||||||
#include "inst_gen.h"
|
#include "inst_gen.h"
|
||||||
#include "rand_int.h"
|
#include "rand_int.h"
|
||||||
#include "testenv.h"
|
#include "testenv.h"
|
||||||
|
|
Loading…
Reference in a new issue