From f1661baf30faf76dbad7d23aeac0c3dbe4dd045c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 16 Oct 2006 15:56:46 -0400 Subject: [PATCH] Fix up microcode support. src/arch/sparc/isa/formats/blockmem.isa: Several small and medium bug fixes. src/cpu/simple/base.cc: Fixed a few compiler errors and made sure the next micro pc is set to 1 to prevent the first microop from executing twice. Also fixed a fetching bug. src/cpu/thread_state.cc: Made sure the microPC and nextMicroPC are initialized properly. --HG-- extra : convert_revision : a0fc8aa18d1ade916f17c557181a793c6108a8af --- src/arch/sparc/isa/formats/blockmem.isa | 100 +++++++++++------------- src/cpu/simple/base.cc | 12 +-- src/cpu/thread_state.cc | 4 +- 3 files changed, 54 insertions(+), 62 deletions(-) diff --git a/src/arch/sparc/isa/formats/blockmem.isa b/src/arch/sparc/isa/formats/blockmem.isa index abf5a3e52..a273f07e3 100644 --- a/src/arch/sparc/isa/formats/blockmem.isa +++ b/src/arch/sparc/isa/formats/blockmem.isa @@ -16,9 +16,6 @@ output header {{ ExtMachInst _machInst, OpClass __opClass) : SparcMacroInst(mnem, _machInst, __opClass, 8) {} - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; }; class BlockMemImm : public BlockMem @@ -32,9 +29,6 @@ output header {{ imm(sext<13>(SIMM13)) {} - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - const int32_t imm; }; @@ -74,7 +68,7 @@ output header {{ }}; output decoder {{ - std::string BlockMem::generateDisassembly(Addr pc, + std::string BlockMemMicro::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream response; @@ -101,7 +95,7 @@ output decoder {{ return response.str(); } - std::string BlockMemImm::generateDisassembly(Addr pc, + std::string BlockMemImmMicro::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream response; @@ -165,17 +159,14 @@ def template BlockMemDeclare {{ { public: //Constructor - %(class_name)s(MachInst machInst); + %(class_name)s(ExtMachInst machInst); protected: class %(class_name)s_0 : public %(base_class)sMicro { public: //Constructor - %(class_name)s_0(MachInst machInst) : - %(base_class)sMicro("%(mnemonic)s[0]", - machInst, %(op_class)s, 0*8) - {;} + %(class_name)s_0(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -183,10 +174,7 @@ def template BlockMemDeclare {{ { public: //Constructor - %(class_name)s_1(MachInst machInst) : - %(base_class)sMicro("%(mnemonic)s[1]", - machInst, %(op_class)s, 1*8) - {;} + %(class_name)s_1(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -194,10 +182,7 @@ def template BlockMemDeclare {{ { public: //Constructor - %(class_name)s_2(MachInst machInst) : - %(base_class)sMicro("%(mnemonic)s[2]", - machInst, %(op_class)s, 2*8) - {;} + %(class_name)s_2(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -205,10 +190,7 @@ def template BlockMemDeclare {{ { public: //Constructor - %(class_name)s_3(MachInst machInst) : - %(base_class)sMicro("%(mnemonic)s[3]", - machInst, %(op_class)s, 3*8) - {;} + %(class_name)s_3(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -216,10 +198,7 @@ def template BlockMemDeclare {{ { public: //Constructor - %(class_name)s_4(MachInst machInst) : - %(base_class)sMicro("%(mnemonic)s[4]", - machInst, %(op_class)s, 4*8) - {;} + %(class_name)s_4(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -227,10 +206,7 @@ def template BlockMemDeclare {{ { public: //Constructor - %(class_name)s_5(MachInst machInst) : - %(base_class)sMicro("%(mnemonic)s[5]", - machInst, %(op_class)s, 5*8) - {;} + %(class_name)s_5(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -238,10 +214,7 @@ def template BlockMemDeclare {{ { public: //Constructor - %(class_name)s_6(MachInst machInst) : - %(base_class)sMicro("%(mnemonic)s[6]", - machInst, %(op_class)s, 6*8) - {;} + %(class_name)s_6(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -249,12 +222,7 @@ def template BlockMemDeclare {{ { public: //Constructor - %(class_name)s_7(MachInst machInst) : - %(base_class)sMicro("%(mnemonic)s[7]", - machInst, %(op_class)s, 7*8) - { - flags[IsLastMicroOp] = true; - } + %(class_name)s_7(ExtMachInst machInst); %(BasicExecDeclare)s }; }; @@ -262,7 +230,7 @@ def template BlockMemDeclare {{ // Basic instruction class constructor template. def template BlockMemConstructor {{ - inline %(class_name)s::%(class_name)s(MachInst machInst) + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(constructor)s; @@ -277,16 +245,28 @@ def template BlockMemConstructor {{ } }}; +def template BlockMemMicroConstructor {{ + inline %(class_name)s:: + %(class_name)s_%(micro_pc)s:: + %(class_name)s_%(micro_pc)s(ExtMachInst machInst) : + %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]", + machInst, %(op_class)s, %(micro_pc)s * 8) + { + %(constructor)s; + %(set_flags)s; + } +}}; + def template MicroLoadExecute {{ - Fault %(class_name)s_%(micro_pc)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const + Fault %(class_name)s::%(class_name)s_%(micro_pc)s::execute( + %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Fault fault = NoFault; Addr EA; %(op_decl)s; %(op_rd)s; - %(fault_check)s; %(ea_code)s; + %(fault_check)s; DPRINTF(Sparc, "The address is 0x%x\n", EA); xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); %(code)s; @@ -310,8 +290,8 @@ def template MicroStoreExecute {{ Addr EA; %(op_decl)s; %(op_rd)s; - %(fault_check)s; %(ea_code)s; + %(fault_check)s; DPRINTF(Sparc, "The address is 0x%x\n", EA); %(code)s; @@ -334,14 +314,17 @@ let {{ # those that are only available in hpriv faultCheck = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0) return new PrivilegedAction; - if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2)) + if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) return new PrivilegedAction; - if(RD & 0xf) + //The LSB can be zero, since it's really the MSB in doubles + //and quads + if(RD & 0xe) return new IllegalInstruction; if(EA & 0x3f) - return new MemAddressNotAligned;''' - addrCalcReg = 'EA = Rs1 + Rs2 + offset;' - addrCalcImm = 'EA = Rs1 + imm + offset;' + return new MemAddressNotAligned; + ''' + addrCalcReg = 'EA = Rs1 + Rs2 + offset * 8;' + addrCalcImm = 'EA = Rs1 + imm + offset * 8;' iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags) iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags) header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm) @@ -350,15 +333,22 @@ let {{ matcher = re.compile(r'Frd_N') exec_output = '' for microPC in range(8): + flag_code = '' + if (microPC == 7): + flag_code = "flags[IsLastMicroOp] = true" pcedCode = matcher.sub("Frd_%d" % microPC, code) iop = InstObjParams(name, Name, 'BlockMem', pcedCode, opt_flags, {"ea_code": addrCalcReg, - "fault_check": faultCheck, "micro_pc": microPC}) + "fault_check": faultCheck, "micro_pc": microPC, + "set_flags": flag_code}) iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode, opt_flags, {"ea_code": addrCalcImm, - "fault_check": faultCheck, "micro_pc": microPC}) + "fault_check": faultCheck, "micro_pc": microPC, + "set_flags": flag_code}) exec_output += execute.subst(iop) exec_output += execute.subst(iop_imm) + decoder_output += BlockMemMicroConstructor.subst(iop) + decoder_output += BlockMemMicroConstructor.subst(iop_imm) faultCheck = '' return (header_output, decoder_output, exec_output, decode_block) }}; diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 1d5c0a6f5..769e400df 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -402,10 +402,12 @@ BaseSimpleCPU::preExecute() if (instPtr->isMacroOp()) { curMacroStaticInst = instPtr; curStaticInst = curMacroStaticInst->fetchMicroOp(0); + } else { + curStaticInst = instPtr; } } else { //Read the next micro op from the macro op - curStaticInst = curMacroStaticInst->fetchMicroOp(thread->readMicroPc()); + curStaticInst = curMacroStaticInst->fetchMicroOp(thread->readMicroPC()); } @@ -464,17 +466,17 @@ BaseSimpleCPU::advancePC(Fault fault) assert(curMacroStaticInst); //Close out this macro op, and clean up the //microcode state - curMacroStaticInst = nullStaticInst; + curMacroStaticInst = StaticInst::nullStaticInstPtr; thread->setMicroPC(0); - thread->setNextMicroPC(0); + thread->setNextMicroPC(1); } //If we're still in a macro op if (curMacroStaticInst) { //Advance the micro pc - thread->setMicroPC(thread->getNextMicroPC()); + thread->setMicroPC(thread->readNextMicroPC()); //Advance the "next" micro pc. Note that there are no delay //slots, and micro ops are "word" addressed. - thread->setNextMicroPC(thread->getNextMicroPC() + 1); + thread->setNextMicroPC(thread->readNextMicroPC() + 1); } else { // go to the next instruction thread->setPC(thread->readNextPC()); diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index 6a96560f1..c644ae8d7 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -42,13 +42,13 @@ ThreadState::ThreadState(int _cpuId, int _tid) : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL), - funcExeInst(0), storeCondFailures(0) + microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0) #else ThreadState::ThreadState(int _cpuId, int _tid, Process *_process, short _asid, MemObject *mem) : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), process(_process), asid(_asid), - funcExeInst(0), storeCondFailures(0) + microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0) #endif { numInst = 0; -- 2.30.2