From fef53599b20b691524068634131c1f9b4cddc7ab Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 7 Dec 2019 02:37:50 -0800 Subject: [PATCH] sparc: Introduce a BitUnion for the CCR register. This avoids opaque masks when accessing fields of this register. Change-Id: If20d82c7c6401e6b1b35bb6d2c69542a56e2fb45 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23446 Reviewed-by: Bobby R. Bruce Maintainer: Gabe Black Tested-by: kokoro --- src/arch/sparc/faults.cc | 8 ++++---- src/arch/sparc/miscregs.hh | 15 +++++++++++++++ src/arch/sparc/process.cc | 24 +++++++++++------------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index c1b49e108..dc68c01bf 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -303,7 +303,7 @@ doREDFault(ThreadContext *tc, TrapType tt) RegVal TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); - RegVal CCR = tc->readIntReg(INTREG_CCR); + CCR ccr = tc->readIntReg(INTREG_CCR); RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI); RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP); RegVal CANSAVE = tc->readMiscRegNoEffect(INTREG_CANSAVE); @@ -317,7 +317,7 @@ doREDFault(ThreadContext *tc, TrapType tt) // set TSTATE.gl to gl replaceBits(TSTATE, 42, 40, GL); // set TSTATE.ccr to ccr - replaceBits(TSTATE, 39, 32, CCR); + replaceBits(TSTATE, 39, 32, ccr); // set TSTATE.asi to asi replaceBits(TSTATE, 31, 24, ASI); // set TSTATE.pstate to pstate @@ -382,7 +382,7 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) RegVal TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); - RegVal CCR = tc->readIntReg(INTREG_CCR); + CCR ccr = tc->readIntReg(INTREG_CCR); RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI); RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP); RegVal CANSAVE = tc->readIntReg(INTREG_CANSAVE); @@ -400,7 +400,7 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) // set TSTATE.gl to gl replaceBits(TSTATE, 42, 40, GL); // set TSTATE.ccr to ccr - replaceBits(TSTATE, 39, 32, CCR); + replaceBits(TSTATE, 39, 32, ccr); // set TSTATE.asi to asi replaceBits(TSTATE, 31, 24, ASI); // set TSTATE.pstate to pstate diff --git a/src/arch/sparc/miscregs.hh b/src/arch/sparc/miscregs.hh index b0679b963..3602c8e50 100644 --- a/src/arch/sparc/miscregs.hh +++ b/src/arch/sparc/miscregs.hh @@ -133,6 +133,21 @@ BitUnion16(PSTATE) Bitfield<11> pid1; EndBitUnion(PSTATE) +BitUnion8(CCR) + SubBitUnion(xcc, 7, 4) + Bitfield<7> n; + Bitfield<6> z; + Bitfield<5> v; + Bitfield<4> c; + EndSubBitUnion(xcc) + SubBitUnion(icc, 3, 0) + Bitfield<3> n; + Bitfield<2> z; + Bitfield<1> v; + Bitfield<0> c; + EndSubBitUnion(icc) +EndBitUnion(CCR) + struct STS { const static int st_idle = 0x00; diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 4c055a9b1..ce201d0b4 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -509,23 +509,21 @@ SparcProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret) { // check for error condition. SPARC syscall convention is to // indicate success/failure in reg the carry bit of the ccr - // and put the return value itself in the standard return value reg (). + // and put the return value itself in the standard return value reg. PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); + CCR ccr = tc->readIntReg(INTREG_CCR); + RegVal val; if (sysret.successful()) { - // no error, clear XCC.C - tc->setIntReg(INTREG_CCR, tc->readIntReg(INTREG_CCR) & 0xEE); - RegVal val = sysret.returnValue(); - if (pstate.am) - val = bits(val, 31, 0); - tc->setIntReg(ReturnValueReg, val); + ccr.xcc.c = ccr.icc.c = 0; + val = sysret.returnValue(); } else { - // got an error, set XCC.C - tc->setIntReg(INTREG_CCR, tc->readIntReg(INTREG_CCR) | 0x11); - RegVal val = sysret.errnoValue(); - if (pstate.am) - val = bits(val, 31, 0); - tc->setIntReg(ReturnValueReg, val); + ccr.xcc.c = ccr.icc.c = 1; + val = sysret.errnoValue(); } + tc->setIntReg(INTREG_CCR, ccr); + if (pstate.am) + val = bits(val, 31, 0); + tc->setIntReg(ReturnValueReg, val); if (sysret.count() > 1) tc->setIntReg(SyscallPseudoReturnReg, sysret.value2()); } -- 2.30.2