ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SgAsmMipsInstruction.C
Go to the documentation of this file.
1 /* SgAsmMipsInstruction member definitions. Do not move them to src/ROSETTA/Grammar/BinaryInstruction.code (or any *.code
2  * file) because then they won't get indexed/formatted/etc. by C-aware tools. */
3 
4 #include "sage3basic.h"
5 
6 // see base class
7 bool
9 {
10  switch (get_kind()) {
11  case mips_beq:
12  case mips_beql:
13  case mips_bgez:
14  case mips_bgezal:
15  case mips_bgezall:
16  case mips_bgezl:
17  case mips_bgtz:
18  case mips_bgtzl:
19  case mips_blez:
20  case mips_blezl:
21  case mips_bltz:
22  case mips_bltzal:
23  case mips_bltzall:
24  case mips_bltzl:
25  case mips_bne:
26  case mips_bnel:
27  case mips_break: // ???
28  case mips_j:
29  case mips_jal:
30  case mips_jalr:
31  case mips_jalx:
32  case mips_jr:
33  case mips_jr_hb:
34  case mips_syscall:
35  case mips_teq:
36  case mips_teqi:
37  case mips_tge:
38  case mips_tgei:
39  case mips_tgeiu:
40  case mips_tgeu:
41  case mips_tlt:
42  case mips_tlti:
43  case mips_tltiu:
44  case mips_tltu:
45  case mips_tne:
46  case mips_tnei:
47  return true;
48  default:
49  return false;
50  }
51 }
52 
53 // see base class
54 bool
55 SgAsmMipsInstruction::is_function_call(const std::vector<SgAsmInstruction*> &insns, rose_addr_t *target, rose_addr_t *return_va)
56 {
57  if (insns.size()==0)
58  return false;
59  SgAsmMipsInstruction *last = isSgAsmMipsInstruction(insns.back());
60  if (!last)
61  return false;
62  switch (last->get_kind()) {
63  case mips_bgezal:
64  case mips_bgezall:
65  case mips_bltzal:
66  case mips_bltzall:
67  case mips_jal:
68  case mips_jalr:
69  case mips_jalr_hb:
70  case mips_jalx: {
71  (void) last->get_branch_target(target); // target will not be changed if unknown
72  if (return_va)
73  *return_va = last->get_address() + last->get_size();
74  return true;
75  }
76  default:
77  return false;
78  }
79 }
80 
81 // see base class
82 bool
83 SgAsmMipsInstruction::is_function_return(const std::vector<SgAsmInstruction*> &insns)
84 {
85  if (insns.empty())
86  return false;
87  SgAsmMipsInstruction *last = isSgAsmMipsInstruction(insns.back());
88  if (!last)
89  return false;
90  if (last->get_kind()!=mips_jr)
91  return false;
92  const SgAsmExpressionPtrList &args = last->get_operandList()->get_operands();
93  if (args.size()<1)
94  return false;
96  if (!rre)
97  return false;
99  return false;
100  return true; // this is a "JR ra" instruction.
101 }
102 
103 // see base class
104 std::set<rose_addr_t>
106 {
107  bool complete = false;
108  rose_addr_t target_va = 0;
109  std::set<rose_addr_t> successors;
110  switch (get_kind()) {
111  case mips_break:
112  case mips_j:
113  case mips_jal:
114  case mips_jalr:
115  case mips_jalx:
116  case mips_jr:
117  case mips_jr_hb:
118  case mips_syscall:
119  // unconditional branch
120  if ((complete=get_branch_target(&target_va)))
121  successors.insert(target_va);
122  break;
123 
124  case mips_beq:
125  case mips_beql:
126  case mips_bgez:
127  case mips_bgezal:
128  case mips_bgezall:
129  case mips_bgezl:
130  case mips_bgtz:
131  case mips_bgtzl:
132  case mips_blez:
133  case mips_blezl:
134  case mips_bltz:
135  case mips_bltzal:
136  case mips_bltzall:
137  case mips_bltzl:
138  case mips_bne:
139  case mips_bnel:
140  case mips_teq:
141  case mips_teqi:
142  case mips_tge:
143  case mips_tgei:
144  case mips_tgeiu:
145  case mips_tgeu:
146  case mips_tlt:
147  case mips_tlti:
148  case mips_tltiu:
149  case mips_tltu:
150  case mips_tne:
151  case mips_tnei:
152  // conditional branch
153  if ((complete=get_branch_target(&target_va)))
154  successors.insert(target_va);
155  successors.insert(get_address() + get_size()); // fall through address
156  break;
157 
158  default:
159  // fall through
160  successors.insert(get_address() + get_size());
161  complete = true;
162  }
163  if (complete_)
164  *complete_ = complete;
165  return successors;
166 }
167 
168 // see base class
169 bool
171 {
173 }
174 
175 bool
177 {
179  switch (get_kind()) {
180  case mips_j:
181  case mips_jal:
182  case mips_jalx: {
183  // target address stored in first argument
184  assert(args.size()>=1);
185  if (target) {
187  assert(ival!=NULL);
188  *target = ival->get_absolute_value();
189  }
190  return true;
191  }
192 
193  case mips_bgez:
194  case mips_bgezal:
195  case mips_bgezall:
196  case mips_bgezl:
197  case mips_bgtz:
198  case mips_bgtzl:
199  case mips_blez:
200  case mips_blezl:
201  case mips_bltz:
202  case mips_bltzal:
203  case mips_bltzall:
204  case mips_bltzl: {
205  // target address stored in the second argument
206  assert(args.size()>=2);
207  if (target) {
209  assert(ival!=NULL);
210  *target = ival->get_absolute_value();
211  }
212  return true;
213  }
214 
215  case mips_beq:
216  case mips_beql:
217  case mips_bne:
218  case mips_bnel: {
219  // target address stored in the third argument
220  assert(args.size()>=3);
221  if (target) {
223  assert(ival!=NULL);
224  *target = ival->get_absolute_value();
225  }
226  return true;
227  }
228 
229  default:
230  // no known target; do not modify *target
231  return false;
232  }
233 }
234 
235 
236 
237 
238