1
0
mirror of https://github.com/prirun/p50em.git synced 2026-02-27 00:39:52 +00:00

em.c, etc: use gv.xxx instead of gvp->xxx for 13% speed increase, from

37.5 Prime MIPS on Linode VM to 42.5 MIPS.  gvp-> was faster on the
PowerPC architecture when gvp was kept in a dedicated register, but
that does not apply to Intel.

Old:

Timing CPU,  20.0 ticks per second...
  35.3 Prime MIPS for 16-bit ADD loop
  40.0 Prime MIPS for 16-bit MPY loop
  42.1 Prime MIPS for 16-bit DIV loop
  21.4 Prime MIPS for 32-bit ADD loop
  30.8 Prime MIPS for 32-bit MPY loop
  28.6 Prime MIPS for 32-bit DIV loop
  57.1 Prime MIPS for 16-bit X=0 loop
  44.4 Prime MIPS for 32-bit X=0 loop
  37.5 average Prime MIPS

New:

Timing CPU,  20.0 ticks per second...
  42.9 Prime MIPS for 16-bit ADD loop
  53.3 Prime MIPS for 16-bit MPY loop
  47.1 Prime MIPS for 16-bit DIV loop
  24.0 Prime MIPS for 32-bit ADD loop
  38.1 Prime MIPS for 32-bit MPY loop
  32.0 Prime MIPS for 32-bit DIV loop
  57.1 Prime MIPS for 16-bit X=0 loop
  44.4 Prime MIPS for 32-bit X=0 loop
  42.4 average Prime MIPS
This commit is contained in:
Jim
2020-03-08 23:46:14 -04:00
parent 35adf0905a
commit 9054d69446
6 changed files with 330 additions and 333 deletions

View File

