summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2019-02-08 18:25:19 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2019-02-08 18:25:19 +0700
commite1bed57f7dcbf7cdf59c9dc937b0e4aada50ac9a (patch)
tree9d0d7d6bbb214d8ca595d92d2651b42b462e1f8d
parente0325a8174b95e17767e8c1fc50b685f9c7b66bd (diff)
r4000: tweak address calculation (nw)
-rw-r--r--src/devices/cpu/mips/r4000.cpp212
1 files changed, 109 insertions, 103 deletions
diff --git a/src/devices/cpu/mips/r4000.cpp b/src/devices/cpu/mips/r4000.cpp
index b42180ae7e5..b1d5274cc1a 100644
--- a/src/devices/cpu/mips/r4000.cpp
+++ b/src/devices/cpu/mips/r4000.cpp
@@ -78,7 +78,7 @@
#define ODD_REGS 0x00010840U
// address computation
-#define ADDR(r, o) (m_64 ? (r + s16(o)) : s64(s32(u32(r) + s16(o))))
+#define ADDR(r, o) (m_64 ? ((r) + (o)) : s64(s32((r) + (o))))
#define SR m_cp0[CP0_Status]
#define CAUSE m_cp0[CP0_Cause]
@@ -668,21 +668,21 @@ void r4000_base_device::cpu_execute(u32 const op)
if (s64(m_r[RSREG]) < 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
break;
case 0x01: // BGEZ
if (s64(m_r[RSREG]) >= 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
break;
case 0x02: // BLTZL
if (s64(m_r[RSREG]) < 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
else
m_branch_state = NULLIFY;
@@ -691,7 +691,7 @@ void r4000_base_device::cpu_execute(u32 const op)
if (s64(m_r[RSREG]) >= 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
else
m_branch_state = NULLIFY;
@@ -730,7 +730,7 @@ void r4000_base_device::cpu_execute(u32 const op)
if (s64(m_r[RSREG]) < 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
m_r[31] = ADDR(m_pc, 8);
break;
@@ -738,7 +738,7 @@ void r4000_base_device::cpu_execute(u32 const op)
if (s64(m_r[RSREG]) >= 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
m_r[31] = ADDR(m_pc, 8);
break;
@@ -746,7 +746,7 @@ void r4000_base_device::cpu_execute(u32 const op)
if (s64(m_r[RSREG]) < 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
else
m_branch_state = NULLIFY;
@@ -756,7 +756,7 @@ void r4000_base_device::cpu_execute(u32 const op)
if (s64(m_r[RSREG]) >= 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
else
m_branch_state = NULLIFY;
@@ -796,28 +796,28 @@ void r4000_base_device::cpu_execute(u32 const op)
if (m_r[RSREG] == m_r[RTREG])
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
break;
case 0x05: // BNE
if (m_r[RSREG] != m_r[RTREG])
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
break;
case 0x06: // BLEZ
if (s64(m_r[RSREG]) <= 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
break;
case 0x07: // BGTZ
if (s64(m_r[RSREG]) > 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
break;
case 0x08: // ADDI
@@ -866,7 +866,7 @@ void r4000_base_device::cpu_execute(u32 const op)
if (m_r[RSREG] == m_r[RTREG])
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
else
m_branch_state = NULLIFY;
@@ -875,7 +875,7 @@ void r4000_base_device::cpu_execute(u32 const op)
if (m_r[RSREG] != m_r[RTREG])
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
else
m_branch_state = NULLIFY;
@@ -884,7 +884,7 @@ void r4000_base_device::cpu_execute(u32 const op)
if (s64(m_r[RSREG]) <= 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
else
m_branch_state = NULLIFY;
@@ -893,7 +893,7 @@ void r4000_base_device::cpu_execute(u32 const op)
if (s64(m_r[RSREG]) > 0)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
else
m_branch_state = NULLIFY;
@@ -929,14 +929,14 @@ void r4000_base_device::cpu_execute(u32 const op)
//case 0x1e: // *
//case 0x1f: // *
case 0x20: // LB
- load<s8>(ADDR(m_r[RSREG], op),
+ load<s8>(ADDR(m_r[RSREG], s16(op)),
[this, op](s8 data)
{
m_r[RTREG] = data;
});
break;
case 0x21: // LH
- load<s16>(ADDR(m_r[RSREG], op),
+ load<s16>(ADDR(m_r[RSREG], s16(op)),
[this, op](s16 data)
{
m_r[RTREG] = data;
@@ -946,21 +946,21 @@ void r4000_base_device::cpu_execute(u32 const op)
cpu_lwl(op);
break;
case 0x23: // LW
- load<s32>(ADDR(m_r[RSREG], op),
+ load<s32>(ADDR(m_r[RSREG], s16(op)),
[this, op](s32 data)
{
m_r[RTREG] = data;
});
break;
case 0x24: // LBU
- load<s8>(ADDR(m_r[RSREG], op),
+ load<s8>(ADDR(m_r[RSREG], s16(op)),
[this, op](u8 data)
{
m_r[RTREG] = data;
});
break;
case 0x25: // LHU
- load<u16>(ADDR(m_r[RSREG], op),
+ load<u16>(ADDR(m_r[RSREG], s16(op)),
[this, op](u16 data)
{
m_r[RTREG] = data;
@@ -970,23 +970,23 @@ void r4000_base_device::cpu_execute(u32 const op)
cpu_lwr(op);
break;
case 0x27: // LWU
- load<u32>(ADDR(m_r[RSREG], op),
+ load<u32>(ADDR(m_r[RSREG], s16(op)),
[this, op](u32 data)
{
m_r[RTREG] = data;
});
break;
case 0x28: // SB
- store<u8>(ADDR(m_r[RSREG], op), u8(m_r[RTREG]));
+ store<u8>(ADDR(m_r[RSREG], s16(op)), u8(m_r[RTREG]));
break;
case 0x29: // SH
- store<u16>(ADDR(m_r[RSREG], op), u16(m_r[RTREG]));
+ store<u16>(ADDR(m_r[RSREG], s16(op)), u16(m_r[RTREG]));
break;
case 0x2a: // SWL
cpu_swl(op);
break;
case 0x2b: // SW
- store<u32>(ADDR(m_r[RSREG], op), u32(m_r[RTREG]));
+ store<u32>(ADDR(m_r[RSREG], s16(op)), u32(m_r[RTREG]));
break;
case 0x2c: // SDL
if (m_64 || !(SR & SR_KSU) || (SR & SR_EXL) || (SR & SR_ERL))
@@ -1015,14 +1015,14 @@ void r4000_base_device::cpu_execute(u32 const op)
case 0x00: // index invalidate (I)
if (ICACHE)
{
- m_icache_tag[(ADDR(m_r[RSREG], op) & m_icache_mask_hi) >> m_icache_shift] &= ~ICACHE_V;
+ m_icache_tag[(ADDR(m_r[RSREG], s16(op)) & m_icache_mask_hi) >> m_icache_shift] &= ~ICACHE_V;
break;
}
case 0x04: // index load tag (I)
if (ICACHE)
{
- u32 const tag = m_icache_tag[(ADDR(m_r[RSREG], op) & m_icache_mask_hi) >> m_icache_shift];
+ u32 const tag = m_icache_tag[(ADDR(m_r[RSREG], s16(op)) & m_icache_mask_hi) >> m_icache_shift];
m_cp0[CP0_TagLo] = ((tag & ICACHE_PTAG) << 8) | ((tag & ICACHE_V) >> 18) | ((tag & ICACHE_P) >> 25);
m_cp0[CP0_ECC] = 0; // data ecc or parity
@@ -1034,7 +1034,7 @@ void r4000_base_device::cpu_execute(u32 const op)
if (ICACHE)
{
// FIXME: compute parity
- m_icache_tag[(ADDR(m_r[RSREG], op) & m_icache_mask_hi) >> m_icache_shift] =
+ m_icache_tag[(ADDR(m_r[RSREG], s16(op)) & m_icache_mask_hi) >> m_icache_shift] =
(m_cp0[CP0_TagLo] & TAGLO_PTAGLO) >> 8 | (m_cp0[CP0_TagLo] & TAGLO_PSTATE) << 18;
break;
@@ -1075,7 +1075,7 @@ void r4000_base_device::cpu_execute(u32 const op)
}
break;
case 0x30: // LL
- load_linked<s32>(ADDR(m_r[RSREG], op),
+ load_linked<s32>(ADDR(m_r[RSREG], s16(op)),
[this, op](u64 address, s32 data)
{
// remove existing tap
@@ -1106,7 +1106,7 @@ void r4000_base_device::cpu_execute(u32 const op)
break;
//case 0x33: // *
case 0x34: // LLD
- load_linked<u64>(ADDR(m_r[RSREG], op),
+ load_linked<u64>(ADDR(m_r[RSREG], s16(op)),
[this, op](u64 address, u64 data)
{
// remove existing tap
@@ -1133,7 +1133,7 @@ void r4000_base_device::cpu_execute(u32 const op)
cp2_execute(op);
break;
case 0x37: // LD
- load<u64>(ADDR(m_r[RSREG], op),
+ load<u64>(ADDR(m_r[RSREG], s16(op)),
[this, op](u64 data)
{
m_r[RTREG] = data;
@@ -1145,7 +1145,7 @@ void r4000_base_device::cpu_execute(u32 const op)
m_ll_watch->remove();
m_ll_watch = nullptr;
- store<u32>(ADDR(m_r[RSREG], op), u32(m_r[RTREG]));
+ store<u32>(ADDR(m_r[RSREG], s16(op)), u32(m_r[RTREG]));
m_r[RTREG] = 1;
}
else
@@ -1164,7 +1164,7 @@ void r4000_base_device::cpu_execute(u32 const op)
m_ll_watch->remove();
m_ll_watch = nullptr;
- store<u64>(ADDR(m_r[RSREG], op), m_r[RTREG]);
+ store<u64>(ADDR(m_r[RSREG], s16(op)), m_r[RTREG]);
m_r[RTREG] = 1;
}
else
@@ -1177,7 +1177,7 @@ void r4000_base_device::cpu_execute(u32 const op)
cp2_execute(op);
break;
case 0x3f: // SD
- store<u64>(ADDR(m_r[RSREG], op), m_r[RTREG]);
+ store<u64>(ADDR(m_r[RSREG], s16(op)), m_r[RTREG]);
break;
default:
@@ -1224,7 +1224,7 @@ void r4000_base_device::cpu_exception(u32 exception, u16 const vector)
void r4000_base_device::cpu_lwl(u32 const op)
{
unsigned const reverse = (SR & SR_RE) && ((SR & SR_KSU) == SR_KSU_U) ? 7 : 0;
- u64 const offset = u64(ADDR(m_r[RSREG], op)) ^ reverse;
+ u64 const offset = u64(ADDR(m_r[RSREG], s16(op))) ^ reverse;
unsigned const shift = ((offset & 3) ^ R4000_ENDIAN_LE_BE(3, 0)) << 3;
load<u32>(offset & ~3,
@@ -1237,7 +1237,7 @@ void r4000_base_device::cpu_lwl(u32 const op)
void r4000_base_device::cpu_lwr(u32 const op)
{
unsigned const reverse = (SR & SR_RE) && ((SR & SR_KSU) == SR_KSU_U) ? 7 : 0;
- u64 const offset = u64(ADDR(m_r[RSREG], op)) ^ reverse;
+ u64 const offset = u64(ADDR(m_r[RSREG], s16(op))) ^ reverse;
unsigned const shift = ((offset & 0x3) ^ R4000_ENDIAN_LE_BE(0, 3)) << 3;
load<u32>(offset & ~3,
@@ -1250,7 +1250,7 @@ void r4000_base_device::cpu_lwr(u32 const op)
void r4000_base_device::cpu_swl(u32 const op)
{
unsigned const reverse = (SR & SR_RE) && ((SR & SR_KSU) == SR_KSU_U) ? 7 : 0;
- u64 const offset = u64(ADDR(m_r[RSREG], op)) ^ reverse;
+ u64 const offset = u64(ADDR(m_r[RSREG], s16(op))) ^ reverse;
unsigned const shift = ((offset & 3) ^ R4000_ENDIAN_LE_BE(3, 0)) << 3;
store<u32>(offset & ~3, u32(m_r[RTREG]) >> shift, ~u32(0) >> shift);
@@ -1259,7 +1259,7 @@ void r4000_base_device::cpu_swl(u32 const op)
void r4000_base_device::cpu_swr(u32 const op)
{
unsigned const reverse = (SR & SR_RE) && ((SR & SR_KSU) == SR_KSU_U) ? 7 : 0;
- u64 const offset = u64(ADDR(m_r[RSREG], op)) ^ reverse;
+ u64 const offset = u64(ADDR(m_r[RSREG], s16(op))) ^ reverse;
unsigned const shift = ((offset & 3) ^ R4000_ENDIAN_LE_BE(0, 3)) << 3;
store<u32>(offset & ~3, u32(m_r[RTREG]) << shift, ~u32(0) << shift);
@@ -1268,7 +1268,7 @@ void r4000_base_device::cpu_swr(u32 const op)
void r4000_base_device::cpu_ldl(u32 const op)
{
unsigned const reverse = (SR & SR_RE) && ((SR & SR_KSU) == SR_KSU_U) ? 7 : 0;
- u64 const offset = u64(ADDR(m_r[RSREG], op)) ^ reverse;
+ u64 const offset = u64(ADDR(m_r[RSREG], s16(op))) ^ reverse;
unsigned const shift = ((offset & 7) ^ R4000_ENDIAN_LE_BE(7, 0)) << 3;
load<u64>(offset & ~7,
@@ -1281,7 +1281,7 @@ void r4000_base_device::cpu_ldl(u32 const op)
void r4000_base_device::cpu_ldr(u32 const op)
{
unsigned const reverse = (SR & SR_RE) && ((SR & SR_KSU) == SR_KSU_U) ? 7 : 0;
- u64 const offset = u64(ADDR(m_r[RSREG], op)) ^ reverse;
+ u64 const offset = u64(ADDR(m_r[RSREG], s16(op))) ^ reverse;
unsigned const shift = ((offset & 7) ^ R4000_ENDIAN_LE_BE(0, 7)) << 3;
load<u64>(offset & ~7,
@@ -1294,7 +1294,7 @@ void r4000_base_device::cpu_ldr(u32 const op)
void r4000_base_device::cpu_sdl(u32 const op)
{
unsigned const reverse = (SR & SR_RE) && ((SR & SR_KSU) == SR_KSU_U) ? 7 : 0;
- u64 const offset = u64(ADDR(m_r[RSREG], op)) ^ reverse;
+ u64 const offset = u64(ADDR(m_r[RSREG], s16(op))) ^ reverse;
unsigned const shift = ((offset & 7) ^ R4000_ENDIAN_LE_BE(7, 0)) << 3;
store<u64>(offset & ~7, m_r[RTREG] >> shift, ~u64(0) >> shift);
@@ -1303,7 +1303,7 @@ void r4000_base_device::cpu_sdl(u32 const op)
void r4000_base_device::cpu_sdr(u32 const op)
{
unsigned const reverse = (SR & SR_RE) && ((SR & SR_KSU) == SR_KSU_U) ? 7 : 0;
- u64 const offset = u64(ADDR(m_r[RSREG], op)) ^ reverse;
+ u64 const offset = u64(ADDR(m_r[RSREG], s16(op))) ^ reverse;
unsigned const shift = ((offset & 7) ^ R4000_ENDIAN_LE_BE(0, 7)) << 3;
store<u64>(offset & ~7, m_r[RTREG] << shift, ~u64(0) << shift);
@@ -1727,21 +1727,21 @@ void r4000_base_device::cp1_execute(u32 const op)
if (!(m_fcr31 & FCR31_C))
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
break;
case 0x01: // BC1T
if (m_fcr31 & FCR31_C)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
break;
case 0x02: // BC1FL
if (!(m_fcr31 & FCR31_C))
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
else
m_branch_state = NULLIFY;
@@ -1750,7 +1750,7 @@ void r4000_base_device::cp1_execute(u32 const op)
if (m_fcr31 & FCR31_C)
{
m_branch_state = BRANCH;
- m_branch_target = ADDR(m_pc, (s16(op) << 2) + 4);
+ m_branch_target = ADDR(m_pc + 4, s32(s16(op)) << 2);
}
else
m_branch_state = NULLIFY;
@@ -2377,7 +2377,7 @@ void r4000_base_device::cp1_execute(u32 const op)
break;
case 0x31: // LWC1
- load<u32>(ADDR(m_r[RSREG], op),
+ load<u32>(ADDR(m_r[RSREG], s16(op)),
[this, op](u32 data)
{
if (SR & SR_FR)
@@ -2393,7 +2393,7 @@ void r4000_base_device::cp1_execute(u32 const op)
break;
case 0x35: // LDC1
- load<u64>(ADDR(m_r[RSREG], op),
+ load<u64>(ADDR(m_r[RSREG], s16(op)),
[this, op](u64 data)
{
if ((SR & SR_FR) || !(RTREG & 1))
@@ -2403,19 +2403,19 @@ void r4000_base_device::cp1_execute(u32 const op)
case 0x39: // SWC1
if (SR & SR_FR)
- store<u32>(ADDR(m_r[RSREG], op), u32(m_f[RTREG]));
+ store<u32>(ADDR(m_r[RSREG], s16(op)), u32(m_f[RTREG]));
else
if (RTREG & 1)
// store the high half of the even floating point register
- store<u32>(ADDR(m_r[RSREG], op), u32(m_f[RTREG & ~1] >> 32));
+ store<u32>(ADDR(m_r[RSREG], s16(op)), u32(m_f[RTREG & ~1] >> 32));
else
// store the low half of the even floating point register
- store<u32>(ADDR(m_r[RSREG], op), u32(m_f[RTREG & ~1]));
+ store<u32>(ADDR(m_r[RSREG], s16(op)), u32(m_f[RTREG & ~1]));
break;
case 0x3d: // SDC1
if ((SR & SR_FR) || !(RTREG & 1))
- store<u64>(ADDR(m_r[RSREG], op), m_f[RTREG]);
+ store<u64>(ADDR(m_r[RSREG], s16(op)), m_f[RTREG]);
break;
}
}
@@ -2588,8 +2588,62 @@ r4000_base_device::translate_t r4000_base_device::translate(int intention, u64 &
bool extended = false;
- if (!(SR & SR_KSU) || (SR & SR_EXL) || (SR & SR_ERL))
+ switch (SR & (SR_KSU | SR_ERL | SR_EXL))
{
+ case SR_KSU_U:
+ // user mode
+ if (SR & SR_UX)
+ {
+ // 64-bit user mode
+ if (address & 0xffff'ff00'0000'0000)
+ return ERROR; // exception
+ else
+ extended = true; // xuseg
+ }
+ else
+ {
+ // 32-bit user mode
+ if (address & 0xffff'ffff'8000'0000)
+ return ERROR; // exception
+ else
+ extended = false; // useg
+ }
+ break;
+
+ case SR_KSU_S:
+ // supervisor mode
+ if (SR & SR_SX)
+ {
+ // 64-bit supervisor mode
+ if (address & 0xffff'ff00'0000'0000)
+ if ((address & 0xffff'ff00'0000'0000) == 0x4000'0000'0000'0000)
+ extended = true; // xsseg
+ else
+ if ((address & 0xffff'ffff'e000'0000) == 0xffff'ffff'c000'0000)
+ extended = true; // csseg
+ else
+ return ERROR; // exception
+ else
+ extended = true; // xsuseg
+ }
+ else
+ {
+ // 32-bit supervisor mode
+ if (address & 0xffff'ffff'8000'0000)
+ if ((address & 0xffff'ffff'e000'0000) == 0xffff'ffff'c000'0000)
+ extended = false; // sseg
+ else
+ return ERROR; // exception
+ else
+ extended = false; // suseg
+ }
+ break;
+
+ case SR_KSU_U | SR_KSU_S:
+ fatalerror("invalid ksu bits 0x%08x (%s)\n", u32(SR), machine().describe_context().c_str());
+ break;
+
+ default:
// kernel mode
if (SR & SR_KX)
{
@@ -2646,55 +2700,7 @@ r4000_base_device::translate_t r4000_base_device::translate(int intention, u64 &
else
extended = false; // kuseg
}
- }
- else if ((SR & SR_KSU) == SR_KSU_S)
- {
- // supervisor mode
- if (SR & SR_SX)
- {
- // 64-bit supervisor mode
- if (address & 0xffff'ff00'0000'0000)
- if ((address & 0xffff'ff00'0000'0000) == 0x4000'0000'0000'0000)
- extended = true; // xsseg
- else
- if ((address & 0xffff'ffff'e000'0000) == 0xffff'ffff'c000'0000)
- extended = true; // csseg
- else
- return ERROR; // exception
- else
- extended = true; // xsuseg
- }
- else
- {
- // 32-bit supervisor mode
- if (address & 0xffff'ffff'8000'0000)
- if ((address & 0xffff'ffff'e000'0000) == 0xffff'ffff'c000'0000)
- extended = false; // sseg
- else
- return ERROR; // exception
- else
- extended = false; // suseg
- }
- }
- else
- {
- // user mode
- if (SR & SR_UX)
- {
- // 64-bit user mode
- if (address & 0xffff'ff00'0000'0000)
- return ERROR; // exception
- else
- extended = true; // xuseg
- }
- else
- {
- // 32-bit user mode
- if (address & 0xffff'ffff'8000'0000)
- return ERROR; // exception
- else
- extended = false; // useg
- }
+ break;
}
// address needs translation, using a combination of VPN2 and ASID