From f378d2ef1b4eb98dc9db9de5367d434de42e3460 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sun, 11 Feb 2018 11:46:18 +0000 Subject: [PATCH] Forward declare IR::Opcode and IR::Type where possible --- src/CMakeLists.txt | 2 + src/frontend/ir/microinstruction.cpp | 6 +++ src/frontend/ir/microinstruction.h | 6 ++- src/frontend/ir/opcodes.cpp | 19 +------- src/frontend/ir/opcodes.h | 38 +-------------- src/frontend/ir/type.cpp | 36 ++++++++++++++ src/frontend/ir/type.h | 53 +++++++++++++++++++++ src/frontend/ir/value.cpp | 2 + src/frontend/ir/value.h | 2 +- src/ir_opt/a32_get_set_elimination_pass.cpp | 1 + src/ir_opt/a64_get_set_elimination_pass.cpp | 1 + src/ir_opt/verification_pass.cpp | 2 + tests/A64/fuzz_with_unicorn.cpp | 1 + 13 files changed, 112 insertions(+), 57 deletions(-) create mode 100644 src/frontend/ir/type.cpp create mode 100644 src/frontend/ir/type.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 75b8b070..9679b0e5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -119,6 +119,8 @@ add_library(dynarmic frontend/ir/opcodes.h frontend/ir/opcodes.inc frontend/ir/terminal.h + frontend/ir/type.cpp + frontend/ir/type.h frontend/ir/value.cpp frontend/ir/value.h ir_opt/a32_constant_memory_reads_pass.cpp diff --git a/src/frontend/ir/microinstruction.cpp b/src/frontend/ir/microinstruction.cpp index 1772370f..2076c607 100644 --- a/src/frontend/ir/microinstruction.cpp +++ b/src/frontend/ir/microinstruction.cpp @@ -8,6 +8,8 @@ #include "common/assert.h" #include "frontend/ir/microinstruction.h" +#include "frontend/ir/opcodes.h" +#include "frontend/ir/type.h" namespace Dynarmic::IR { @@ -349,6 +351,10 @@ Type Inst::GetType() const { return GetTypeOf(op); } +size_t Inst::NumArgs() const { + return GetNumArgsOf(op); +} + Value Inst::GetArg(size_t index) const { ASSERT(index < GetNumArgsOf(op)); ASSERT(!args[index].IsEmpty()); diff --git a/src/frontend/ir/microinstruction.h b/src/frontend/ir/microinstruction.h index bd3a3e25..2349797b 100644 --- a/src/frontend/ir/microinstruction.h +++ b/src/frontend/ir/microinstruction.h @@ -10,11 +10,13 @@ #include "common/common_types.h" #include "common/intrusive_list.h" -#include "frontend/ir/opcodes.h" #include "frontend/ir/value.h" namespace Dynarmic::IR { +enum class Opcode; +enum class Type; + /** * A representation of a microinstruction. A single ARM/Thumb instruction may be * converted into zero or more microinstructions. @@ -98,7 +100,7 @@ public: /// Get the type this instruction returns. Type GetType() const; /// 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; void SetArg(size_t index, Value value); diff --git a/src/frontend/ir/opcodes.cpp b/src/frontend/ir/opcodes.cpp index 98ee3133..abd43625 100644 --- a/src/frontend/ir/opcodes.cpp +++ b/src/frontend/ir/opcodes.cpp @@ -14,6 +14,7 @@ #include #include "frontend/ir/opcodes.h" +#include "frontend/ir/type.h" namespace Dynarmic::IR { @@ -59,26 +60,8 @@ std::string GetNameOf(Opcode op) { return OpcodeInfo::opcode_info.at(op).name; } -std::string GetNameOf(Type type) { - static const std::array names = { - "Void", "A32Reg", "A32ExtReg", "A64Reg", "A64Vec", "Opaque", "U1", "U8", "U16", "U32", "U64", "F32", "F64", "CoprocInfo", "NZCVFlags", "Cond" - }; - const size_t index = static_cast(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) { return o << GetNameOf(opcode); } -std::ostream& operator<<(std::ostream& o, Type type) { - return o << GetNameOf(type); -} - } // namespace Dynarmic::IR diff --git a/src/frontend/ir/opcodes.h b/src/frontend/ir/opcodes.h index 08817955..95180075 100644 --- a/src/frontend/ir/opcodes.h +++ b/src/frontend/ir/opcodes.h @@ -13,6 +13,8 @@ namespace Dynarmic::IR { +enum class Type; + /** * The Opcodes of our intermediate representation. * Type signatures for each opcode can be found in opcodes.inc @@ -30,35 +32,6 @@ enum class Opcode { constexpr size_t OpcodeCount = static_cast(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(static_cast(a) | static_cast(b)); -} - -constexpr Type operator&(Type a, Type b) { - return static_cast(static_cast(a) & static_cast(b)); -} - /// Get return type of an opcode Type GetTypeOf(Opcode op); @@ -71,13 +44,6 @@ Type GetArgTypeOf(Opcode op, size_t arg_index); /// Get the name of an opcode. 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, Type type); } // namespace Dynarmic::IR diff --git a/src/frontend/ir/type.cpp b/src/frontend/ir/type.cpp new file mode 100644 index 00000000..71eff356 --- /dev/null +++ b/src/frontend/ir/type.cpp @@ -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 +#include +#include + +#include +#include + +#include "frontend/ir/type.h" + +namespace Dynarmic::IR { + +std::string GetNameOf(Type type) { + static const std::array names = { + "Void", "A32Reg", "A32ExtReg", "A64Reg", "A64Vec", "Opaque", "U1", "U8", "U16", "U32", "U64", "F32", "F64", "CoprocInfo", "NZCVFlags", "Cond" + }; + const size_t index = static_cast(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 diff --git a/src/frontend/ir/type.h b/src/frontend/ir/type.h new file mode 100644 index 00000000..593a9918 --- /dev/null +++ b/src/frontend/ir/type.h @@ -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 +#include + +#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(static_cast(a) | static_cast(b)); +} + +constexpr Type operator&(Type a, Type b) { + return static_cast(static_cast(a) & static_cast(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 diff --git a/src/frontend/ir/value.cpp b/src/frontend/ir/value.cpp index e52615c9..7d3851a0 100644 --- a/src/frontend/ir/value.cpp +++ b/src/frontend/ir/value.cpp @@ -6,6 +6,8 @@ #include "common/assert.h" #include "frontend/ir/microinstruction.h" +#include "frontend/ir/opcodes.h" +#include "frontend/ir/type.h" #include "frontend/ir/value.h" namespace Dynarmic::IR { diff --git a/src/frontend/ir/value.h b/src/frontend/ir/value.h index f43a41fe..28e663b1 100644 --- a/src/frontend/ir/value.h +++ b/src/frontend/ir/value.h @@ -13,7 +13,7 @@ #include "frontend/A32/types.h" #include "frontend/A64/types.h" #include "frontend/ir/cond.h" -#include "frontend/ir/opcodes.h" +#include "frontend/ir/type.h" namespace Dynarmic::IR { diff --git a/src/ir_opt/a32_get_set_elimination_pass.cpp b/src/ir_opt/a32_get_set_elimination_pass.cpp index b06bccf5..522f9a2b 100644 --- a/src/ir_opt/a32_get_set_elimination_pass.cpp +++ b/src/ir_opt/a32_get_set_elimination_pass.cpp @@ -9,6 +9,7 @@ #include "common/assert.h" #include "common/common_types.h" #include "frontend/ir/basic_block.h" +#include "frontend/ir/opcodes.h" #include "frontend/ir/value.h" #include "ir_opt/passes.h" diff --git a/src/ir_opt/a64_get_set_elimination_pass.cpp b/src/ir_opt/a64_get_set_elimination_pass.cpp index fc3ee474..45294bcf 100644 --- a/src/ir_opt/a64_get_set_elimination_pass.cpp +++ b/src/ir_opt/a64_get_set_elimination_pass.cpp @@ -10,6 +10,7 @@ #include "common/common_types.h" #include "frontend/ir/basic_block.h" #include "frontend/ir/ir_emitter.h" +#include "frontend/ir/opcodes.h" #include "frontend/ir/value.h" #include "ir_opt/passes.h" diff --git a/src/ir_opt/verification_pass.cpp b/src/ir_opt/verification_pass.cpp index cae0fec4..ef590b45 100644 --- a/src/ir_opt/verification_pass.cpp +++ b/src/ir_opt/verification_pass.cpp @@ -10,6 +10,8 @@ #include "common/common_types.h" #include "frontend/ir/basic_block.h" #include "frontend/ir/microinstruction.h" +#include "frontend/ir/opcodes.h" +#include "frontend/ir/type.h" #include "ir_opt/passes.h" namespace Dynarmic::Optimization { diff --git a/tests/A64/fuzz_with_unicorn.cpp b/tests/A64/fuzz_with_unicorn.cpp index 509f4ade..5668337e 100644 --- a/tests/A64/fuzz_with_unicorn.cpp +++ b/tests/A64/fuzz_with_unicorn.cpp @@ -15,6 +15,7 @@ #include "frontend/A64/location_descriptor.h" #include "frontend/A64/translate/translate.h" #include "frontend/ir/basic_block.h" +#include "frontend/ir/opcodes.h" #include "inst_gen.h" #include "rand_int.h" #include "testenv.h"