summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/i960/i960.cpp
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2020-05-25 16:42:42 +0200
committer Olivier Galibert <galibert@pobox.com>2020-05-25 16:42:57 +0200
commit22513fb6fe281f5ccb75aaddb6417a12a66c313d (patch)
tree3cf84032cc6482d685a8dbb57e015bd17c7f7fdc /src/devices/cpu/i960/i960.cpp
parente42c2d2874cf9c1092c01ab5ce9ef997d465ce25 (diff)
emumem: A little more speedup. cache and specific change syntax, and are not pointers anymore [O. Galibert]
The last(?) two changes are: - Add a template parameter to everything (theoretically the address space width, in practice a level derived from it to keep as much compatibility between widths as possible) so that the shift size becomes a constant. - Change the syntax of declaring and initializing the caches and specifics so that they're embedded in the owner device. Solves lifetime issues and also removes one indirection (looking up the base dispatch pointer through the cache/specific pointer).
Diffstat (limited to 'src/devices/cpu/i960/i960.cpp')
-rw-r--r--src/devices/cpu/i960/i960.cpp130
1 files changed, 65 insertions, 65 deletions
diff --git a/src/devices/cpu/i960/i960.cpp b/src/devices/cpu/i960/i960.cpp
index abf2c089cb2..9db9d6ab095 100644
--- a/src/devices/cpu/i960/i960.cpp
+++ b/src/devices/cpu/i960/i960.cpp
@@ -19,7 +19,7 @@ i960_cpu_device::i960_cpu_device(const machine_config &mconfig, const char *tag,
: cpu_device(mconfig, I960, tag, owner, clock)
, m_stalled(false), m_program_config("program", ENDIANNESS_LITTLE, 32, 32, 0)
, m_rcache_pos(0), m_SAT(0), m_PRCB(0), m_PC(0), m_AC(0), m_IP(0), m_PIP(0), m_ICR(0), m_bursting(0), m_immediate_irq(0)
- , m_immediate_vector(0), m_immediate_pri(0), m_program(nullptr), m_cache(nullptr), m_icount(0)
+ , m_immediate_vector(0), m_immediate_pri(0), m_icount(0)
{
std::fill(std::begin(m_r), std::end(m_r), 0);
std::fill(std::begin(m_rcache_frame_addr), std::end(m_rcache_frame_addr), 0);
@@ -41,31 +41,31 @@ device_memory_interface::space_config_vector i960_cpu_device::memory_space_confi
uint32_t i960_cpu_device::i960_read_dword_unaligned(uint32_t address)
{
if (!DWORD_ALIGNED(address))
- return m_program->read_byte(address) | m_program->read_byte(address+1)<<8 | m_program->read_byte(address+2)<<16 | m_program->read_byte(address+3)<<24;
+ return m_program.read_byte(address) | m_program.read_byte(address+1)<<8 | m_program.read_byte(address+2)<<16 | m_program.read_byte(address+3)<<24;
else
- return m_program->read_dword(address);
+ return m_program.read_dword(address);
}
uint16_t i960_cpu_device::i960_read_word_unaligned(uint32_t address)
{
if (!WORD_ALIGNED(address))
- return m_program->read_byte(address) | m_program->read_byte(address+1)<<8;
+ return m_program.read_byte(address) | m_program.read_byte(address+1)<<8;
else
- return m_program->read_word(address);
+ return m_program.read_word(address);
}
void i960_cpu_device::i960_write_dword_unaligned(uint32_t address, uint32_t data)
{
if (!DWORD_ALIGNED(address))
{
- m_program->write_byte(address, data & 0xff);
- m_program->write_byte(address+1, (data>>8)&0xff);
- m_program->write_byte(address+2, (data>>16)&0xff);
- m_program->write_byte(address+3, (data>>24)&0xff);
+ m_program.write_byte(address, data & 0xff);
+ m_program.write_byte(address+1, (data>>8)&0xff);
+ m_program.write_byte(address+2, (data>>16)&0xff);
+ m_program.write_byte(address+3, (data>>24)&0xff);
}
else
{
- m_program->write_dword(address, data);
+ m_program.write_dword(address, data);
}
}
@@ -73,22 +73,22 @@ void i960_cpu_device::i960_write_word_unaligned(uint32_t address, uint16_t data)
{
if (!WORD_ALIGNED(address))
{
- m_program->write_byte(address, data & 0xff);
- m_program->write_byte(address+1, (data>>8)&0xff);
+ m_program.write_byte(address, data & 0xff);
+ m_program.write_byte(address+1, (data>>8)&0xff);
}
else
{
- m_program->write_word(address, data);
+ m_program.write_word(address, data);
}
}
void i960_cpu_device::send_iac(uint32_t adr)
{
uint32_t iac[4];
- iac[0] = m_program->read_dword(adr);
- iac[1] = m_program->read_dword(adr+4);
- iac[2] = m_program->read_dword(adr+8);
- iac[3] = m_program->read_dword(adr+12);
+ iac[0] = m_program.read_dword(adr);
+ iac[1] = m_program.read_dword(adr+4);
+ iac[2] = m_program.read_dword(adr+8);
+ iac[3] = m_program.read_dword(adr+12);
switch(iac[0]>>24) {
case 0x40: // generate irq
@@ -99,8 +99,8 @@ void i960_cpu_device::send_iac(uint32_t adr)
check_irqs();
break;
case 0x80: // store SAT & PRCB in memory
- m_program->write_dword(iac[1], m_SAT);
- m_program->write_dword(iac[1]+4, m_PRCB);
+ m_program.write_dword(iac[1], m_SAT);
+ m_program.write_dword(iac[1]+4, m_PRCB);
break;
case 0x89: // invalidate internal instruction cache
// we do not emulate the instruction cache, so this is safe to ignore
@@ -143,7 +143,7 @@ uint32_t i960_cpu_device::get_ea(uint32_t opcode)
case 0x5: // address of this instruction + the offset dword + 8
// which in reality is "address of next instruction + the offset dword"
- ret = m_cache->read_dword(m_IP);
+ ret = m_cache.read_dword(m_IP);
m_IP += 4;
ret += m_IP;
return ret;
@@ -152,22 +152,22 @@ uint32_t i960_cpu_device::get_ea(uint32_t opcode)
return m_r[abase] + (m_r[index] << scale);
case 0xc:
- ret = m_cache->read_dword(m_IP);
+ ret = m_cache.read_dword(m_IP);
m_IP += 4;
return ret;
case 0xd:
- ret = m_cache->read_dword(m_IP) + m_r[abase];
+ ret = m_cache.read_dword(m_IP) + m_r[abase];
m_IP += 4;
return ret;
case 0xe:
- ret = m_cache->read_dword(m_IP) + (m_r[index] << scale);
+ ret = m_cache.read_dword(m_IP) + (m_r[index] << scale);
m_IP += 4;
return ret;
case 0xf:
- ret = m_cache->read_dword(m_IP) + m_r[abase] + (m_r[index] << scale);
+ ret = m_cache.read_dword(m_IP) + m_r[abase] + (m_r[index] << scale);
m_IP += 4;
return ret;
@@ -430,12 +430,12 @@ void i960_cpu_device::test(uint32_t opcode, int mask)
// interrupt dispatch
void i960_cpu_device::take_interrupt(int vector, int lvl)
{
- int int_tab = m_program->read_dword(m_PRCB+20); // interrupt table
- int int_SP = m_program->read_dword(m_PRCB+24); // interrupt stack
+ int int_tab = m_program.read_dword(m_PRCB+20); // interrupt table
+ int int_SP = m_program.read_dword(m_PRCB+24); // interrupt stack
int SP;
uint32_t IRQV;
- IRQV = m_program->read_dword(int_tab + 36 + (vector-8)*4);
+ IRQV = m_program.read_dword(int_tab + 36 + (vector-8)*4);
// start the process
if(!(m_PC & 0x2000)) // if this is a nested interrupt, don't re-get int_SP
@@ -453,10 +453,10 @@ void i960_cpu_device::take_interrupt(int vector, int lvl)
do_call(IRQV, 7, SP);
// save the processor state
- m_program->write_dword(m_r[I960_FP]-16, m_PC);
- m_program->write_dword(m_r[I960_FP]-12, m_AC);
+ m_program.write_dword(m_r[I960_FP]-16, m_PC);
+ m_program.write_dword(m_r[I960_FP]-12, m_AC);
// store the vector
- m_program->write_dword(m_r[I960_FP]-8, vector-8);
+ m_program.write_dword(m_r[I960_FP]-8, vector-8);
m_PC &= ~0x1f00; // clear priority, state, trace-fault pending, and trace enable
m_PC |= (lvl<<16); // set CPU level to current IRQ level
@@ -465,14 +465,14 @@ void i960_cpu_device::take_interrupt(int vector, int lvl)
void i960_cpu_device::check_irqs()
{
- int int_tab = m_program->read_dword(m_PRCB+20); // interrupt table
+ int int_tab = m_program.read_dword(m_PRCB+20); // interrupt table
int cpu_pri = (m_PC>>16)&0x1f;
int pending_pri;
int lvl, irq, take = -1;
int vword;
static const uint32_t lvlmask[4] = { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
- pending_pri = m_program->read_dword(int_tab); // read pending priorities
+ pending_pri = m_program.read_dword(int_tab); // read pending priorities
if ((m_immediate_irq) && ((cpu_pri < m_immediate_pri) || (m_immediate_pri == 31)))
{
@@ -490,14 +490,14 @@ void i960_cpu_device::check_irqs()
wordl = (lvl % 4) * 8;
wordh = (wordl + 8) - 1;
- vword = m_program->read_dword(int_tab + word);
+ vword = m_program.read_dword(int_tab + word);
// take the first vector we find for this level
for (irq = wordh; irq >= wordl; irq--) {
if(vword & (1 << irq)) {
// clear pending bit
vword &= ~(1 << irq);
- m_program->write_dword(int_tab + word, vword);
+ m_program.write_dword(int_tab + word, vword);
take = irq;
break;
}
@@ -509,14 +509,14 @@ void i960_cpu_device::check_irqs()
// try to recover...
pending_pri &= ~(1 << lvl);
- m_program->write_dword(int_tab, pending_pri);
+ m_program.write_dword(int_tab, pending_pri);
return;
}
// if no vectors are waiting for this level, clear the level bit
if(!(vword & lvlmask[lvl % 4])) {
pending_pri &= ~(1 << lvl);
- m_program->write_dword(int_tab, pending_pri);
+ m_program.write_dword(int_tab, pending_pri);
}
take += ((lvl/4) * 32);
@@ -545,7 +545,7 @@ void i960_cpu_device::do_call(uint32_t adr, int type, uint32_t stack)
// flush the current register set to the current frame
FP = m_r[I960_FP] & ~0x3f;
for (i = 0; i < 16; i++) {
- m_program->write_dword(FP + (i*4), m_r[i]);
+ m_program.write_dword(FP + (i*4), m_r[i]);
}
}
else // a cache entry is available, use it
@@ -584,7 +584,7 @@ void i960_cpu_device::do_ret_0()
{
int i;
for(i=0; i<0x10; i++)
- m_r[i] = m_program->read_dword(m_r[I960_FP]+4*i);
+ m_r[i] = m_program.read_dword(m_r[I960_FP]+4*i);
if (m_rcache_pos < 0)
{
@@ -610,8 +610,8 @@ void i960_cpu_device::do_ret()
break;
case 7:
- x = m_program->read_dword(m_r[I960_FP]-16);
- y = m_program->read_dword(m_r[I960_FP]-12);
+ x = m_program.read_dword(m_r[I960_FP]-16);
+ y = m_program.read_dword(m_r[I960_FP]-12);
do_ret_0();
m_AC = y;
// #### test supervisor
@@ -1349,9 +1349,9 @@ void i960_cpu_device::execute_op(uint32_t opcode)
t2 = get_2_ri(opcode);
// interrupt control register
if(t1 == 0xff000004)
- m_ICR = m_program->read_dword(t2);
+ m_ICR = m_program.read_dword(t2);
else
- m_program->write_dword(t1, m_program->read_dword(t2));
+ m_program.write_dword(t1, m_program.read_dword(t2));
m_AC = (m_AC & ~7) | 2;
break;
@@ -1362,10 +1362,10 @@ void i960_cpu_device::execute_op(uint32_t opcode)
if(t1 == 0xff000010)
send_iac(t2);
else {
- m_program->write_dword(t1, m_program->read_dword(t2));
- m_program->write_dword(t1+4, m_program->read_dword(t2+4));
- m_program->write_dword(t1+8, m_program->read_dword(t2+8));
- m_program->write_dword(t1+12, m_program->read_dword(t2+12));
+ m_program.write_dword(t1, m_program.read_dword(t2));
+ m_program.write_dword(t1+4, m_program.read_dword(t2+4));
+ m_program.write_dword(t1+8, m_program.read_dword(t2+8));
+ m_program.write_dword(t1+12, m_program.read_dword(t2+12));
}
m_AC = (m_AC & ~7) | 2;
break;
@@ -1457,8 +1457,8 @@ void i960_cpu_device::execute_op(uint32_t opcode)
switch((opcode >> 7) & 0xf) {
case 0x0: // calls
t1 = get_1_ri(opcode);
- t2 = m_program->read_dword(m_SAT + 152); // get pointer to system procedure table
- t2 = m_program->read_dword(t2 + 48 + (t1 * 4));
+ t2 = m_program.read_dword(m_SAT + 152); // get pointer to system procedure table
+ t2 = m_program.read_dword(t2 + 48 + (t1 * 4));
if ((t2 & 3) != 0)
{
fatalerror("I960: system calls that jump into supervisor mode aren't yet supported\n");
@@ -1477,7 +1477,7 @@ void i960_cpu_device::execute_op(uint32_t opcode)
for (i = 0; i < 0x10; i++)
{
- m_program->write_dword(m_rcache_frame_addr[t1] + (i * sizeof(uint32_t)), m_rcache[t1][i]);
+ m_program.write_dword(m_rcache_frame_addr[t1] + (i * sizeof(uint32_t)), m_rcache[t1][i]);
}
}
m_rcache_pos = 0;
@@ -1935,7 +1935,7 @@ void i960_cpu_device::execute_op(uint32_t opcode)
case 0x80: { // ldob
m_icount -= 4;
- u8 v = m_program->read_byte(get_ea(opcode));
+ u8 v = m_program.read_byte(get_ea(opcode));
if(!m_stalled)
m_r[(opcode>>19)&0x1f] = v;
break;
@@ -1943,7 +1943,7 @@ void i960_cpu_device::execute_op(uint32_t opcode)
case 0x82: // stob
m_icount -= 2;
- m_program->write_byte(get_ea(opcode), m_r[(opcode>>19)&0x1f]);
+ m_program.write_byte(get_ea(opcode), m_r[(opcode>>19)&0x1f]);
break;
case 0x84: // bx
@@ -2113,7 +2113,7 @@ void i960_cpu_device::execute_op(uint32_t opcode)
case 0xc0: { // ldib
m_icount -= 4;
- s8 v = m_program->read_byte(get_ea(opcode));
+ s8 v = m_program.read_byte(get_ea(opcode));
if(!m_stalled)
m_r[(opcode>>19)&0x1f] = v;
break;
@@ -2121,7 +2121,7 @@ void i960_cpu_device::execute_op(uint32_t opcode)
case 0xc2: // stib
m_icount -= 2;
- m_program->write_byte(get_ea(opcode), m_r[(opcode>>19)&0x1f]);
+ m_program.write_byte(get_ea(opcode), m_r[(opcode>>19)&0x1f]);
break;
case 0xc8: { // ldis
@@ -2157,7 +2157,7 @@ void i960_cpu_device::execute_run()
m_bursting = 0;
- opcode = m_cache->read_dword(m_IP);
+ opcode = m_cache.read_dword(m_IP);
m_IP += 4;
m_stalled = false;
@@ -2171,7 +2171,7 @@ void i960_cpu_device::execute_run()
void i960_cpu_device::execute_set_input(int irqline, int state)
{
- int int_tab = m_program->read_dword(m_PRCB+20); // interrupt table
+ int int_tab = m_program.read_dword(m_PRCB+20); // interrupt table
int cpu_pri = (m_PC>>16)&0x1f;
int vector =0;
int priority;
@@ -2220,16 +2220,16 @@ void i960_cpu_device::execute_set_input(int irqline, int state)
else
{
// store the interrupt in the "pending" table
- pend = m_program->read_dword(int_tab);
+ pend = m_program.read_dword(int_tab);
pend |= (1 << priority);
- m_program->write_dword(int_tab, pend);
+ m_program.write_dword(int_tab, pend);
// now bitfield-ize the vector
word = ((vector / 32) * 4) + 4;
wordofs = vector % 32;
- pend = m_program->read_dword(int_tab + word);
+ pend = m_program.read_dword(int_tab + word);
pend |= (1 << wordofs);
- m_program->write_dword(int_tab + word, pend);
+ m_program.write_dword(int_tab + word, pend);
}
// and ack it to the core now that it's queued
@@ -2240,8 +2240,8 @@ void i960_cpu_device::execute_set_input(int irqline, int state)
void i960_cpu_device::device_start()
{
- m_program = &space(AS_PROGRAM);
- m_cache = m_program->cache<2, 0, ENDIANNESS_LITTLE>();
+ space(AS_PROGRAM).cache(m_cache);
+ space(AS_PROGRAM).specific(m_program);
save_item(NAME(m_IP));
save_item(NAME(m_PIP));
@@ -2336,9 +2336,9 @@ void i960_cpu_device::state_string_export(const device_state_entry &entry, std::
void i960_cpu_device::device_reset()
{
- m_SAT = m_program->read_dword(0);
- m_PRCB = m_program->read_dword(4);
- m_IP = m_program->read_dword(12);
+ m_SAT = m_program.read_dword(0);
+ m_PRCB = m_program.read_dword(4);
+ m_IP = m_program.read_dword(12);
m_PC = 0x001f2002;
m_AC = 0;
m_ICR = 0xff000000;
@@ -2348,7 +2348,7 @@ void i960_cpu_device::device_reset()
memset(m_r, 0, sizeof(m_r));
memset(m_rcache, 0, sizeof(m_rcache));
- m_r[I960_FP] = m_program->read_dword(m_PRCB+24);
+ m_r[I960_FP] = m_program.read_dword(m_PRCB+24);
m_r[I960_SP] = m_r[I960_FP] + 64;
m_rcache_pos = 0;
}