--- previous/src/dimension/i860dec.cpp 2018/04/24 19:30:01 1.1.1.1 +++ previous/src/dimension/i860dec.cpp 2018/04/24 19:33:27 1.1.1.3 @@ -1,6 +1,6 @@ /*************************************************************************** - i860dec.inc + i860dec.cpp Execution engine for the Intel i860 emulator. @@ -35,6 +35,7 @@ * - (SC) Instruction cache implemented (not present in MAME version) * - (SC) Added dual-instruction-mode support (removed in MAME version) * - (SC) Added rounding mode support and insn_fix + * - (AG) Added machine independent floating point emulation library * Generic notes: * - There is some amount of code duplication (e.g., see the * various insn_* routines for the branches and FP routines) that @@ -45,11 +46,6 @@ * today also use IEEE FP. * */ -#include -#include -#include - -#pragma STDC FENV_ACCESS on #define DELAY_SLOT_PC() ((m_dim == DIM_FULL) ? 12 : 8) #define DELAY_SLOT() do{\ @@ -87,9 +83,7 @@ void i860_cpu_device::gen_interrupt() } SET_EPSR_INT (1); -#if TRACE_EXT_INT - Log_Printf(LOG_WARN, "[i860] i860_gen_interrupt: External interrupt received %s", GET_PSR_IM() ? "[PSR.IN set, preparing to trap]" : "[ignored (interrupts disabled)]"); -#endif + Log_Printf(TRACE_EXT_INT, "[i860] i860_gen_interrupt: External interrupt received %s", GET_PSR_IM() ? "[PSR.IN set, preparing to trap]" : "[ignored (interrupts disabled)]"); #if ENABLE_PERF_COUNTERS m_intrs++; #endif @@ -128,42 +122,46 @@ UINT32 i860_cpu_device::ifetch(const UIN return pc & 4 ? ifetch64(pc) >> 32 : ifetch64(pc); } -UINT64 i860_cpu_device::ifetch64(const UINT32 pc) { - const UINT32 vaddr = pc & ~7; - const int cidx = (vaddr>>3) & I860_ICACHE_MASK; - if(m_icache_vaddr[cidx] != vaddr) { +UINT64 i860_cpu_device::ifetch64(const UINT32 pc, const UINT32 vaddr, int const cidx) { #if ENABLE_PERF_COUNTERS - m_icache_miss++; + m_icache_miss++; #endif - UINT32 paddr; - - if (GET_DIRBASE_ATE ()) { - paddr = get_address_translation (pc, 0 /* is_dataref */, 0 /* is_write */) & ~7; - m_flow &= ~EXITING_IFETCH; - if (PENDING_TRAP() && (GET_PSR_DAT () || GET_PSR_IAT ())) { - m_flow |= EXITING_IFETCH; - return 0xffeeffeeffeeffeeLL; - } - } else - paddr = vaddr; - - m_icache_vaddr[cidx] = vaddr; - UINT64 insn64; - if (GET_DIRBASE_CS8()) { - insn64 = rdcs8(paddr+7); insn64 <<= 8; - insn64 |= rdcs8(paddr+6); insn64 <<= 8; - insn64 |= rdcs8(paddr+5); insn64 <<= 8; - insn64 |= rdcs8(paddr+4); insn64 <<= 8; - insn64 |= rdcs8(paddr+3); insn64 <<= 8; - insn64 |= rdcs8(paddr+2); insn64 <<= 8; - insn64 |= rdcs8(paddr+1); insn64 <<= 8; - insn64 |= rdcs8(paddr+0); - } else { - nd_board_rd64_be(paddr, (UINT32*)&insn64); + UINT32 paddr; + + if (GET_DIRBASE_ATE ()) { + paddr = get_address_translation (pc, 0 /* is_dataref */, 0 /* is_write */) & ~7; + m_flow &= ~EXITING_IFETCH; + if (PENDING_TRAP() && (GET_PSR_DAT () || GET_PSR_IAT ())) { + m_flow |= EXITING_IFETCH; + return 0xffeeffeeffeeffeeLL; } - m_icache[cidx] = insn64; - - return insn64; + } else + paddr = vaddr; + + m_icache_vaddr[cidx] = vaddr; + UINT64 insn64; + if (GET_DIRBASE_CS8()) { + insn64 = rdcs8(paddr+7); insn64 <<= 8; + insn64 |= rdcs8(paddr+6); insn64 <<= 8; + insn64 |= rdcs8(paddr+5); insn64 <<= 8; + insn64 |= rdcs8(paddr+4); insn64 <<= 8; + insn64 |= rdcs8(paddr+3); insn64 <<= 8; + insn64 |= rdcs8(paddr+2); insn64 <<= 8; + insn64 |= rdcs8(paddr+1); insn64 <<= 8; + insn64 |= rdcs8(paddr+0); + } else { + NextDimension::i860_rd64_be(nd, paddr, (UINT32*)&insn64); + } + m_icache[cidx] = insn64; + + return insn64; +} + +inline UINT64 i860_cpu_device::ifetch64(const UINT32 pc) { + const UINT32 vaddr = pc & ~7; + const int cidx = (vaddr>>3) & I860_ICACHE_MASK; + if(m_icache_vaddr[cidx] != vaddr) { + return ifetch64(pc, vaddr, cidx); } else { #if ENABLE_PERF_COUNTERS m_icache_hit++; @@ -186,7 +184,7 @@ UINT64 i860_cpu_device::ifetch64(const U (SC) added TLB support. Read access updates even entries, Write access updates odd entries. TLB lookup checks both entries. R/W separation is for DPS copy loops. */ -UINT32 i860_cpu_device::get_address_translation (UINT32 vaddr, int is_dataref, int is_write) +inline UINT32 i860_cpu_device::get_address_translation (UINT32 vaddr, int is_dataref, int is_write) { UINT32 voffset = vaddr & I860_PAGE_OFF_MASK; UINT32 tlbidx = ((vaddr << 1) | is_write) & I860_TLB_MASK; @@ -204,7 +202,11 @@ UINT32 i860_cpu_device::get_address_tran #endif return (m_tlb_paddr[tlbidx ^ 1] & I860_PAGE_FRAME_MASK) + voffset; } + + return get_address_translation(vaddr, voffset, tlbidx, is_dataref, is_write); +} +UINT32 i860_cpu_device::get_address_translation(UINT32 vaddr, UINT32 voffset, UINT32 tlbidx, int is_dataref, int is_write) { #if ENABLE_PERF_COUNTERS m_tlb_miss++; #endif @@ -226,7 +228,7 @@ UINT32 i860_cpu_device::get_address_tran /* Get page directory entry at DTB:DIR:00. */ pg_dir_entry_a = dtb | (vdir << 2); - nd_board_rd32_le(pg_dir_entry_a, &pg_dir_entry); + NextDimension::i860_rd32_le(nd, pg_dir_entry_a, &pg_dir_entry); /* Check for non-present PDE. */ if (!(pg_dir_entry & 1)) @@ -271,7 +273,7 @@ UINT32 i860_cpu_device::get_address_tran /* Get page table entry at PFA1:PAGE:00. */ pfa1 = pg_dir_entry & I860_PAGE_FRAME_MASK; pg_tbl_entry_a = pfa1 | (vpage << 2); - nd_board_rd32_le(pg_tbl_entry_a, &pg_tbl_entry); + NextDimension::i860_rd32_le(nd, pg_tbl_entry_a, &pg_tbl_entry); /* Check for non-present PTE. */ if (!(pg_tbl_entry & 1)) @@ -314,8 +316,8 @@ UINT32 i860_cpu_device::get_address_tran /* Update A bit and check D bit. */ ttpde = pg_dir_entry | 0x20; ttpte = pg_tbl_entry | 0x20; - nd_board_wr32_le(pg_dir_entry_a, &ttpde); - nd_board_wr32_le(pg_tbl_entry_a, &ttpte); + NextDimension::i860_wr32_le(nd, pg_dir_entry_a, &ttpde); + NextDimension::i860_wr32_le(nd, pg_tbl_entry_a, &ttpte); if (is_write && is_dataref && (pg_tbl_entry & 0x40) == 0) { @@ -334,9 +336,7 @@ UINT32 i860_cpu_device::get_address_tran ret = pfa2 | voffset; -#if TRACE_ADDR_TRANSLATION - Log_Printf(LOG_WARN, "[i860] get_address_translation: virt(%08X) -> phys(%08X)\n", vaddr, ret); -#endif + Log_Printf(TRACE_ADDR_TRANSLATION, "[i860] get_address_translation: virt(%08X) -> phys(%08X)\n", vaddr, ret); return ret; } @@ -345,10 +345,8 @@ UINT32 i860_cpu_device::get_address_tran addr = address to write. size = size of write in bytes. data = data to write. */ -void i860_cpu_device::writemem_emu (UINT32 addr, int size, UINT8 *data) { -#if TRACE_RDWR_MEM - Log_Printf(LOG_WARN, "[i860] wrmem (ATE=%d) addr = %08X, size = %d, data = %08X\n", GET_DIRBASE_ATE (), addr, size, data); fflush(0); -#endif +inline void i860_cpu_device::writemem_emu (UINT32 addr, int size, UINT8 *data) { + Log_Printf(TRACE_RDWR_MEM, "[i860] wrmem (ATE=%d) addr = %08X, size = %d, data = %08X\n", GET_DIRBASE_ATE (), addr, size, *data); #if ENABLE_DEBUGGER dbg_check_wr(addr, size, data); @@ -360,9 +358,7 @@ void i860_cpu_device::writemem_emu (UINT UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 1 /* is_write */); if (PENDING_TRAP() && (GET_PSR_IAT () || GET_PSR_DAT ())) { -#if TRACE_PAGE_FAULT - Log_Printf(LOG_WARN, "[i860] %08X: ## Page fault (writememi_emu) virt=%08X", m_pc, addr); -#endif + Log_Printf(TRACE_PAGE_FAULT, "[i860] %08X: ## Page fault (writememi_emu) virt=%08X", m_pc, addr); SET_EXITING_MEMRW(EXITING_WRITEMEM); return; } @@ -380,7 +376,7 @@ void i860_cpu_device::writemem_emu (UINT #endif /* Now do the actual write. */ - wrmem[size](addr, (UINT32*)data); + wrmem[size](nd, addr, (UINT32*)data); } @@ -388,11 +384,9 @@ void i860_cpu_device::writemem_emu (UINT addr = address to read. size = size of read in bytes. dest = memory to put read data. */ -void i860_cpu_device::readmem_emu (UINT32 addr, int size, UINT8 *dest) +inline void i860_cpu_device::readmem_emu (UINT32 addr, int size, UINT8 *dest) { -#if TRACE_RDWR_MEM - Log_Printf(LOG_WARN, "[i860] fp_rdmem (ATE=%d) addr = %08X, size = %d\n", GET_DIRBASE_ATE (), addr, size); fflush(0); -#endif + Log_Printf(TRACE_RDWR_MEM, "[i860] fp_rdmem (ATE=%d) addr = %08X, size = %d\n", GET_DIRBASE_ATE (), addr, size); /* If virtual mode, do translation. */ if (GET_DIRBASE_ATE ()) @@ -400,10 +394,8 @@ void i860_cpu_device::readmem_emu (UINT3 UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 0 /* is_write */); if (PENDING_TRAP() && (GET_PSR_IAT () || GET_PSR_DAT ())) { -#if TRACE_PAGE_FAULT - Log_Printf(LOG_WARN, "[i860] %08X: ## Page fault (fp_readmem_emu) virt=%08X",m_pc,addr); + Log_Printf(TRACE_PAGE_FAULT, "[i860] %08X: ## Page fault (fp_readmem_emu) virt=%08X",m_pc,addr); // debugger(); -#endif SET_EXITING_MEMRW(EXITING_FPREADMEM); return; } @@ -419,7 +411,7 @@ void i860_cpu_device::readmem_emu (UINT3 return; } #endif - rdmem[size](addr, (UINT32*)dest); + rdmem[size](nd, addr, (UINT32*)dest); } @@ -428,11 +420,9 @@ void i860_cpu_device::readmem_emu (UINT3 size = size of write in bytes. data = pointer to the data. wmask = bit mask of bytes to write (only for pst.d). */ -void i860_cpu_device::writemem_emu (UINT32 addr, int size, UINT8 *data, UINT32 wmask) +inline void i860_cpu_device::writemem_emu (UINT32 addr, int size, UINT8 *data, UINT32 wmask) { -#if TRACE_RDWR_MEM - Log_Printf(LOG_WARN, "[i860] fp_wrmem (ATE=%d) addr = %08X, size = %d", GET_DIRBASE_ATE (), addr, size); fflush(0); -#endif + Log_Printf(TRACE_RDWR_MEM, "[i860] fp_wrmem (ATE=%d) addr = %08X, size = %d", GET_DIRBASE_ATE (), addr, size); /* If virtual mode, do translation. */ if (GET_DIRBASE_ATE ()) @@ -440,10 +430,8 @@ void i860_cpu_device::writemem_emu (UINT UINT32 phys = get_address_translation (addr, 1 /* is_dataref */, 1 /* is_write */); if (PENDING_TRAP() && GET_PSR_DAT ()) { -#if TRACE_PAGE_FAULT - Log_Printf(LOG_WARN, "[i860] %08X: ## Page fault (fp_writememi_emu) virt=%08X", m_pc,addr); + Log_Printf(TRACE_PAGE_FAULT, "[i860] %08X: ## Page fault (fp_writememi_emu) virt=%08X", m_pc,addr); // debugger(); -#endif SET_EXITING_MEMRW(EXITING_WRITEMEM); return; } @@ -461,16 +449,16 @@ void i860_cpu_device::writemem_emu (UINT #endif if(size == 8 && wmask != 0xff) { - if (wmask & 0x80) wrmem[1](addr+0, (UINT32*)&data[0]); - if (wmask & 0x40) wrmem[1](addr+1, (UINT32*)&data[1]); - if (wmask & 0x20) wrmem[1](addr+2, (UINT32*)&data[2]); - if (wmask & 0x10) wrmem[1](addr+3, (UINT32*)&data[3]); - if (wmask & 0x08) wrmem[1](addr+4, (UINT32*)&data[4]); - if (wmask & 0x04) wrmem[1](addr+5, (UINT32*)&data[5]); - if (wmask & 0x02) wrmem[1](addr+6, (UINT32*)&data[6]); - if (wmask & 0x01) wrmem[1](addr+7, (UINT32*)&data[7]); + if (wmask & 0x80) wrmem[1](nd, addr+0, (UINT32*)&data[0]); + if (wmask & 0x40) wrmem[1](nd, addr+1, (UINT32*)&data[1]); + if (wmask & 0x20) wrmem[1](nd, addr+2, (UINT32*)&data[2]); + if (wmask & 0x10) wrmem[1](nd, addr+3, (UINT32*)&data[3]); + if (wmask & 0x08) wrmem[1](nd, addr+4, (UINT32*)&data[4]); + if (wmask & 0x04) wrmem[1](nd, addr+5, (UINT32*)&data[5]); + if (wmask & 0x02) wrmem[1](nd, addr+6, (UINT32*)&data[6]); + if (wmask & 0x01) wrmem[1](nd, addr+7, (UINT32*)&data[7]); } else { - wrmem[size](addr, (UINT32*)data); + wrmem[size](nd, addr, (UINT32*)data); } } @@ -501,7 +489,7 @@ void i860_cpu_device::insn_ld_ctrl (UINT if (csrc2 > 5) { /* Control register not between 0..5. Undefined i860XR behavior. */ - Log_Printf(LOG_WARN, "[i860:%08X] insn_ld_from_ctrl: bad creg in ld.c (ignored)", m_pc); + Log_Printf(TRACE_UNDEFINED_I860, "[i860:%08X] insn_ld_from_ctrl: bad creg in ld.c (ignored)", m_pc); return; } #endif @@ -535,7 +523,7 @@ void i860_cpu_device::insn_st_ctrl (UINT if (csrc2 > 5) { /* Control register not between 0..5. Undefined i860XR behavior. */ - Log_Printf(LOG_WARN, "[i860:%08X] insn_st_to_ctrl: bad creg in st.c (ignored)", m_pc); + Log_Printf(TRACE_UNDEFINED_I860, "[i860:%08X] insn_st_to_ctrl: bad creg in st.c (ignored)", m_pc); return; } #endif @@ -601,12 +589,8 @@ void i860_cpu_device::insn_st_ctrl (UINT UINT32 enew = get_iregval (isrc1) & 0x003e01ef; UINT32 tmp = m_cregs[CR_FSR] & ~0x003e01ef; m_cregs[CR_FSR] = enew | tmp; - switch(GET_FSR_RM()) { - case 0: fesetround(FE_TONEAREST); break; - case 1: fesetround(FE_DOWNWARD); break; - case 2: fesetround(FE_UPWARD); break; - case 3: fesetround(FE_TOWARDZERO); break; - } + + float_set_rounding_mode (GET_FSR_RM(), &m_fpcs); } else if (csrc2 != CR_FIR) m_cregs[csrc2] = get_iregval (isrc1); @@ -623,18 +607,15 @@ void i860_cpu_device::insn_ldx (UINT32 i UINT32 idest = get_idest (insn); UINT32 eff = 0; /* Operand size, in bytes. */ - int sizes[4] = { 1, 1, 2, 4}; + const int sizes[4] = { 1, 1, 2, 4}; int size = 0; - int form_disp_reg = 0; /* Bits 28 and 0 determine the operand size. */ size = sizes[((insn >> 27) & 2) | (insn & 1)]; - /* Bit 26 determines the addressing mode (reg+reg or disp+reg). */ - form_disp_reg = (insn & 0x04000000); - + /* Bit 26 determines the addressing mode (reg+reg or disp+reg). */ /* Get effective address depending on disp+reg or reg+reg form. */ - if (form_disp_reg) + if (insn & 0x04000000) { /* Chop off lower bits of displacement. */ immsrc1 &= ~(size - 1); @@ -646,7 +627,7 @@ void i860_cpu_device::insn_ldx (UINT32 i #if TRACE_UNALIGNED_MEM if (eff & (size - 1)) { - Log_Printf(LOG_WARN, "[i860:%08X] Unaligned access detected (%08X)", m_pc, eff); + Log_Printf(TRACE_UNALIGNED_MEM, "[i860:%08X] Unaligned access detected (%08X)", m_pc, eff); SET_PSR_DAT (1); m_flow |= TRAP_NORMAL; return; @@ -662,18 +643,15 @@ void i860_cpu_device::insn_ldx (UINT32 i UINT32 readval = 0; readmem_emu(eff, size, (UINT8*)&readval); readval = sign_ext (readval, size * 8); /* Do not update register on page fault. */ - if (GET_EXITING_MEMRW()) - { + if (GET_EXITING_MEMRW()) { return; } set_iregval (idest, readval); } - else - { + else { UINT32 readval; readmem_emu(eff, size, (UINT8*)&readval); /* Do not update register on page fault. */ - if (GET_EXITING_MEMRW()) - { + if (GET_EXITING_MEMRW()) { return; } set_iregval (idest, readval); @@ -691,7 +669,7 @@ void i860_cpu_device::insn_stx (UINT32 i UINT32 isrc2 = get_isrc2 (insn); UINT32 eff = 0; /* Operand size, in bytes. */ - int sizes[4] = { 1, 1, 2, 4}; + const int sizes[4] = { 1, 1, 2, 4}; int size = 0; /* Bits 28 and 0 determine the operand size. */ @@ -722,7 +700,7 @@ void i860_cpu_device::insn_fsty (UINT32 UINT32 fdest = get_fdest (insn); UINT32 eff = 0; /* Operand size, in bytes. */ - int sizes[4] = { 8, 4, 16, 4}; + const int sizes[4] = { 8, 4, 16, 4}; int size = 0; int form_disp_reg = 0; int auto_inc = (insn & 1); @@ -749,7 +727,7 @@ void i860_cpu_device::insn_fsty (UINT32 #if TRACE_UNALIGNED_MEM if (eff & (size - 1)) { - Log_Printf(LOG_WARN, "[i860:%08X] Unaligned access detected (%08X)", m_pc, eff); + Log_Printf(TRACE_UNALIGNED_MEM, "[i860:%08X] Unaligned access detected (%08X)", m_pc, eff); SET_PSR_DAT (1); m_flow |= TRAP_NORMAL; return; @@ -765,7 +743,7 @@ void i860_cpu_device::insn_fsty (UINT32 if (isrc1 == isrc2) { /* Undefined i860XR behavior. */ - Log_Printf(LOG_WARN, "[i860:%08X] insn_fsty: isrc1 = isrc2 in fst with auto-inc (ignored)", m_pc); + Log_Printf(TRACE_UNDEFINED_I860, "[i860:%08X] insn_fsty: isrc1 = isrc2 in fst with auto-inc (ignored)", m_pc); return; } #endif @@ -787,7 +765,7 @@ void i860_cpu_device::insn_fldy (UINT32 UINT32 fdest = get_fdest (insn); UINT32 eff = 0; /* Operand size, in bytes. */ - int sizes[4] = { 8, 4, 16, 4}; + const int sizes[4] = { 8, 4, 16, 4}; int size = 0; int form_disp_reg = 0; int auto_inc = (insn & 1); @@ -830,7 +808,7 @@ void i860_cpu_device::insn_fldy (UINT32 if (isrc1 == isrc2) { /* Undefined i860XR behavior. */ - Log_Printf(LOG_WARN, "[i860:%08X] insn_fldy: isrc1 = isrc2 in fst with auto-inc (ignored)", m_pc); + Log_Printf(TRACE_UNDEFINED_I860, "[i860:%08X] insn_fldy: isrc1 = isrc2 in fst with auto-inc (ignored)", m_pc); return; } #endif @@ -839,7 +817,7 @@ void i860_cpu_device::insn_fldy (UINT32 #if TRACE_UNALIGNED_MEM if (eff & (size - 1)) { - Log_Printf(LOG_WARN, "[i860:%08X] Unaligned access detected (%08X)", m_pc, eff); + Log_Printf(TRACE_UNALIGNED_MEM, "[i860:%08X] Unaligned access detected (%08X)", m_pc, eff); SET_PSR_DAT (1); m_flow |= TRAP_NORMAL; return; @@ -891,10 +869,10 @@ void i860_cpu_device::insn_fldy (UINT32 m_L[2] = m_L[1]; m_L[1] = m_L[0]; if (size == 8) { - m_L[0].val.d = *((double*)bebuf); + m_L[0].val.d = *((FLOAT64*)bebuf); m_L[0].stat.lrp = 1; } else { - m_L[0].val.s = *((float*)bebuf); + m_L[0].val.s = *((FLOAT32*)bebuf); m_L[0].stat.lrp = 0; } } @@ -923,7 +901,7 @@ void i860_cpu_device::insn_pstd (UINT32 #if TRACE_UNDEFINED_I860 if (!(ps == 0 || ps == 1 || ps == 2)) - Log_Printf(LOG_WARN, "[i860:%08X] insn_pstd: Undefined i860XR behavior, invalid value %d for pixel size", m_pc, ps); + Log_Printf(TRACE_UNDEFINED_I860, "[i860:%08X] insn_pstd: Undefined i860XR behavior, invalid value %d for pixel size", m_pc, ps); #endif #if TRACE_UNDEFINED_I860 @@ -932,7 +910,7 @@ void i860_cpu_device::insn_pstd (UINT32 if (insn & 0x6) { /* Undefined i860XR behavior. */ - Log_Printf(LOG_WARN, "[i860:%08X] insn_pstd: bad operand size specifier", m_pc); + Log_Printf(TRACE_UNDEFINED_I860, "[i860:%08X] insn_pstd: bad operand size specifier", m_pc); } #endif @@ -945,7 +923,7 @@ void i860_cpu_device::insn_pstd (UINT32 #if TRACE_UNALIGNED_MEM if (eff & (8 - 1)) { - Log_Printf(LOG_WARN, "[i860:%08X] Unaligned access detected (%08X)", m_pc, eff); + Log_Printf(TRACE_UNALIGNED_MEM, "[i860:%08X] Unaligned access detected (%08X)", m_pc, eff); SET_PSR_DAT (1); m_flow |= TRAP_NORMAL; return; @@ -1010,7 +988,7 @@ void i860_cpu_device::insn_ixfr (UINT32 /* This is a bit-pattern transfer, not a conversion. */ iv = get_iregval (isrc1); - set_fregval_s (fdest, *(float *)&iv); + set_fregval_s (fdest, *(FLOAT32 *)&iv); } @@ -2072,7 +2050,7 @@ void i860_cpu_device::insn_calli (UINT32 if (isrc1 == 1) { /* Src1 must not be r1. */ - Log_Printf(LOG_WARN, "[i860:%08X] insn_calli: isrc1 = r1 on a calli", m_pc); + Log_Printf(TRACE_UNDEFINED_I860, "[i860:%08X] insn_calli: isrc1 = r1 on a calli", m_pc); } #endif @@ -2112,7 +2090,7 @@ void i860_cpu_device::insn_bla (UINT32 i if (isrc1 == isrc2) { /* Src1 and src2 the same is undefined i860XR behavior. */ - Log_Printf(LOG_WARN, "[i860:%08X] insn_bla: isrc1 and isrc2 are the same (ignored)", m_pc); + Log_Printf(TRACE_UNDEFINED_I860, "[i860:%08X] insn_bla: isrc1 and isrc2 are the same (ignored)", m_pc); return; } #endif @@ -2195,10 +2173,10 @@ void i860_cpu_device::insn_fmul (UINT32 int src_prec = insn & 0x100; /* 1 = double, 0 = single. */ int res_prec = insn & 0x080; /* 1 = double, 0 = single. */ int piped = insn & 0x400; /* 1 = pipelined, 0 = scalar. */ - double dbl_tmp_dest = 0.0; - float sgl_tmp_dest = 0.0; - double dbl_last_stage_contents = 0.0; - float sgl_last_stage_contents = 0.0; + FLOAT64 dbl_tmp_dest = FLOAT64_ZERO; + FLOAT32 sgl_tmp_dest = FLOAT32_ZERO; + FLOAT64 dbl_last_stage_contents = FLOAT64_ZERO; + FLOAT32 sgl_last_stage_contents = FLOAT32_ZERO; int is_pfmul3 = insn & 0x4; int num_stages = (src_prec && !is_pfmul3) ? 2 : 3; @@ -2235,8 +2213,8 @@ void i860_cpu_device::insn_fmul (UINT32 precision. */ if (src_prec) { - double v1 = get_fregval_d (fsrc1); - double v2 = get_fregval_d (fsrc2); + FLOAT64 v1 = get_fregval_d (fsrc1); + FLOAT64 v2 = get_fregval_d (fsrc2); /* For pipelined mul, if fsrc2 is the same as fdest, then the last stage is bypassed to fsrc2 (rather than using the value in fsrc2). @@ -2247,14 +2225,14 @@ void i860_cpu_device::insn_fmul (UINT32 v2 = dbl_last_stage_contents; if (res_prec) - dbl_tmp_dest = v1 * v2; + dbl_tmp_dest = float64_mul (v1, v2); else - sgl_tmp_dest = (float)(v1 * v2); + sgl_tmp_dest = float64_to_float32 (float64_mul (v1, v2)); } else { - float v1 = get_fregval_s (fsrc1); - float v2 = get_fregval_s (fsrc2); + FLOAT32 v1 = get_fregval_s (fsrc1); + FLOAT32 v2 = get_fregval_s (fsrc2); /* For pipelined mul, if fsrc2 is the same as fdest, then the last stage is bypassed to fsrc2 (rather than using the value in fsrc2). @@ -2265,9 +2243,9 @@ void i860_cpu_device::insn_fmul (UINT32 v2 = sgl_last_stage_contents; if (res_prec) - dbl_tmp_dest = (double)(v1 * v2); + dbl_tmp_dest = float64_mul (float32_to_float64 (v1), float32_to_float64 (v2)); else - sgl_tmp_dest = v1 * v2; + sgl_tmp_dest = float32_mul (v1, v2); } /* FIXME: Set result-status bits besides MRP. And copy to fsr from @@ -2331,8 +2309,8 @@ void i860_cpu_device::insn_fmlow (UINT32 UINT32 fsrc2 = get_fsrc2 (insn); UINT32 fdest = get_fdest (insn); - double v1 = get_fregval_d (fsrc1); - double v2 = get_fregval_d (fsrc2); + FLOAT64 v1 = get_fregval_d (fsrc1); + FLOAT64 v2 = get_fregval_d (fsrc2); INT64 i1 = *(UINT64 *)&v1; INT64 i2 = *(UINT64 *)&v2; INT64 tmp = 0; @@ -2355,7 +2333,7 @@ void i860_cpu_device::insn_fmlow (UINT32 tmp = i1 * i2; tmp &= 0x001fffffffffffffULL; tmp |= (i1 & 0x8000000000000000LL) ^ (i2 & 0x8000000000000000LL); - set_fregval_d (fdest, *(double *)&tmp); + set_fregval_d (fdest, *(FLOAT64 *)&tmp); } @@ -2369,11 +2347,11 @@ void i860_cpu_device::insn_fadd_sub (UIN int res_prec = insn & 0x080; /* 1 = double, 0 = single. */ int piped = insn & 0x400; /* 1 = pipelined, 0 = scalar. */ int is_sub = insn & 1; /* 1 = sub, 0 = add. */ - double dbl_tmp_dest = 0.0; - float sgl_tmp_dest = 0.0; - double dbl_last_stage_contents = 0.0; - float sgl_last_stage_contents = 0.0; - + FLOAT64 dbl_tmp_dest = FLOAT64_ZERO; + FLOAT32 sgl_tmp_dest = FLOAT32_ZERO; + FLOAT64 dbl_last_stage_contents = FLOAT64_ZERO; + FLOAT32 sgl_last_stage_contents = FLOAT32_ZERO; + #if TRACE_UNDEFINED_I860 /* Check for invalid .ds combination. */ if ((insn & 0x180) == 0x100) @@ -2399,8 +2377,8 @@ void i860_cpu_device::insn_fadd_sub (UIN precision. */ if (src_prec) { - double v1 = get_fregval_d (fsrc1); - double v2 = get_fregval_d (fsrc2); + FLOAT64 v1 = get_fregval_d (fsrc1); + FLOAT64 v2 = get_fregval_d (fsrc2); /* For pipelined add/sub, if fsrc1 is the same as fdest, then the last stage is bypassed to fsrc1 (rather than using the value in fsrc1). @@ -2411,14 +2389,14 @@ void i860_cpu_device::insn_fadd_sub (UIN v2 = dbl_last_stage_contents; if (res_prec) - dbl_tmp_dest = is_sub ? v1 - v2 : v1 + v2; + dbl_tmp_dest = is_sub ? float64_sub (v1, v2) : float64_add (v1, v2); else - sgl_tmp_dest = is_sub ? (float)(v1 - v2) : (float)(v1 + v2); + sgl_tmp_dest = is_sub ? float64_to_float32 (float64_sub (v1, v2)) : float64_to_float32 (float64_add (v1, v2)); } else { - float v1 = get_fregval_s (fsrc1); - float v2 = get_fregval_s (fsrc2); + FLOAT32 v1 = get_fregval_s (fsrc1); + FLOAT32 v2 = get_fregval_s (fsrc2); /* For pipelined add/sub, if fsrc1 is the same as fdest, then the last stage is bypassed to fsrc1 (rather than using the value in fsrc1). @@ -2429,9 +2407,9 @@ void i860_cpu_device::insn_fadd_sub (UIN v2 = sgl_last_stage_contents; if (res_prec) - dbl_tmp_dest = is_sub ? (double)(v1 - v2) : (double)(v1 + v2); + dbl_tmp_dest = is_sub ? float64_sub (float32_to_float64 (v1), float32_to_float64 (v2)) : float64_add (float32_to_float64 (v1), float32_to_float64 (v2)); else - sgl_tmp_dest = is_sub ? v1 - v2 : v1 + v2; + sgl_tmp_dest = is_sub ? float32_sub (v1, v2) : float32_add (v1, v2); } /* FIXME: Set result-status bits besides ARP. And copy to fsr from @@ -2500,19 +2478,19 @@ void i860_cpu_device::insn_fix(UINT32 in precision. Operation: fdest = integer part of fsrc1 in lower 32-bits. */ if (src_prec) { - double v1 = get_fregval_d (fsrc1); - INT32 iv = rint(v1); + FLOAT64 v1 = get_fregval_d (fsrc1); + INT32 iv = float64_to_int32 (v1); /* We always write a single, since the lower 32-bits of fdest get the result (and the even numbered reg is the lower). */ - set_fregval_s (fdest, *(float *)&iv); + set_fregval_s (fdest, *(FLOAT32 *)&iv); } else { - float v1 = get_fregval_s (fsrc1); - INT32 iv = rint(v1); + FLOAT32 v1 = get_fregval_s (fsrc1); + INT32 iv = float32_to_int32 (v1); /* We always write a single, since the lower 32-bits of fdest get the result (and the even numbered reg is the lower). */ - set_fregval_s (fdest, *(float *)&iv); + set_fregval_s (fdest, *(FLOAT32 *)&iv); } /* FIXME: Handle updating of pipestages for pfix. */ @@ -2521,9 +2499,9 @@ void i860_cpu_device::insn_fix(UINT32 in { Log_Printf(LOG_WARN, "[i860:%08X] insn_fix: FIXME: pipelined not functional yet", m_pc); if (res_prec) - set_fregval_d (fdest, 0.0); + set_fregval_d (fdest, FLOAT64_ZERO); else - set_fregval_s (fdest, 0.0); + set_fregval_s (fdest, FLOAT32_ZERO); } } @@ -2573,9 +2551,9 @@ static const struct /* 1111 */ { OP_SRC1, OP_SRC2, OP_T, OP_APIPE|FLAGM, 0, 0} }; -float i860_cpu_device::get_fval_from_optype_s (UINT32 insn, int optype) +FLOAT32 i860_cpu_device::get_fval_from_optype_s (UINT32 insn, int optype) { - float retval = 0.0; + FLOAT32 retval = FLOAT32_ZERO; UINT32 fsrc1 = get_fsrc1 (insn); UINT32 fsrc2 = get_fsrc2 (insn); @@ -2612,9 +2590,9 @@ float i860_cpu_device::get_fval_from_opt } -double i860_cpu_device::get_fval_from_optype_d (UINT32 insn, int optype) +FLOAT64 i860_cpu_device::get_fval_from_optype_d (UINT32 insn, int optype) { - double retval = 0.0; + FLOAT64 retval = FLOAT64_ZERO; UINT32 fsrc1 = get_fsrc1 (insn); UINT32 fsrc2 = get_fsrc2 (insn); @@ -2670,14 +2648,14 @@ void i860_cpu_device::insn_dualop (UINT3 int res_prec = insn & 0x080; /* 1 = double, 0 = single. */ int is_pfam = insn & 0x400; /* 1 = pfam, 0 = pfmam. */ int is_sub = insn & 0x10; /* 1 = pf[m]sm, 0 = pf[m]am. */ - double dbl_tmp_dest_mul = 0.0; - float sgl_tmp_dest_mul = 0.0; - double dbl_tmp_dest_add = 0.0; - float sgl_tmp_dest_add = 0.0; - double dbl_last_Mstage_contents = 0.0; - float sgl_last_Mstage_contents = 0.0; - double dbl_last_Astage_contents = 0.0; - float sgl_last_Astage_contents = 0.0; + FLOAT64 dbl_tmp_dest_mul = FLOAT64_ZERO; + FLOAT32 sgl_tmp_dest_mul = FLOAT32_ZERO; + FLOAT64 dbl_tmp_dest_add = FLOAT64_ZERO; + FLOAT32 sgl_tmp_dest_add = FLOAT32_ZERO; + FLOAT64 dbl_last_Mstage_contents = FLOAT64_ZERO; + FLOAT32 sgl_last_Mstage_contents = FLOAT32_ZERO; + FLOAT64 dbl_last_Astage_contents = FLOAT64_ZERO; + FLOAT32 sgl_last_Astage_contents = FLOAT32_ZERO; int num_mul_stages = src_prec ? 2 : 3; int dpc = insn & 0xf; @@ -2736,8 +2714,8 @@ void i860_cpu_device::insn_dualop (UINT3 precision. */ if (src_prec) { - double v1 = get_fval_from_optype_d (insn, M_unit_op1); - double v2 = get_fval_from_optype_d (insn, M_unit_op2); + FLOAT64 v1 = get_fval_from_optype_d (insn, M_unit_op1); + FLOAT64 v2 = get_fval_from_optype_d (insn, M_unit_op2); /* For mul, if fsrc2 is the same as fdest, then the last stage is bypassed to fsrc2 (rather than using the value in fsrc2). @@ -2748,14 +2726,14 @@ void i860_cpu_device::insn_dualop (UINT3 v2 = is_pfam ? dbl_last_Astage_contents : dbl_last_Mstage_contents; if (res_prec) - dbl_tmp_dest_mul = v1 * v2; + dbl_tmp_dest_mul = float64_mul (v1, v2); else - sgl_tmp_dest_mul = (float)(v1 * v2); + sgl_tmp_dest_mul = float64_to_float32 (float64_mul (v1, v2)); } else { - float v1 = get_fval_from_optype_s (insn, M_unit_op1); - float v2 = get_fval_from_optype_s (insn, M_unit_op2); + FLOAT32 v1 = get_fval_from_optype_s (insn, M_unit_op1); + FLOAT32 v2 = get_fval_from_optype_s (insn, M_unit_op2); /* For mul, if fsrc2 is the same as fdest, then the last stage is bypassed to fsrc2 (rather than using the value in fsrc2). @@ -2766,9 +2744,9 @@ void i860_cpu_device::insn_dualop (UINT3 v2 = is_pfam ? sgl_last_Astage_contents : sgl_last_Mstage_contents; if (res_prec) - dbl_tmp_dest_mul = (double)(v1 * v2); + dbl_tmp_dest_mul = float64_mul (float32_to_float64 (v1), float32_to_float64 (v2)); else - sgl_tmp_dest_mul = v1 * v2; + sgl_tmp_dest_mul = float32_mul (v1, v2); } /* Do the add operation, being careful about source and result @@ -2776,8 +2754,8 @@ void i860_cpu_device::insn_dualop (UINT3 here. */ if (res_prec) { - double v1 = get_fval_from_optype_d (insn, A_unit_op1); - double v2 = get_fval_from_optype_d (insn, A_unit_op2); + FLOAT64 v1 = get_fval_from_optype_d (insn, A_unit_op1); + FLOAT64 v2 = get_fval_from_optype_d (insn, A_unit_op2); /* For add/sub, if fsrc1 is the same as fdest, then the last stage is bypassed to fsrc1 (rather than using the value in fsrc1). @@ -2788,14 +2766,14 @@ void i860_cpu_device::insn_dualop (UINT3 v2 = is_pfam ? dbl_last_Astage_contents : dbl_last_Mstage_contents; if (res_prec) - dbl_tmp_dest_add = is_sub ? v1 - v2 : v1 + v2; + dbl_tmp_dest_add = is_sub ? float64_sub (v1, v2) : float64_add (v1, v2); else - sgl_tmp_dest_add = is_sub ? (float)(v1 - v2) : (float)(v1 + v2); + sgl_tmp_dest_add = is_sub ? float64_to_float32 (float64_sub (v1, v2)) : float64_to_float32 (float64_add (v1, v2)); } else { - float v1 = get_fval_from_optype_s (insn, A_unit_op1); - float v2 = get_fval_from_optype_s (insn, A_unit_op2); + FLOAT32 v1 = get_fval_from_optype_s (insn, A_unit_op1); + FLOAT32 v2 = get_fval_from_optype_s (insn, A_unit_op2); /* For add/sub, if fsrc1 is the same as fdest, then the last stage is bypassed to fsrc1 (rather than using the value in fsrc1). @@ -2806,9 +2784,9 @@ void i860_cpu_device::insn_dualop (UINT3 v2 = is_pfam ? sgl_last_Astage_contents : sgl_last_Mstage_contents; if (res_prec) - dbl_tmp_dest_add = is_sub ? (double)(v1 - v2) : (double)(v1 + v2); + dbl_tmp_dest_add = is_sub ? float64_sub (float32_to_float64 (v1), float32_to_float64 (v2)) : float64_add (float32_to_float64 (v1), float32_to_float64 (v2)); else - sgl_tmp_dest_add = is_sub ? v1 - v2 : v1 + v2; + sgl_tmp_dest_add = is_sub ? float32_sub (v1, v2) : float32_add (v1, v2); } /* If necessary, load T. */ @@ -2937,9 +2915,9 @@ void i860_cpu_device::insn_frcp (UINT32 precision. */ if (src_prec) { - double v = get_fregval_d (fsrc2); - double res; - if (v == (double)0.0) + FLOAT64 v = get_fregval_d (fsrc2); + FLOAT64 res; + if (FLOAT64_IS_ZERO(v)) { /* Generate source-exception trap if fsrc2 is 0. */ if (0 /* && GET_FSR_FTE () */) @@ -2956,19 +2934,19 @@ void i860_cpu_device::insn_frcp (UINT32 be okay. */ SET_FSR_SE (0); *((UINT64 *)&v) &= 0xfffff00000000000ULL; - res = (double)1.0/v; + res = float64_div (FLOAT64_ONE, v); *((UINT64 *)&res) &= 0xfffff00000000000ULL; if (res_prec) set_fregval_d (fdest, res); else - set_fregval_s (fdest, (float)res); + set_fregval_s (fdest, float64_to_float32 (res)); } } else { - float v = get_fregval_s (fsrc2); - float res; - if (v == 0.0) + FLOAT32 v = get_fregval_s (fsrc2); + FLOAT32 res; + if (FLOAT32_IS_ZERO(v)) { /* Generate source-exception trap if fsrc2 is 0. */ if (0 /* GET_FSR_FTE () */) @@ -2985,10 +2963,10 @@ void i860_cpu_device::insn_frcp (UINT32 be okay. */ SET_FSR_SE (0); *((UINT32 *)&v) &= 0xffff8000; - res = (float)1.0/v; + res = float32_div (FLOAT32_ONE, v); *((UINT32 *)&res) &= 0xffff8000; if (res_prec) - set_fregval_d (fdest, (double)res); + set_fregval_d (fdest, float32_to_float64 (res)); else set_fregval_s (fdest, res); } @@ -3024,9 +3002,9 @@ void i860_cpu_device::insn_frsqr (UINT32 precision. */ if (src_prec) { - double v = get_fregval_d (fsrc2); - double res; - if (v == 0.0 || v < 0.0) + FLOAT64 v = get_fregval_d (fsrc2); + FLOAT64 res; + if (FLOAT64_IS_ZERO(v) || FLOAT64_IS_NEG(v)) { /* Generate source-exception trap if fsrc2 is 0 or negative. */ if (0 /* GET_FSR_FTE () */) @@ -3041,19 +3019,19 @@ void i860_cpu_device::insn_frsqr (UINT32 { SET_FSR_SE (0); *((UINT64 *)&v) &= 0xfffff00000000000ULL; - res = (double)1.0/sqrt (v); + res = float64_div (FLOAT64_ONE, float64_sqrt (v)); *((UINT64 *)&res) &= 0xfffff00000000000ULL; if (res_prec) set_fregval_d (fdest, res); else - set_fregval_s (fdest, (float)res); + set_fregval_s (fdest, float64_to_float32 (res)); } } else { - float v = get_fregval_s (fsrc2); - float res; - if (v == 0.0 || v < 0.0) + FLOAT32 v = get_fregval_s (fsrc2); + FLOAT32 res; + if (FLOAT32_IS_ZERO(v) || FLOAT32_IS_NEG(v)) { /* Generate source-exception trap if fsrc2 is 0 or negative. */ if (0 /* GET_FSR_FTE () */) @@ -3068,10 +3046,10 @@ void i860_cpu_device::insn_frsqr (UINT32 { SET_FSR_SE (0); *((UINT32 *)&v) &= 0xffff8000; - res = (float)1.0/sqrt (v); + res = float32_div (FLOAT32_ONE, float32_sqrt (v)); *((UINT32 *)&res) &= 0xffff8000; if (res_prec) - set_fregval_d (fdest, (double)res); + set_fregval_d (fdest, float32_to_float64 (res)); else set_fregval_s (fdest, res); } @@ -3084,7 +3062,7 @@ void i860_cpu_device::insn_fxfr (UINT32 { UINT32 fsrc1 = get_fsrc1 (insn); UINT32 idest = get_idest (insn); - float fv = 0; + FLOAT32 fv = FLOAT32_ZERO; /* This is a bit-pattern transfer, not a conversion. */ fv = get_fregval_s (fsrc1); @@ -3122,19 +3100,19 @@ void i860_cpu_device::insn_ftrunc (UINT3 lower 32-bits. */ if (src_prec) { - double v1 = get_fregval_d (fsrc1); - INT32 iv = (INT32)v1; + FLOAT64 v1 = get_fregval_d (fsrc1); + INT32 iv = float64_to_int32_round_to_zero (v1); /* We always write a single, since the lower 32-bits of fdest get the result (and the even numbered reg is the lower). */ - set_fregval_s (fdest, *(float *)&iv); + set_fregval_s (fdest, *(FLOAT32 *)&iv); } else { - float v1 = get_fregval_s (fsrc1); - INT32 iv = (INT32)v1; + FLOAT32 v1 = get_fregval_s (fsrc1); + INT32 iv = float32_to_int32_round_to_zero (v1); /* We always write a single, since the lower 32-bits of fdest get the result (and the even numbered reg is the lower). */ - set_fregval_s (fdest, *(float *)&iv); + set_fregval_s (fdest, *(FLOAT32 *)&iv); } /* FIXME: Handle updating of pipestages for pftrunc. */ @@ -3143,9 +3121,9 @@ void i860_cpu_device::insn_ftrunc (UINT3 { Log_Printf(LOG_WARN, "[i860:%08X] insn_ftrunc: FIXME: pipelined not functional yet", m_pc); if (res_prec) - set_fregval_d (fdest, 0.0); + set_fregval_d (fdest, FLOAT64_ZERO); else - set_fregval_s (fdest, 0.0); + set_fregval_s (fdest, FLOAT32_ZERO); } } @@ -3158,24 +3136,24 @@ void i860_cpu_device::insn_famov (UINT32 int src_prec = insn & 0x100; /* 1 = double, 0 = single. */ int res_prec = insn & 0x080; /* 1 = double, 0 = single. */ int piped = insn & 0x400; /* 1 = pipelined, 0 = scalar. */ - double dbl_tmp_dest = 0.0; - double sgl_tmp_dest = 0.0; + FLOAT64 dbl_tmp_dest = FLOAT64_ZERO; + FLOAT32 sgl_tmp_dest = FLOAT32_ZERO; /* Do the operation, being careful about source and result precision. */ if (src_prec) { - double v1 = get_fregval_d (fsrc1); + FLOAT64 v1 = get_fregval_d (fsrc1); if (res_prec) dbl_tmp_dest = v1; else - sgl_tmp_dest = (float)v1; + sgl_tmp_dest = float64_to_float32 (v1); } else { - float v1 = get_fregval_s (fsrc1); + FLOAT32 v1 = get_fregval_s (fsrc1); if (res_prec) - dbl_tmp_dest = (double)v1; + dbl_tmp_dest = float32_to_float64 (v1); else sgl_tmp_dest = v1; } @@ -3237,8 +3215,8 @@ void i860_cpu_device::insn_fiadd_sub (UI int res_prec = insn & 0x080; /* 1 = double, 0 = single. */ int piped = insn & 0x400; /* 1 = pipelined, 0 = scalar. */ int is_sub = insn & 0x4; /* 1 = sub, 0 = add. */ - double dbl_tmp_dest = 0.0; - float sgl_tmp_dest = 0.0; + FLOAT64 dbl_tmp_dest = FLOAT64_ZERO; + FLOAT32 sgl_tmp_dest = FLOAT32_ZERO; #if TRACE_UNDEFINED_I860 /* Check for invalid .ds and .sd combinations. */ @@ -3253,8 +3231,8 @@ void i860_cpu_device::insn_fiadd_sub (UI precision. */ if (src_prec) { - double v1 = get_fregval_d (fsrc1); - double v2 = get_fregval_d (fsrc2); + FLOAT64 v1 = get_fregval_d (fsrc1); + FLOAT64 v2 = get_fregval_d (fsrc2); UINT64 iv1 = *(UINT64 *)&v1; UINT64 iv2 = *(UINT64 *)&v2; UINT64 r; @@ -3263,14 +3241,14 @@ void i860_cpu_device::insn_fiadd_sub (UI else r = iv1 + iv2; if (res_prec) - dbl_tmp_dest = *(double *)&r; + dbl_tmp_dest = *(FLOAT64 *)&r; else assert (0); /* .ds not allowed. */ } else { - float v1 = get_fregval_s (fsrc1); - float v2 = get_fregval_s (fsrc2); + FLOAT32 v1 = get_fregval_s (fsrc1); + FLOAT32 v2 = get_fregval_s (fsrc2); UINT64 iv1 = (UINT64)(*(UINT32 *)&v1); UINT64 iv2 = (UINT64)(*(UINT32 *)&v2); UINT32 r; @@ -3281,7 +3259,7 @@ void i860_cpu_device::insn_fiadd_sub (UI if (res_prec) assert (0); /* .sd not allowed. */ else - sgl_tmp_dest = *(float *)&r; + sgl_tmp_dest = *(FLOAT32 *)&r; } /* FIXME: Copy result-status bit IRP to fsr from last stage. */ @@ -3334,8 +3312,8 @@ void i860_cpu_device::insn_fcmp (UINT32 UINT32 fsrc2 = get_fsrc2 (insn); UINT32 fdest = get_fdest (insn); int src_prec = insn & 0x100; /* 1 = double, 0 = single. */ - double dbl_tmp_dest = 0.0; - double sgl_tmp_dest = 0.0; + FLOAT64 dbl_tmp_dest = FLOAT64_ZERO; + FLOAT32 sgl_tmp_dest = FLOAT32_ZERO; /* int is_eq = insn & 1; */ int is_gt = ((insn & 0x81) == 0x00); int is_le = ((insn & 0x81) == 0x80); @@ -3353,23 +3331,23 @@ void i860_cpu_device::insn_fcmp (UINT32 result into the first stage of the adder pipeline. We'll model this by just pushing in dbl_ or sgl_tmp_dest which equal 0.0. */ if (src_prec) { - double v1 = get_fregval_d (fsrc1); - double v2 = get_fregval_d (fsrc2); + FLOAT64 v1 = get_fregval_d (fsrc1); + FLOAT64 v2 = get_fregval_d (fsrc2); if (is_gt) /* gt. */ - SET_PSR_CC_F (v1 > v2 ? 1 : 0); + SET_PSR_CC_F (float64_gt (v1, v2) ? 1 : 0); // v1 > v2 else if (is_le) /* le. */ - SET_PSR_CC_F (v1 <= v2 ? 0 : 1); + SET_PSR_CC_F (float64_le (v1, v2) ? 0 : 1); // v1 <= v2 else /* eq. */ - SET_PSR_CC_F (v1 == v2 ? 1 : 0); + SET_PSR_CC_F (float64_eq (v1, v2) ? 1 : 0); // v1 == v2 } else { - float v1 = get_fregval_s (fsrc1); - float v2 = get_fregval_s (fsrc2); + FLOAT32 v1 = get_fregval_s (fsrc1); + FLOAT32 v2 = get_fregval_s (fsrc2); if (is_gt) /* gt. */ - SET_PSR_CC_F (v1 > v2 ? 1 : 0); + SET_PSR_CC_F (float32_gt (v1, v2) ? 1 : 0); // v1 > v2 else if (is_le) /* le. */ - SET_PSR_CC_F (v1 <= v2 ? 0 : 1); + SET_PSR_CC_F (float32_le (v1, v2) ? 0 : 1); // v1 <= v2 else /* eq. */ - SET_PSR_CC_F (v1 == v2 ? 1 : 0); + SET_PSR_CC_F (float32_eq (v1, v2) ? 1 : 0); // v1 == v2 } /* FIXME: Set result-status bits besides ARP. And copy to fsr from @@ -3412,10 +3390,10 @@ void i860_cpu_device::insn_fzchk (UINT32 UINT32 fdest = get_fdest (insn); int piped = insn & 0x400; /* 1 = pipelined, 0 = scalar. */ int is_fzchks = insn & 8; /* 1 = fzchks, 0 = fzchkl. */ - double dbl_tmp_dest = 0.0; + FLOAT64 dbl_tmp_dest = FLOAT64_ZERO; int i; - double v1 = get_fregval_d (fsrc1); - double v2 = get_fregval_d (fsrc2); + FLOAT64 v1 = get_fregval_d (fsrc1); + FLOAT64 v2 = get_fregval_d (fsrc2); UINT64 iv1 = *(UINT64 *)&v1; UINT64 iv2 = *(UINT64 *)&v2; UINT64 r = 0; @@ -3472,7 +3450,7 @@ void i860_cpu_device::insn_fzchk (UINT32 } } - dbl_tmp_dest = *(double *)&r; + dbl_tmp_dest = *(FLOAT64 *)&r; SET_PSR_PM (pm); m_merge = 0; @@ -3508,8 +3486,8 @@ void i860_cpu_device::insn_form (UINT32 UINT32 fsrc1 = get_fsrc1 (insn); UINT32 fdest = get_fdest (insn); int piped = insn & 0x400; /* 1 = pipelined, 0 = scalar. */ - double dbl_tmp_dest = 0.0; - double v1 = get_fregval_d (fsrc1); + FLOAT64 dbl_tmp_dest = FLOAT64_ZERO; + FLOAT64 v1 = get_fregval_d (fsrc1); UINT64 iv1 = *(UINT64 *)&v1; #if TRACE_UNDEFINED_I860 @@ -3522,7 +3500,7 @@ void i860_cpu_device::insn_form (UINT32 #endif iv1 |= m_merge; - dbl_tmp_dest = *(double *)&iv1; + dbl_tmp_dest = *(FLOAT64 *)&iv1; m_merge = 0; /* FIXME: Copy result-status bit IRP to fsr from last stage. */ @@ -3557,16 +3535,16 @@ void i860_cpu_device::insn_faddp (UINT32 UINT32 fsrc2 = get_fsrc2 (insn); UINT32 fdest = get_fdest (insn); int piped = insn & 0x400; /* 1 = pipelined, 0 = scalar. */ - double dbl_tmp_dest = 0.0; - double v1 = get_fregval_d (fsrc1); - double v2 = get_fregval_d (fsrc2); + FLOAT64 dbl_tmp_dest = FLOAT64_ZERO; + FLOAT64 v1 = get_fregval_d (fsrc1); + FLOAT64 v2 = get_fregval_d (fsrc2); UINT64 iv1 = *(UINT64 *)&v1; UINT64 iv2 = *(UINT64 *)&v2; UINT64 r = 0; int ps = GET_PSR_PS (); r = iv1 + iv2; - dbl_tmp_dest = *(double *)&r; + dbl_tmp_dest = *(FLOAT64 *)&r; /* Update the merge register depending on the pixel size. PS: 0 = 8 bits, 1 = 16 bits, 2 = 32-bits. */ @@ -3585,11 +3563,10 @@ void i860_cpu_device::insn_faddp (UINT32 m_merge = ((m_merge >> 8) & ~0xff000000ff000000ULL); m_merge |= (r & 0xff000000ff000000ULL); } -#if TRACE_UNDEFINED_I860 - else - Log_Printf(LOG_WARN, "[i860:%08X] insn_faddp: Undefined i860XR behavior, invalid value %d for pixel size", m_pc, ps); -#endif - + else { + Log_Printf(TRACE_UNDEFINED_I860, "[i860:%08X] insn_faddp: Undefined i860XR behavior, invalid value %d for pixel size", m_pc, ps); + } + /* FIXME: Copy result-status bit IRP to fsr from last stage. */ /* FIXME: Scalar version flows through all stages. */ if (!piped) @@ -3622,15 +3599,15 @@ void i860_cpu_device::insn_faddz (UINT32 UINT32 fsrc2 = get_fsrc2 (insn); UINT32 fdest = get_fdest (insn); int piped = insn & 0x400; /* 1 = pipelined, 0 = scalar. */ - double dbl_tmp_dest = 0.0; - double v1 = get_fregval_d (fsrc1); - double v2 = get_fregval_d (fsrc2); + FLOAT64 dbl_tmp_dest = FLOAT64_ZERO; + FLOAT64 v1 = get_fregval_d (fsrc1); + FLOAT64 v2 = get_fregval_d (fsrc2); UINT64 iv1 = *(UINT64 *)&v1; UINT64 iv2 = *(UINT64 *)&v2; UINT64 r = 0; r = iv1 + iv2; - dbl_tmp_dest = *(double *)&r; + dbl_tmp_dest = *(FLOAT64 *)&r; /* Update the merge register. */ m_merge = ((m_merge >> 16) & ~0xffff0000ffff0000ULL); @@ -3660,236 +3637,230 @@ void i860_cpu_device::insn_faddz (UINT32 } } - -/* Flags for the decode table. */ -enum { - DEC_MORE = 1, /* More decoding necessary. */ - DEC_DECODED = 2 /* Fully decoded, go. */ -}; - - /* First-level decode table (i.e., for the 6 primary opcode bits). */ -const i860_cpu_device::decode_tbl_t i860_cpu_device::decode_tbl[64] = { +const i860_cpu_device::insn_func i860_cpu_device::decode_tbl[64] = { /* A slight bit of decoding for loads and stores is done in the execution routines (operand size and addressing mode), which is why their respective entries are identical. */ - { &i860_cpu_device::insn_ldx, DEC_DECODED}, /* ld.b isrc1(isrc2),idest. */ - { &i860_cpu_device::insn_ldx, DEC_DECODED}, /* ld.b #const(isrc2),idest. */ - { &i860_cpu_device::insn_ixfr, DEC_DECODED}, /* ixfr isrc1ni,fdest. */ - { &i860_cpu_device::insn_stx, DEC_DECODED}, /* st.b isrc1ni,#const(isrc2). */ - { &i860_cpu_device::insn_ldx, DEC_DECODED}, /* ld.{s,l} isrc1(isrc2),idest. */ - { &i860_cpu_device::insn_ldx, DEC_DECODED}, /* ld.{s,l} #const(isrc2),idest. */ - { 0, 0}, - { &i860_cpu_device::insn_stx, DEC_DECODED}, /* st.{s,l} isrc1ni,#const(isrc2),idest.*/ - { &i860_cpu_device::insn_fldy, DEC_DECODED}, /* fld.{l,d,q} isrc1(isrc2)[++],fdest. */ - { &i860_cpu_device::insn_fldy, DEC_DECODED}, /* fld.{l,d,q} #const(isrc2)[++],fdest. */ - { &i860_cpu_device::insn_fsty, DEC_DECODED}, /* fst.{l,d,q} fdest,isrc1(isrc2)[++] */ - { &i860_cpu_device::insn_fsty, DEC_DECODED}, /* fst.{l,d,q} fdest,#const(isrc2)[++] */ - { &i860_cpu_device::insn_ld_ctrl, DEC_DECODED}, /* ld.c csrc2,idest. */ - { &i860_cpu_device::insn_flush, DEC_DECODED}, /* flush #const(isrc2) (or autoinc). */ - { &i860_cpu_device::insn_st_ctrl, DEC_DECODED}, /* st.c isrc1,csrc2. */ - { &i860_cpu_device::insn_pstd, DEC_DECODED}, /* pst.d fdest,#const(isrc2)[++]. */ - { &i860_cpu_device::insn_bri, DEC_DECODED}, /* bri isrc1ni. */ - { &i860_cpu_device::insn_trap, DEC_DECODED}, /* trap isrc1ni,isrc2,idest. */ - { 0, DEC_MORE}, /* FP ESCAPE FORMAT, more decode. */ - { 0, DEC_MORE}, /* CORE ESCAPE FORMAT, more decode. */ - { &i860_cpu_device::insn_btne, DEC_DECODED}, /* btne isrc1,isrc2,sbroff. */ - { &i860_cpu_device::insn_btne_imm, DEC_DECODED}, /* btne #const,isrc2,sbroff. */ - { &i860_cpu_device::insn_bte, DEC_DECODED}, /* bte isrc1,isrc2,sbroff. */ - { &i860_cpu_device::insn_bte_imm, DEC_DECODED}, /* bte #const5,isrc2,idest. */ - { &i860_cpu_device::insn_fldy, DEC_DECODED}, /* pfld.{l,d,q} isrc1(isrc2)[++],fdest.*/ - { &i860_cpu_device::insn_fldy, DEC_DECODED}, /* pfld.{l,d,q} #const(isrc2)[++],fdest.*/ - { &i860_cpu_device::insn_br, DEC_DECODED}, /* br lbroff. */ - { &i860_cpu_device::insn_call, DEC_DECODED}, /* call lbroff . */ - { &i860_cpu_device::insn_bc, DEC_DECODED}, /* bc lbroff. */ - { &i860_cpu_device::insn_bct, DEC_DECODED}, /* bc.t lbroff. */ - { &i860_cpu_device::insn_bnc, DEC_DECODED}, /* bnc lbroff. */ - { &i860_cpu_device::insn_bnct, DEC_DECODED}, /* bnc.t lbroff. */ - { &i860_cpu_device::insn_addu, DEC_DECODED}, /* addu isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_addu_imm, DEC_DECODED}, /* addu #const,isrc2,idest. */ - { &i860_cpu_device::insn_subu, DEC_DECODED}, /* subu isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_subu_imm, DEC_DECODED}, /* subu #const,isrc2,idest. */ - { &i860_cpu_device::insn_adds, DEC_DECODED}, /* adds isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_adds_imm, DEC_DECODED}, /* adds #const,isrc2,idest. */ - { &i860_cpu_device::insn_subs, DEC_DECODED}, /* subs isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_subs_imm, DEC_DECODED}, /* subs #const,isrc2,idest. */ - { &i860_cpu_device::insn_shl, DEC_DECODED}, /* shl isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_shl_imm, DEC_DECODED}, /* shl #const,isrc2,idest. */ - { &i860_cpu_device::insn_shr, DEC_DECODED}, /* shr isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_shr_imm, DEC_DECODED}, /* shr #const,isrc2,idest. */ - { &i860_cpu_device::insn_shrd, DEC_DECODED}, /* shrd isrc1ni,isrc2,idest. */ - { &i860_cpu_device::insn_bla, DEC_DECODED}, /* bla isrc1ni,isrc2,sbroff. */ - { &i860_cpu_device::insn_shra, DEC_DECODED}, /* shra isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_shra_imm, DEC_DECODED}, /* shra #const,isrc2,idest. */ - { &i860_cpu_device::insn_and, DEC_DECODED}, /* and isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_and_imm, DEC_DECODED}, /* and #const,isrc2,idest. */ - { 0, 0}, - { &i860_cpu_device::insn_andh_imm, DEC_DECODED}, /* andh #const,isrc2,idest. */ - { &i860_cpu_device::insn_andnot, DEC_DECODED}, /* andnot isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_andnot_imm, DEC_DECODED}, /* andnot #const,isrc2,idest. */ - { 0, 0}, - { &i860_cpu_device::insn_andnoth_imm, DEC_DECODED}, /* andnoth #const,isrc2,idest. */ - { &i860_cpu_device::insn_or, DEC_DECODED}, /* or isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_or_imm, DEC_DECODED}, /* or #const,isrc2,idest. */ - { 0, 0}, - { &i860_cpu_device::insn_orh_imm, DEC_DECODED}, /* orh #const,isrc2,idest. */ - { &i860_cpu_device::insn_xor, DEC_DECODED}, /* xor isrc1,isrc2,idest. */ - { &i860_cpu_device::insn_xor_imm, DEC_DECODED}, /* xor #const,isrc2,idest. */ - { 0, 0}, - { &i860_cpu_device::insn_xorh_imm, DEC_DECODED}, /* xorh #const,isrc2,idest. */ + &i860_cpu_device::insn_ldx, /* ld.b isrc1(isrc2),idest. */ + &i860_cpu_device::insn_ldx, /* ld.b #const(isrc2),idest. */ + &i860_cpu_device::insn_ixfr, /* ixfr isrc1ni,fdest. */ + &i860_cpu_device::insn_stx, /* st.b isrc1ni,#const(isrc2). */ + &i860_cpu_device::insn_ldx, /* ld.{s,l} isrc1(isrc2),idest. */ + &i860_cpu_device::insn_ldx, /* ld.{s,l} #const(isrc2),idest. */ + &i860_cpu_device::dec_unrecog, + &i860_cpu_device::insn_stx, /* st.{s,l} isrc1ni,#const(isrc2),idest.*/ + &i860_cpu_device::insn_fldy, /* fld.{l,d,q} isrc1(isrc2)[++],fdest. */ + &i860_cpu_device::insn_fldy, /* fld.{l,d,q} #const(isrc2)[++],fdest. */ + &i860_cpu_device::insn_fsty, /* fst.{l,d,q} fdest,isrc1(isrc2)[++] */ + &i860_cpu_device::insn_fsty, /* fst.{l,d,q} fdest,#const(isrc2)[++] */ + &i860_cpu_device::insn_ld_ctrl, /* ld.c csrc2,idest. */ + &i860_cpu_device::insn_flush, /* flush #const(isrc2) (or autoinc). */ + &i860_cpu_device::insn_st_ctrl, /* st.c isrc1,csrc2. */ + &i860_cpu_device::insn_pstd, /* pst.d fdest,#const(isrc2)[++]. */ + &i860_cpu_device::insn_bri, /* bri isrc1ni. */ + &i860_cpu_device::insn_trap, /* trap isrc1ni,isrc2,idest. */ + &i860_cpu_device::dec_unrecog, /* FP ESCAPE FORMAT, more decode. */ + &i860_cpu_device::dec_unrecog, /* CORE ESCAPE FORMAT, more decode. */ + &i860_cpu_device::insn_btne, /* btne isrc1,isrc2,sbroff. */ + &i860_cpu_device::insn_btne_imm, /* btne #const,isrc2,sbroff. */ + &i860_cpu_device::insn_bte, /* bte isrc1,isrc2,sbroff. */ + &i860_cpu_device::insn_bte_imm, /* bte #const5,isrc2,idest. */ + &i860_cpu_device::insn_fldy, /* pfld.{l,d,q} isrc1(isrc2)[++],fdest.*/ + &i860_cpu_device::insn_fldy, /* pfld.{l,d,q} #const(isrc2)[++],fdest.*/ + &i860_cpu_device::insn_br, /* br lbroff. */ + &i860_cpu_device::insn_call, /* call lbroff . */ + &i860_cpu_device::insn_bc, /* bc lbroff. */ + &i860_cpu_device::insn_bct, /* bc.t lbroff. */ + &i860_cpu_device::insn_bnc, /* bnc lbroff. */ + &i860_cpu_device::insn_bnct, /* bnc.t lbroff. */ + &i860_cpu_device::insn_addu, /* addu isrc1,isrc2,idest. */ + &i860_cpu_device::insn_addu_imm, /* addu #const,isrc2,idest. */ + &i860_cpu_device::insn_subu, /* subu isrc1,isrc2,idest. */ + &i860_cpu_device::insn_subu_imm, /* subu #const,isrc2,idest. */ + &i860_cpu_device::insn_adds, /* adds isrc1,isrc2,idest. */ + &i860_cpu_device::insn_adds_imm, /* adds #const,isrc2,idest. */ + &i860_cpu_device::insn_subs, /* subs isrc1,isrc2,idest. */ + &i860_cpu_device::insn_subs_imm, /* subs #const,isrc2,idest. */ + &i860_cpu_device::insn_shl, /* shl isrc1,isrc2,idest. */ + &i860_cpu_device::insn_shl_imm, /* shl #const,isrc2,idest. */ + &i860_cpu_device::insn_shr, /* shr isrc1,isrc2,idest. */ + &i860_cpu_device::insn_shr_imm, /* shr #const,isrc2,idest. */ + &i860_cpu_device::insn_shrd, /* shrd isrc1ni,isrc2,idest. */ + &i860_cpu_device::insn_bla, /* bla isrc1ni,isrc2,sbroff. */ + &i860_cpu_device::insn_shra, /* shra isrc1,isrc2,idest. */ + &i860_cpu_device::insn_shra_imm, /* shra #const,isrc2,idest. */ + &i860_cpu_device::insn_and, /* and isrc1,isrc2,idest. */ + &i860_cpu_device::insn_and_imm, /* and #const,isrc2,idest. */ + &i860_cpu_device::dec_unrecog, + &i860_cpu_device::insn_andh_imm, /* andh #const,isrc2,idest. */ + &i860_cpu_device::insn_andnot, /* andnot isrc1,isrc2,idest. */ + &i860_cpu_device::insn_andnot_imm, /* andnot #const,isrc2,idest. */ + &i860_cpu_device::dec_unrecog, + &i860_cpu_device::insn_andnoth_imm, /* andnoth #const,isrc2,idest. */ + &i860_cpu_device::insn_or, /* or isrc1,isrc2,idest. */ + &i860_cpu_device::insn_or_imm, /* or #const,isrc2,idest. */ + &i860_cpu_device::dec_unrecog, + &i860_cpu_device::insn_orh_imm, /* orh #const,isrc2,idest. */ + &i860_cpu_device::insn_xor, /* xor isrc1,isrc2,idest. */ + &i860_cpu_device::insn_xor_imm, /* xor #const,isrc2,idest. */ + &i860_cpu_device::dec_unrecog, + &i860_cpu_device::insn_xorh_imm, /* xorh #const,isrc2,idest. */ }; /* Second-level decode table (i.e., for the 3 core escape opcode bits). */ -const i860_cpu_device::decode_tbl_t i860_cpu_device::core_esc_decode_tbl[8] = { - { 0, 0}, - { 0, 0}, /* lock (FIXME: unimplemented). */ - { &i860_cpu_device::insn_calli, DEC_DECODED}, /* calli isrc1ni. */ - { 0, 0}, - { &i860_cpu_device::insn_intovr, DEC_DECODED}, /* intovr. */ - { 0, 0}, - { 0, 0}, - { 0, 0}, /* unlock (FIXME: unimplemented). */ +const i860_cpu_device::insn_func i860_cpu_device::core_esc_decode_tbl[8] = { + &i860_cpu_device::dec_unrecog, + &i860_cpu_device::dec_unrecog, /* lock (FIXME: unimplemented). */ + &i860_cpu_device::insn_calli, /* calli isrc1ni. */ + &i860_cpu_device::dec_unrecog, + &i860_cpu_device::insn_intovr, /* intovr. */ + &i860_cpu_device::dec_unrecog, + &i860_cpu_device::dec_unrecog, + &i860_cpu_device::dec_unrecog, /* unlock (FIXME: unimplemented). */ }; /* Second-level decode table (i.e., for the 7 FP extended opcode bits). */ -const i860_cpu_device::decode_tbl_t i860_cpu_device::fp_decode_tbl[128] = { +const i860_cpu_device::insn_func i860_cpu_device::fp_decode_tbl[128] = { /* Floating point instructions. The least significant 7 bits are the (extended) opcode and bits 10:7 are P,D,S,R respectively ([p]ipelined, [d]ual, [s]ource prec., [r]esult prec.). For some operations, I defer decoding the P,S,R bits to the emulation routine for them. */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x00 pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x01 pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x02 pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x03 pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x04 pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x05 pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x06 pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x07 pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x08 pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x09 pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x0A pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x0B pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x0C pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x0D pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x0E pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x0F pf[m]am */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x10 pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x11 pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x12 pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x13 pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x14 pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x15 pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x16 pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x17 pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x18 pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x19 pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x1A pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x1B pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x1C pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x1D pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x1E pf[m]sm */ - { &i860_cpu_device::insn_dualop, DEC_DECODED}, /* 0x1F pf[m]sm */ - { &i860_cpu_device::insn_fmul, DEC_DECODED}, /* 0x20 [p]fmul */ - { &i860_cpu_device::insn_fmlow, DEC_DECODED}, /* 0x21 fmlow.dd */ - { &i860_cpu_device::insn_frcp, DEC_DECODED}, /* 0x22 frcp.{ss,sd,dd} */ - { &i860_cpu_device::insn_frsqr, DEC_DECODED}, /* 0x23 frsqr.{ss,sd,dd} */ - { &i860_cpu_device::insn_fmul, DEC_DECODED}, /* 0x24 pfmul3.dd */ - { 0, 0}, /* 0x25 */ - { 0, 0}, /* 0x26 */ - { 0, 0}, /* 0x27 */ - { 0, 0}, /* 0x28 */ - { 0, 0}, /* 0x29 */ - { 0, 0}, /* 0x2A */ - { 0, 0}, /* 0x2B */ - { 0, 0}, /* 0x2C */ - { 0, 0}, /* 0x2D */ - { 0, 0}, /* 0x2E */ - { 0, 0}, /* 0x2F */ - { &i860_cpu_device::insn_fadd_sub, DEC_DECODED}, /* 0x30, [p]fadd.{ss,sd,dd} */ - { &i860_cpu_device::insn_fadd_sub, DEC_DECODED}, /* 0x31, [p]fsub.{ss,sd,dd} */ - { &i860_cpu_device::insn_fix, DEC_DECODED}, /* 0x32, [p]fix.{ss,sd,dd} */ - { &i860_cpu_device::insn_famov, DEC_DECODED}, /* 0x33, [p]famov.{ss,sd,ds,dd} */ - { &i860_cpu_device::insn_fcmp, DEC_DECODED}, /* 0x34, pf{gt,le}.{ss,dd} */ - { &i860_cpu_device::insn_fcmp, DEC_DECODED}, /* 0x35, pfeq.{ss,dd} */ - { 0, 0}, /* 0x36 */ - { 0, 0}, /* 0x37 */ - { 0, 0}, /* 0x38 */ - { 0, 0}, /* 0x39 */ - { &i860_cpu_device::insn_ftrunc, DEC_DECODED}, /* 0x3A, [p]ftrunc.{ss,sd,dd} */ - { 0, 0}, /* 0x3B */ - { 0, 0}, /* 0x3C */ - { 0, 0}, /* 0x3D */ - { 0, 0}, /* 0x3E */ - { 0, 0}, /* 0x3F */ - { &i860_cpu_device::insn_fxfr, DEC_DECODED}, /* 0x40, fxfr */ - { 0, 0}, /* 0x41 */ - { 0, 0}, /* 0x42 */ - { 0, 0}, /* 0x43 */ - { 0, 0}, /* 0x44 */ - { 0, 0}, /* 0x45 */ - { 0, 0}, /* 0x46 */ - { 0, 0}, /* 0x47 */ - { 0, 0}, /* 0x48 */ - { &i860_cpu_device::insn_fiadd_sub, DEC_DECODED}, /* 0x49, [p]fiadd.{ss,dd} */ - { 0, 0}, /* 0x4A */ - { 0, 0}, /* 0x4B */ - { 0, 0}, /* 0x4C */ - { &i860_cpu_device::insn_fiadd_sub, DEC_DECODED}, /* 0x4D, [p]fisub.{ss,dd} */ - { 0, 0}, /* 0x4E */ - { 0, 0}, /* 0x4F */ - { &i860_cpu_device::insn_faddp, DEC_DECODED}, /* 0x50, [p]faddp */ - { &i860_cpu_device::insn_faddz, DEC_DECODED}, /* 0x51, [p]faddz */ - { 0, 0}, /* 0x52 */ - { 0, 0}, /* 0x53 */ - { 0, 0}, /* 0x54 */ - { 0, 0}, /* 0x55 */ - { 0, 0}, /* 0x56 */ - { &i860_cpu_device::insn_fzchk, DEC_DECODED}, /* 0x57, [p]fzchkl */ - { 0, 0}, /* 0x58 */ - { 0, 0}, /* 0x59 */ - { &i860_cpu_device::insn_form, DEC_DECODED}, /* 0x5A, [p]form.dd */ - { 0, 0}, /* 0x5B */ - { 0, 0}, /* 0x5C */ - { 0, 0}, /* 0x5D */ - { 0, 0}, /* 0x5E */ - { &i860_cpu_device::insn_fzchk, DEC_DECODED}, /* 0x5F, [p]fzchks */ - { 0, 0}, /* 0x60 */ - { 0, 0}, /* 0x61 */ - { 0, 0}, /* 0x62 */ - { 0, 0}, /* 0x63 */ - { 0, 0}, /* 0x64 */ - { 0, 0}, /* 0x65 */ - { 0, 0}, /* 0x66 */ - { 0, 0}, /* 0x67 */ - { 0, 0}, /* 0x68 */ - { 0, 0}, /* 0x69 */ - { 0, 0}, /* 0x6A */ - { 0, 0}, /* 0x6B */ - { 0, 0}, /* 0x6C */ - { 0, 0}, /* 0x6D */ - { 0, 0}, /* 0x6E */ - { 0, 0}, /* 0x6F */ - { 0, 0}, /* 0x70 */ - { 0, 0}, /* 0x71 */ - { 0, 0}, /* 0x72 */ - { 0, 0}, /* 0x73 */ - { 0, 0}, /* 0x74 */ - { 0, 0}, /* 0x75 */ - { 0, 0}, /* 0x76 */ - { 0, 0}, /* 0x77 */ - { 0, 0}, /* 0x78 */ - { 0, 0}, /* 0x79 */ - { 0, 0}, /* 0x7A */ - { 0, 0}, /* 0x7B */ - { 0, 0}, /* 0x7C */ - { 0, 0}, /* 0x7D */ - { 0, 0}, /* 0x7E */ - { 0, 0}, /* 0x7F */ + &i860_cpu_device::insn_dualop, /* 0x00 pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x01 pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x02 pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x03 pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x04 pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x05 pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x06 pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x07 pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x08 pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x09 pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x0A pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x0B pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x0C pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x0D pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x0E pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x0F pf[m]am */ + &i860_cpu_device::insn_dualop, /* 0x10 pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x11 pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x12 pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x13 pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x14 pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x15 pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x16 pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x17 pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x18 pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x19 pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x1A pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x1B pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x1C pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x1D pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x1E pf[m]sm */ + &i860_cpu_device::insn_dualop, /* 0x1F pf[m]sm */ + &i860_cpu_device::insn_fmul, /* 0x20 [p]fmul */ + &i860_cpu_device::insn_fmlow, /* 0x21 fmlow.dd */ + &i860_cpu_device::insn_frcp, /* 0x22 frcp.{ss,sd,dd} */ + &i860_cpu_device::insn_frsqr, /* 0x23 frsqr.{ss,sd,dd} */ + &i860_cpu_device::insn_fmul, /* 0x24 pfmul3.dd */ + &i860_cpu_device::dec_unrecog, /* 0x25 */ + &i860_cpu_device::dec_unrecog, /* 0x26 */ + &i860_cpu_device::dec_unrecog, /* 0x27 */ + &i860_cpu_device::dec_unrecog, /* 0x28 */ + &i860_cpu_device::dec_unrecog, /* 0x29 */ + &i860_cpu_device::dec_unrecog, /* 0x2A */ + &i860_cpu_device::dec_unrecog, /* 0x2B */ + &i860_cpu_device::dec_unrecog, /* 0x2C */ + &i860_cpu_device::dec_unrecog, /* 0x2D */ + &i860_cpu_device::dec_unrecog, /* 0x2E */ + &i860_cpu_device::dec_unrecog, /* 0x2F */ + &i860_cpu_device::insn_fadd_sub, /* 0x30, [p]fadd.{ss,sd,dd} */ + &i860_cpu_device::insn_fadd_sub, /* 0x31, [p]fsub.{ss,sd,dd} */ + &i860_cpu_device::insn_fix, /* 0x32, [p]fix.{ss,sd,dd} */ + &i860_cpu_device::insn_famov, /* 0x33, [p]famov.{ss,sd,ds,dd} */ + &i860_cpu_device::insn_fcmp, /* 0x34, pf{gt,le}.{ss,dd} */ + &i860_cpu_device::insn_fcmp, /* 0x35, pfeq.{ss,dd} */ + &i860_cpu_device::dec_unrecog, /* 0x36 */ + &i860_cpu_device::dec_unrecog, /* 0x37 */ + &i860_cpu_device::dec_unrecog, /* 0x38 */ + &i860_cpu_device::dec_unrecog, /* 0x39 */ + &i860_cpu_device::insn_ftrunc, /* 0x3A, [p]ftrunc.{ss,sd,dd} */ + &i860_cpu_device::dec_unrecog, /* 0x3B */ + &i860_cpu_device::dec_unrecog, /* 0x3C */ + &i860_cpu_device::dec_unrecog, /* 0x3D */ + &i860_cpu_device::dec_unrecog, /* 0x3E */ + &i860_cpu_device::dec_unrecog, /* 0x3F */ + &i860_cpu_device::insn_fxfr, /* 0x40, fxfr */ + &i860_cpu_device::dec_unrecog, /* 0x41 */ + &i860_cpu_device::dec_unrecog, /* 0x42 */ + &i860_cpu_device::dec_unrecog, /* 0x43 */ + &i860_cpu_device::dec_unrecog, /* 0x44 */ + &i860_cpu_device::dec_unrecog, /* 0x45 */ + &i860_cpu_device::dec_unrecog, /* 0x46 */ + &i860_cpu_device::dec_unrecog, /* 0x47 */ + &i860_cpu_device::dec_unrecog, /* 0x48 */ + &i860_cpu_device::insn_fiadd_sub, /* 0x49, [p]fiadd.{ss,dd} */ + &i860_cpu_device::dec_unrecog, /* 0x4A */ + &i860_cpu_device::dec_unrecog, /* 0x4B */ + &i860_cpu_device::dec_unrecog, /* 0x4C */ + &i860_cpu_device::insn_fiadd_sub, /* 0x4D, [p]fisub.{ss,dd} */ + &i860_cpu_device::dec_unrecog, /* 0x4E */ + &i860_cpu_device::dec_unrecog, /* 0x4F */ + &i860_cpu_device::insn_faddp, /* 0x50, [p]faddp */ + &i860_cpu_device::insn_faddz, /* 0x51, [p]faddz */ + &i860_cpu_device::dec_unrecog, /* 0x52 */ + &i860_cpu_device::dec_unrecog, /* 0x53 */ + &i860_cpu_device::dec_unrecog, /* 0x54 */ + &i860_cpu_device::dec_unrecog, /* 0x55 */ + &i860_cpu_device::dec_unrecog, /* 0x56 */ + &i860_cpu_device::insn_fzchk, /* 0x57, [p]fzchkl */ + &i860_cpu_device::dec_unrecog, /* 0x58 */ + &i860_cpu_device::dec_unrecog, /* 0x59 */ + &i860_cpu_device::insn_form, /* 0x5A, [p]form.dd */ + &i860_cpu_device::dec_unrecog, /* 0x5B */ + &i860_cpu_device::dec_unrecog, /* 0x5C */ + &i860_cpu_device::dec_unrecog, /* 0x5D */ + &i860_cpu_device::dec_unrecog, /* 0x5E */ + &i860_cpu_device::insn_fzchk, /* 0x5F, [p]fzchks */ + &i860_cpu_device::dec_unrecog, /* 0x60 */ + &i860_cpu_device::dec_unrecog, /* 0x61 */ + &i860_cpu_device::dec_unrecog, /* 0x62 */ + &i860_cpu_device::dec_unrecog, /* 0x63 */ + &i860_cpu_device::dec_unrecog, /* 0x64 */ + &i860_cpu_device::dec_unrecog, /* 0x65 */ + &i860_cpu_device::dec_unrecog, /* 0x66 */ + &i860_cpu_device::dec_unrecog, /* 0x67 */ + &i860_cpu_device::dec_unrecog, /* 0x68 */ + &i860_cpu_device::dec_unrecog, /* 0x69 */ + &i860_cpu_device::dec_unrecog, /* 0x6A */ + &i860_cpu_device::dec_unrecog, /* 0x6B */ + &i860_cpu_device::dec_unrecog, /* 0x6C */ + &i860_cpu_device::dec_unrecog, /* 0x6D */ + &i860_cpu_device::dec_unrecog, /* 0x6E */ + &i860_cpu_device::dec_unrecog, /* 0x6F */ + &i860_cpu_device::dec_unrecog, /* 0x70 */ + &i860_cpu_device::dec_unrecog, /* 0x71 */ + &i860_cpu_device::dec_unrecog, /* 0x72 */ + &i860_cpu_device::dec_unrecog, /* 0x73 */ + &i860_cpu_device::dec_unrecog, /* 0x74 */ + &i860_cpu_device::dec_unrecog, /* 0x75 */ + &i860_cpu_device::dec_unrecog, /* 0x76 */ + &i860_cpu_device::dec_unrecog, /* 0x77 */ + &i860_cpu_device::dec_unrecog, /* 0x78 */ + &i860_cpu_device::dec_unrecog, /* 0x79 */ + &i860_cpu_device::dec_unrecog, /* 0x7A */ + &i860_cpu_device::dec_unrecog, /* 0x7B */ + &i860_cpu_device::dec_unrecog, /* 0x7C */ + &i860_cpu_device::dec_unrecog, /* 0x7D */ + &i860_cpu_device::dec_unrecog, /* 0x7E */ + &i860_cpu_device::dec_unrecog, /* 0x7F */ }; +i860_cpu_device::insn_func i860_cpu_device::decoder_tbl[8192]; + /* * Main decoder driver. * insn = instruction at the current PC to execute. @@ -3906,34 +3877,14 @@ void i860_cpu_device::decode_exec (UINT3 m_traceback[m_traceback_idx++] = m_pc; if(m_traceback_idx >= (sizeof(m_traceback) / sizeof(m_traceback[0]))) m_traceback_idx = 0; -#endif - - int unrecognized = 1; - const int upper_6bits = (insn >> 26) & 0x3f; - const char flags = decode_tbl[upper_6bits].flags; - if (flags & DEC_DECODED) { - (this->*decode_tbl[upper_6bits].insn_exec)(insn); - unrecognized = 0; - } else if (flags & DEC_MORE) { - if (upper_6bits == 0x12) { - /* FP instruction format handled here. */ - if (fp_decode_tbl[insn & 0x7f].flags & DEC_DECODED) { - (this->*fp_decode_tbl[insn & 0x7f].insn_exec)(insn); - unrecognized = 0; - } - } else if (upper_6bits == 0x13) { - /* Core escape instruction format handled here. */ - if (core_esc_decode_tbl[insn & 0x3].flags & DEC_DECODED) { - (this->*core_esc_decode_tbl[insn & 0x3].insn_exec)(insn); - unrecognized = 0; - } - } - } - - if (unrecognized) - unrecog_opcode (m_pc, insn); +#endif +// (this->*decode_tbl[(insn >> 26) & 0x3f])(insn); + (this->*decoder_tbl[((insn >> 19) & 0x1F80) | (insn & 0x7F)])(insn); } +void i860_cpu_device::dec_unrecog(UINT32 insn) { + unrecog_opcode(m_pc, insn); +} /* Set-up all the default power-on/reset values. */ void i860_cpu_device::reset() { @@ -3964,11 +3915,11 @@ void i860_cpu_device::reset() { /* Set grs and frs to undefined/nonsense values, except r0. */ for (i = 0; i < 32; i++){ set_iregval (i, UNDEF_VAL | i); - set_fregval_s (i, 0.0); + set_fregval_s (i, FLOAT32_ZERO); } set_iregval (0, 0); - set_fregval_s (0, 0.0); - set_fregval_s (1, 0.0); + set_fregval_s (0, FLOAT32_ZERO); + set_fregval_s (1, FLOAT32_ZERO); /* Set whole psr to 0. This sets the proper bits to 0 as specified above, and zeroes the undefined bits. */ @@ -3984,7 +3935,7 @@ void i860_cpu_device::reset() { Proc type: 1 = XR, 2 = XP (XR has 8KB data cache -> DCS = 1). Steppings (XR): 3,4,5,6,7 = (B2, C0, B3, C1, D0 respectively). Steppings (XP): 0, 2, 3, 4 = (A0, B0, B1, B2) (any others?). */ - m_cregs[CR_EPSR] = 0x00040701; + m_cregs[CR_EPSR] = 0x00040601; /* Set DPS, BL, ATE = 0 and the undefined parts also to 0. But CS8 mode to 1 */ m_cregs[CR_DIRBASE] = 0x00000080; @@ -3992,9 +3943,9 @@ void i860_cpu_device::reset() { /* Set fir, fsr, KR, KI, MERGE, T to undefined. */ m_cregs[CR_FIR] = UNDEF_VAL; m_cregs[CR_FSR] = UNDEF_VAL; - m_KR.d = 0.0; - m_KI.d = 0.0; - m_T.d = 0.0; + m_KR.d = FLOAT64_ZERO; + m_KI.d = FLOAT64_ZERO; + m_T.d = FLOAT64_ZERO; m_merge = 0; m_flow = 0; @@ -4010,4 +3961,4 @@ void i860_cpu_device::reset() { set_mem_access(false); halt(false); -} \ No newline at end of file +}