diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2008-12-16 23:06:37 -0800 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2008-12-16 23:06:37 -0800 |
commit | 02cd18f536544d4b5fa19681b4c9dbd5b2cb87ff (patch) | |
tree | 0e43f983937e2964aaa29ea6809fd5636a2e1446 | |
parent | ab5eeb4b62e14528beaf41d21305dfda075c5133 (diff) | |
download | gem5-02cd18f536544d4b5fa19681b4c9dbd5b2cb87ff.tar.xz |
SPARC: Truncate syscall args and return values appropriately.
-rw-r--r-- | src/arch/sparc/syscallreturn.hh | 14 | ||||
-rw-r--r-- | src/cpu/simple_thread.hh | 11 |
2 files changed, 21 insertions, 4 deletions
diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh index cf13fc3e8..d4e6c7c50 100644 --- a/src/arch/sparc/syscallreturn.hh +++ b/src/arch/sparc/syscallreturn.hh @@ -50,13 +50,23 @@ namespace SparcISA tc->setIntReg(NumIntArchRegs + 2, tc->readIntReg(NumIntArchRegs + 2) & 0xEE); //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE); - tc->setIntReg(ReturnValueReg, return_value.value()); + IntReg val = return_value.value(); + if (bits(tc->readMiscRegNoEffect( + SparcISA::MISCREG_PSTATE), 3, 3)) { + val = bits(val, 31, 0); + } + tc->setIntReg(ReturnValueReg, val); } else { // got an error, set XCC.C tc->setIntReg(NumIntArchRegs + 2, tc->readIntReg(NumIntArchRegs + 2) | 0x11); //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11); - tc->setIntReg(ReturnValueReg, -return_value.value()); + IntReg val = -return_value.value(); + if (bits(tc->readMiscRegNoEffect( + SparcISA::MISCREG_PSTATE), 3, 3)) { + val = bits(val, 31, 0); + } + tc->setIntReg(ReturnValueReg, val); } } }; diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index a503ab600..4831b701a 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -385,8 +385,15 @@ class SimpleThread : public ThreadState TheISA::IntReg getSyscallArg(int i) { assert(i < TheISA::NumArgumentRegs); - return regs.readIntReg(TheISA::flattenIntIndex(getTC(), - TheISA::ArgumentReg[i])); + TheISA::IntReg val = regs.readIntReg( + TheISA::flattenIntIndex(getTC(), TheISA::ArgumentReg[i])); +#if THE_ISA == SPARC_ISA + if (bits(this->readMiscRegNoEffect( + SparcISA::MISCREG_PSTATE), 3, 3)) { + val = bits(val, 31, 0); + } +#endif + return val; } // used to shift args for indirect syscall |