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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
// -*- mode:c++ -*-
let {{
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
postacc_code = '', base_class = 'Memory',
decode_template = BasicDecode, exec_template_base = ''):
# Make sure flags are in lists (convert to lists if not).
mem_flags = makeList(mem_flags)
inst_flags = makeList(inst_flags)
# add hook to get effective addresses into execution trace output.
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
# generate code block objects
ea_cblk = CodeBlock(ea_code)
memacc_cblk = CodeBlock(memacc_code)
postacc_cblk = CodeBlock(postacc_code)
# Some CPU models execute the memory operation as an atomic unit,
# while others want to separate them into an effective address
# computation and a memory access operation. As a result, we need
# to generate three StaticInst objects. Note that the latter two
# are nested inside the larger "atomic" one.
# generate InstObjParams for EAComp object
ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
# generate InstObjParams for MemAcc object
memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
# in the split execution model, the MemAcc portion is responsible
# for the post-access code.
memacc_iop.postacc_code = postacc_cblk.code
# generate InstObjParams for InitiateAcc, CompleteAcc object
# The code used depends on the template being used
if (exec_template_base == 'Load'):
initiateacc_cblk = CodeBlock(ea_code + memacc_code)
completeacc_cblk = CodeBlock(memacc_code + postacc_code)
elif (exec_template_base == 'Store'):
initiateacc_cblk = CodeBlock(ea_code + memacc_code)
completeacc_cblk = CodeBlock(postacc_code)
else:
initiateacc_cblk = ''
completeacc_cblk = ''
initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
inst_flags)
completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
inst_flags)
if (exec_template_base == 'Load'):
initiateacc_iop.ea_code = ea_cblk.code
initiateacc_iop.memacc_code = memacc_cblk.code
completeacc_iop.memacc_code = memacc_cblk.code
completeacc_iop.postacc_code = postacc_cblk.code
elif (exec_template_base == 'Store'):
initiateacc_iop.ea_code = ea_cblk.code
initiateacc_iop.memacc_code = memacc_cblk.code
completeacc_iop.postacc_code = postacc_cblk.code
# generate InstObjParams for unified execution
cblk = CodeBlock(ea_code + memacc_code + postacc_code)
iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
iop.ea_constructor = ea_cblk.constructor
iop.ea_code = ea_cblk.code
iop.memacc_constructor = memacc_cblk.constructor
iop.memacc_code = memacc_cblk.code
iop.postacc_code = postacc_cblk.code
if mem_flags:
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
iop.constructor += s
memacc_iop.constructor += s
# select templates
memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
fullExecTemplate = eval(exec_template_base + 'Execute')
initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
# (header_output, decoder_output, decode_block, exec_output)
return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
decode_template.subst(iop),
EACompExecute.subst(ea_iop)
+ memAccExecTemplate.subst(memacc_iop)
+ fullExecTemplate.subst(iop)
+ initiateAccTemplate.subst(initiateacc_iop)
+ completeAccTemplate.subst(completeacc_iop))
}};
output exec {{
using namespace MipsISA;
/// CLEAR ALL CPU INST/EXE HAZARDS
inline void
clear_exe_inst_hazards()
{
//CODE HERE
}
/// Check "FP enabled" machine status bit. Called when executing any FP
/// instruction in full-system mode.
/// @retval Full-system mode: NoFault if FP is enabled, FenFault
/// if not. Non-full-system mode: always returns NoFault.
#if FULL_SYSTEM
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
Fault fault = NoFault; // dummy... this ipr access should not fault
if (!Mips34k::ICSR_FPE(xc->readIpr(MipsISA::IPR_ICSR, fault))) {
fault = FloatEnableFault;
}
return fault;
}
#else
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
return NoFault;
}
#endif
double convert_and_round(float w, int x, int y, int z)
{
double temp = .34000;
return temp;
}
enum FPTypes{
FP_SINGLE,
FP_DOUBLE,
FP_LONG,
FP_PS_LO,
FP_PS_HI,
FP_WORD,
RND_NEAREST,
RND_ZERO,
RND_UP,
RND_DOWN
};
}};
|