1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_INL_H_
18 #define ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_INL_H_
19
20 #include "dex_instruction.h"
21
22 namespace art {
23
24 //------------------------------------------------------------------------------
25 // VRegA
26 //------------------------------------------------------------------------------
HasVRegA()27 inline bool Instruction::HasVRegA() const {
28 switch (FormatOf(Opcode())) {
29 case k10t: return true;
30 case k10x: return true;
31 case k11n: return true;
32 case k11x: return true;
33 case k12x: return true;
34 case k20t: return true;
35 case k21c: return true;
36 case k21h: return true;
37 case k21s: return true;
38 case k21t: return true;
39 case k22b: return true;
40 case k22c: return true;
41 case k22s: return true;
42 case k22t: return true;
43 case k22x: return true;
44 case k23x: return true;
45 case k30t: return true;
46 case k31c: return true;
47 case k31i: return true;
48 case k31t: return true;
49 case k32x: return true;
50 case k35c: return true;
51 case k3rc: return true;
52 case k45cc: return true;
53 case k4rcc: return true;
54 case k51l: return true;
55 default: return false;
56 }
57 }
58
VRegA()59 inline int32_t Instruction::VRegA() const {
60 switch (FormatOf(Opcode())) {
61 case k10t: return VRegA_10t();
62 case k10x: return VRegA_10x();
63 case k11n: return VRegA_11n();
64 case k11x: return VRegA_11x();
65 case k12x: return VRegA_12x();
66 case k20t: return VRegA_20t();
67 case k21c: return VRegA_21c();
68 case k21h: return VRegA_21h();
69 case k21s: return VRegA_21s();
70 case k21t: return VRegA_21t();
71 case k22b: return VRegA_22b();
72 case k22c: return VRegA_22c();
73 case k22s: return VRegA_22s();
74 case k22t: return VRegA_22t();
75 case k22x: return VRegA_22x();
76 case k23x: return VRegA_23x();
77 case k30t: return VRegA_30t();
78 case k31c: return VRegA_31c();
79 case k31i: return VRegA_31i();
80 case k31t: return VRegA_31t();
81 case k32x: return VRegA_32x();
82 case k35c: return VRegA_35c();
83 case k3rc: return VRegA_3rc();
84 case k45cc: return VRegA_45cc();
85 case k4rcc: return VRegA_4rcc();
86 case k51l: return VRegA_51l();
87 default:
88 LOG(FATAL) << "Tried to access vA of instruction " << Name() << " which has no A operand.";
89 exit(EXIT_FAILURE);
90 }
91 }
92
VRegA_10t(uint16_t inst_data)93 inline int8_t Instruction::VRegA_10t(uint16_t inst_data) const {
94 DCHECK_EQ(FormatOf(Opcode()), k10t);
95 return static_cast<int8_t>(InstAA(inst_data));
96 }
97
VRegA_10x(uint16_t inst_data)98 inline uint8_t Instruction::VRegA_10x(uint16_t inst_data) const {
99 DCHECK_EQ(FormatOf(Opcode()), k10x);
100 return InstAA(inst_data);
101 }
102
VRegA_11n(uint16_t inst_data)103 inline uint4_t Instruction::VRegA_11n(uint16_t inst_data) const {
104 DCHECK_EQ(FormatOf(Opcode()), k11n);
105 return InstA(inst_data);
106 }
107
VRegA_11x(uint16_t inst_data)108 inline uint8_t Instruction::VRegA_11x(uint16_t inst_data) const {
109 DCHECK_EQ(FormatOf(Opcode()), k11x);
110 return InstAA(inst_data);
111 }
112
VRegA_12x(uint16_t inst_data)113 inline uint4_t Instruction::VRegA_12x(uint16_t inst_data) const {
114 DCHECK_EQ(FormatOf(Opcode()), k12x);
115 return InstA(inst_data);
116 }
117
VRegA_20t()118 inline int16_t Instruction::VRegA_20t() const {
119 DCHECK_EQ(FormatOf(Opcode()), k20t);
120 return static_cast<int16_t>(Fetch16(1));
121 }
122
VRegA_21c(uint16_t inst_data)123 inline uint8_t Instruction::VRegA_21c(uint16_t inst_data) const {
124 DCHECK_EQ(FormatOf(Opcode()), k21c);
125 return InstAA(inst_data);
126 }
127
VRegA_21h(uint16_t inst_data)128 inline uint8_t Instruction::VRegA_21h(uint16_t inst_data) const {
129 DCHECK_EQ(FormatOf(Opcode()), k21h);
130 return InstAA(inst_data);
131 }
132
VRegA_21s(uint16_t inst_data)133 inline uint8_t Instruction::VRegA_21s(uint16_t inst_data) const {
134 DCHECK_EQ(FormatOf(Opcode()), k21s);
135 return InstAA(inst_data);
136 }
137
VRegA_21t(uint16_t inst_data)138 inline uint8_t Instruction::VRegA_21t(uint16_t inst_data) const {
139 DCHECK_EQ(FormatOf(Opcode()), k21t);
140 return InstAA(inst_data);
141 }
142
VRegA_22b(uint16_t inst_data)143 inline uint8_t Instruction::VRegA_22b(uint16_t inst_data) const {
144 DCHECK_EQ(FormatOf(Opcode()), k22b);
145 return InstAA(inst_data);
146 }
147
VRegA_22c(uint16_t inst_data)148 inline uint4_t Instruction::VRegA_22c(uint16_t inst_data) const {
149 DCHECK_EQ(FormatOf(Opcode()), k22c);
150 return InstA(inst_data);
151 }
152
VRegA_22s(uint16_t inst_data)153 inline uint4_t Instruction::VRegA_22s(uint16_t inst_data) const {
154 DCHECK_EQ(FormatOf(Opcode()), k22s);
155 return InstA(inst_data);
156 }
157
VRegA_22t(uint16_t inst_data)158 inline uint4_t Instruction::VRegA_22t(uint16_t inst_data) const {
159 DCHECK_EQ(FormatOf(Opcode()), k22t);
160 return InstA(inst_data);
161 }
162
VRegA_22x(uint16_t inst_data)163 inline uint8_t Instruction::VRegA_22x(uint16_t inst_data) const {
164 DCHECK_EQ(FormatOf(Opcode()), k22x);
165 return InstAA(inst_data);
166 }
167
VRegA_23x(uint16_t inst_data)168 inline uint8_t Instruction::VRegA_23x(uint16_t inst_data) const {
169 DCHECK_EQ(FormatOf(Opcode()), k23x);
170 return InstAA(inst_data);
171 }
172
VRegA_30t()173 inline int32_t Instruction::VRegA_30t() const {
174 DCHECK_EQ(FormatOf(Opcode()), k30t);
175 return static_cast<int32_t>(Fetch32(1));
176 }
177
VRegA_31c(uint16_t inst_data)178 inline uint8_t Instruction::VRegA_31c(uint16_t inst_data) const {
179 DCHECK_EQ(FormatOf(Opcode()), k31c);
180 return InstAA(inst_data);
181 }
182
VRegA_31i(uint16_t inst_data)183 inline uint8_t Instruction::VRegA_31i(uint16_t inst_data) const {
184 DCHECK_EQ(FormatOf(Opcode()), k31i);
185 return InstAA(inst_data);
186 }
187
VRegA_31t(uint16_t inst_data)188 inline uint8_t Instruction::VRegA_31t(uint16_t inst_data) const {
189 DCHECK_EQ(FormatOf(Opcode()), k31t);
190 return InstAA(inst_data);
191 }
192
VRegA_32x()193 inline uint16_t Instruction::VRegA_32x() const {
194 DCHECK_EQ(FormatOf(Opcode()), k32x);
195 return Fetch16(1);
196 }
197
VRegA_35c(uint16_t inst_data)198 inline uint4_t Instruction::VRegA_35c(uint16_t inst_data) const {
199 DCHECK_EQ(FormatOf(Opcode()), k35c);
200 return InstB(inst_data); // This is labeled A in the spec.
201 }
202
VRegA_3rc(uint16_t inst_data)203 inline uint8_t Instruction::VRegA_3rc(uint16_t inst_data) const {
204 DCHECK_EQ(FormatOf(Opcode()), k3rc);
205 return InstAA(inst_data);
206 }
207
VRegA_51l(uint16_t inst_data)208 inline uint8_t Instruction::VRegA_51l(uint16_t inst_data) const {
209 DCHECK_EQ(FormatOf(Opcode()), k51l);
210 return InstAA(inst_data);
211 }
212
VRegA_45cc(uint16_t inst_data)213 inline uint4_t Instruction::VRegA_45cc(uint16_t inst_data) const {
214 DCHECK_EQ(FormatOf(Opcode()), k45cc);
215 return InstB(inst_data); // This is labeled A in the spec.
216 }
217
VRegA_4rcc(uint16_t inst_data)218 inline uint8_t Instruction::VRegA_4rcc(uint16_t inst_data) const {
219 DCHECK_EQ(FormatOf(Opcode()), k4rcc);
220 return InstAA(inst_data);
221 }
222
223 //------------------------------------------------------------------------------
224 // VRegB
225 //------------------------------------------------------------------------------
HasVRegB()226 inline bool Instruction::HasVRegB() const {
227 switch (FormatOf(Opcode())) {
228 case k11n: return true;
229 case k12x: return true;
230 case k21c: return true;
231 case k21h: return true;
232 case k21s: return true;
233 case k21t: return true;
234 case k22b: return true;
235 case k22c: return true;
236 case k22s: return true;
237 case k22t: return true;
238 case k22x: return true;
239 case k23x: return true;
240 case k31c: return true;
241 case k31i: return true;
242 case k31t: return true;
243 case k32x: return true;
244 case k35c: return true;
245 case k3rc: return true;
246 case k45cc: return true;
247 case k4rcc: return true;
248 case k51l: return true;
249 default: return false;
250 }
251 }
252
HasWideVRegB()253 inline bool Instruction::HasWideVRegB() const {
254 return FormatOf(Opcode()) == k51l;
255 }
256
VRegB()257 inline int32_t Instruction::VRegB() const {
258 switch (FormatOf(Opcode())) {
259 case k11n: return VRegB_11n();
260 case k12x: return VRegB_12x();
261 case k21c: return VRegB_21c();
262 case k21h: return VRegB_21h();
263 case k21s: return VRegB_21s();
264 case k21t: return VRegB_21t();
265 case k22b: return VRegB_22b();
266 case k22c: return VRegB_22c();
267 case k22s: return VRegB_22s();
268 case k22t: return VRegB_22t();
269 case k22x: return VRegB_22x();
270 case k23x: return VRegB_23x();
271 case k31c: return VRegB_31c();
272 case k31i: return VRegB_31i();
273 case k31t: return VRegB_31t();
274 case k32x: return VRegB_32x();
275 case k35c: return VRegB_35c();
276 case k3rc: return VRegB_3rc();
277 case k45cc: return VRegB_45cc();
278 case k4rcc: return VRegB_4rcc();
279 case k51l: return VRegB_51l();
280 default:
281 LOG(FATAL) << "Tried to access vB of instruction " << Name() << " which has no B operand.";
282 exit(EXIT_FAILURE);
283 }
284 }
285
WideVRegB()286 inline uint64_t Instruction::WideVRegB() const {
287 return VRegB_51l();
288 }
289
VRegB_11n(uint16_t inst_data)290 inline int4_t Instruction::VRegB_11n(uint16_t inst_data) const {
291 DCHECK_EQ(FormatOf(Opcode()), k11n);
292 return static_cast<int4_t>((InstB(inst_data) << 28) >> 28);
293 }
294
VRegB_12x(uint16_t inst_data)295 inline uint4_t Instruction::VRegB_12x(uint16_t inst_data) const {
296 DCHECK_EQ(FormatOf(Opcode()), k12x);
297 return InstB(inst_data);
298 }
299
VRegB_21c()300 inline uint16_t Instruction::VRegB_21c() const {
301 DCHECK_EQ(FormatOf(Opcode()), k21c);
302 return Fetch16(1);
303 }
304
VRegB_21h()305 inline uint16_t Instruction::VRegB_21h() const {
306 DCHECK_EQ(FormatOf(Opcode()), k21h);
307 return Fetch16(1);
308 }
309
VRegB_21s()310 inline int16_t Instruction::VRegB_21s() const {
311 DCHECK_EQ(FormatOf(Opcode()), k21s);
312 return static_cast<int16_t>(Fetch16(1));
313 }
314
VRegB_21t()315 inline int16_t Instruction::VRegB_21t() const {
316 DCHECK_EQ(FormatOf(Opcode()), k21t);
317 return static_cast<int16_t>(Fetch16(1));
318 }
319
VRegB_22b()320 inline uint8_t Instruction::VRegB_22b() const {
321 DCHECK_EQ(FormatOf(Opcode()), k22b);
322 return static_cast<uint8_t>(Fetch16(1) & 0xff);
323 }
324
VRegB_22c(uint16_t inst_data)325 inline uint4_t Instruction::VRegB_22c(uint16_t inst_data) const {
326 DCHECK_EQ(FormatOf(Opcode()), k22c);
327 return InstB(inst_data);
328 }
329
VRegB_22s(uint16_t inst_data)330 inline uint4_t Instruction::VRegB_22s(uint16_t inst_data) const {
331 DCHECK_EQ(FormatOf(Opcode()), k22s);
332 return InstB(inst_data);
333 }
334
VRegB_22t(uint16_t inst_data)335 inline uint4_t Instruction::VRegB_22t(uint16_t inst_data) const {
336 DCHECK_EQ(FormatOf(Opcode()), k22t);
337 return InstB(inst_data);
338 }
339
VRegB_22x()340 inline uint16_t Instruction::VRegB_22x() const {
341 DCHECK_EQ(FormatOf(Opcode()), k22x);
342 return Fetch16(1);
343 }
344
VRegB_23x()345 inline uint8_t Instruction::VRegB_23x() const {
346 DCHECK_EQ(FormatOf(Opcode()), k23x);
347 return static_cast<uint8_t>(Fetch16(1) & 0xff);
348 }
349
VRegB_31c()350 inline uint32_t Instruction::VRegB_31c() const {
351 DCHECK_EQ(FormatOf(Opcode()), k31c);
352 return Fetch32(1);
353 }
354
VRegB_31i()355 inline int32_t Instruction::VRegB_31i() const {
356 DCHECK_EQ(FormatOf(Opcode()), k31i);
357 return static_cast<int32_t>(Fetch32(1));
358 }
359
VRegB_31t()360 inline int32_t Instruction::VRegB_31t() const {
361 DCHECK_EQ(FormatOf(Opcode()), k31t);
362 return static_cast<int32_t>(Fetch32(1));
363 }
364
VRegB_32x()365 inline uint16_t Instruction::VRegB_32x() const {
366 DCHECK_EQ(FormatOf(Opcode()), k32x);
367 return Fetch16(2);
368 }
369
VRegB_35c()370 inline uint16_t Instruction::VRegB_35c() const {
371 DCHECK_EQ(FormatOf(Opcode()), k35c);
372 return Fetch16(1);
373 }
374
VRegB_3rc()375 inline uint16_t Instruction::VRegB_3rc() const {
376 DCHECK_EQ(FormatOf(Opcode()), k3rc);
377 return Fetch16(1);
378 }
379
VRegB_45cc()380 inline uint16_t Instruction::VRegB_45cc() const {
381 DCHECK_EQ(FormatOf(Opcode()), k45cc);
382 return Fetch16(1);
383 }
384
VRegB_4rcc()385 inline uint16_t Instruction::VRegB_4rcc() const {
386 DCHECK_EQ(FormatOf(Opcode()), k4rcc);
387 return Fetch16(1);
388 }
389
VRegB_51l()390 inline uint64_t Instruction::VRegB_51l() const {
391 DCHECK_EQ(FormatOf(Opcode()), k51l);
392 uint64_t vB_wide = Fetch32(1) | ((uint64_t) Fetch32(3) << 32);
393 return vB_wide;
394 }
395
396 //------------------------------------------------------------------------------
397 // VRegC
398 //------------------------------------------------------------------------------
HasVRegC()399 inline bool Instruction::HasVRegC() const {
400 switch (FormatOf(Opcode())) {
401 case k22b: return true;
402 case k22c: return true;
403 case k22s: return true;
404 case k22t: return true;
405 case k23x: return true;
406 case k35c: return true;
407 case k3rc: return true;
408 case k45cc: return true;
409 case k4rcc: return true;
410 default: return false;
411 }
412 }
413
VRegC()414 inline int32_t Instruction::VRegC() const {
415 switch (FormatOf(Opcode())) {
416 case k22b: return VRegC_22b();
417 case k22c: return VRegC_22c();
418 case k22s: return VRegC_22s();
419 case k22t: return VRegC_22t();
420 case k23x: return VRegC_23x();
421 case k35c: return VRegC_35c();
422 case k3rc: return VRegC_3rc();
423 case k45cc: return VRegC_45cc();
424 case k4rcc: return VRegC_4rcc();
425 default:
426 LOG(FATAL) << "Tried to access vC of instruction " << Name() << " which has no C operand.";
427 exit(EXIT_FAILURE);
428 }
429 }
430
VRegC_22b()431 inline int8_t Instruction::VRegC_22b() const {
432 DCHECK_EQ(FormatOf(Opcode()), k22b);
433 return static_cast<int8_t>(Fetch16(1) >> 8);
434 }
435
VRegC_22c()436 inline uint16_t Instruction::VRegC_22c() const {
437 DCHECK_EQ(FormatOf(Opcode()), k22c);
438 return Fetch16(1);
439 }
440
VRegC_22s()441 inline int16_t Instruction::VRegC_22s() const {
442 DCHECK_EQ(FormatOf(Opcode()), k22s);
443 return static_cast<int16_t>(Fetch16(1));
444 }
445
VRegC_22t()446 inline int16_t Instruction::VRegC_22t() const {
447 DCHECK_EQ(FormatOf(Opcode()), k22t);
448 return static_cast<int16_t>(Fetch16(1));
449 }
450
VRegC_23x()451 inline uint8_t Instruction::VRegC_23x() const {
452 DCHECK_EQ(FormatOf(Opcode()), k23x);
453 return static_cast<uint8_t>(Fetch16(1) >> 8);
454 }
455
VRegC_35c()456 inline uint4_t Instruction::VRegC_35c() const {
457 DCHECK_EQ(FormatOf(Opcode()), k35c);
458 return static_cast<uint4_t>(Fetch16(2) & 0x0f);
459 }
460
VRegC_3rc()461 inline uint16_t Instruction::VRegC_3rc() const {
462 DCHECK_EQ(FormatOf(Opcode()), k3rc);
463 return Fetch16(2);
464 }
465
VRegC_45cc()466 inline uint4_t Instruction::VRegC_45cc() const {
467 DCHECK_EQ(FormatOf(Opcode()), k45cc);
468 return static_cast<uint4_t>(Fetch16(2) & 0x0f);
469 }
470
VRegC_4rcc()471 inline uint16_t Instruction::VRegC_4rcc() const {
472 DCHECK_EQ(FormatOf(Opcode()), k4rcc);
473 return Fetch16(2);
474 }
475
476 //------------------------------------------------------------------------------
477 // VRegH
478 //------------------------------------------------------------------------------
HasVRegH()479 inline bool Instruction::HasVRegH() const {
480 switch (FormatOf(Opcode())) {
481 case k45cc: return true;
482 case k4rcc: return true;
483 default : return false;
484 }
485 }
486
VRegH()487 inline int32_t Instruction::VRegH() const {
488 switch (FormatOf(Opcode())) {
489 case k45cc: return VRegH_45cc();
490 case k4rcc: return VRegH_4rcc();
491 default :
492 LOG(FATAL) << "Tried to access vH of instruction " << Name() << " which has no H operand.";
493 exit(EXIT_FAILURE);
494 }
495 }
496
VRegH_45cc()497 inline uint16_t Instruction::VRegH_45cc() const {
498 DCHECK_EQ(FormatOf(Opcode()), k45cc);
499 return Fetch16(3);
500 }
501
VRegH_4rcc()502 inline uint16_t Instruction::VRegH_4rcc() const {
503 DCHECK_EQ(FormatOf(Opcode()), k4rcc);
504 return Fetch16(3);
505 }
506
HasVarArgs()507 inline bool Instruction::HasVarArgs() const {
508 return (FormatOf(Opcode()) == k35c) || (FormatOf(Opcode()) == k45cc);
509 }
510
GetVarArgs(uint32_t arg[kMaxVarArgRegs],uint16_t inst_data)511 inline uint32_t Instruction::GetVarArgs(uint32_t arg[kMaxVarArgRegs], uint16_t inst_data) const {
512 DCHECK(HasVarArgs());
513
514 /*
515 * Note that the fields mentioned in the spec don't appear in
516 * their "usual" positions here compared to most formats. This
517 * was done so that the field names for the argument count and
518 * reference index match between this format and the corresponding
519 * range formats (3rc and friends).
520 *
521 * Bottom line: The argument count is always in vA, and the
522 * method constant (or equivalent) is always in vB.
523 */
524 uint16_t regList = Fetch16(2);
525 uint4_t count = InstB(inst_data); // This is labeled A in the spec.
526 DCHECK_LE(count, 5U) << "Invalid arg count in 35c (" << count << ")";
527
528 /*
529 * Copy the argument registers into the arg[] array, and
530 * also copy the first argument (if any) into vC. (The
531 * DecodedInstruction structure doesn't have separate
532 * fields for {vD, vE, vF, vG}, so there's no need to make
533 * copies of those.) Note that cases 5..2 fall through.
534 */
535 switch (count) {
536 case 5:
537 arg[4] = InstA(inst_data);
538 FALLTHROUGH_INTENDED;
539 case 4:
540 arg[3] = (regList >> 12) & 0x0f;
541 FALLTHROUGH_INTENDED;
542 case 3:
543 arg[2] = (regList >> 8) & 0x0f;
544 FALLTHROUGH_INTENDED;
545 case 2:
546 arg[1] = (regList >> 4) & 0x0f;
547 FALLTHROUGH_INTENDED;
548 case 1:
549 arg[0] = regList & 0x0f;
550 break;
551 default: // case 0
552 break; // Valid, but no need to do anything.
553 }
554 return count;
555 }
556
557 } // namespace art
558
559 #endif // ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_INL_H_
560