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:
parent
91f8780e43
commit
d99d16932d
10
ea32i.h
10
ea32i.h
@ -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
16
ea64v.h
@ -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
73
em.c
@ -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 */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user