diff options
Diffstat (limited to 'src/arch/sparc')
23 files changed, 272 insertions, 206 deletions
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 64cfc832a..92fdbfdbb 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -302,10 +302,12 @@ void doREDFault(ThreadContext *tc, TrapType tt) MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); - MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + //MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); MiscReg ASI = tc->readMiscReg(MISCREG_ASI); MiscReg CWP = tc->readMiscReg(MISCREG_CWP); - MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + MiscReg CANSAVE = tc->readMiscReg(NumIntArchRegs + 3); MiscReg GL = tc->readMiscReg(MISCREG_GL); MiscReg PC = tc->readPC(); MiscReg NPC = tc->readNextPC(); @@ -396,10 +398,12 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); - MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + //MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); MiscReg ASI = tc->readMiscReg(MISCREG_ASI); MiscReg CWP = tc->readMiscReg(MISCREG_CWP); - MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3); MiscReg GL = tc->readMiscReg(MISCREG_GL); MiscReg PC = tc->readPC(); MiscReg NPC = tc->readNextPC(); @@ -679,19 +683,21 @@ void PageTableFault::invoke(ThreadContext *tc) { Process *p = tc->getProcessPtr(); - // address is higher than the stack region or in the current stack region - if (vaddr > p->stack_base || vaddr > p->stack_min) - FaultBase::invoke(tc); - - // We've accessed the next page - if (vaddr > p->stack_min - PageBytes) { + // We've accessed the next page of the stack, so extend the stack + // to cover it. + if(vaddr < p->stack_min && vaddr >= p->stack_min - PageBytes) + { p->stack_min -= PageBytes; - if (p->stack_base - p->stack_min > 8*1024*1024) + if(p->stack_base - p->stack_min > 8*1024*1024) fatal("Over max stack size for one thread\n"); p->pTable->allocate(p->stack_min, PageBytes); warn("Increasing stack size by one page."); - } else { - FaultBase::invoke(tc); + } + // Otherwise, we have an unexpected page fault. Report that fact, + // and what address was accessed to cause the fault. + else + { + panic("Page table fault when accessing virtual address %#x\n", vaddr); } } diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 0a8ac055f..594fe4bea 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -66,6 +66,7 @@ void IntRegFile::clear() memset(regGlobals[x], 0, sizeof(IntReg) * RegsPerFrame); for(int x = 0; x < 2 * NWindows; x++) memset(regSegments[x], 0, sizeof(IntReg) * RegsPerFrame); + memset(regs, 0, sizeof(IntReg) * NumIntRegs); } IntRegFile::IntRegFile() @@ -78,6 +79,8 @@ IntRegFile::IntRegFile() IntReg IntRegFile::readReg(int intReg) { + DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, regs[intReg]); + return regs[intReg]; IntReg val; if(intReg < NumIntArchRegs) val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; @@ -96,6 +99,12 @@ void IntRegFile::setReg(int intReg, const IntReg &val) if(intReg) { DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); + regs[intReg] = val; + } + return; + if(intReg) + { + DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); if(intReg < NumIntArchRegs) regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; else if((intReg -= NumIntArchRegs) < NumMicroIntRegs) diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh index d66d0fcb7..716d45a65 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -34,6 +34,7 @@ #include "arch/sparc/isa_traits.hh" #include "arch/sparc/types.hh" +#include "base/bitfield.hh" #include <string> @@ -54,15 +55,19 @@ namespace SparcISA private: friend class RegFile; protected: + //The number of bits needed to index into each 8 register frame static const int FrameOffsetBits = 3; + //The number of bits to choose between the 4 sets of 8 registers static const int FrameNumBits = 2; + //The number of registers per "frame" (8) static const int RegsPerFrame = 1 << FrameOffsetBits; - static const int FrameNumMask = + //A mask to get the frame number + static const uint64_t FrameNumMask = (FrameNumBits == sizeof(int)) ? (unsigned int)(-1) : (1 << FrameNumBits) - 1; - static const int FrameOffsetMask = + static const uint64_t FrameOffsetMask = (FrameOffsetBits == sizeof(int)) ? (unsigned int)(-1) : (1 << FrameOffsetBits) - 1; @@ -70,6 +75,7 @@ namespace SparcISA IntReg regGlobals[MaxGL+1][RegsPerFrame]; IntReg regSegments[2 * NWindows][RegsPerFrame]; IntReg microRegs[NumMicroIntRegs]; + IntReg regs[NumIntRegs]; enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames}; diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 7a48042c2..5c69598d5 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -76,9 +76,15 @@ decode OP default Unknown::unknown() }}); 0x2: bpccx(19, {{ if(passesCondition(Ccr<7:4>, COND2)) + { + //warn("Took branch!\n"); NNPC = xc->readPC() + disp; + } else + { + //warn("Didn't take branch!\n"); handle_annul + } }}); } } @@ -247,16 +253,14 @@ decode OP default Unknown::unknown() ((Rs1 & val2) | (carryin & (Rs1 | val2)))<0:>)<63:>}}, {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} ); - 0x1A: umulcc({{ + 0x1A: IntOpCcRes::umulcc({{ uint64_t resTemp; Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>; - Y = resTemp<63:32>;}}, - {{0}},{{0}},{{0}},{{0}}); - 0x1B: smulcc({{ + Y = resTemp<63:32>;}}); + 0x1B: IntOpCcRes::smulcc({{ int64_t resTemp; Rd = resTemp = Rs1.sdw<31:0> * Rs2_or_imm13.sdw<31:0>; - Y = resTemp<63:32>;}}, - {{0}},{{0}},{{0}},{{0}}); + Y = resTemp<63:32>;}}); 0x1C: subccc({{ int64_t resTemp, val2 = Rs2_or_imm13; int64_t carryin = Ccr<0:0>; @@ -266,10 +270,9 @@ decode OP default Unknown::unknown() {{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}}, {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} ); - 0x1D: udivxcc({{ + 0x1D: IntOpCcRes::udivxcc({{ if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; - else Rd = Rs1.udw / Rs2_or_imm13.udw;}} - ,{{0}},{{0}},{{0}},{{0}}); + else Rd = Rs1.udw / Rs2_or_imm13.udw;}}); 0x1E: udivcc({{ uint32_t resTemp, val2 = Rs2_or_imm13.udw; int32_t overflow = 0; @@ -880,16 +883,11 @@ decode OP default Unknown::unknown() } }}); 0x39: Branch::return({{ - //If both MemAddressNotAligned and - //a fill trap happen, it's not clear - //which one should be returned. Addr target = Rs1 + Rs2_or_imm13; - if(target & 0x3) - fault = new MemAddressNotAligned; - else - NNPC = target; if(fault == NoFault) { + //Check for fills which are higher priority than alignment + //faults. if(Canrestore == 0) { if(Otherwin) @@ -897,18 +895,15 @@ decode OP default Unknown::unknown() else fault = new FillNNormal(Wstate<2:0>); } + //Check for alignment faults + else if(target & 0x3) + fault = new MemAddressNotAligned; else { - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one + NNPC = target; Cwp = (Cwp - 1 + NWindows) % NWindows; Cansave = Cansave + 1; Canrestore = Canrestore - 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } } }}); @@ -926,7 +921,7 @@ decode OP default Unknown::unknown() xc->syscall(R1); #endif } - }}); + }}, IsSerializeAfter, IsNonSpeculative); 0x2: Trap::tccx({{ if(passesCondition(Ccr<7:4>, COND2)) { @@ -939,36 +934,27 @@ decode OP default Unknown::unknown() xc->syscall(R1); #endif } - }}); + }}, IsSerializeAfter, IsNonSpeculative); } 0x3B: Nop::flush({{/*Instruction memory flush*/}}); 0x3C: save({{ - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one if(Cansave == 0) { if(Otherwin) fault = new SpillNOther(Wstate<5:3>); else fault = new SpillNNormal(Wstate<2:0>); - //Cwp = (Cwp + 2) % NWindows; } else if(Cleanwin - Canrestore == 0) { - //Cwp = (Cwp + 1) % NWindows; fault = new CleanWindow; } else { Cwp = (Cwp + 1) % NWindows; - Rd = Rs1 + Rs2_or_imm13; + Rd_next = Rs1 + Rs2_or_imm13; Cansave = Cansave - 1; Canrestore = Canrestore + 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } }}); 0x3D: restore({{ @@ -981,17 +967,10 @@ decode OP default Unknown::unknown() } else { - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one Cwp = (Cwp - 1 + NWindows) % NWindows; - Rd = Rs1 + Rs2_or_imm13; + Rd_prev = Rs1 + Rs2_or_imm13; Cansave = Cansave + 1; Canrestore = Canrestore - 1; - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } }}); 0x3E: decode FCN { diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa index a4c05387b..56e933763 100644 --- a/src/arch/sparc/isa/formats/basic.isa +++ b/src/arch/sparc/isa/formats/basic.isa @@ -95,8 +95,7 @@ def template BasicDecodeWithMnemonic {{ // The most basic instruction format... used only for a few misc. insts def format BasicOperate(code, *flags) {{ - iop = InstObjParams(name, Name, 'SparcStaticInst', - CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa index 5fb7ade2d..2db756320 100644 --- a/src/arch/sparc/isa/formats/branch.isa +++ b/src/arch/sparc/isa/formats/branch.isa @@ -170,7 +170,7 @@ output decoder {{ printMnemonic(response, mnemonic); ccprintf(response, "0x%x", target); - if(symtab->findNearestSymbol(target, symbol, symbolAddr)) + if(symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) { ccprintf(response, " <%s", symbol); if(symbolAddr != target) @@ -178,6 +178,10 @@ output decoder {{ else ccprintf(response, ">"); } + else + { + ccprintf(response, "<%d>", target); + } return response.str(); } @@ -244,7 +248,6 @@ def format Branch(code, *opt_flags) {{ // Primary format for branch instructions: def format BranchN(bits, code, *opt_flags) {{ code = re.sub(r'handle_annul', handle_annul, code) - codeBlk = CodeBlock(code) new_opt_flags = [] for flag in opt_flags: if flag == ',a': @@ -252,7 +255,7 @@ def format BranchN(bits, code, *opt_flags) {{ Name += 'Annul' else: new_opt_flags += flag - iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, new_opt_flags) + iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = BranchExecute.subst(iop) @@ -262,8 +265,7 @@ def format BranchN(bits, code, *opt_flags) {{ // Primary format for branch instructions: def format BranchSplit(code, *opt_flags) {{ code = re.sub(r'handle_annul', handle_annul, code) - codeBlk = CodeBlock(code) - iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags) + iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = BranchExecute.subst(iop) diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa index 4f8ebebcc..363aca1a1 100644 --- a/src/arch/sparc/isa/formats/integerop.isa +++ b/src/arch/sparc/isa/formats/integerop.isa @@ -263,14 +263,15 @@ let {{ def doIntFormat(code, ccCode, name, Name, opt_flags): (usesImm, code, immCode, rString, iString) = splitOutImm(code) - iop = InstObjParams(name, Name, 'IntOp', code, - opt_flags, {"cc_code": ccCode}) + iop = InstObjParams(name, Name, 'IntOp', + {"code": code, "cc_code": ccCode}, + opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = IntOpExecute.subst(iop) if usesImm: imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString, - immCode, opt_flags, {"cc_code": ccCode}) + {"code": immCode, "cc_code": ccCode}, opt_flags) header_output += BasicDeclare.subst(imm_iop) decoder_output += BasicConstructor.subst(imm_iop) exec_output += IntOpExecute.subst(imm_iop) @@ -341,7 +342,7 @@ def format IntOpCcRes(code, *opt_flags) {{ def format SetHi(code, *opt_flags) {{ iop = InstObjParams(name, Name, 'SetHi', - code, opt_flags, {"cc_code": ''}) + {"code": code, "cc_code": ''}, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) exec_output = IntOpExecute.subst(iop) diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index 55e9fba45..ed0c41e61 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -55,16 +55,20 @@ let {{ def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags): addrCalcReg = 'EA = Rs1 + Rs2;' addrCalcImm = 'EA = Rs1 + imm;' - iop = InstObjParams(name, Name, 'Mem', code, - opt_flags, {"fault_check": faultCode, "ea_code": addrCalcReg}) - iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code, - opt_flags, {"fault_check": faultCode, "ea_code": addrCalcImm}) + iop = InstObjParams(name, Name, 'Mem', + {"code": code, "fault_check": faultCode, + "ea_code": addrCalcReg}, + opt_flags) + iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', + {"code": code, "fault_check": faultCode, + "ea_code": addrCalcImm}, + opt_flags) header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm) decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm) decode_block = ROrImmDecode.subst(iop) exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm, - execute, faultCode, name, name + "Imm", Name, Name + "Imm", - asi, opt_flags) + execute, faultCode, name, name + "Imm", + Name, Name + "Imm", opt_flags) return (header_output, decoder_output, exec_output, decode_block) }}; @@ -72,7 +76,7 @@ def format LoadAlt(code, asi, *opt_flags) {{ (header_output, decoder_output, exec_output, - decode_block) = doMemFormat(code, LoadExecute, + decode_block) = doMemFormat(code, LoadFuncs, AlternateASIPrivFaultCheck, name, Name, asi, opt_flags) }}; @@ -80,7 +84,7 @@ def format StoreAlt(code, asi, *opt_flags) {{ (header_output, decoder_output, exec_output, - decode_block) = doMemFormat(code, StoreExecute, + decode_block) = doMemFormat(code, StoreFuncs, AlternateASIPrivFaultCheck, name, Name, asi, opt_flags) }}; @@ -89,7 +93,7 @@ def format Load(code, *opt_flags) {{ decoder_output, exec_output, decode_block) = doMemFormat(code, - LoadExecute, '', name, Name, 0, opt_flags) + LoadFuncs, '', name, Name, 0, opt_flags) }}; def format Store(code, *opt_flags) {{ @@ -97,5 +101,5 @@ def format Store(code, *opt_flags) {{ decoder_output, exec_output, decode_block) = doMemFormat(code, - StoreExecute, '', name, Name, 0, opt_flags) + StoreFuncs, '', name, Name, 0, opt_flags) }}; diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 7a1a58d13..a0b235a61 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -293,14 +293,14 @@ let {{ else: flag_code = "flags[IsDelayedCommit] = true;" pcedCode = matcher.sub("Frd_%d" % microPc, code) - iop = InstObjParams(name, Name, 'BlockMem', pcedCode, - opt_flags, {"ea_code": addrCalcReg, + iop = InstObjParams(name, Name, 'BlockMem', + {"code": pcedCode, "ea_code": addrCalcReg, "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}) - iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode, - opt_flags, {"ea_code": addrCalcImm, + "set_flags": flag_code}, opt_flags) + iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', + {"code": pcedCode, "ea_code": addrCalcImm, "fault_check": faultCode, "micro_pc": microPc, - "set_flags": flag_code}) + "set_flags": flag_code}, opt_flags) decoder_output += BlockMemMicroConstructor.subst(iop) decoder_output += BlockMemMicroConstructor.subst(iop_imm) exec_output += doDualSplitExecute( @@ -323,7 +323,7 @@ def format BlockLoad(code, asi, *opt_flags) {{ decoder_output, exec_output, decode_block) = doBlockMemFormat(code, faultCode, - LoadExecute, name, Name, asi, opt_flags) + LoadFuncs, name, Name, asi, opt_flags) }}; def format BlockStore(code, asi, *opt_flags) {{ @@ -335,5 +335,5 @@ def format BlockStore(code, asi, *opt_flags) {{ decoder_output, exec_output, decode_block) = doBlockMemFormat(code, faultCode, - StoreExecute, name, Name, asi, opt_flags) + StoreFuncs, name, Name, asi, opt_flags) }}; diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index 3e9fd7a7d..03b08ae18 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -144,7 +144,7 @@ def template LoadExecute {{ %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -162,16 +162,19 @@ def template LoadExecute {{ return fault; } +}}; +def template LoadInitiateAcc {{ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { Fault fault = NoFault; Addr EA; uint%(mem_acc_size)s_t Mem; - %(ea_decl)s; - %(ea_rd)s; + %(op_decl)s; + %(op_rd)s; %(ea_code)s; + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -179,18 +182,20 @@ def template LoadExecute {{ } return fault; } +}}; +def template LoadCompleteAcc {{ Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { Fault fault = NoFault; - %(code_decl)s; - %(code_rd)s; + %(op_decl)s; + %(op_rd)s; Mem = pkt->get<typeof(Mem)>(); %(code)s; if(fault == NoFault) { - %(code_wb)s; + %(op_wb)s; } return fault; } @@ -209,7 +214,7 @@ def template StoreExecute {{ %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -228,7 +233,9 @@ def template StoreExecute {{ return fault; } +}}; +def template StoreInitiateAcc {{ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { @@ -238,7 +245,7 @@ def template StoreExecute {{ %(op_decl)s; %(op_rd)s; %(ea_code)s; - DPRINTF(Sparc, "The address is 0x%x\n", EA); + DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); %(fault_check)s; if(fault == NoFault) { @@ -256,7 +263,9 @@ def template StoreExecute {{ } return fault; } +}}; +def template StoreCompleteAcc {{ Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { @@ -276,6 +285,8 @@ def template CompleteAccDeclare {{ //Here are some code snippets which check for various fault conditions let {{ + LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc] + StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc] # The LSB can be zero, since it's really the MSB in doubles and quads # and we're dealing with doubles BlockAlignmentFaultCheck = ''' @@ -310,21 +321,11 @@ let {{ //and in the other they're distributed across two. Also note that for //execute functions, the name of the base class doesn't matter. let {{ - def doSplitExecute(code, execute, name, Name, asi, opt_flags, microParam): + def doSplitExecute(execute, name, Name, asi, opt_flags, microParam): microParam["asi_val"] = asi; - codeParam = microParam.copy() - codeParam["ea_code"] = '' - codeIop = InstObjParams(name, Name, '', code, opt_flags, codeParam) - eaIop = InstObjParams(name, Name, '', microParam["ea_code"], - opt_flags, microParam) - iop = InstObjParams(name, Name, '', code, opt_flags, microParam) - (iop.ea_decl, - iop.ea_rd, - iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb) - (iop.code_decl, - iop.code_rd, - iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb) - return execute.subst(iop) + iop = InstObjParams(name, Name, '', microParam, opt_flags) + (execf, initf, compf) = execute + return execf.subst(iop) + initf.subst(iop) + compf.subst(iop) def doDualSplitExecute(code, eaRegCode, eaImmCode, execute, @@ -333,8 +334,9 @@ let {{ for (eaCode, name, Name) in ( (eaRegCode, nameReg, NameReg), (eaImmCode, nameImm, NameImm)): - microParams = {"ea_code" : eaCode, "fault_check": faultCode} - executeCode += doSplitExecute(code, execute, name, Name, + microParams = {"code": code, "ea_code": eaCode, + "fault_check": faultCode} + executeCode += doSplitExecute(execute, name, Name, asi, opt_flags, microParams) return executeCode }}; diff --git a/src/arch/sparc/isa/formats/nop.isa b/src/arch/sparc/isa/formats/nop.isa index 37ef2e8d0..de2ba2f54 100644 --- a/src/arch/sparc/isa/formats/nop.isa +++ b/src/arch/sparc/isa/formats/nop.isa @@ -88,9 +88,7 @@ def template NopExecute {{ // Primary format for integer operate instructions: def format Nop(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'Nop', cblk, opt_flags) + iop = InstObjParams(name, Name, 'Nop', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index 3d47ca02f..36403afb4 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -235,8 +235,9 @@ let {{ name = mnem regBase = 'WrPriv' break - iop = InstObjParams(name, Name, regBase, code, - opt_flags, {"check": checkCode, "reg_name": regName}) + iop = InstObjParams(name, Name, regBase, + {"code": code, "check": checkCode, "reg_name": regName}, + opt_flags) header_output = BasicDeclare.subst(iop) if regName == '': decoder_output = BasicConstructor.subst(iop) @@ -245,7 +246,8 @@ let {{ exec_output = PrivExecute.subst(iop) if usesImm: imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm', - immCode, opt_flags, {"check": checkCode, "reg_name": regName}) + {"code": immCode, "check": checkCode, "reg_name": regName}, + opt_flags) header_output += BasicDeclare.subst(imm_iop) if regName == '': decoder_output += BasicConstructor.subst(imm_iop) diff --git a/src/arch/sparc/isa/formats/trap.isa b/src/arch/sparc/isa/formats/trap.isa index 04d467cfe..9c118b227 100644 --- a/src/arch/sparc/isa/formats/trap.isa +++ b/src/arch/sparc/isa/formats/trap.isa @@ -83,9 +83,7 @@ def template TrapExecute {{ }}; def format Trap(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'Trap', cblk, opt_flags) + iop = InstObjParams(name, Name, 'Trap', code, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index 624afb693..2e7b16f20 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -37,12 +37,13 @@ output header {{ #include <sstream> #include <iostream> -#include "cpu/static_inst.hh" #include "arch/sparc/faults.hh" -#include "mem/request.hh" // some constructors use MemReq flags -#include "mem/packet.hh" #include "arch/sparc/isa_traits.hh" #include "arch/sparc/regfile.hh" +#include "base/misc.hh" +#include "cpu/static_inst.hh" +#include "mem/packet.hh" +#include "mem/request.hh" // some constructors use MemReq flags }}; output decoder {{ diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index 80ed7362c..256f2fa43 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -56,12 +56,23 @@ def operands {{ # Int regs default to unsigned, but code should not count on this. # For clarity, descriptions that depend on unsigned behavior should # explicitly specify '.uq'. + 'Rd': ('IntReg', 'udw', 'RD', 'IsInteger', 1), - 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 2), - 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3), - 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4), - 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5), - 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 6), + # The Rd from the previous window + 'Rd_prev': ('IntReg', 'udw', 'RD + NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 2), + # The Rd from the next window + 'Rd_next': ('IntReg', 'udw', 'RD + 2 * NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 3), + # The low (even) register of a two register pair + 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 4), + # The high (odd) register of a two register pair + 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 5), + 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 6), + 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 7), + # A microcode register. Right now, this is the only one. + 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 8), + # Because double and quad precision register numbers are decoded + # differently, they get different operands. The single precision versions + # have an s post pended to their name. 'Frds': ('FloatReg', 'sf', 'RD', 'IsFloating', 10), 'Frd': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10), # Each Frd_N refers to the Nth double precision register from Frd. @@ -80,14 +91,17 @@ def operands {{ 'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12), 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31), 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32), + # Registers which are used explicitly in instructions 'R0': ('IntReg', 'udw', '0', None, 6), 'R1': ('IntReg', 'udw', '1', None, 7), 'R15': ('IntReg', 'udw', '15', 'IsInteger', 8), 'R16': ('IntReg', 'udw', '16', None, 9), # Control registers - 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), - 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), +# 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), +# 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), + 'Y': ('IntReg', 'udw', 'NumIntArchRegs + 1', None, 40), + 'Ccr': ('IntReg', 'udw', 'NumIntArchRegs + 2', None, 41), 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42), 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43), 'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44), @@ -109,12 +123,17 @@ def operands {{ 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59), 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60), 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61), - 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 62), - 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), - 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), - 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), - 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), - 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), + 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 62), +# 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), +# 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), +# 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), +# 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), +# 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), + 'Cansave': ('IntReg', 'udw', 'NumIntArchRegs + 3', None, 63), + 'Canrestore': ('IntReg', 'udw', 'NumIntArchRegs + 4', None, 64), + 'Cleanwin': ('IntReg', 'udw', 'NumIntArchRegs + 5', None, 65), + 'Otherwin': ('IntReg', 'udw', 'NumIntArchRegs + 6', None, 66), + 'Wstate': ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67), 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68), 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69), diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 3f0b9cad5..2b136856a 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -58,8 +58,8 @@ namespace SparcISA // These enumerate all the registers for dependence tracking. enum DependenceTags { - FP_Base_DepTag = 33, - Ctrl_Base_DepTag = 97, + FP_Base_DepTag = 32*3+8, + Ctrl_Base_DepTag = FP_Base_DepTag + 64, }; // semantically meaningful register indices diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 53559c072..6641d38bb 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -46,15 +46,9 @@ class Checkpoint; string SparcISA::getMiscRegName(RegIndex index) { static::string miscRegName[NumMiscRegs] = - {"y", "ccr", "asi", "tick", "fprs", "pcr", "pic", - "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr", - "stick", "stick_cmpr", - "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl", - "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin", - "wstate", "gl", - "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg", - "hstick_cmpr", - "fsr"}; + {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic", + "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin", + "wstate",*/ "gl", return miscRegName[index]; } diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index c879fd357..ace916f5b 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -47,8 +47,8 @@ namespace SparcISA enum MiscRegIndex { /** Ancillary State Registers */ - MISCREG_Y, /* 0 */ - MISCREG_CCR, +// MISCREG_Y, +// MISCREG_CCR, MISCREG_ASI, MISCREG_TICK, MISCREG_FPRS, @@ -73,11 +73,11 @@ namespace SparcISA MISCREG_TL, MISCREG_PIL, MISCREG_CWP, - MISCREG_CANSAVE, - MISCREG_CANRESTORE, - MISCREG_CLEANWIN, - MISCREG_OTHERWIN, - MISCREG_WSTATE, +// MISCREG_CANSAVE, +// MISCREG_CANRESTORE, +// MISCREG_CLEANWIN, +// MISCREG_OTHERWIN, +// MISCREG_WSTATE, MISCREG_GL, /** Hyper privileged registers */ diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 405e408e5..073117a84 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -95,17 +95,22 @@ SparcLiveProcess::startup() */ //No windows contain info from other programs - threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0); + //threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0); + threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0); //There are no windows to pop - threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0); + //threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0); + threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0); //All windows are available to save into - threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2); + //threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2); + threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2); //All windows are "clean" - threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows); + //threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows); + threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows); //Start with register window 0 threadContexts[0]->setMiscReg(MISCREG_CWP, 0); //Always use spill and fill traps 0 - threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0); + //threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0); + threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0); //Set the trap level to 0 threadContexts[0]->setMiscReg(MISCREG_TL, 0); //Set the ASI register to something fixed diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 5d8ac6a17..691d0a0f1 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -151,6 +151,72 @@ void RegFile::setIntReg(int intReg, const IntReg &val) intRegFile.setReg(intReg, val); } +int SparcISA::flattenIntIndex(ThreadContext * tc, int reg) +{ + int gl = tc->readMiscReg(MISCREG_GL); + int cwp = tc->readMiscReg(MISCREG_CWP); + //DPRINTF(Sparc, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp); + int newReg; + if(reg < 8) + { + //Global register + //Put it in the appropriate set of globals + newReg = reg + gl * 8; + } + else if(reg < NumIntArchRegs) + { + //Regular windowed register + //Put it in the window pointed to by cwp + newReg = MaxGL * 8 + + ((reg - 8 - cwp * 16 + NWindows * 16) % (NWindows * 16)); + } + else if(reg < NumIntArchRegs + NumMicroIntRegs) + { + //Microcode register + //Displace from the end of the regular registers + newReg = reg - NumIntArchRegs + MaxGL * 8 + NWindows * 16; + } + else if(reg < 2 * NumIntArchRegs + NumMicroIntRegs) + { + reg -= (NumIntArchRegs + NumMicroIntRegs); + if(reg < 8) + { + //Global register from the next window + //Put it in the appropriate set of globals + newReg = reg + gl * 8; + } + else + { + //Windowed register from the previous window + //Put it in the window before the one pointed to by cwp + newReg = MaxGL * 8 + + ((reg - 8 - (cwp - 1) * 16 + NWindows * 16) % (NWindows * 16)); + } + } + else if(reg < 3 * NumIntArchRegs + NumMicroIntRegs) + { + reg -= (2 * NumIntArchRegs + NumMicroIntRegs); + if(reg < 8) + { + //Global register from the previous window + //Put it in the appropriate set of globals + newReg = reg + gl * 8; + } + else + { + //Windowed register from the next window + //Put it in the window after the one pointed to by cwp + newReg = MaxGL * 8 + + ((reg - 8 - (cwp + 1) * 16 + NWindows * 16) % (NWindows * 16)); + } + } + else + panic("Tried to flatten invalid register index %d!\n", reg); + DPRINTF(Sparc, "Flattened register %d to %d.\n", reg, newReg); + return newReg; + //return intRegFile.flattenIndex(reg); +} + void RegFile::serialize(std::ostream &os) { intRegFile.serialize(os); @@ -220,8 +286,8 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) // ASRs - dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y)); - dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR)); +// dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y)); +// dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR)); dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI)); dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK)); dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS)); @@ -236,11 +302,11 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE)); dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL)); dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP)); - dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE)); - dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE)); - dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN)); - dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN)); - dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE)); +// dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE)); +// dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE)); +// dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN)); +// dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN)); +// dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE)); dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL)); // Hyperprivilged registers diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index 0a09d0f66..d9af0757c 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -120,6 +120,8 @@ namespace SparcISA void changeContext(RegContextParam param, RegContextVal val); }; + int flattenIntIndex(ThreadContext * tc, int reg); + void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/sparc/sparc_traits.hh b/src/arch/sparc/sparc_traits.hh index a3d29ea8a..d89ec1119 100644 --- a/src/arch/sparc/sparc_traits.hh +++ b/src/arch/sparc/sparc_traits.hh @@ -41,7 +41,8 @@ namespace SparcISA // Number of register windows, can legally be 3 to 32 const int NWindows = 8; - const int NumMicroIntRegs = 1; + //const int NumMicroIntRegs = 1; + const int NumMicroIntRegs = 8; // const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16; // const int NumMicroIntRegs = 1; diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh index 75a063da1..d92b12790 100644 --- a/src/arch/sparc/syscallreturn.hh +++ b/src/arch/sparc/syscallreturn.hh @@ -33,58 +33,30 @@ #include <inttypes.h> +#include "sim/syscallreturn.hh" #include "arch/sparc/regfile.hh" - -class SyscallReturn -{ - public: - template <class T> - SyscallReturn(T v, bool s) - { - retval = (uint64_t)v; - success = s; - } - - template <class T> - SyscallReturn(T v) - { - success = (v >= 0); - retval = (uint64_t)v; - } - - ~SyscallReturn() {} - - SyscallReturn& operator=(const SyscallReturn& s) - { - retval = s.retval; - success = s.success; - return *this; - } - - bool successful() { return success; } - uint64_t value() { return retval; } - - private: - uint64_t retval; - bool success; -}; +#include "cpu/thread_context.hh" namespace SparcISA { static inline void setSyscallReturn(SyscallReturn return_value, - RegFile *regs) + ThreadContext * tc) { // 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 (). if (return_value.successful()) { // no error, clear XCC.C - regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEE); - regs->setIntReg(ReturnValueReg, return_value.value()); + tc->setIntReg(NumIntArchRegs + 2, + tc->readIntReg(NumIntArchRegs + 2) & 0xEE); + //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) & 0xEE); + tc->setIntReg(ReturnValueReg, return_value.value()); } else { // got an error, set XCC.C - regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x11); - regs->setIntReg(ReturnValueReg, return_value.value()); + tc->setIntReg(NumIntArchRegs + 2, + tc->readIntReg(NumIntArchRegs + 2) | 0x11); + //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) | 0x11); + tc->setIntReg(ReturnValueReg, -return_value.value()); } } }; |