mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
SPARC disassembler improvements: [Vas Crabb]
* Fix addcc/andcc in SPARCv7 mode and simplify integer op tables * Allow ASI descriptions to be supplied with MCFG macro sun4: add SPARC ASI descriptions [Vas Crabb]
This commit is contained in:
parent
496fb0609b
commit
5b9e7bcccf
@ -24,8 +24,6 @@
|
||||
|
||||
#define SPARCV8 (0)
|
||||
|
||||
CPU_DISASSEMBLE( sparc );
|
||||
|
||||
const device_type MB86901 = &device_creator<mb86901_device>;
|
||||
|
||||
const int mb86901_device::WINDOW_COUNT = 7;
|
||||
|
@ -40,6 +40,10 @@
|
||||
#define SPARC_INT15 31
|
||||
#define SPARC_TRAP_INSTRUCTION 128
|
||||
|
||||
// TODO: when there are more SPARC CPUs, move setter to a base class
|
||||
#define MCFG_SPARC_ADD_ASI_DESC(desc) \
|
||||
mb86901_device::add_asi_desc(*device, desc);
|
||||
|
||||
class mb86901_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
@ -76,7 +80,11 @@ public:
|
||||
void hold_bus() { m_hold_bus = true; }
|
||||
void release_bus() { m_hold_bus = false; }
|
||||
|
||||
template<typename T> static void add_asi_desc(device_t &device, const T &desc) { return downcast<mb86901_device &>(device).add_asi_desc(desc); }
|
||||
|
||||
protected:
|
||||
template<typename T> void add_asi_desc(const T &desc) { m_dasm.add_asi_desc(desc); }
|
||||
|
||||
bool invoke_queued_traps();
|
||||
bool check_main_traps(UINT32 op, bool privileged, UINT32 alignment, UINT8 registeralign, bool noimmediate);
|
||||
|
||||
|
@ -86,45 +86,40 @@ const sparc_disassembler::branch_desc sparc_disassembler::CBCCC_DESC = {
|
||||
}
|
||||
};
|
||||
|
||||
const sparc_disassembler::int_op_desc_map::value_type sparc_disassembler::SIMPLE_INT_OP_DESC[] = {
|
||||
{ 0x00, { 7, false, "add" } },
|
||||
{ 0x01, { 7, true, "and" } },
|
||||
{ 0x02, { 7, true, "or" } },
|
||||
{ 0x03, { 7, true, "xor" } },
|
||||
{ 0x04, { 7, false, "sub" } },
|
||||
{ 0x05, { 7, true, "andn" } },
|
||||
{ 0x06, { 7, true, "orn" } },
|
||||
{ 0x07, { 7, true, "xnor" } },
|
||||
{ 0x08, { 7, false, "addx" } },
|
||||
{ 0x09, { 9, false, "mulx" } },
|
||||
{ 0x0a, { 8, false, "umul" } },
|
||||
{ 0x0b, { 8, false, "smul" } },
|
||||
{ 0x0c, { 7, false, "subx" } },
|
||||
{ 0x0d, { 9, false, "udivx" } },
|
||||
{ 0x0e, { 8, false, "udiv" } },
|
||||
{ 0x0f, { 8, false, "sdiv" } },
|
||||
{ 0x10, { 8, false, "addcc" } },
|
||||
{ 0x11, { 8, true, "andcc" } },
|
||||
{ 0x12, { 7, true, "orcc" } },
|
||||
{ 0x13, { 7, true, "xorcc" } },
|
||||
{ 0x14, { 7, false, "subcc" } },
|
||||
{ 0x15, { 7, true, "andncc" } },
|
||||
{ 0x16, { 7, true, "orncc" } },
|
||||
{ 0x17, { 7, true, "xnorcc" } },
|
||||
{ 0x18, { 7, false, "addxcc" } },
|
||||
{ 0x1a, { 8, false, "umulcc" } },
|
||||
{ 0x1b, { 8, false, "smulcc" } },
|
||||
{ 0x1c, { 7, false, "subxcc" } },
|
||||
{ 0x1e, { 8, false, "udivcc" } },
|
||||
{ 0x1f, { 8, false, "sdivcc" } },
|
||||
{ 0x20, { 7, false, "taddcc" } },
|
||||
{ 0x21, { 7, false, "tsubcc" } },
|
||||
{ 0x22, { 7, false, "taddcctv" } },
|
||||
{ 0x23, { 7, false, "tsubcctv" } },
|
||||
{ 0x24, { 7, false, "mulscc" } },
|
||||
{ 0x2d, { 9, false, "sdivx" } },
|
||||
{ 0x3c, { 7, false, "save" } },
|
||||
{ 0x3d, { 7, false, "restore" } }
|
||||
const sparc_disassembler::int_op_desc_map::value_type sparc_disassembler::V7_INT_OP_DESC[] = {
|
||||
{ 0x00, { false, "add" } }, { 0x10, { false, "addcc" } },
|
||||
{ 0x01, { true, "and" } }, { 0x11, { true, "andcc" } },
|
||||
{ 0x02, { true, "or" } }, { 0x12, { true, "orcc" } },
|
||||
{ 0x03, { true, "xor" } }, { 0x13, { true, "xorcc" } },
|
||||
{ 0x04, { false, "sub" } }, { 0x14, { false, "subcc" } },
|
||||
{ 0x05, { true, "andn" } }, { 0x15, { true, "andncc" } },
|
||||
{ 0x06, { true, "orn" } }, { 0x16, { true, "orncc" } },
|
||||
{ 0x07, { true, "xnor" } }, { 0x17, { true, "xnorcc" } },
|
||||
{ 0x08, { false, "addx" } }, { 0x18, { false, "addxcc" } },
|
||||
{ 0x0c, { false, "subx" } }, { 0x1c, { false, "subxcc" } },
|
||||
|
||||
{ 0x20, { false, "taddcc" } },
|
||||
{ 0x21, { false, "tsubcc" } },
|
||||
{ 0x22, { false, "taddcctv" } },
|
||||
{ 0x23, { false, "tsubcctv" } },
|
||||
{ 0x24, { false, "mulscc" } },
|
||||
|
||||
{ 0x3c, { false, "save" } },
|
||||
{ 0x3d, { false, "restore" } }
|
||||
};
|
||||
|
||||
const sparc_disassembler::int_op_desc_map::value_type sparc_disassembler::V8_INT_OP_DESC[] = {
|
||||
{ 0x0a, { false, "umul" } }, { 0x1a, { false, "umulcc" } },
|
||||
{ 0x0b, { false, "smul" } }, { 0x1b, { false, "smulcc" } },
|
||||
{ 0x0e, { false, "udiv" } }, { 0x1e, { false, "udivcc" } },
|
||||
{ 0x0f, { false, "sdiv" } }, { 0x1f, { false, "sdivcc" } }
|
||||
};
|
||||
|
||||
const sparc_disassembler::int_op_desc_map::value_type sparc_disassembler::V9_INT_OP_DESC[] = {
|
||||
{ 0x09, { false, "mulx" } },
|
||||
{ 0x0d, { false, "udivx" } },
|
||||
|
||||
{ 0x2d, { false, "sdivx" } }
|
||||
};
|
||||
|
||||
const sparc_disassembler::state_reg_desc_map::value_type sparc_disassembler::V9_STATE_REG_DESC[] = {
|
||||
@ -301,6 +296,12 @@ inline UINT32 sparc_disassembler::freg(UINT32 val, bool shift) const
|
||||
return (shift && (m_version >= 9)) ? ((val & 0x1e) | ((val << 5) & 0x20)) : val;
|
||||
}
|
||||
|
||||
template <typename T> inline void sparc_disassembler::add_int_op_desc(const T &desc)
|
||||
{
|
||||
for (const auto &it : desc)
|
||||
m_int_op_desc.insert(it);
|
||||
}
|
||||
|
||||
template <typename T> inline void sparc_disassembler::add_fpop1_desc(const T &desc)
|
||||
{
|
||||
for (const auto &it : desc)
|
||||
@ -346,7 +347,7 @@ sparc_disassembler::sparc_disassembler(unsigned version)
|
||||
FBFCC_DESC, // branch on floating-point condition codes
|
||||
(version == 8) ? CBCCC_DESC : EMPTY_BRANCH_DESC // branch on coprocessor condition codes, SPARCv8
|
||||
}
|
||||
, m_simple_int_op_desc(std::begin(SIMPLE_INT_OP_DESC), std::end(SIMPLE_INT_OP_DESC))
|
||||
, m_int_op_desc(std::begin(V7_INT_OP_DESC), std::end(V7_INT_OP_DESC))
|
||||
, m_state_reg_desc()
|
||||
, m_fpop1_desc(std::begin(V7_FPOP1_DESC), std::end(V7_FPOP1_DESC))
|
||||
, m_fpop2_desc(std::begin(V7_FPOP2_DESC), std::end(V7_FPOP2_DESC))
|
||||
@ -354,14 +355,20 @@ sparc_disassembler::sparc_disassembler(unsigned version)
|
||||
, m_asi_desc()
|
||||
, m_prftch_desc()
|
||||
{
|
||||
if (m_version >= 8)
|
||||
{
|
||||
add_int_op_desc(V8_INT_OP_DESC);
|
||||
}
|
||||
|
||||
if (m_version >= 9)
|
||||
{
|
||||
m_op_field_width = 11;
|
||||
|
||||
m_simple_int_op_desc.find(0x08)->second.mnemonic = "addc";
|
||||
m_simple_int_op_desc.find(0x0c)->second.mnemonic = "subc";
|
||||
m_simple_int_op_desc.find(0x18)->second.mnemonic = "addccc";
|
||||
m_simple_int_op_desc.find(0x1c)->second.mnemonic = "subccc";
|
||||
m_int_op_desc.find(0x08)->second.mnemonic = "addc";
|
||||
m_int_op_desc.find(0x0c)->second.mnemonic = "subc";
|
||||
m_int_op_desc.find(0x18)->second.mnemonic = "addccc";
|
||||
m_int_op_desc.find(0x1c)->second.mnemonic = "subccc";
|
||||
add_int_op_desc(V9_INT_OP_DESC);
|
||||
|
||||
add_state_reg_desc(V9_STATE_REG_DESC),
|
||||
add_fpop1_desc(V9_FPOP1_DESC);
|
||||
@ -654,8 +661,8 @@ offs_t sparc_disassembler::dasm(char *buf, offs_t pc, UINT32 op) const
|
||||
break;
|
||||
}
|
||||
{
|
||||
const auto it(m_simple_int_op_desc.find(OP3));
|
||||
if ((it != m_simple_int_op_desc.end()) && (m_version >= it->second.min_version))
|
||||
const auto it(m_int_op_desc.find(OP3));
|
||||
if (it != m_int_op_desc.end())
|
||||
{
|
||||
if (!USEIMM)
|
||||
print(buf, "%-*s%s,%s,%s", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], REG_NAMES[RS2], REG_NAMES[RD]);
|
||||
|
@ -97,7 +97,6 @@ private:
|
||||
|
||||
struct int_op_desc
|
||||
{
|
||||
unsigned min_version;
|
||||
bool hex_imm;
|
||||
const char *mnemonic;
|
||||
};
|
||||
@ -152,6 +151,7 @@ private:
|
||||
|
||||
UINT32 freg(UINT32 val, bool shift) const;
|
||||
|
||||
template <typename T> void add_int_op_desc(const T &desc);
|
||||
template <typename T> void add_fpop1_desc(const T &desc);
|
||||
template <typename T> void add_fpop2_desc(const T &desc);
|
||||
template <typename T> void add_ldst_desc(const T &desc);
|
||||
@ -167,7 +167,9 @@ private:
|
||||
static const branch_desc FBPFCC_DESC;
|
||||
static const branch_desc FBFCC_DESC;
|
||||
static const branch_desc CBCCC_DESC;
|
||||
static const int_op_desc_map::value_type SIMPLE_INT_OP_DESC[];
|
||||
static const int_op_desc_map::value_type V7_INT_OP_DESC[];
|
||||
static const int_op_desc_map::value_type V8_INT_OP_DESC[];
|
||||
static const int_op_desc_map::value_type V9_INT_OP_DESC[];
|
||||
static const state_reg_desc_map::value_type V9_STATE_REG_DESC[];
|
||||
static const char * const MOVCC_CC_NAMES[8];
|
||||
static const char * const MOVCC_COND_NAMES[32];
|
||||
@ -185,7 +187,7 @@ private:
|
||||
unsigned m_version;
|
||||
int m_op_field_width;
|
||||
branch_desc m_branch_desc[8];
|
||||
int_op_desc_map m_simple_int_op_desc;
|
||||
int_op_desc_map m_int_op_desc;
|
||||
state_reg_desc_map m_state_reg_desc;
|
||||
fpop1_desc_map m_fpop1_desc;
|
||||
fpop2_desc_map m_fpop2_desc;
|
||||
|
@ -429,6 +429,42 @@
|
||||
#define PM_ACCESSED (0x02000000) // accessed flag
|
||||
#define PM_MODIFIED (0x01000000) // modified flag
|
||||
|
||||
namespace
|
||||
{
|
||||
const sparc_disassembler::asi_desc_map::value_type sun4_asi_desc[] = {
|
||||
{ 0x10, { nullptr, "Flush I-Cache (Segment)" } },
|
||||
{ 0x11, { nullptr, "Flush I-Cache (Page)" } },
|
||||
{ 0x02, { nullptr, "System Space" } }, { 0x12, { nullptr, "Flush I-Cache (Context)" } },
|
||||
{ 0x03, { nullptr, "Segment Map" } }, { 0x13, { nullptr, "Flush I-Cache (User)" } },
|
||||
{ 0x04, { nullptr, "Page Map" } }, { 0x14, { nullptr, "Flush D-Cache (Segment)" } },
|
||||
{ 0x05, { nullptr, "Block Copy" } }, { 0x15, { nullptr, "Flush D-Cache (Page)" } },
|
||||
{ 0x06, { nullptr, "Region Map" } }, { 0x16, { nullptr, "Flush D-Cache (Context)" } },
|
||||
{ 0x07, { nullptr, "Flush Cache (Region)" } }, { 0x17, { nullptr, "Flush D-Cache (User)" } },
|
||||
{ 0x08, { nullptr, "User Instruction" } },
|
||||
{ 0x09, { nullptr, "Supervisor Instruction" } },
|
||||
{ 0x0a, { nullptr, "User Data" } },
|
||||
{ 0x0b, { nullptr, "Supervisor Data" } }, { 0x1b, { nullptr, "Flush I-Cache (Region)" } },
|
||||
{ 0x0c, { nullptr, "Flush Cache (Segment)" } },
|
||||
{ 0x0d, { nullptr, "Flush Cache (Page)" } },
|
||||
{ 0x0e, { nullptr, "Flush Cache (Context)" } },
|
||||
{ 0x0f, { nullptr, "Flush Cache (User)" } }, { 0x1f, { nullptr, "Flush D-Cache (Region)" } }
|
||||
};
|
||||
/* TODO: make SPARCstation-1 a different machine type so it can load its own ASI descriptions - it's a subset of Sun4
|
||||
const sparc_disassembler::asi_desc_map::value_type sun4c_asi_desc[] = {
|
||||
{ 0x02, { nullptr, "System Space" } },
|
||||
{ 0x03, { nullptr, "Segment Map" } },
|
||||
{ 0x04, { nullptr, "Page Map" } },
|
||||
{ 0x08, { nullptr, "User Instruction" } },
|
||||
{ 0x09, { nullptr, "Supervisor Instruction" } },
|
||||
{ 0x0a, { nullptr, "User Data" } },
|
||||
{ 0x0b, { nullptr, "Supervisor Data" } },
|
||||
{ 0x0c, { nullptr, "Flush Cache (Segment)" } },
|
||||
{ 0x0d, { nullptr, "Flush Cache (Page)" } },
|
||||
{ 0x0e, { nullptr, "Flush Cache (Context)" } }
|
||||
};
|
||||
*/
|
||||
}
|
||||
|
||||
class sun4_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -822,6 +858,7 @@ static MACHINE_CONFIG_START( sun4, sun4_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", MB86901, 16670000)
|
||||
MCFG_DEVICE_ADDRESS_MAP(AS_PROGRAM, sun4_mem)
|
||||
MCFG_SPARC_ADD_ASI_DESC(sun4_asi_desc)
|
||||
|
||||
MCFG_RAM_ADD(RAM_TAG)
|
||||
MCFG_RAM_DEFAULT_SIZE("4M")
|
||||
|
Loading…
Reference in New Issue
Block a user