1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
////////////////////////////////////////////////////////////////////
//
// Noop instruction
//
output header {{
/**
* Base class for integer operations.
*/
class Noop : public MipsStaticInst
{
protected:
/// Constructor
Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string Noop::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return "Disassembly of integer instruction\n";
}
}};
def template NoopExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
//Nothing to see here, move along
return No_Fault;
}
}};
// Primary format for integer operate instructions:
def format Noop(code, *opt_flags) {{
orig_code = code
cblk = CodeBlock(code)
iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecodeWithMnemonic.subst(iop)
exec_output = NoopExecute.subst(iop)
}};
////////////////////////////////////////////////////////////////////
//
// Nop
//
output header {{
/**
* Static instruction class for no-ops. This is a leaf class.
*/
class Nop : public AlphaStaticInst
{
/// Disassembly of original instruction.
const std::string originalDisassembly;
public:
/// Constructor
Nop(const std::string _originalDisassembly, MachInst _machInst)
: AlphaStaticInst("nop", _machInst, No_OpClass),
originalDisassembly(_originalDisassembly)
{
flags[IsNop] = true;
}
~Nop() { }
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
%(BasicExecDeclare)s
};
}};
output decoder {{
std::string Nop::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return originalDisassembly;
#else
return csprintf("%-10s (%s)", "nop", originalDisassembly);
#endif
}
/// Helper function for decoding nops. Substitute Nop object
/// for original inst passed in as arg (and delete latter).
inline
AlphaStaticInst *
makeNop(AlphaStaticInst *inst)
{
AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
delete inst;
return nop;
}
}};
output exec {{
Fault
Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
return No_Fault;
}
}};
// integer & FP operate instructions use Rc as dest, so check for
// Rc == 31 to detect nops
def template OperateNopCheckDecode {{
{
AlphaStaticInst *i = new %(class_name)s(machInst);
if (RC == 31) {
i = makeNop(i);
}
return i;
}
}};
// Like BasicOperate format, but generates NOP if RC/FC == 31
def format BasicOperateWithNopCheck(code, *opt_args) {{
iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code),
opt_args)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = OperateNopCheckDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
|