2016-08-12 18:17:31 +01:00
|
|
|
/* 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.
|
|
|
|
*/
|
|
|
|
|
2016-08-17 13:29:05 +01:00
|
|
|
#include <array>
|
2016-08-12 18:17:31 +01:00
|
|
|
#include <map>
|
2018-01-27 23:42:30 +00:00
|
|
|
#include <ostream>
|
|
|
|
#include <string>
|
2016-08-12 18:17:31 +01:00
|
|
|
#include <vector>
|
|
|
|
|
2018-01-27 23:42:30 +00:00
|
|
|
#include <fmt/format.h>
|
|
|
|
#include <fmt/ostream.h>
|
|
|
|
|
2016-08-12 18:17:31 +01:00
|
|
|
#include "frontend/ir/opcodes.h"
|
2018-02-11 11:46:18 +00:00
|
|
|
#include "frontend/ir/type.h"
|
2016-08-12 18:17:31 +01:00
|
|
|
|
2018-01-26 13:51:48 +00:00
|
|
|
namespace Dynarmic::IR {
|
2016-08-12 18:17:31 +01:00
|
|
|
|
|
|
|
// Opcode information
|
|
|
|
|
|
|
|
namespace OpcodeInfo {
|
|
|
|
|
|
|
|
struct Meta {
|
|
|
|
const char* name;
|
|
|
|
Type type;
|
|
|
|
std::vector<Type> arg_types;
|
|
|
|
};
|
|
|
|
|
2018-08-18 19:36:02 +01:00
|
|
|
constexpr Type Void = Type::Void;
|
|
|
|
constexpr Type A32Reg = Type::A32Reg;
|
|
|
|
constexpr Type A32ExtReg = Type::A32ExtReg;
|
|
|
|
constexpr Type A64Reg = Type::A64Reg;
|
|
|
|
constexpr Type A64Vec = Type::A64Vec;
|
|
|
|
constexpr Type Opaque = Type::Opaque;
|
|
|
|
constexpr Type U1 = Type::U1;
|
|
|
|
constexpr Type U8 = Type::U8;
|
|
|
|
constexpr Type U16 = Type::U16;
|
|
|
|
constexpr Type U32 = Type::U32;
|
|
|
|
constexpr Type U64 = Type::U64;
|
|
|
|
constexpr Type U128 = Type::U128;
|
|
|
|
constexpr Type CoprocInfo = Type::CoprocInfo;
|
|
|
|
constexpr Type NZCV = Type::NZCVFlags;
|
|
|
|
constexpr Type Cond = Type::Cond;
|
2018-08-18 21:08:34 +01:00
|
|
|
constexpr Type Table = Type::Table;
|
2018-08-18 19:36:02 +01:00
|
|
|
|
2016-08-12 18:17:31 +01:00
|
|
|
static const std::map<Opcode, Meta> opcode_info {{
|
|
|
|
#define OPCODE(name, type, ...) { Opcode::name, { #name, type, { __VA_ARGS__ } } },
|
2018-01-01 16:19:43 +00:00
|
|
|
#define A32OPC(name, type, ...) { Opcode::A32##name, { #name, type, { __VA_ARGS__ } } },
|
2018-01-07 00:11:57 +00:00
|
|
|
#define A64OPC(name, type, ...) { Opcode::A64##name, { #name, type, { __VA_ARGS__ } } },
|
2016-08-12 18:17:31 +01:00
|
|
|
#include "opcodes.inc"
|
|
|
|
#undef OPCODE
|
2018-01-01 16:19:43 +00:00
|
|
|
#undef A32OPC
|
2018-01-07 00:11:57 +00:00
|
|
|
#undef A64OPC
|
2016-12-31 10:46:13 +00:00
|
|
|
}};
|
2016-08-12 18:17:31 +01:00
|
|
|
|
|
|
|
} // namespace OpcodeInfo
|
|
|
|
|
|
|
|
Type GetTypeOf(Opcode op) {
|
|
|
|
return OpcodeInfo::opcode_info.at(op).type;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t GetNumArgsOf(Opcode op) {
|
|
|
|
return OpcodeInfo::opcode_info.at(op).arg_types.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
Type GetArgTypeOf(Opcode op, size_t arg_index) {
|
|
|
|
return OpcodeInfo::opcode_info.at(op).arg_types.at(arg_index);
|
|
|
|
}
|
|
|
|
|
2018-01-27 23:42:30 +00:00
|
|
|
std::string GetNameOf(Opcode op) {
|
|
|
|
if (OpcodeInfo::opcode_info.count(op) == 0)
|
|
|
|
return fmt::format("Unknown Opcode {}", static_cast<Opcode>(op));
|
2016-08-12 18:17:31 +01:00
|
|
|
return OpcodeInfo::opcode_info.at(op).name;
|
|
|
|
}
|
|
|
|
|
2018-01-27 23:42:30 +00:00
|
|
|
std::ostream& operator<<(std::ostream& o, Opcode opcode) {
|
|
|
|
return o << GetNameOf(opcode);
|
|
|
|
}
|
|
|
|
|
2018-01-26 13:51:48 +00:00
|
|
|
} // namespace Dynarmic::IR
|