Get MIPS_SE actually working again by actually by fixing TLB stuff and running hello...
[gem5.git] / src / arch / mips / isa / formats / branch.isa
1 // -*- mode:c++ -*-
2
3 // Copyright \e.A\eN) 2007 MIPS Technologies, Inc. All Rights Reserved
4
5 // This software is part of the M5 simulator.
6
7 // THIS IS A LEGAL AGREEMENT. BY DOWNLOADING, USING, COPYING, CREATING
8 // DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING
9 // TO THESE TERMS AND CONDITIONS.
10
11 // Permission is granted to use, copy, create derivative works and
12 // distribute this software and such derivative works for any purpose,
13 // so long as (1) the copyright notice above, this grant of permission,
14 // and the disclaimer below appear in all copies and derivative works
15 // made, (2) the copyright notice above is augmented as appropriate to
16 // reflect the addition of any new copyrightable work in a derivative
17 // work (e.g., Copyright \e.A\eN) <Publication Year> Copyright Owner), and (3)
18 // the name of MIPS Technologies, Inc. (\e$B!H\e(BMIPS\e$B!I\e(B) is not used in any
19 // advertising or publicity pertaining to the use or distribution of
20 // this software without specific, written prior authorization.
21
22 // THIS SOFTWARE IS PROVIDED \e$B!H\e(BAS IS.\e$B!I\e(B MIPS MAKES NO WARRANTIES AND
23 // DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR
24 // OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
26 // NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE.
27 // IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT,
28 // INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF
29 // ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT,
30 // THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY
31 // IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR
32 // STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE
33 // POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE.
34
35 //Authors: Korey L. Sewell
36
37 ////////////////////////////////////////////////////////////////////
38 //
39 // Control transfer instructions
40 //
41
42 output header {{
43
44 #include <iostream>
45 using namespace std;
46
47 /**
48 * Base class for instructions whose disassembly is not purely a
49 * function of the machine instruction (i.e., it depends on the
50 * PC). This class overrides the disassemble() method to check
51 * the PC and symbol table values before re-using a cached
52 * disassembly string. This is necessary for branches and jumps,
53 * where the disassembly string includes the target address (which
54 * may depend on the PC and/or symbol table).
55 */
56 class PCDependentDisassembly : public MipsStaticInst
57 {
58 protected:
59 /// Cached program counter from last disassembly
60 mutable Addr cachedPC;
61
62 /// Cached symbol table pointer from last disassembly
63 mutable const SymbolTable *cachedSymtab;
64
65 /// Constructor
66 PCDependentDisassembly(const char *mnem, MachInst _machInst,
67 OpClass __opClass)
68 : MipsStaticInst(mnem, _machInst, __opClass),
69 cachedPC(0), cachedSymtab(0)
70 {
71 }
72
73 const std::string &
74 disassemble(Addr pc, const SymbolTable *symtab) const;
75 };
76
77 /**
78 * Base class for branches (PC-relative control transfers),
79 * conditional or unconditional.
80 */
81 class Branch : public PCDependentDisassembly
82 {
83 protected:
84 /// target address (signed) Displacement .
85 int32_t disp;
86
87 /// Constructor.
88 Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
89 : PCDependentDisassembly(mnem, _machInst, __opClass),
90 disp(OFFSET << 2)
91 {
92 //If Bit 17 is 1 then Sign Extend
93 if ( (disp & 0x00020000) > 0 ) {
94 disp |= 0xFFFE0000;
95 }
96 }
97
98 Addr branchTarget(Addr branchPC) const;
99
100 std::string
101 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
102 };
103
104 /**
105 * Base class for jumps (register-indirect control transfers). In
106 * the Mips ISA, these are always unconditional.
107 */
108 class Jump : public PCDependentDisassembly
109 {
110 protected:
111
112 /// Displacement to target address (signed).
113 int32_t disp;
114
115 uint32_t target;
116
117 public:
118 /// Constructor
119 Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
120 : PCDependentDisassembly(mnem, _machInst, __opClass),
121 disp(JMPTARG << 2)
122 {
123 }
124
125 Addr branchTarget(ThreadContext *tc) const;
126
127 std::string
128 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
129 };
130 }};
131
132 output decoder {{
133 Addr
134 Branch::branchTarget(Addr branchPC) const
135 {
136 return branchPC + 4 + disp;
137 }
138
139 Addr
140 Jump::branchTarget(ThreadContext *tc) const
141 {
142 Addr NPC = tc->readNextPC();
143 return (NPC & 0xF0000000) | (disp);
144 }
145
146 const std::string &
147 PCDependentDisassembly::disassemble(Addr pc,
148 const SymbolTable *symtab) const
149 {
150 if (!cachedDisassembly ||
151 pc != cachedPC || symtab != cachedSymtab)
152 {
153 if (cachedDisassembly)
154 delete cachedDisassembly;
155
156 cachedDisassembly =
157 new std::string(generateDisassembly(pc, symtab));
158 cachedPC = pc;
159 cachedSymtab = symtab;
160 }
161
162 return *cachedDisassembly;
163 }
164
165 std::string
166 Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
167 {
168 std::stringstream ss;
169
170 ccprintf(ss, "%-10s ", mnemonic);
171
172 // There's only one register arg (RA), but it could be
173 // either a source (the condition for conditional
174 // branches) or a destination (the link reg for
175 // unconditional branches)
176 if (_numSrcRegs == 1) {
177 printReg(ss, _srcRegIdx[0]);
178 ss << ", ";
179 } else if(_numSrcRegs == 2) {
180 printReg(ss, _srcRegIdx[0]);
181 ss << ", ";
182 printReg(ss, _srcRegIdx[1]);
183 ss << ", ";
184 }
185
186 Addr target = pc + 4 + disp;
187
188 std::string str;
189 if (symtab && symtab->findSymbol(target, str))
190 ss << str;
191 else
192 ccprintf(ss, "0x%x", target);
193
194 return ss.str();
195 }
196
197 std::string
198 Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
199 {
200 std::stringstream ss;
201
202 ccprintf(ss, "%-10s ", mnemonic);
203
204 if ( mnemonic == "jal" ) {
205 Addr npc = pc + 4;
206 ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp);
207 } else if (_numSrcRegs == 0) {
208 std::string str;
209 if (symtab && symtab->findSymbol(disp, str))
210 ss << str;
211 else
212 ccprintf(ss, "0x%x", disp);
213 } else if (_numSrcRegs == 1) {
214 printReg(ss, _srcRegIdx[0]);
215 } else if(_numSrcRegs == 2) {
216 printReg(ss, _srcRegIdx[0]);
217 ss << ", ";
218 printReg(ss, _srcRegIdx[1]);
219 }
220
221 return ss.str();
222 }
223 }};
224
225 def format Branch(code, *opt_flags) {{
226 not_taken_code = ' NNPC = NNPC;\n'
227 not_taken_code += '} \n'
228
229 #Build Instruction Flags
230 #Use Link & Likely Flags to Add Link/Condition Code
231 inst_flags = ('IsDirectControl', )
232 for x in opt_flags:
233 if x == 'Link':
234 code += 'R31 = NNPC;\n'
235 elif x == 'Likely':
236 not_taken_code = ' NPC = NNPC;\n'
237 not_taken_code += ' NNPC = NNPC + 4;\n'
238 not_taken_code += '} \n'
239 inst_flags += ('IsCondDelaySlot', )
240 else:
241 inst_flags += (x, )
242
243 #Take into account uncond. branch instruction
244 if 'cond = 1' in code:
245 inst_flags += ('IsUncondControl', )
246 else:
247 inst_flags += ('IsCondControl', )
248
249 #Condition code
250 code = 'bool cond;\n' + code
251 code += 'if (cond) {\n'
252 code += ' NNPC = NPC + disp;\n'
253 code += '} else {\n'
254 code += not_taken_code
255
256 iop = InstObjParams(name, Name, 'Branch', code, inst_flags)
257 header_output = BasicDeclare.subst(iop)
258 decoder_output = BasicConstructor.subst(iop)
259 decode_block = BasicDecode.subst(iop)
260 exec_output = BasicExecute.subst(iop)
261 }};
262
263 def format DspBranch(code, *opt_flags) {{
264 not_taken_code = ' NNPC = NNPC;\n'
265 not_taken_code += '} \n'
266
267 #Build Instruction Flags
268 #Use Link & Likely Flags to Add Link/Condition Code
269 inst_flags = ('IsDirectControl', )
270 for x in opt_flags:
271 if x == 'Link':
272 code += 'R31 = NNPC;\n'
273 elif x == 'Likely':
274 not_taken_code = ' NPC = NNPC;\n'
275 not_taken_code += ' NNPC = NNPC + 4;\n'
276 not_taken_code += '} \n'
277 inst_flags += ('IsCondDelaySlot', )
278 else:
279 inst_flags += (x, )
280
281 #Take into account uncond. branch instruction
282 if 'cond = 1' in code:
283 inst_flags += ('IsUncondControl', )
284 else:
285 inst_flags += ('IsCondControl', )
286
287 #Declaration code
288 decl_code = 'bool cond;\n'
289 decl_code += 'uint32_t dspctl;\n'
290
291 #Fetch code
292 fetch_code = 'dspctl = DSPControl;\n'
293
294 #Condition code
295 code = decl_code + fetch_code + code
296 code += 'if (cond) {\n'
297 code += ' NNPC = NPC + disp;\n'
298 code += '} else {\n'
299 code += not_taken_code
300
301 iop = InstObjParams(name, Name, 'Branch', code, inst_flags)
302 header_output = BasicDeclare.subst(iop)
303 decoder_output = BasicConstructor.subst(iop)
304 decode_block = BasicDecode.subst(iop)
305 exec_output = BasicExecute.subst(iop)
306 }};
307
308 def format Jump(code, *opt_flags) {{
309 #Build Instruction Flags
310 #Use Link Flag to Add Link Code
311 inst_flags = ('IsIndirectControl', 'IsUncondControl')
312 for x in opt_flags:
313 if x == 'Link':
314 code = 'R31 = NNPC;\n' + code
315 elif x == 'ClearHazards':
316 code += '/* Code Needed to Clear Execute & Inst Hazards */\n'
317 else:
318 inst_flags += (x, )
319
320 iop = InstObjParams(name, Name, 'Jump', code, inst_flags)
321 header_output = BasicDeclare.subst(iop)
322 decoder_output = BasicConstructor.subst(iop)
323 decode_block = BasicDecode.subst(iop)
324 exec_output = BasicExecute.subst(iop)
325 }};
326
327
328
329