@@ -166,8 +166,8 @@ AMLC status word (from AMLCT5):
/* macro to setup the next AMLC poll */
#define AMLC_SET_POLL \
if (devpoll[device] == 0 || devpoll[device] > AMLCPOLL*gvp->instpermsec/pollspeedup) \
devpoll[device] = AMLCPOLL*gvp->instpermsec/pollspeedup; /* setup another poll */
if (devpoll[device] == 0 || devpoll[device] > AMLCPOLL*gv.instpermsec/pollspeedup) \
devpoll[device] = AMLCPOLL*gv.instpermsec/pollspeedup; /* setup another poll */
int devamlc (int class, int func, int device) {
@@ -1296,8 +1296,8 @@ dorecv:
if (class == 4) /* this was a poll */
wascti = 1;
if (dc[dx].intenable && (wascti || neweor)) {
if (gvp->intvec == -1) {
gvp->intvec = dc[dx].intvector;
if (gv.intvec == -1) {
gv.intvec = dc[dx].intvector;
dc[dx].interrupting = 1;
} else
devpoll[device] = 100; /* come back soon! */

View File

@@ -333,7 +333,7 @@ char * pncdumppkt(unsigned char * pkt, int len) {
struct timeval tv1;
#ifndef NOTRACE
if (!gvp->traceflags & T_RIO) return;
if (!gv.traceflags & T_RIO) return;
if (gettimeofday(&tv1, NULL) != 0)
fatal("pnc gettimeofday 3 failed");
@@ -868,7 +868,7 @@ int devpnc (int class, int func, int device) {
struct timeval tv0,tv1;
double pollts;
//gvp->traceflags = ~T_MAP;
//gv.traceflags = ~T_MAP;
if (class >= 0 && !configured) {
TRACE(T_INST|T_RIO, "PIO to PNC ignored, class=%d, func='%02o, device=%02o\n", class, func, device);
@@ -1066,7 +1066,7 @@ int devpnc (int class, int func, int device) {
}
TRACE(T_RIO, "PNC configured\n");
devpoll[device] = PNCPOLL*gvp->instpermsec;
devpoll[device] = PNCPOLL*gv.instpermsec;
if (gettimeofday(&tv0, NULL) != 0)
fatal("pnc gettimeofday 1 failed");
@@ -1283,7 +1283,7 @@ int devpnc (int class, int func, int device) {
devpoll[device] = olddevpoll;
sawsigio = 0;
} else {
devpoll[device] = PNCPOLL*gvp->instpermsec;
devpoll[device] = PNCPOLL*gv.instpermsec;
time(&timenow);
pncaccept(timenow); /* accept 1 new connection each poll */
pncconnect(timenow); /* finish a pending connection */
@@ -1295,8 +1295,8 @@ rcvexit:
intrexit:
if (enabled && ((pncstat & 0xC000) | intstat) != intstat) {
if (gvp->intvec == -1) {
gvp->intvec = pncvec;
if (gv.intvec == -1) {
gv.intvec = pncvec;
intstat |= (pncstat & 0xC000);
} else
devpoll[device] = 100;

View File

@@ -40,28 +40,28 @@
/* set an entry in the R-mode memory reference opcode dispatch table */
#define MRGEN_R(opcode, name, target) \
gvp->disp_rmr[MRPRIMEIX(opcode)] = &⌖ \
gv.disp_rmr[MRPRIMEIX(opcode)] = &⌖ \
/* printf("R-MR opcode %05o (%s), ix=%0d\n", opcode, name, MRPRIMEIX(opcode)); */ \
if ((opcode & 01700) != 01500) { \
gvp->disp_rmr[MRPRIMEIX(opcode | 02000)] = &⌖ \
gv.disp_rmr[MRPRIMEIX(opcode | 02000)] = &⌖ \
/* printf("R-MR opcode %05o (%s), ix=%0d\n", opcode | 02000, name, MRPRIMEIX(opcode | 02000)); */ \
}
/* set an entry in the V-mode memory reference opcode dispatch table */
#define MRGEN_V(opcode, name, target) \
gvp->disp_vmr[MRPRIMEIX(opcode)] = &⌖ \
gv.disp_vmr[MRPRIMEIX(opcode)] = &⌖ \
/* printf("V-MR opcode %05o (%s), ix=%0d\n", opcode, name, MRPRIMEIX(opcode)); */ \
if ((opcode & 01700) != 01500) { \
gvp->disp_vmr[MRPRIMEIX(opcode | 02000)] = &⌖ \
gv.disp_vmr[MRPRIMEIX(opcode | 02000)] = &⌖ \
/* printf("V-MR opcode %05o (%s), ix=%0d\n", opcode | 02000, name, MRPRIMEIX(opcode | 02000)); */ \
}
/* initialize tables to "bad memory reference instruction" */
for (i=0; i < 128; i++) {
gvp->disp_rmr[i] = &&d_badmr;
gvp->disp_vmr[i] = &&d_badmr;
gv.disp_rmr[i] = &&d_badmr;
gv.disp_vmr[i] = &&d_badmr;
}
MRGEN_R(00100, "JMP", d_jmp);

26
ea64v.h
View File

@@ -40,7 +40,7 @@ static inline ea_t ea64v (unsigned short inst, ea_t earp) {
xok = (inst & 036000) != 032000; /* true if indexing is okay */
br = (inst & 3);
eap = &gvp->brp[br];
eap = &gv.brp[br];
#ifndef NOTRACE
int opcode;
@@ -65,8 +65,8 @@ static inline ea_t ea64v (unsigned short inst, ea_t earp) {
NOTE: this has been disabled, because gcov showed it only
occurred 0.5% of the time */
if (br == 0 && ((((ea_s & 0x8FFF) << 16) | (ea_w & 0xFC00)) == gvp->brp[RPBR].vpn))
eap = &gvp->brp[RPBR];
if (br == 0 && ((((ea_s & 0x8FFF) << 16) | (ea_w & 0xFC00)) == gv.brp[RPBR].vpn))
eap = &gv.brp[RPBR];
#endif
if (ixy >= 3) {
@@ -84,7 +84,7 @@ static inline ea_t ea64v (unsigned short inst, ea_t earp) {
UNBR if the new ea is still in the current page */
if ((((ea_s & 0x8FFF) << 16) | (ea_w & 0xFC00)) != (eap->vpn & 0x0FFFFFFF))
eap = &gvp->brp[UNBR];
eap = &gv.brp[UNBR];
if (xok)
if (ixy == 7) {
@@ -109,13 +109,13 @@ static inline ea_t ea64v (unsigned short inst, ea_t earp) {
}
if (inst & 0400) {
TRACE(T_EAV, " Short LB relative, LB=%o/%o\n", getcrs16(LBH), getcrs16(LBL));
eap = &gvp->brp[LBBR];
eap = &gv.brp[LBBR];
ea_s = getcrs16(LBH) | (ea_s & RINGMASK16);
ea_w += getcrs16(LBL);
return MAKEVA(ea_s, ea_w);
}
if (ea_w >= gvp->livereglim) {
eap = &gvp->brp[SBBR];
if (ea_w >= gv.livereglim) {
eap = &gv.brp[SBBR];
ea_s = getcrs16(SBH) | (ea_s & RINGMASK16);
ea_w += getcrs16(SBL);
TRACE(T_EAV, " Short SB relative, SB=%o/%o\n", getcrs16(SBH), getcrs16(SBL));
@@ -135,14 +135,14 @@ static inline ea_t ea64v (unsigned short inst, ea_t earp) {
if (inst & 001000) { /* sector bit 7 set? */
ea_w = rpl + (((short) (inst << 7)) >> 7); /* yes, sign extend D */
TRACE(T_EAV, " PC relative, P=%o, new ea_w=%o\n", rpl, ea_w);
eap = &gvp->brp[RPBR];
eap = &gv.brp[RPBR];
} else {
#if DBG
if (!i)
fatal ("ea64v: i not set?");
#endif
eap = &gvp->brp[S0BR];
eap = &gv.brp[S0BR];
ea_w = (inst & 0777); /* sector 0 */
TRACE(T_EAV, " Sector 0, new ea_w=%o\n", ea_w);
if (ea_w < 0100 && x) { /* preindex by X */
@@ -154,7 +154,7 @@ static inline ea_t ea64v (unsigned short inst, ea_t earp) {
}
if (i) {
if (ea_w >= gvp->livereglim) {
if (ea_w >= gv.livereglim) {
TRACE(T_EAV, " Indirect, ea_s=%o, ea_w=%o\n", ea_s, ea_w);
ea_w = get16(MAKEVA(ea_s, ea_w));
} else {
@@ -173,11 +173,11 @@ static inline ea_t ea64v (unsigned short inst, ea_t earp) {
/* if ea_w is within RP's brp cache page, set eap to match;
otherwise, use PB's cache page */
if (ea_w >= gvp->livereglim) {
if (ea_w >= gv.livereglim) {
if (((ea_w ^ RPL) & 0xFC00) == 0)
eap = &gvp->brp[RPBR]; /* occurs 80% */
eap = &gv.brp[RPBR]; /* occurs 80% */
else
eap = &gvp->brp[PBBR]; /* occurs 20% */
eap = &gv.brp[PBBR]; /* occurs 20% */
return MAKEVA(ea_s, ea_w);
}

541
em.c

File diff suppressed because it is too large Load Diff

64
emdev.h
View File

@@ -420,7 +420,7 @@ int devasr (int class, int func, int device) {
else {
timeout.tv_sec = 1; /* single user: okay to delay */
#ifndef NOTRACE
fflush(gvp->tracefile); /* flush for DIAG testing */
fflush(gv.tracefile); /* flush for DIAG testing */
#endif
}
timeout.tv_usec = 0;
@@ -457,7 +457,7 @@ int devasr (int class, int func, int device) {
ttyflags = newflags;
if (doblock) { /* doblock = no PX = running diags */
#ifndef NOTRACE
fflush(gvp->tracefile); /* flush trace buffer when testing */
fflush(gv.tracefile); /* flush trace buffer when testing */
#endif
if (needflush) {
if (fflush(stdout) == 0) {
@@ -481,19 +481,19 @@ readasr:
}
} else if (n == 1) {
if (!(getcrs16(MODALS) & 010) && (ch == '')) {
printf("\nRebooting at instruction #%u\n", gvp->instcount);
// gvp->savetraceflags = ~T_MAP; /****/
printf("\nRebooting at instruction #%u\n", gv.instcount);
// gv.savetraceflags = ~T_MAP; /****/
longjmp(bootjmp, 1);
}
#ifndef NOTRACE
if (ch == '') {
gvp->tracetriggered = !gvp->tracetriggered;
if (gvp->tracetriggered) {
gv.tracetriggered = !gv.tracetriggered;
if (gv.tracetriggered) {
TRACEA("\nTRACE ENABLED:\n\n");
} else {
TRACEA("\nTRACE DISABLED:\n\n");
}
fflush(gvp->tracefile);
fflush(gv.tracefile);
goto readasr;
}
#endif
@@ -521,7 +521,7 @@ readasr:
TRACE(T_INST, " character read=%o: %c\n", getcrs16(A), getcrs16(A) & 0x7f);
fflush(conslog); /* immediately flush when typing */
#ifndef NOTRACE
fflush(gvp->tracefile);
fflush(gv.tracefile);
#endif
IOSKIP;
} else {
@@ -582,7 +582,7 @@ readasr:
putc(ch, conslog);
needflush = 1;
if (devpoll[device] == 0)
devpoll[device] = gvp->instpermsec*100;
devpoll[device] = gv.instpermsec*100;
IOSKIP;
} else if (func == 1) { /* write control word */
TRACEA("OTA 4, func %d, A='%o/%d\n", func, getcrs16(A), getcrs16s(A));
@@ -639,7 +639,7 @@ readasr:
if (fflush(stdout) == 0)
needflush = 0;
else
devpoll[device] = gvp->instpermsec*100;
devpoll[device] = gv.instpermsec*100;
fflush(conslog);
}
}
@@ -1113,7 +1113,7 @@ int devmt (int class, int func, int device) {
devpoll[device] = 10;
if ((getcrs16(A) & 0x00E0) == 0x0020) { /* rewind */
//gvp->traceflags = ~T_MAP;
//gv.traceflags = ~T_MAP;
TRACE(T_TIO, " rewind\n");
if (lseek(unit[u].fd, 0, SEEK_SET) == -1) {
perror("Unable to rewind tape drive file");
@@ -1337,9 +1337,9 @@ int devmt (int class, int func, int device) {
TRACE(T_TIO, " POLL device '%02o, enabled=%d, interrupting=%d\n", device, enabled, interrupting);
if (enabled && (interrupting == 1)) {
devpoll[device] = 100; /* assume interrupt will be deferred */
if (gvp->intvec == -1 && (getcrs16(MODALS) & 0100000)) {
if (gv.intvec == -1 && (getcrs16(MODALS) & 0100000)) {
TRACE(T_TIO, " CPU interrupt to vector '%o\n", mtvec);
gvp->intvec = mtvec;
gv.intvec = mtvec;
devpoll[device] = 0;
interrupting = 2;
}
@@ -1432,7 +1432,7 @@ int devcp (int class, int func, int device) {
unsigned int elapsedms,targetticks;
int i;
#define SETCLKPOLL devpoll[device] = gvp->instpermsec*(-clkpic*clkrate)/1000;
#define SETCLKPOLL devpoll[device] = gv.instpermsec*(-clkpic*clkrate)/1000;
switch (class) {
@@ -1465,7 +1465,7 @@ int devcp (int class, int func, int device) {
} else if (func == 015) { /* set interrupt mask */
/* this enables tracing when the clock process initializes */
//gvp->traceflags = ~T_MAP;
//gv.traceflags = ~T_MAP;
//TRACEA("Clock interrupt enabled!\n");
enabled = 1;
SETCLKPOLL;
@@ -1492,7 +1492,7 @@ int devcp (int class, int func, int device) {
if (func == 011) { /* input ID */
putcrs16(A, 020); /* this is the Option-A board */
putcrs16(A, 0120); /* this is the SOC board */
//gvp->traceflags = ~T_MAP;
//gv.traceflags = ~T_MAP;
} else if (func == 016) { /* read switches that are up */
putcrs16(A, sswitch);
} else if (func == 017) { /* read switches pushed down */
@@ -1567,8 +1567,8 @@ int devcp (int class, int func, int device) {
/* interrupt if enabled and no interrupt active */
if (enabled) {
if (gvp->intvec == -1) {
gvp->intvec = clkvec;
if (gv.intvec == -1) {
gv.intvec = clkvec;
SETCLKPOLL;
ticks++;
if (gettimeofday(&tv, NULL) != 0)
@@ -1576,7 +1576,7 @@ int devcp (int class, int func, int device) {
if (ticks == 0) {
start_tv = tv;
prev_tv = tv;
previnstcount = gvp->instcount;
previnstcount = gv.instcount;
if (datnowea != 0)
initclock(datnowea);
}
@@ -1630,19 +1630,19 @@ int devcp (int class, int func, int device) {
#define IPMTIME 5000
if ((gvp->instcount < previnstcount) || (gvp->instcount-previnstcount > gvp->instpermsec*IPMTIME)) {
if (gvp->instcount-previnstcount > gvp->instpermsec*IPMTIME) {
i = (gvp->instcount-previnstcount) /
if ((gv.instcount < previnstcount) || (gv.instcount-previnstcount > gv.instpermsec*IPMTIME)) {
if (gv.instcount-previnstcount > gv.instpermsec*IPMTIME) {
i = (gv.instcount-previnstcount) /
((tv.tv_sec-prev_tv.tv_sec)*1000.0 + (tv.tv_usec-prev_tv.tv_usec)/1000.0);
if (i > 0) {
//printf("ic= %u, prev= %u, diff= %u, ipmsec= %d, prev= %d, diff= %d\n", gvp->instcount, previnstcount, gvp->instcount-previnstcount, i, gvp->instpermsec, i-gvp->instpermsec);
gvp->instpermsec = i;
//printf("ic= %u, prev= %u, diff= %u, ipmsec= %d, prev= %d, diff= %d\n", gv.instcount, previnstcount, gv.instcount-previnstcount, i, gv.instpermsec, i-gv.instpermsec);
gv.instpermsec = i;
}
#ifdef NOIDLE
//printf("\ninstpermsec=%d\n", gvp->instpermsec);
//printf("\ninstpermsec=%d\n", gv.instpermsec);
#endif
}
previnstcount = gvp->instcount;
previnstcount = gv.instcount;
prev_tv = tv;
}
} else {
@@ -1787,7 +1787,7 @@ int devdisk (int class, int func, int device) {
}
//gvp->traceflags |= T_DIO;
//gv.traceflags |= T_DIO;
switch (class) {
@@ -1844,7 +1844,7 @@ int devdisk (int class, int func, int device) {
TRACE(T_INST|T_DIO, " INA '%2o%2o\n", func, device);
/* this turns tracing on when the Primos disk processes initialize */
//gvp->traceflags = ~T_MAP;
//gv.traceflags = ~T_MAP;
/* INA's are only accepted when the controller is not busy */
@@ -2173,7 +2173,7 @@ int devdisk (int class, int func, int device) {
if (getcrs16(MODALS) & 010) /* PX enabled? */
break; /* yes, no stall */
devpoll[device] = gvp->instpermsec/5; /* 200 microseconds, sb 210 */
devpoll[device] = gv.instpermsec/5; /* 200 microseconds, sb 210 */
return;
case 9: /* DSTAT = Store status to memory */
@@ -2194,13 +2194,13 @@ int devdisk (int class, int func, int device) {
case 14: /* DINT = generate interrupt through vector address */
TRACE(T_INST|T_DIO, " interrupt through '%o\n", m1);
if (gvp->intvec >= 0 || !(getcrs16(MODALS) & 0100000))
if (gv.intvec >= 0 || !(getcrs16(MODALS) & 0100000))
dc[dx].oar -= 2; /* can't take interrupt right now */
else {
gvp->intvec = m1;
gv.intvec = m1;
dc[dx].state = S_INT;
}
//gvp->traceflags = ~T_MAP;
//gv.traceflags = ~T_MAP;
devpoll[device] = 10;
return;