fxos: generate defs from insn table + some renaming
This commit is contained in:
parent
c299a5f1b6
commit
74fade0042
|
@ -28,6 +28,22 @@ if(FXOS_CLEAN_LOGS)
|
|||
"${PROJECT_BINARY_DIR}/compiler_filter.sh")
|
||||
endif()
|
||||
|
||||
#---
|
||||
# tooling for generating code at compile-time
|
||||
#---
|
||||
|
||||
add_executable(mkdefs_insn tools/mkdefs_insn.cc)
|
||||
target_link_libraries(mkdefs_insn PRIVATE -lfmt)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/gendefs/insn.h"
|
||||
COMMAND mkdir -p "${CMAKE_CURRENT_BINARY_DIR}/gendefs/"
|
||||
COMMAND "$<TARGET_FILE:mkdefs_insn>"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lib/sh3.def"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lib/sh4.def" >
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/gendefs/insn.h"
|
||||
DEPENDS mkdefs_insn lib/sh3.def lib/sh4.def)
|
||||
|
||||
#---
|
||||
# fxos core
|
||||
#---
|
||||
|
@ -69,10 +85,13 @@ set(fxos_core_SOURCES
|
|||
lib/util/bson.cpp
|
||||
lib/util/Buffer.cpp
|
||||
lib/util/log.cpp
|
||||
lib/util/Timer.cpp)
|
||||
lib/util/Timer.cpp
|
||||
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/gendefs/insn.h")
|
||||
|
||||
add_library(fxos-core ${fxos_core_SOURCES} ${FLEX_LoadAsm_OUTPUTS})
|
||||
target_include_directories(fxos-core PUBLIC include)
|
||||
target_include_directories(fxos-core
|
||||
PUBLIC include "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
#---
|
||||
# fxos shell
|
||||
|
|
|
@ -168,7 +168,7 @@ struct AsmInstruction
|
|||
|
||||
/* Original opcode. Initialized to 0 when unset, which is an invalid
|
||||
instruction by design. */
|
||||
u32 opcode;
|
||||
u32 encoding;
|
||||
/* Operation size (0, 1, 2 or 4) */
|
||||
i8 opsize;
|
||||
/* Number of arguments */
|
||||
|
|
|
@ -109,7 +109,7 @@ static ProgramStateDiff interpretInstruction(
|
|||
diff.setUnknown();
|
||||
|
||||
// TODO: Do this properly
|
||||
u16 opc = ins.opcode().opcode;
|
||||
u16 opc = ins.opcode().encoding;
|
||||
if((opc & 0xf000) == 0xe000) {
|
||||
int reg = (opc >> 8) & 0xf;
|
||||
int val = (int8_t)opc;
|
||||
|
|
|
@ -19,13 +19,13 @@ std::array<std::optional<AsmInstruction>, 65536> insmap;
|
|||
|
||||
void register_instruction(AsmInstruction const &ins)
|
||||
{
|
||||
uint16_t opcode = ins.opcode;
|
||||
uint16_t encoding = ins.encoding;
|
||||
|
||||
if(insmap[opcode])
|
||||
FxOS_log(ERR, "opcode collision between a %s and a %s at %04x",
|
||||
insmap[opcode]->mnemonic, ins.mnemonic, opcode);
|
||||
if(insmap[encoding])
|
||||
FxOS_log(ERR, "encoding collision between a %s and a %s at %04x",
|
||||
insmap[encoding]->mnemonic, ins.mnemonic, encoding);
|
||||
else
|
||||
insmap[opcode] = ins;
|
||||
insmap[encoding] = ins;
|
||||
}
|
||||
|
||||
//---
|
||||
|
@ -40,7 +40,7 @@ Argument::Argument()
|
|||
}
|
||||
|
||||
OldInstruction::OldInstruction(AsmInstruction const *inst):
|
||||
inst {inst}, args {}, opcode {inst->opcode}, leader {false},
|
||||
inst {inst}, args {}, opcode {inst->encoding}, leader {false},
|
||||
delayslot {false}, terminal {false}, jump {false}, condjump {false},
|
||||
jmptarget {0xffffffff}
|
||||
{
|
||||
|
|
|
@ -196,7 +196,7 @@ u32 AsmArgument::getPCRelativeTarget(u32 pc, int size) const
|
|||
//---
|
||||
|
||||
AsmInstruction::AsmInstruction(char const *mn):
|
||||
opcode {0}, opsize {0}, arg_count {0}
|
||||
encoding {0}, opsize {0}, arg_count {0}
|
||||
{
|
||||
int len = strlen(mn);
|
||||
int pos = std::max(0, len - 2);
|
||||
|
|
|
@ -268,7 +268,7 @@ static int instantiate(struct Pattern p, char const *mnemonic, int argtoken1,
|
|||
opcode |= (i << p.i_sh);
|
||||
|
||||
AsmInstruction ins(mnemonic);
|
||||
ins.opcode = opcode;
|
||||
ins.encoding = opcode;
|
||||
ins.tags = insntags;
|
||||
|
||||
if(argtoken1) {
|
||||
|
|
|
@ -141,7 +141,7 @@ static void doOldInst(u32 pc, OldInstruction &i,
|
|||
}
|
||||
|
||||
/* Raw data if instruction cannot be decoded */
|
||||
printf(" %08x: %04x", pc, (i.inst ? i.inst->opcode : i.opcode));
|
||||
printf(" %08x: %04x", pc, (i.inst ? i.inst->encoding : i.opcode));
|
||||
if(!i.inst) {
|
||||
printf("\n");
|
||||
m_lastAddress = pc;
|
||||
|
@ -239,7 +239,7 @@ void viewAssemblyInstruction(Instruction const &ins, ViewAssemblyOptions *opts)
|
|||
ArgumentOutput argout;
|
||||
u32 pc = ins.address();
|
||||
|
||||
printf(" %08x: %04x", pc, opcode.opcode);
|
||||
printf(" %08x: %04x", pc, opcode.encoding);
|
||||
|
||||
/* Mnemonic */
|
||||
static char const *suffixes[5] = {"", ".b", ".w", "", ".l"};
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
#include <fmt/core.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
|
||||
static void usage(int rc)
|
||||
{
|
||||
fprintf(stderr, "usage: ./mkdefs_insn <insn listing...>\n");
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
std::string encodeMnemonic(std::string mnemonic)
|
||||
{
|
||||
for(size_t i = 0; i < mnemonic.size(); i++) {
|
||||
if(!isalnum(mnemonic[i]))
|
||||
mnemonic[i] = '_';
|
||||
}
|
||||
|
||||
return mnemonic;
|
||||
}
|
||||
|
||||
static void parseTable(
|
||||
char const *file, std::map<std::string, std::string> &allMnemonics)
|
||||
{
|
||||
std::ifstream fin {file};
|
||||
std::string line, pattern, mnemonic;
|
||||
|
||||
while(std::getline(fin, line)) {
|
||||
if(line.size() == 0 || !strchr("01nmdi", line[0]))
|
||||
continue;
|
||||
|
||||
std::istringstream stream {line};
|
||||
stream >> pattern >> mnemonic;
|
||||
|
||||
if(mnemonic.ends_with(".b") || mnemonic.ends_with(".w") ||
|
||||
mnemonic.ends_with(".l"))
|
||||
mnemonic = mnemonic.substr(0, mnemonic.size() - 2);
|
||||
|
||||
std::string enc = encodeMnemonic(mnemonic);
|
||||
assert(!allMnemonics.count(enc) || allMnemonics.at(enc) == mnemonic);
|
||||
allMnemonics.insert({ enc, mnemonic });
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
for(int i = 1; i < argc; i++) {
|
||||
if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
|
||||
usage(0);
|
||||
}
|
||||
if(argc <= 1)
|
||||
usage(1);
|
||||
|
||||
std::map<std::string, std::string> allMnemonics;
|
||||
for(int i = 1; i < argc; i++)
|
||||
parseTable(argv[i], allMnemonics);
|
||||
|
||||
for(auto const &[e,m]: allMnemonics)
|
||||
fmt::print("GENDEFS_INSN({}, \"{}\")\n", e, m);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue