fxos: switch to symbolic opcodes in AsmInstruction

This commit is contained in:
Lephenixnoir 2023-11-14 04:27:55 +01:00
parent 74fade0042
commit 068898c2d6
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
4 changed files with 42 additions and 10 deletions

View File

@ -159,6 +159,14 @@ struct AsmInstruction
IsDynamicJump = 0x40,
};
#define GENDEFS_INSN(NAME, STR) SH_##NAME,
enum {
#include "gendefs/insn.h"
SH_MAX,
};
#undef GENDEFS_INSN
static_assert(SH_MAX <= 0xff);
AsmInstruction() = default;
/* Construct with one or several arguments */
@ -177,7 +185,7 @@ struct AsmInstruction
u16 tags;
/* Mnemonic **without the size indicator** */
char mnemonic[12];
char const *mnemonic() const;
/* Arguments (up to 2) */
AsmArgument args[2];
@ -235,6 +243,10 @@ struct AsmInstruction
/* Get the PC-relative target, assuming the instruction is at the provided
address, for instructions with PC-relative offsets. */
u32 getPCRelativeTarget(u32 pc) const;
private:
/* Assembler instruction name (mov, add, etc), without size modifier. */
u8 m_opcode;
};
} /* namespace FxOS */

View File

@ -23,7 +23,7 @@ void register_instruction(AsmInstruction const &ins)
if(insmap[encoding])
FxOS_log(ERR, "encoding collision between a %s and a %s at %04x",
insmap[encoding]->mnemonic, ins.mnemonic, encoding);
insmap[encoding]->mnemonic(), ins.mnemonic(), encoding);
else
insmap[encoding] = ins;
}

View File

@ -9,6 +9,7 @@
#include <fxos/util/format.h>
#include <string>
#include <cstring>
#include <cassert>
namespace FxOS {
@ -195,6 +196,12 @@ u32 AsmArgument::getPCRelativeTarget(u32 pc, int size) const
// Instruction management
//---
static char const *instructionMnemonics[] = {
#define GENDEFS_INSN(NAME, STR) [AsmInstruction::SH_##NAME] = STR,
#include "gendefs/insn.h"
#undef GENDEFS_INSN
};
AsmInstruction::AsmInstruction(char const *mn):
encoding {0}, opsize {0}, arg_count {0}
{
@ -214,9 +221,15 @@ AsmInstruction::AsmInstruction(char const *mn):
len -= 2;
}
len = std::min(len, 11);
strncpy(mnemonic, mn, len);
mnemonic[len] = 0;
int i;
for(i = 0; i < SH_MAX; i++) {
if(!strncmp(mn, instructionMnemonics[i], len)
&& !instructionMnemonics[i][len]) {
m_opcode = i;
break;
}
}
assert(i < SH_MAX && "AsmInstruction with unknown opcode string");
}
AsmInstruction::AsmInstruction(char const *mn, AsmArgument arg):
@ -235,6 +248,12 @@ AsmInstruction::AsmInstruction(
arg_count = 2;
}
char const *AsmInstruction::mnemonic() const
{
assert(m_opcode < SH_MAX);
return instructionMnemonics[m_opcode];
}
u32 AsmInstruction::getPCRelativeTarget(u32 pc) const
{
for(int i = 0; i < this->arg_count; i++) {

View File

@ -152,9 +152,10 @@ static void doOldInst(u32 pc, OldInstruction &i,
static char const *suffixes[5] = {"", ".b", ".w", "", ".l"};
char const *suffix = suffixes[(i.inst->opsize <= 4) ? i.inst->opsize : 0];
int spacing
= i.inst->arg_count ? 8 - strlen(i.inst->mnemonic) - strlen(suffix) : 0;
printf(" %s%s%*s", i.inst->mnemonic, suffix, spacing, "");
int spacing = i.inst->arg_count
? 8 - strlen(i.inst->mnemonic()) - strlen(suffix)
: 0;
printf(" %s%s%*s", i.inst->mnemonic(), suffix, spacing, "");
/* Arguments */
for(size_t n = 0; n < i.inst->arg_count; n++) {
@ -246,9 +247,9 @@ void viewAssemblyInstruction(Instruction const &ins, ViewAssemblyOptions *opts)
char const *suffix = suffixes[(opcode.opsize <= 4) ? opcode.opsize : 0];
int spacing
= opcode.arg_count ? 8 - strlen(opcode.mnemonic) - strlen(suffix) : 0;
= opcode.arg_count ? 8 - strlen(opcode.mnemonic()) - strlen(suffix) : 0;
std::string str = " ";
str += opcode.mnemonic;
str += opcode.mnemonic();
str += suffix;
str += std::string(spacing, ' ');