Support NNPC and branch instructions ... Outputs to decoder.cc correctly
Edits to the CPU model may still need to be made to handle branch likely insts... arch/isa_parser.py: add a NNPC operand ... arch/mips/isa/base.isa: change SPARC to MIPS arch/mips/isa/decoder.isa: typo < to >= arch/mips/isa/formats/basic.isa: spacing arch/mips/isa/formats/branch.isa: add code for branch instructions (still need adjustments for the branch likely) arch/mips/isa/operands.isa: support for NNPC and R31 arch/mips/isa_traits.hh: NNPC Addr variable --HG-- extra : convert_revision : df03d2a71c36dbc00270c2e3d7882b4f09ed97ad
This commit is contained in:
parent
bd17580928
commit
a48c24b61e
7 changed files with 35 additions and 14 deletions
|
@ -1355,6 +1355,7 @@ class MemOperand(Operand):
|
|||
def makeAccSize(self):
|
||||
return self.size
|
||||
|
||||
|
||||
class NPCOperand(Operand):
|
||||
def makeConstructor(self):
|
||||
return ''
|
||||
|
@ -1365,6 +1366,15 @@ class NPCOperand(Operand):
|
|||
def makeWrite(self):
|
||||
return 'xc->setNextPC(%s);\n' % self.base_name
|
||||
|
||||
class NNPCOperand(Operand):
|
||||
def makeConstructor(self):
|
||||
return ''
|
||||
|
||||
def makeRead(self):
|
||||
return '%s = xc->readPC() + 8;\n' % self.base_name
|
||||
|
||||
def makeWrite(self):
|
||||
return 'xc->setNextNPC(%s);\n' % self.base_name
|
||||
|
||||
def buildOperandNameMap(userDict, lineno):
|
||||
global operandNameMap
|
||||
|
|
|
@ -16,7 +16,7 @@ output header {{
|
|||
|
||||
// Constructor.
|
||||
MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||
: StaticInst<SPARCISA>(mnem, _machInst, __opClass)
|
||||
: StaticInst<MIPSISA>(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ decode OPCODE_HI default Unknown::unknown() {
|
|||
0x1: decode REGIMM_LO {
|
||||
format Trap {
|
||||
0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }});
|
||||
0x1: tgeiu({{ cond = (Rs.uw < INTIMM); }});
|
||||
0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }});
|
||||
0x2: tlti( {{ cond = (Rs.sw < INTIMM); }});
|
||||
0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
|
||||
0x4: teqi( {{ cond = (Rs.sw == INTIMM);}});
|
||||
|
|
|
@ -40,7 +40,7 @@ def template BasicExecute {{
|
|||
|
||||
if(fault == No_Fault)
|
||||
{
|
||||
%(op_wb)s;
|
||||
%(op_wb)s;
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
|
|
@ -45,12 +45,12 @@ output header {{
|
|||
{
|
||||
protected:
|
||||
/// target address (signed) Displacement .
|
||||
int32_t targetOffset;
|
||||
int32_t disp;
|
||||
|
||||
/// Constructor.
|
||||
Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||
targetOffset(OFFSET << 2)
|
||||
disp(OFFSET << 2)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -67,12 +67,12 @@ output header {{
|
|||
{
|
||||
protected:
|
||||
/// target address (signed) Displacement .
|
||||
int32_t targetOffset;
|
||||
int32_t disp;
|
||||
|
||||
/// Constructor.
|
||||
Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||
targetOffset(OFFSET << 2)
|
||||
disp(OFFSET << 2)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -255,9 +255,12 @@ def format Branch(code,*flags) {{
|
|||
#Add Link Code if Link instruction
|
||||
strlen = len(name)
|
||||
if name[strlen-2:] == 'al':
|
||||
code += 'R31 = NPC + 8;\n'
|
||||
code += 'R31 = NPC + 4;\n'
|
||||
|
||||
code += '\nif (cond) NPC = NPC + disp;\n';
|
||||
# condition code
|
||||
code += 'if (cond) {'
|
||||
code += ' NPC = NPC + disp;\n'
|
||||
code += ' NNPC = NNPC + disp;\n } \n'
|
||||
|
||||
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
|
||||
('IsDirectControl', 'IsCondControl'))
|
||||
|
@ -267,15 +270,20 @@ def format Branch(code,*flags) {{
|
|||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
|
||||
def format BranchLikely(code,*flags) {{
|
||||
code = 'bool cond;\n\t\t\t' + code
|
||||
|
||||
#Add Link Code if Link instruction
|
||||
strlen = len(name)
|
||||
if name[strlen-3:] == 'all':
|
||||
code += 'R31 = NPC + 8;\n'
|
||||
code += 'R31 = NPC + 4;\n'
|
||||
|
||||
#condition code
|
||||
code += 'if (cond) {'
|
||||
code += ' NPC = NPC + disp;\n'
|
||||
code += ' NNPC = NNPC + disp;\n } \n'
|
||||
|
||||
code = '\t\t\tif (cond) NPC = NPC + disp;\n';
|
||||
|
||||
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
|
||||
('IsDirectControl', 'IsCondControl','IsCondDelaySlot'))
|
||||
|
|
|
@ -16,6 +16,7 @@ def operands {{
|
|||
'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1),
|
||||
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2),
|
||||
'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3),
|
||||
'R31': ('IntReg', 'uw','R31','IsInteger', 4),
|
||||
|
||||
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
|
||||
'Sa': ('IntReg', 'uw', 'SA', 'IsInteger', 4),
|
||||
|
@ -24,12 +25,12 @@ def operands {{
|
|||
'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2),
|
||||
'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
|
||||
|
||||
'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4)
|
||||
'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
|
||||
|
||||
#'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4),
|
||||
'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4),
|
||||
'NNPC': ('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4)
|
||||
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
|
||||
#'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1),
|
||||
# The next two are hacks for non-full-system call-pal emulation
|
||||
#'R0': ('IntReg', 'uq', '0', None, 1),
|
||||
#'R31': ('IntReg', 'uw', '31', None, 1)
|
||||
}};
|
||||
|
|
|
@ -430,6 +430,8 @@ class MipsISA
|
|||
|
||||
Addr pc; // Program Counter
|
||||
Addr npc; // Next Program Counter
|
||||
Addr nnpc; // Next next program Counter
|
||||
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
|
Loading…
Reference in a new issue