Forward declare IR::Opcode and IR::Type where possible

This commit is contained in:
MerryMage 2018-02-11 11:46:18 +00:00
parent 6c9b4f0114
commit f378d2ef1b
13 changed files with 112 additions and 57 deletions

View file

@ -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

View file

@ -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());

View file

@ -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);

View file

@ -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

View file

@ -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
View 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
View 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

View file

@ -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 {

View file

@ -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 {

View file

@ -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"

View file

@ -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"

View file

@ -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 {

View file

@ -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"