diff --git a/ea32i.h b/ea32i.h index 38da3aa..0e5c743 100644 --- a/ea32i.h +++ b/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); diff --git a/ea64v.h b/ea64v.h index 391a3bf..ce785d2 100644 --- a/ea64v.h +++ b/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]; diff --git a/em.c b/em.c index 1bed95f..69fdc6f 100644 --- a/em.c +++ b/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 */