#ifndef __ARCH_SPARC_DECODER_HH__
#define __ARCH_SPARC_DECODER_HH__
+#include "arch/generic/decode_cache.hh"
+#include "arch/sparc/registers.hh"
#include "arch/types.hh"
-#include "cpu/decode_cache.hh"
-#include "cpu/static_inst_fwd.hh"
+#include "cpu/static_inst.hh"
namespace SparcISA
{
+class ISA;
class Decoder
{
+ protected:
+ // The extended machine instruction being generated
+ ExtMachInst emi;
+ bool instDone;
+ MiscReg asi;
+
+ public:
+ Decoder(ISA* isa = nullptr) : instDone(false), asi(0)
+ {}
+
+ void process() {}
+
+ void
+ reset()
+ {
+ instDone = false;
+ }
+
+ // Use this to give data to the predecoder. This should be used
+ // when there is control flow.
+ void
+ moreBytes(const PCState &pc, Addr fetchPC, MachInst inst)
+ {
+ emi = inst;
+ // The I bit, bit 13, is used to figure out where the ASI
+ // should come from. Use that in the ExtMachInst. This is
+ // slightly redundant, but it removes the need to put a condition
+ // into all the execute functions
+ if (inst & (1 << 13)) {
+ emi |= (static_cast<ExtMachInst>(
+ asi << (sizeof(MachInst) * 8)));
+ } else {
+ emi |= (static_cast<ExtMachInst>(bits(inst, 12, 5))
+ << (sizeof(MachInst) * 8));
+ }
+ instDone = true;
+ }
+
+ bool
+ needMoreBytes()
+ {
+ return true;
+ }
+
+ bool
+ instReady()
+ {
+ return instDone;
+ }
+
+ void
+ setContext(MiscReg _asi)
+ {
+ asi = _asi;
+ }
+
+ void takeOverFrom(Decoder *old) {}
+
protected:
/// A cache of decoded instruction objects.
- static DecodeCache defaultCache;
+ static GenericISA::BasicDecodeCache defaultCache;
public:
StaticInstPtr decodeInst(ExtMachInst mach_inst);
{
return defaultCache.decode(this, mach_inst, addr);
}
+
+ StaticInstPtr
+ decode(SparcISA::PCState &nextPC)
+ {
+ if (!instDone)
+ return NULL;
+ instDone = false;
+ return decode(emi, nextPC.instAddr());
+ }
};
} // namespace SparcISA