2007-03-27 15:09:14 +00:00
|
|
|
#include "MipsAssemblerDefinitions.h"
|
|
|
|
#include "MIPSAssembler.h"
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <boost/lexical_cast.hpp>
|
|
|
|
#include <boost/bind.hpp>
|
|
|
|
#include "lexical_cast_ex.h"
|
|
|
|
|
|
|
|
using namespace boost;
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
namespace MipsAssemblerDefinitions
|
|
|
|
{
|
2007-04-08 02:31:15 +00:00
|
|
|
//RsRtImm Parser
|
|
|
|
//-----------------------------
|
|
|
|
struct RsRtImm
|
|
|
|
{
|
|
|
|
typedef void (CMIPSAssembler::*AssemblerFunctionType) (unsigned int, unsigned int, uint16);
|
|
|
|
|
|
|
|
RsRtImm(AssemblerFunctionType Assembler) :
|
|
|
|
m_Assembler(Assembler)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator ()(tokenizer<>& Tokens, tokenizer<>::iterator& itToken, CMIPSAssembler* pAssembler)
|
|
|
|
{
|
|
|
|
unsigned int nRT, nRS;
|
|
|
|
uint16 nImm;
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRS = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRT = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nImm = lexical_cast_hex<string>((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(nRT == -1) throw exception();
|
|
|
|
if(nRS == -1) throw exception();
|
|
|
|
|
|
|
|
bind(m_Assembler, pAssembler, _1, _2, _3)(nRS, nRT, nImm);
|
|
|
|
}
|
|
|
|
|
|
|
|
AssemblerFunctionType m_Assembler;
|
|
|
|
};
|
|
|
|
|
2007-03-27 15:09:14 +00:00
|
|
|
//RtRsImm Parser
|
|
|
|
//-----------------------------
|
|
|
|
struct RtRsImm
|
|
|
|
{
|
|
|
|
typedef void (CMIPSAssembler::*AssemblerFunctionType) (unsigned int, unsigned int, uint16);
|
|
|
|
|
|
|
|
RtRsImm(AssemblerFunctionType Assembler) :
|
|
|
|
m_Assembler(Assembler)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator ()(tokenizer<>& Tokens, tokenizer<>::iterator& itToken, CMIPSAssembler* pAssembler)
|
|
|
|
{
|
|
|
|
unsigned int nRT, nRS;
|
|
|
|
uint16 nImm;
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRT = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRS = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nImm = lexical_cast_hex<string>((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(nRT == -1) throw exception();
|
|
|
|
if(nRS == -1) throw exception();
|
|
|
|
|
|
|
|
bind(m_Assembler, pAssembler, _1, _2, _3)(nRT, nRS, nImm);
|
|
|
|
}
|
|
|
|
|
|
|
|
AssemblerFunctionType m_Assembler;
|
|
|
|
};
|
|
|
|
|
2007-03-28 00:43:39 +00:00
|
|
|
//RdRsRt Parser
|
|
|
|
//-----------------------------
|
|
|
|
struct RdRsRt
|
|
|
|
{
|
|
|
|
typedef void (CMIPSAssembler::*AssemblerFunctionType) (unsigned int, unsigned int, unsigned int);
|
|
|
|
|
|
|
|
RdRsRt(AssemblerFunctionType Assembler) :
|
|
|
|
m_Assembler(Assembler)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator ()(tokenizer<>& Tokens, tokenizer<>::iterator& itToken, CMIPSAssembler* pAssembler)
|
|
|
|
{
|
|
|
|
unsigned int nRT, nRS, nRD;
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRD = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRS = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRT = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(nRT == -1) throw exception();
|
|
|
|
if(nRS == -1) throw exception();
|
|
|
|
if(nRD == -1) throw exception();
|
|
|
|
|
|
|
|
bind(m_Assembler, pAssembler, _1, _2, _3)(nRD, nRS, nRT);
|
|
|
|
}
|
|
|
|
|
|
|
|
AssemblerFunctionType m_Assembler;
|
|
|
|
};
|
|
|
|
|
2007-04-08 02:31:15 +00:00
|
|
|
//RsImm Parser
|
|
|
|
//-----------------------------
|
|
|
|
struct RsImm
|
|
|
|
{
|
|
|
|
typedef void (CMIPSAssembler::*AssemblerFunctionType) (unsigned int, uint16);
|
|
|
|
|
|
|
|
RsImm(AssemblerFunctionType Assembler) :
|
|
|
|
m_Assembler(Assembler)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator ()(tokenizer<>& Tokens, tokenizer<>::iterator& itToken, CMIPSAssembler* pAssembler)
|
|
|
|
{
|
|
|
|
unsigned int nRS;
|
|
|
|
uint16 nImm;
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRS = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nImm = lexical_cast_hex<string>((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(nRS == -1) throw exception();
|
|
|
|
|
|
|
|
bind(m_Assembler, pAssembler, _1, _2)(nRS, nImm);
|
|
|
|
}
|
|
|
|
|
|
|
|
AssemblerFunctionType m_Assembler;
|
|
|
|
};
|
|
|
|
|
2007-03-27 15:09:14 +00:00
|
|
|
//RtImm Parser
|
|
|
|
//-----------------------------
|
|
|
|
struct RtImm
|
|
|
|
{
|
|
|
|
typedef void (CMIPSAssembler::*AssemblerFunctionType) (unsigned int, uint16);
|
|
|
|
|
|
|
|
RtImm(AssemblerFunctionType Assembler) :
|
|
|
|
m_Assembler(Assembler)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator ()(tokenizer<>& Tokens, tokenizer<>::iterator& itToken, CMIPSAssembler* pAssembler)
|
|
|
|
{
|
|
|
|
unsigned int nRT;
|
|
|
|
uint16 nImm;
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRT = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nImm = lexical_cast_hex<string>((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(nRT == -1) throw exception();
|
|
|
|
|
|
|
|
bind(m_Assembler, pAssembler, _1, _2)(nRT, nImm);
|
|
|
|
}
|
|
|
|
|
|
|
|
AssemblerFunctionType m_Assembler;
|
|
|
|
};
|
|
|
|
|
|
|
|
//RtRsSa Parser
|
|
|
|
//-----------------------------
|
|
|
|
struct RtRsSa
|
|
|
|
{
|
|
|
|
typedef void (CMIPSAssembler::*AssemblerFunctionType) (unsigned int, unsigned int, unsigned int);
|
|
|
|
|
|
|
|
RtRsSa(AssemblerFunctionType Assembler) :
|
|
|
|
m_Assembler(Assembler)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator()(tokenizer<>& Tokens, tokenizer<>::iterator& itToken, CMIPSAssembler* pAssembler)
|
|
|
|
{
|
|
|
|
unsigned int nRT, nRS, nSA;
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRT = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRS = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nSA = lexical_cast<unsigned int>((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(nRT == -1) throw exception();
|
|
|
|
if(nRS == -1) throw exception();
|
|
|
|
|
|
|
|
bind(m_Assembler, pAssembler, _1, _2, _3)(nRT, nRS, nSA);
|
|
|
|
}
|
|
|
|
|
|
|
|
AssemblerFunctionType m_Assembler;
|
|
|
|
};
|
|
|
|
|
2007-03-31 00:33:07 +00:00
|
|
|
//RtOfsBase Parser
|
|
|
|
//-----------------------------
|
|
|
|
struct RtOfsBase
|
|
|
|
{
|
|
|
|
typedef void (CMIPSAssembler::*AssemblerFunctionType) (unsigned int, uint16, unsigned int);
|
|
|
|
|
|
|
|
RtOfsBase(AssemblerFunctionType Assembler) :
|
|
|
|
m_Assembler(Assembler)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator ()(tokenizer<>& Tokens, tokenizer<>::iterator& itToken, CMIPSAssembler* pAssembler)
|
|
|
|
{
|
|
|
|
unsigned int nRT, nBase;
|
|
|
|
uint16 nOfs;
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nRT = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nOfs = lexical_cast_hex<string>((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(itToken == Tokens.end()) throw exception();
|
|
|
|
nBase = CMIPSAssembler::GetRegisterIndex((*(++itToken)).c_str());
|
|
|
|
|
|
|
|
if(nBase == -1) throw exception();
|
|
|
|
if(nRT == -1) throw exception();
|
|
|
|
|
|
|
|
((pAssembler)->*(m_Assembler))(nRT, nOfs, nBase);
|
|
|
|
}
|
|
|
|
|
|
|
|
AssemblerFunctionType m_Assembler;
|
|
|
|
};
|
|
|
|
|
2007-03-27 15:09:14 +00:00
|
|
|
template <typename Functor>
|
|
|
|
struct SpecInstruction : public Instruction
|
|
|
|
{
|
|
|
|
SpecInstruction(const char* sMnemonic, const Functor& Parser) :
|
|
|
|
Instruction(sMnemonic),
|
|
|
|
m_Parser(Parser)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void Invoke(tokenizer<>& Tokens, tokenizer<>::iterator& itToken, CMIPSAssembler* pAssembler)
|
|
|
|
{
|
|
|
|
m_Parser(Tokens, itToken, pAssembler);
|
|
|
|
}
|
|
|
|
|
|
|
|
Functor m_Parser;
|
|
|
|
};
|
|
|
|
|
|
|
|
//Instruction definitions
|
|
|
|
//-------------------------------
|
|
|
|
|
2007-04-01 01:32:04 +00:00
|
|
|
SpecInstruction<RdRsRt> Instruction_ADDU = SpecInstruction<RdRsRt>("ADDU", RdRsRt(&CMIPSAssembler::ADDU));
|
2007-03-27 15:09:14 +00:00
|
|
|
SpecInstruction<RtRsImm> Instruction_ADDIU = SpecInstruction<RtRsImm>("ADDIU", RtRsImm(&CMIPSAssembler::ADDIU));
|
2007-04-08 02:31:15 +00:00
|
|
|
SpecInstruction<RsRtImm> Instruction_BEQ = SpecInstruction<RsRtImm>("BEQ", RsRtImm(&CMIPSAssembler::BEQ));
|
|
|
|
SpecInstruction<RsImm> Instruction_BGEZ = SpecInstruction<RsImm>("BGEZ", RsImm(&CMIPSAssembler::BGEZ));
|
|
|
|
SpecInstruction<RsImm> Instruction_BLEZ = SpecInstruction<RsImm>("BLEZ", RsImm(&CMIPSAssembler::BLEZ));
|
|
|
|
SpecInstruction<RsRtImm> Instruction_BNE = SpecInstruction<RsRtImm>("BNE", RsRtImm(&CMIPSAssembler::BNE));
|
2007-04-02 23:46:56 +00:00
|
|
|
SpecInstruction<RtOfsBase> Instruction_LHU = SpecInstruction<RtOfsBase>("LHU", RtOfsBase(&CMIPSAssembler::LHU));
|
2007-03-27 15:09:14 +00:00
|
|
|
SpecInstruction<RtImm> Instruction_LUI = SpecInstruction<RtImm>("LUI", RtImm(&CMIPSAssembler::LUI));
|
2007-03-31 00:33:07 +00:00
|
|
|
SpecInstruction<RtOfsBase> Instruction_LW = SpecInstruction<RtOfsBase>("LW", RtOfsBase(&CMIPSAssembler::LW));
|
2007-04-01 01:32:04 +00:00
|
|
|
SpecInstruction<RdRsRt> Instruction_MULT = SpecInstruction<RdRsRt>("MULT", RdRsRt(&CMIPSAssembler::MULT));
|
2007-04-04 01:03:30 +00:00
|
|
|
SpecInstruction<RdRsRt> Instruction_OR = SpecInstruction<RdRsRt>("OR", RdRsRt(&CMIPSAssembler::OR));
|
2007-03-27 15:09:14 +00:00
|
|
|
SpecInstruction<RtRsSa> Instruction_SLL = SpecInstruction<RtRsSa>("SLL", RtRsSa(&CMIPSAssembler::SLL));
|
2007-04-23 06:40:16 +00:00
|
|
|
SpecInstruction<RtRsImm> Instruction_SLTIU = SpecInstruction<RtRsImm>("SLTIU", RtRsImm(&CMIPSAssembler::SLTIU));
|
2007-03-28 00:43:39 +00:00
|
|
|
SpecInstruction<RdRsRt> Instruction_SLTU = SpecInstruction<RdRsRt>("SLTU", RdRsRt(&CMIPSAssembler::SLTU));
|
2007-03-27 15:09:14 +00:00
|
|
|
SpecInstruction<RtRsSa> Instruction_SRA = SpecInstruction<RtRsSa>("SRA", RtRsSa(&CMIPSAssembler::SRA));
|
|
|
|
|
|
|
|
Instruction* g_Instructions[] =
|
|
|
|
{
|
2007-04-01 01:32:04 +00:00
|
|
|
&Instruction_ADDU,
|
2007-03-27 15:09:14 +00:00
|
|
|
&Instruction_ADDIU,
|
2007-04-08 02:31:15 +00:00
|
|
|
&Instruction_BEQ,
|
|
|
|
&Instruction_BGEZ,
|
|
|
|
&Instruction_BLEZ,
|
|
|
|
&Instruction_BNE,
|
2007-04-02 23:46:56 +00:00
|
|
|
&Instruction_LHU,
|
2007-03-27 15:09:14 +00:00
|
|
|
&Instruction_LUI,
|
2007-03-31 00:33:07 +00:00
|
|
|
&Instruction_LW,
|
2007-04-01 01:32:04 +00:00
|
|
|
&Instruction_MULT,
|
2007-04-04 01:03:30 +00:00
|
|
|
&Instruction_OR,
|
2007-03-27 15:09:14 +00:00
|
|
|
&Instruction_SLL,
|
2007-04-23 06:40:16 +00:00
|
|
|
&Instruction_SLTIU,
|
2007-03-28 00:43:39 +00:00
|
|
|
&Instruction_SLTU,
|
2007-03-27 15:09:14 +00:00
|
|
|
&Instruction_SRA,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|