OSDN Git Service

[VM][I386_NP21] OPTIMIZE: Make cpu_wait() inline to be more faster.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Thu, 10 Feb 2022 14:21:45 +0000 (23:21 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Thu, 10 Feb 2022 14:21:45 +0000 (23:21 +0900)
[VM][I386_NP21] OPTIMIZE: Make some branches __UNLIKELY_IF() / __LIKELY_IF().
[VM][I386_NP21] Move i386_memory_wait to inside of I386:: .Will be capsulized any functions.

source/src/vm/common_vm/CMakeLists.txt
source/src/vm/i386_np21.cpp
source/src/vm/i386_np21.h
source/src/vm/np21/i386c/cpumem.cpp
source/src/vm/np21/i386c/cpumem.h
source/src/vm/np21/i386c/ia32/cpu.h

index 3c62165..b844341 100644 (file)
@@ -1,6 +1,6 @@
 message("* vm/common_vm")
 
-SET(THIS_LIB_VERSION 3.11.1)
+SET(THIS_LIB_VERSION 3.11.2)
 
 #include(cotire)
 set(s_vm_common_vm_srcs
index 5c021b1..f2e5014 100644 (file)
@@ -280,35 +280,11 @@ void I386::reset()
        write_signals(&outputs_extreset, 0xffffffff);
 }
 
-void I386::cpu_wait(int clocks)
-{
-       if(clocks <= 0) clocks = 1;
-       int64_t wfactor = waitfactor;
-       int64_t wcount = waitcount;
-       int64_t mwait = i386_memory_wait;
-       int64_t ncount;
-       if(wfactor > 65536) {
-               wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock.
-               wcount += (wfactor * mwait);  // memory wait
-       } else {
-               wcount += (mwait << 16);
-       }
-       if(wcount >= 65536) {
-               ncount = wcount >> 16;
-               wcount = wcount - (ncount << 16);
-               extra_cycles += (int)ncount;
-       } else if(wcount < 0) {
-               wcount = 0;
-       }
-       waitcount = wcount;
-       i386_memory_wait = 0;
-}
-
 bool I386::check_interrupts()
 {
-       if(nmi_pending) {
+       __UNLIKELY_IF(nmi_pending) {
                return true;
-       } else if(irq_pending && CPU_isEI) {
+       } else __LIKELY_IF(irq_pending && CPU_isEI) {
                return true;
        }
        return false;
@@ -319,12 +295,13 @@ int I386::run_one_opecode()
 //#ifdef USE_DEBUGGER
        
        bool now_debugging = false;
-       if((_USE_DEBUGGER) && (device_debugger != NULL)) {
+       __LIKELY_IF((_USE_DEBUGGER) && (device_debugger != NULL)) {
                now_debugging = device_debugger->now_debugging;
        }
-       if((now_debugging)) {
+       
+       __UNLIKELY_IF(now_debugging) {
                device_debugger->check_break_points(get_next_pc());
-               if(device_debugger->now_suspended) {
+               __UNLIKELY_IF(device_debugger->now_suspended) {
                        device_debugger->now_waiting = true;
                        emu->start_waiting_in_debugger();
                        while(device_debugger->now_debugging && device_debugger->now_suspended) {
@@ -333,61 +310,42 @@ int I386::run_one_opecode()
                        emu->finish_waiting_in_debugger();
                        device_debugger->now_waiting = false;
                }
-               if(device_debugger->now_debugging) {
+               __LIKELY_IF(device_debugger->now_debugging) {
                        device_mem = device_io = device_debugger;
                } else {
                        now_debugging = false;
                }
-               
+       }
+       {
+//#endif
                PREV_CS_BASE = CS_BASE;
                CPU_REMCLOCK = CPU_BASECLOCK = 1;
                CPU_EXEC();
-               if(nmi_pending) {
+               __UNLIKELY_IF(nmi_pending) {
                        CPU_INTERRUPT(2, 0);
-                       if(device_debugger != NULL) {
+                       __LIKELY_IF(device_debugger != NULL) {
                                device_debugger->add_cpu_trace_irq(get_pc(), 2);
                        }
                        nmi_pending = false;
-               } else if(irq_pending && CPU_isEI) {
+               } else __LIKELY_IF(irq_pending && CPU_isEI) {
+                       // ToDo: Multiple interrupt within rep prefix.
                        uint32_t intr_level = device_pic->get_intr_ack();
                        CPU_INTERRUPT(intr_level, 0);
-                       if(device_debugger != NULL) {
+                       __LIKELY_IF(device_debugger != NULL) {
                                device_debugger->add_cpu_trace_irq(get_pc(), intr_level);
                        }
                        irq_pending = false;
                        device_pic->update_intr();
                }
-               check_interrupts();
-               if(now_debugging) {
-                       if(!device_debugger->now_going) {
+               //check_interrupts();  // OK?This may be enable only debugging;
+               __UNLIKELY_IF(now_debugging) {
+                       __UNLIKELY_IF(!device_debugger->now_going) {
                                device_debugger->now_suspended = true;
                        }
                        device_mem = device_mem_stored;
                        device_io = device_io_stored;
                }
                return CPU_BASECLOCK - CPU_REMCLOCK;
-       } else {
-//#endif
-               PREV_CS_BASE = CS_BASE;
-               CPU_REMCLOCK = CPU_BASECLOCK = 1;
-               CPU_EXEC();
-               if(nmi_pending) {
-                       CPU_INTERRUPT(2, 0);
-                       if(device_debugger != NULL) {
-                               device_debugger->add_cpu_trace_irq(get_pc(), 2);
-                       }
-                       nmi_pending = false;
-               } else if(irq_pending && CPU_isEI) {
-                       // ToDo: Multiple interrupt within rep prefix.
-                       uint32_t intr_level = device_pic->get_intr_ack();
-                       CPU_INTERRUPT(intr_level, 0);
-                       if(device_debugger != NULL) {
-                               device_debugger->add_cpu_trace_irq(get_pc(), intr_level);
-                       }
-                       irq_pending = false;
-                       device_pic->update_intr();
-               }
-               return CPU_BASECLOCK - CPU_REMCLOCK;
 //#ifdef USE_DEBUGGER
        }
 //#endif
@@ -395,12 +353,13 @@ int I386::run_one_opecode()
 
 int I386::run(int cycles)
 {
-       if(cycles == -1) {
+       // Prefer to run as one step (cycles == -1). 20220210 K.O
+       __LIKELY_IF(cycles == -1) {
                int passed_cycles;
                __UNLIKELY_IF(busreq) {
                        // don't run cpu!
 //#ifdef SINGLE_MODE_DMA
-                       if(_SINGLE_MODE_DMA) {
+                       __LIKELY_IF(_SINGLE_MODE_DMA) {
                                if(device_dma != NULL) device_dma->do_dma();
                        }
 //#endif
@@ -413,11 +372,11 @@ int I386::run(int cycles)
                        passed_cycles += run_one_opecode();
                }
 //#ifdef USE_DEBUGGER
-               if(_USE_DEBUGGER) {
+               __UNLIKELY_IF(_USE_DEBUGGER) {
                        total_cycles += passed_cycles;
                }
 //#endif
-               cpu_wait(passed_cycles);
+               cpu_wait(passed_cycles, i386_memory_wait);
                return passed_cycles;
        } else {
                remained_cycles += cycles + extra_cycles;
@@ -442,7 +401,7 @@ int I386::run(int cycles)
                        remained_cycles = 0;
                }
                int passed_cycles = first_cycles - remained_cycles;
-               cpu_wait(passed_cycles);
+               cpu_wait(passed_cycles, i386_memory_wait);
                return passed_cycles;
        }
 }
index 9b6dc10..fad8c60 100644 (file)
@@ -78,7 +78,7 @@ private:
        
        int run_one_opecode();
        uint32_t __FASTCALL convert_address(uint32_t cs, uint32_t eip);
-       void __FASTCALL cpu_wait(int clocks);
+       inline void __FASTCALL cpu_wait(int clocks, int64_t& memory_wait);
 
 public:
        I386(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu)
@@ -184,7 +184,34 @@ public:
        uint32_t get_address_mask();
        void set_shutdown_flag(int shutdown);
        int get_shutdown_flag();
+       int64_t i386_memory_wait;
        int device_model;
 };
 
+inline void __FASTCALL I386::cpu_wait(int clocks, int64_t& memory_wait)
+{
+       __UNLIKELY_IF(clocks < 0) {
+               clocks = 0;
+       }
+       int64_t wfactor = waitfactor;
+       int64_t wcount = waitcount;
+       int64_t mwait = memory_wait;
+       int64_t ncount;
+       __UNLIKELY_IF(wfactor > 65536) {
+               wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock.
+               wcount += (wfactor * mwait);  // memory wait
+       } else {
+               wcount += (mwait << 16);
+       }
+       __LIKELY_IF(wcount >= 65536) {
+               ncount = wcount >> 16;
+               wcount = wcount - (ncount << 16);
+               extra_cycles += (int)ncount;
+       } else __UNLIKELY_IF(wcount < 0) {
+               wcount = 0;
+       }
+       waitcount = wcount;
+       memory_wait = 0;
+}
+
 #endif
index b337ebc..b9a1510 100644 (file)
@@ -48,7 +48,7 @@ DEVICE *device_bios = NULL;
 //#ifdef SINGLE_MODE_DMA
 DEVICE *device_dma = NULL;
 //#endif
-SINT64 i386_memory_wait;
+//SINT64 i386_memory_wait;
 DEBUGGER *device_debugger = NULL;
 UINT32 codefetch_address;
 SINT32 __exception_set;
index 53a3584..02f9b96 100644 (file)
@@ -20,7 +20,8 @@
 //#endif
 #include "../../common.h"
 #include "../device.h"
-class I386;
+//class I386;
+#include "../i386_np21.h"
 
 extern I386   *device_cpu;
 extern DEVICE *device_mem;
@@ -31,7 +32,7 @@ extern DEVICE *device_bios;
 //#ifdef SINGLE_MODE_DMA
 extern DEVICE *device_dma;
 //#endif
-extern SINT64 i386_memory_wait;
+//extern SINT64 i386_memory_wait;
 extern DEBUGGER *device_debugger;
 extern UINT32 codefetch_address;
 extern SINT32 __exception_set;
@@ -148,7 +149,7 @@ inline REG8 MEMCALL memp_read8(UINT32 address) {
        int wait = 0;
        REG8 val;
        val = device_mem->read_data8w(address, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
        return val;
 }
 
@@ -158,7 +159,7 @@ inline REG16 MEMCALL memp_read16(UINT32 address) {
        int wait = 0;
        REG16 val;
        val = device_mem->read_data16w(address, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
        return val;
 //     return device_mem->read_data16(address);
 }
@@ -168,7 +169,7 @@ inline UINT32 MEMCALL memp_read32(UINT32 address) {
        int wait = 0;
        UINT32 val;
        val = device_mem->read_data32w(address, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
        return val;
 //     return device_mem->read_data32(address);
 }
@@ -181,7 +182,7 @@ inline REG8 MEMCALL memp_read8_codefetch(UINT32 address) {
        REG8 val;
        codefetch_address = address;
        val = device_mem->read_data8w(codefetch_address, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
        return val;
 //     return device_mem->read_data8(address);
 }
@@ -193,7 +194,7 @@ inline REG16 MEMCALL memp_read16_codefetch(UINT32 address) {
        REG16 val;
        codefetch_address = address;
        val = device_mem->read_data16w(codefetch_address, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
        return val;
 //     return device_mem->read_data16(address);
 }
@@ -205,7 +206,7 @@ inline UINT32 MEMCALL memp_read32_codefetch(UINT32 address) {
        UINT32 val;
        codefetch_address = address;
        val = device_mem->read_data32w(codefetch_address, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
        return val;
 //     return device_mem->read_data32(address);
 }
@@ -230,7 +231,7 @@ inline void MEMCALL memp_write8(UINT32 address, REG8 value) {
        address = address & CPU_ADRSMASK;
        int wait = 0;
        device_mem->write_data8w(address, value, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
 }
 
 inline void MEMCALL memp_write16(UINT32 address, REG16 value) {
@@ -238,7 +239,7 @@ inline void MEMCALL memp_write16(UINT32 address, REG16 value) {
        address = address & CPU_ADRSMASK;
        int wait = 0;
        device_mem->write_data16w(address, value, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
 //     device_mem->write_data16(address, value);
 }
 
@@ -247,7 +248,7 @@ inline void MEMCALL memp_write32(UINT32 address, UINT32 value) {
        address = address & CPU_ADRSMASK;
        int wait = 0;
        device_mem->write_data32w(address, value, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
 //     device_mem->write_data32(address, value);
 }
 
@@ -256,7 +257,7 @@ inline void MEMCALL memp_write8_paging(UINT32 address, REG8 value) {
        address = address & CPU_ADRSMASK;
        int wait = 0;
        device_mem->write_data8w(address, value, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
 //     device_mem->write_data8(address, value);
 }
 
@@ -265,7 +266,7 @@ inline void MEMCALL memp_write16_paging(UINT32 address, REG16 value) {
        address = address & CPU_ADRSMASK;
        int wait = 0;
        device_mem->write_data16w(address, value, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
 //     device_mem->write_data16(address, value);
 }
 
@@ -275,7 +276,7 @@ inline void MEMCALL memp_write32_paging(UINT32 address, UINT32 value) {
 //     device_mem->write_data32(address, value);
        int wait = 0;
        device_mem->write_data32w(address, value, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
 }
 
 
@@ -314,14 +315,14 @@ inline void IOOUTCALL iocore_out8(UINT port, REG8 dat)
 {
        int wait = 0;
        device_io->write_io8w(port, dat, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
 }
 
 inline REG8 IOINPCALL iocore_inp8(UINT port)
 {
        int wait = 0;
        REG8 val = device_io->read_io8w(port, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
        return val;
 }
 
@@ -329,7 +330,7 @@ inline void IOOUTCALL iocore_out16(UINT port, REG16 dat)
 {
        int wait = 0;
        device_io->write_io16w(port, dat, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
 //     device_io->write_io16(port, dat);       
 }
 
@@ -337,7 +338,7 @@ inline REG16 IOINPCALL iocore_inp16(UINT port)
 {
        int wait = 0;
        REG16 val = device_io->read_io16w(port, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
        return val;
 //     return device_io->read_io16(port);
 }
@@ -346,7 +347,7 @@ inline void IOOUTCALL iocore_out32(UINT port, UINT32 dat)
 {
        int wait = 0;
        device_io->write_io32w(port, dat, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
 //     device_io->write_io32(port, dat);       
 }
 
@@ -354,7 +355,7 @@ inline UINT32 IOINPCALL iocore_inp32(UINT port)
 {
        int wait = 0;
        UINT32 val = device_io->read_io32w(port, &wait);
-       i386_memory_wait += wait;
+       device_cpu->i386_memory_wait += wait;
        return val;
 //     return device_io->read_io32(port);
 }
index d5da9c8..12ec567 100644 (file)
@@ -592,7 +592,7 @@ extern DEVICE               *device_bios;
 extern DEVICE          *device_dma;
 extern DEBUGGER                *device_debugger;
 //#endif
-extern int64_t      i386_memory_wait;
+//extern int64_t      i386_memory_wait;
 extern UINT32          codefetch_address;
 
 /*