branch.isa (6243:3a1698fbbc9f) branch.isa (6253:988a001820f8)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007-2008 The Florida State University
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright

--- 19 unchanged lines hidden (view full) ---

28//
29// Authors: Stephen Hines
30
31////////////////////////////////////////////////////////////////////
32//
33// Control transfer instructions
34//
35
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007-2008 The Florida State University
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright

--- 19 unchanged lines hidden (view full) ---

28//
29// Authors: Stephen Hines
30
31////////////////////////////////////////////////////////////////////
32//
33// Control transfer instructions
34//
35
36output header {{
37
38#include <iostream>
39
40 /**
41 * Base class for instructions whose disassembly is not purely a
42 * function of the machine instruction (i.e., it depends on the
43 * PC). This class overrides the disassemble() method to check
44 * the PC and symbol table values before re-using a cached
45 * disassembly string. This is necessary for branches and jumps,
46 * where the disassembly string includes the target address (which
47 * may depend on the PC and/or symbol table).
48 */
49 class PCDependentDisassembly : public PredOp
50 {
51 protected:
52 /// Cached program counter from last disassembly
53 mutable Addr cachedPC;
54
55 /// Cached symbol table pointer from last disassembly
56 mutable const SymbolTable *cachedSymtab;
57
58 /// Constructor
59 PCDependentDisassembly(const char *mnem, MachInst _machInst,
60 OpClass __opClass)
61 : PredOp(mnem, _machInst, __opClass),
62 cachedPC(0), cachedSymtab(0)
63 {
64 }
65
66 const std::string &
67 disassemble(Addr pc, const SymbolTable *symtab) const;
68 };
69
70 /**
71 * Base class for branches (PC-relative control transfers),
72 * conditional or unconditional.
73 */
74 class Branch : public PCDependentDisassembly
75 {
76 protected:
77 /// target address (signed) Displacement .
78 int32_t disp;
79
80 /// Constructor.
81 Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
82 : PCDependentDisassembly(mnem, _machInst, __opClass),
83 disp(OFFSET << 2)
84 {
85 //If Bit 26 is 1 then Sign Extend
86 if ( (disp & 0x02000000) > 0 ) {
87 disp |= 0xFC000000;
88 }
89 }
90
91 Addr branchTarget(Addr branchPC) const;
92
93 std::string
94 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
95 };
96
97 /**
98 * Base class for branch and exchange instructions on the ARM
99 */
100 class BranchExchange : public PredOp
101 {
102 protected:
103 /// Constructor
104 BranchExchange(const char *mnem, MachInst _machInst,
105 OpClass __opClass)
106 : PredOp(mnem, _machInst, __opClass)
107 {
108 }
109
110 std::string
111 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
112 };
113
114
115 /**
116 * Base class for jumps (register-indirect control transfers). In
117 * the Arm ISA, these are always unconditional.
118 */
119 class Jump : public PCDependentDisassembly
120 {
121 protected:
122
123 /// Displacement to target address (signed).
124 int32_t disp;
125
126 uint32_t target;
127
128 public:
129 /// Constructor
130 Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
131 : PCDependentDisassembly(mnem, _machInst, __opClass),
132 disp(OFFSET << 2)
133 {
134 }
135
136 Addr branchTarget(ThreadContext *tc) const;
137
138 std::string
139 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
140 };
141}};
142
143output decoder {{
144 Addr
145 Branch::branchTarget(Addr branchPC) const
146 {
147 return branchPC + 8 + disp;
148 }
149
150 Addr
151 Jump::branchTarget(ThreadContext *tc) const
152 {
153 Addr NPC = tc->readPC() + 8;
154 uint64_t Rb = tc->readIntReg(_srcRegIdx[0]);
155 return (Rb & ~3) | (NPC & 1);
156 }
157
158 const std::string &
159 PCDependentDisassembly::disassemble(Addr pc,
160 const SymbolTable *symtab) const
161 {
162 if (!cachedDisassembly ||
163 pc != cachedPC || symtab != cachedSymtab)
164 {
165 if (cachedDisassembly)
166 delete cachedDisassembly;
167
168 cachedDisassembly =
169 new std::string(generateDisassembly(pc, symtab));
170 cachedPC = pc;
171 cachedSymtab = symtab;
172 }
173
174 return *cachedDisassembly;
175 }
176
177 std::string
178 Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
179 {
180 std::stringstream ss;
181
182 ccprintf(ss, "%-10s ", mnemonic);
183
184 Addr target = pc + 8 + disp;
185
186 std::string str;
187 if (symtab && symtab->findSymbol(target, str))
188 ss << str;
189 else
190 ccprintf(ss, "0x%x", target);
191
192 return ss.str();
193 }
194
195 std::string
196 BranchExchange::generateDisassembly(Addr pc, const SymbolTable *symtab) const
197 {
198 std::stringstream ss;
199
200 ccprintf(ss, "%-10s ", mnemonic);
201
202 if (_numSrcRegs > 0) {
203 printReg(ss, _srcRegIdx[0]);
204 }
205
206 return ss.str();
207 }
208
209 std::string
210 Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
211 {
212 std::stringstream ss;
213
214 ccprintf(ss, "%-10s ", mnemonic);
215
216 return ss.str();
217 }
218}};
219
220def format Branch(code,*opt_flags) {{
221
222 #Build Instruction Flags
223 #Use Link & Likely Flags to Add Link/Condition Code
224 inst_flags = ('IsDirectControl', )
225 for x in opt_flags:
226 if x == 'Link':
227 code += 'LR = NPC;\n'

--- 80 unchanged lines hidden ---
36def format Branch(code,*opt_flags) {{
37
38 #Build Instruction Flags
39 #Use Link & Likely Flags to Add Link/Condition Code
40 inst_flags = ('IsDirectControl', )
41 for x in opt_flags:
42 if x == 'Link':
43 code += 'LR = NPC;\n'

--- 80 unchanged lines hidden ---