From 22513fb6fe281f5ccb75aaddb6417a12a66c313d Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Mon, 25 May 2020 16:42:42 +0200 Subject: 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). --- src/devices/cpu/i960/i960.cpp | 130 +++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 65 deletions(-) (limited to 'src/devices/cpu/i960/i960.cpp') 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; } -- cgit v1.2.3-70-g09d2