3 // Copyright
\e.A
\eN) 2007 MIPS Technologies, Inc. All Rights Reserved
5 // This software is part of the M5 simulator.
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.
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.
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.
35 //Authors: Korey L. Sewell
37 ////////////////////////////////////////////////////////////////////
39 // Control transfer instructions
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).
56 class PCDependentDisassembly : public MipsStaticInst
59 /// Cached program counter from last disassembly
60 mutable Addr cachedPC;
62 /// Cached symbol table pointer from last disassembly
63 mutable const SymbolTable *cachedSymtab;
66 PCDependentDisassembly(const char *mnem, MachInst _machInst,
68 : MipsStaticInst(mnem, _machInst, __opClass),
69 cachedPC(0), cachedSymtab(0)
74 disassemble(Addr pc, const SymbolTable *symtab) const;
78 * Base class for branches (PC-relative control transfers),
79 * conditional or unconditional.
81 class Branch : public PCDependentDisassembly
84 /// target address (signed) Displacement .
88 Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
89 : PCDependentDisassembly(mnem, _machInst, __opClass),
92 //If Bit 17 is 1 then Sign Extend
93 if ( (disp & 0x00020000) > 0 ) {
98 Addr branchTarget(Addr branchPC) const;
101 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
105 * Base class for jumps (register-indirect control transfers). In
106 * the Mips ISA, these are always unconditional.
108 class Jump : public PCDependentDisassembly
112 /// Displacement to target address (signed).
119 Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
120 : PCDependentDisassembly(mnem, _machInst, __opClass),
125 Addr branchTarget(ThreadContext *tc) const;
128 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
134 Branch::branchTarget(Addr branchPC) const
136 return branchPC + 4 + disp;
140 Jump::branchTarget(ThreadContext *tc) const
142 Addr NPC = tc->readNextPC();
143 return (NPC & 0xF0000000) | (disp);
147 PCDependentDisassembly::disassemble(Addr pc,
148 const SymbolTable *symtab) const
150 if (!cachedDisassembly ||
151 pc != cachedPC || symtab != cachedSymtab)
153 if (cachedDisassembly)
154 delete cachedDisassembly;
157 new std::string(generateDisassembly(pc, symtab));
159 cachedSymtab = symtab;
162 return *cachedDisassembly;
166 Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
168 std::stringstream ss;
170 ccprintf(ss, "%-10s ", mnemonic);
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]);
179 } else if(_numSrcRegs == 2) {
180 printReg(ss, _srcRegIdx[0]);
182 printReg(ss, _srcRegIdx[1]);
186 Addr target = pc + 4 + disp;
189 if (symtab && symtab->findSymbol(target, str))
192 ccprintf(ss, "0x%x", target);
198 Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
200 std::stringstream ss;
202 ccprintf(ss, "%-10s ", mnemonic);
204 if ( mnemonic == "jal" ) {
206 ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp);
207 } else if (_numSrcRegs == 0) {
209 if (symtab && symtab->findSymbol(disp, str))
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]);
218 printReg(ss, _srcRegIdx[1]);
225 def format Branch(code, *opt_flags) {{
226 not_taken_code = ' NNPC = NNPC;\n'
227 not_taken_code += '} \n'
229 #Build Instruction Flags
230 #Use Link & Likely Flags to Add Link/Condition Code
231 inst_flags = ('IsDirectControl', )
234 code += 'R31 = NNPC;\n'
236 not_taken_code = ' NPC = NNPC;\n'
237 not_taken_code += ' NNPC = NNPC + 4;\n'
238 not_taken_code += '} \n'
239 inst_flags += ('IsCondDelaySlot', )
243 #Take into account uncond. branch instruction
244 if 'cond = 1' in code:
245 inst_flags += ('IsUncondControl', )
247 inst_flags += ('IsCondControl', )
250 code = 'bool cond;\n' + code
251 code += 'if (cond) {\n'
252 code += ' NNPC = NPC + disp;\n'
254 code += not_taken_code
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)
263 def format DspBranch(code, *opt_flags) {{
264 not_taken_code = ' NNPC = NNPC;\n'
265 not_taken_code += '} \n'
267 #Build Instruction Flags
268 #Use Link & Likely Flags to Add Link/Condition Code
269 inst_flags = ('IsDirectControl', )
272 code += 'R31 = NNPC;\n'
274 not_taken_code = ' NPC = NNPC;\n'
275 not_taken_code += ' NNPC = NNPC + 4;\n'
276 not_taken_code += '} \n'
277 inst_flags += ('IsCondDelaySlot', )
281 #Take into account uncond. branch instruction
282 if 'cond = 1' in code:
283 inst_flags += ('IsUncondControl', )
285 inst_flags += ('IsCondControl', )
288 decl_code = 'bool cond;\n'
289 decl_code += 'uint32_t dspctl;\n'
292 fetch_code = 'dspctl = DSPControl;\n'
295 code = decl_code + fetch_code + code
296 code += 'if (cond) {\n'
297 code += ' NNPC = NPC + disp;\n'
299 code += not_taken_code
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)
308 def format Jump(code, *opt_flags) {{
309 #Build Instruction Flags
310 #Use Link Flag to Add Link Code
311 inst_flags = ('IsIndirectControl', 'IsUncondControl')
314 code = 'R31 = NNPC;\n' + code
315 elif x == 'ClearHazards':
316 code += '/* Code Needed to Clear Execute & Inst Hazards */\n'
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)