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_RUNTIME_DEX_INSTRUCTION_INL_H_
18 #define ART_RUNTIME_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 void 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 }
555 
556 }  // namespace art
557 
558 #endif  // ART_RUNTIME_DEX_INSTRUCTION_INL_H_
559