1
0
mirror of https://github.com/prirun/p50em.git synced 2026-01-24 11:01:43 +00:00

More performance tweeaks: get/put(16/32)r, eaxxx()

changed get/put(16,32)r to check for ring change and use regular
  get/put call if possible, so brp supercache can be used
FUTURE: could add separate brp cache entry for R0 accesses
changed ea32r64r live register test so normal path is first
changed ea64v live register test so normal path is first
change ea32i to use INCRP macro instead of RPL++
This commit is contained in:
Jim 2007-09-15 00:00:00 -04:00
parent 91f8780e43
commit d99d16932d
3 changed files with 56 additions and 43 deletions

10
ea32i.h
View File

@ -36,7 +36,7 @@ static inline ea_t ea32i (ea_t earp, unsigned short inst, unsigned long *immu32,
switch (sr) {
case 0: /* imm type 3 */
d = iget16(RP);
RPL++;
INCRP;
*immu64 = (((long long)(d & 0xFF00)) << 48) | (d & 0xFF);
return IMM_EA;
case 1: /* FAC0 source */
@ -59,7 +59,7 @@ static inline ea_t ea32i (ea_t earp, unsigned short inst, unsigned long *immu32,
case 3: /* GR relative */
d = iget16(RP);
RPL++;
INCRP;
ea = (crsl[sr] & 0xFFFF0000) | ((crsl[sr] + d) & 0xFFFF);
TRACE(T_EAI, " GRR, d=%x, crsl[sr]=%o/%o, ea=%o/%o\n", d, crsl[sr]>>16, crsl[sr]&0xFFFF, ea>>16, ea&0xFFFF);
if (ea & 0x80000000)
@ -73,7 +73,7 @@ static inline ea_t ea32i (ea_t earp, unsigned short inst, unsigned long *immu32,
case 1: /* TM=1: Direct and Indexed */
d = iget16(RP);
RPL++;
INCRP;
if (sr == 0)
ea = (crsl[BR+br] & 0xFFFF0000) | ((crsl[BR+br] + d) & 0xFFFF);
else
@ -82,7 +82,7 @@ static inline ea_t ea32i (ea_t earp, unsigned short inst, unsigned long *immu32,
case 2: /* TM=2: Indirect and Indirect Preindexed */
d = iget16(RP);
RPL++;
INCRP;
if (sr == 0)
ea = (crsl[BR+br] & 0xFFFF0000) | ((crsl[BR+br] + d) & 0xFFFF);
else
@ -95,7 +95,7 @@ static inline ea_t ea32i (ea_t earp, unsigned short inst, unsigned long *immu32,
case 3: /* TM=3: Indirect and Indirect Postindexed */
TRACE(T_EAI, " TM=3: Indirect [Postindexed]");
d = iget16(RP);
RPL++;
INCRP;
ea = (crsl[BR+br] & 0xFFFF0000) | ((crsl[BR+br] + d) & 0xFFFF);
TRACE(T_EAI, " BR[%d]=%o/%o, d=%o, ip ea=%o/%o\n", br, crsl[BR+br]>>16, crsl[BR+br]&0xFFFF, d, ea>>16, ea&0xFFFF);
ip = get32(ea | ring);

16
ea64v.h
View File

@ -86,12 +86,12 @@ static inline ea_t ea64v (unsigned short inst, ea_t earp) {
fatal("goto labA?");
if (i) {
if (ea_w < gvp->livereglim) {
TRACE(T_EAV, " Indirect through live register '%o\n", ea_w);
ea_w = get16trap(ea_w);
} else {
if (ea_w >= gvp->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 {
TRACE(T_EAV, " Indirect through live register '%o\n", ea_w);
ea_w = get16trap(ea_w);
}
TRACE(T_EAV, " After indirect, new ea_w=%o\n", ea_w);
}
@ -142,6 +142,8 @@ labB:
else if (ixy == 2 || ixy == 6)
ea_w += crs[X];
/* if this is a PB% address, use RPBR instead if it's in range */
if (br == 0 && ((((ea_s & 0x8FFF) << 16) | (ea_w & 0xFC00)) == gvp->brp[RPBR].vpn))
eap = &gvp->brp[RPBR];
@ -153,15 +155,11 @@ labB:
fault(POINTERFAULT, m, ea);
ea_s = m | (ea_s & RINGMASK16);
ea_w = get16(INCVA(ea,1));
#if 0
if (ea_s & EXTMASK16)
warn("em: extension bit set in ea64v");
#endif
TRACE(T_EAV, " After indirect, ea_s=%o, ea_w=%o\n", ea_s, ea_w);
/* when passing stack variables, callee references will be
SB%+20,*, which may still be in the same page. Don't switch to
UNBR if the new ea is still in the page */
UNBR if the new ea is still in the current page */
if ((((ea_s & 0x8FFF) << 16) | (ea_w & 0xFC00)) != eap->vpn)
eap = &gvp->brp[UNBR];

73
em.c
View File

@ -1105,6 +1105,14 @@ static unsigned short get16r(ea_t ea, ea_t rpring) {
warn("address trap in get16r");
#endif
/* if passed-in ring == RP ring, use get16 and maybe avoid mapva;
PCL uses "r" versions of get/put because it may be crossing
rings. However, if PCL isn't crossing rings (user calls his own
subroutine for example), then the if below will try to use the
brp supercache. */
if (((rpring ^ RP) & RINGMASK32) == 0)
return get16(ea);
return MEM[mapva(ea, rpring, RACC, &access)];
}
@ -1168,8 +1176,12 @@ static unsigned int get32r(ea_t ea, ea_t rpring) {
warn("address trap in get32r");
#endif
pa = mapva(ea, rpring, RACC, &access);
/* if passed-in ring == RP ring, use get32 and maybe avoid mapva */
if (((rpring ^ RP) & RINGMASK32) == 0)
return get32(ea);
pa = mapva(ea, rpring, RACC, &access);
if ((pa & 01777) <= 01776)
return *(unsigned int *)(MEM+pa);
return (MEM[pa] << 16) | get16r(INCVA(ea,1), rpring);
@ -1316,6 +1328,11 @@ static put16r(unsigned short value, ea_t ea, ea_t rpring) {
warn("address trap in put16r");
#endif
/* if passed-in ring == RP ring, use put16 and maybe avoid mapva */
if (((rpring ^ RP) & RINGMASK32) == 0)
return put16(value, ea);
MEM[mapva(ea, rpring, WACC, &access)] = value;
}
@ -1409,6 +1426,11 @@ static put32r(unsigned int value, ea_t ea, ea_t rpring) {
warn("address trap in put32");
#endif
/* if passed-in ring == RP ring, use put32 and maybe avoid mapva */
if (((rpring ^ RP) & RINGMASK32) == 0)
return put32(value, ea);
pa = mapva(ea, rpring, WACC, &access);
if ((pa & 01777) <= 01776)
*(unsigned int *)(MEM+pa) = value;
@ -1655,7 +1677,6 @@ static void fatal(char *msg) {
stopwatch_report(&sw_io);
stopwatch_report(&sw_add16);
stopwatch_report(&sw_cas);
stopwatch_report(&sw_irs);
stopwatch_report(&sw_zmv);
stopwatch_report(&sw_zfil);
stopwatch_report(&sw_zmvd);
@ -1791,7 +1812,7 @@ static void fault(unsigned short fvec, unsigned short fcode, ea_t faddr) {
last = get16r0(pcbp+PCBCSLAST);
TRACE(T_FAULT, "fault: PX enabled, pcbp=%o/%o, cs first=%o, next=%o, last=%o\n", pcbp>>16, pcbp&0xFFFF, first, next, last);
if (next > last) {
#if 1
#ifdef DBG
/* this is better for debugging */
TRACE(T_FAULT, "fault: Concealed stack wraparound to first");
fatal("fault: Concealed stack wraparound to first");
@ -1816,6 +1837,7 @@ static void fault(unsigned short fvec, unsigned short fcode, ea_t faddr) {
gvp->inhcount = 1; /* supposed to do this only for Ring 0, but shouldn't hurt */
#if 0
/* this was useful, but also can cause page faults - careful! */
if (T_FAULT && fvec == POINTERFAULT) {
ea = get32(faddr);
if ((ea & 0xF0000000) == 0x80000000) {
@ -1838,12 +1860,7 @@ static void fault(unsigned short fvec, unsigned short fcode, ea_t faddr) {
if (m != 0) {
TRACE(T_FLOW, " fault JST* '%o [%o]\n", fvec, m);
put16(faultrp & 0xFFFF, m);
/* NOTE: should this set RP to m (segment 0), or just set RPL? */
#if 0
RPL = m;
#else
RP = m;
#endif
RP = m; /* NOTE: changes RP(segno) to segment 0 */
INCRP;
} else {
printf("#%d: fault '%o, fcode=%o, faddr=%o/%o, faultrp=%o/%o\n", gvp->instcount, fvec, fcode, faddr>>16, faddr&0xFFFF, faultrp>>16, faultrp&0xFFFF);
@ -1971,10 +1988,10 @@ static inline ea_t ea32r64r (ea_t earp, unsigned short inst) {
}
}
while (i) {
if (ea < gvp->livereglim)
m = get16trap(ea);
else
if (ea >= gvp->livereglim)
m = get16(MAKEVA(rph,ea));
else
m = get16trap(ea);
TRACE(T_EAR, " Indirect, old ea=%o, [ea]=%o\n", ea, m);
if ((crs[KEYS] & 016000) == 06000) /* 32R mode? */
i = m & 0100000; /* yes, multiple indirects */
@ -2019,10 +2036,10 @@ special:
TRACE(T_EAR, " Preindex, new ea=%o\n", ea);
}
while (i) {
if (ea < gvp->livereglim)
m = get16trap(ea);
else
if (ea >= gvp->livereglim)
m = get16(MAKEVA(rph,ea));
else
m = get16trap(ea);
TRACE(T_EAR, " Indirect, old ea=%o, [ea]=%o\n", ea, m);
if ((crs[KEYS] & 016000) == 06000)
i = m & 0100000;
@ -2043,10 +2060,10 @@ special:
eap = &gvp->brp[SBBR];
}
while (i) {
if (ea < gvp->livereglim)
m = get16trap(ea);
else
if (ea >= gvp->livereglim)
m = get16(MAKEVA(rph,ea));
else
m = get16trap(ea);
TRACE(T_EAR, " Indirect, ea=%o, [ea]=%o\n", ea, m);
if ((crs[KEYS] & 016000) == 06000)
i = m & 0100000;
@ -2068,19 +2085,19 @@ special:
ea = --crs[S];
TRACE(T_EAR, " Class 2/3, new ea=%o, new S=%o\n", ea, crs[S]);
if (x) {
if (ea < gvp->livereglim)
m = get16trap(ea);
else
if (ea >= gvp->livereglim)
m = get16(MAKEVA(rph,ea));
else
m = get16trap(ea);
if ((crs[KEYS] & 016000) == 06000)
i = m & 0100000;
ea = m & amask;
}
while (i) {
if (ea < gvp->livereglim)
m = get16trap(ea);
else
if (ea >= gvp->livereglim)
m = get16(MAKEVA(rph,ea));
else
m = get16trap(ea);
if ((crs[KEYS] & 016000) == 06000)
i = m & 0100000;
else
@ -2095,9 +2112,9 @@ special:
}
ea &= amask;
va = MAKEVA(rph, ea);
if (ea < gvp->livereglim) /* flag live register ea */
return va | 0x80000000;
return va;
if (ea >= gvp->livereglim)
return va;
return va | 0x80000000; /* flag live register ea */
}
#include "ea64v.h"
@ -9018,13 +9035,11 @@ d_cas: /* 01100 */
goto fetch;
d_irs: /* 01200 */
stopwatch_push(&sw_irs);
TRACE(T_FLOW, " IRS\n");
utempa = get16t(ea) + 1;
put16t(utempa, ea);
if (utempa == 0)
INCRP;
stopwatch_pop(&sw_irs);
goto fetch;
d_ima: /* 01300 */