Fix up microcode support.
authorGabe Black <gblack@eecs.umich.edu>
Mon, 16 Oct 2006 19:56:46 +0000 (15:56 -0400)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 16 Oct 2006 19:56:46 +0000 (15:56 -0400)
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
src/cpu/simple/base.cc
src/cpu/thread_state.cc

index abf5a3e520f83c1ca0c6aabb5d28edc2a8a18aab..a273f07e3fd341ed1a3410f3e65f14f2424ab3fe 100644 (file)
@@ -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)
 }};
index 1d5c0a6f5f170f1af9dac9f5b44f9ed14bcb8a35..769e400df9466985bbad00f4307909ee12b25095 100644 (file)
@@ -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());
index 6a96560f194e63cf3238be1a56d59f099c43dcf5..c644ae8d75025d39900adfaadf729c19e92a6a7c 100644 (file)
 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;