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 k51l: return true;
53     default: return false;
54   }
55 }
56 
VRegA()57 inline int32_t Instruction::VRegA() const {
58   switch (FormatOf(Opcode())) {
59     case k10t: return VRegA_10t();
60     case k10x: return VRegA_10x();
61     case k11n: return VRegA_11n();
62     case k11x: return VRegA_11x();
63     case k12x: return VRegA_12x();
64     case k20t: return VRegA_20t();
65     case k21c: return VRegA_21c();
66     case k21h: return VRegA_21h();
67     case k21s: return VRegA_21s();
68     case k21t: return VRegA_21t();
69     case k22b: return VRegA_22b();
70     case k22c: return VRegA_22c();
71     case k22s: return VRegA_22s();
72     case k22t: return VRegA_22t();
73     case k22x: return VRegA_22x();
74     case k23x: return VRegA_23x();
75     case k30t: return VRegA_30t();
76     case k31c: return VRegA_31c();
77     case k31i: return VRegA_31i();
78     case k31t: return VRegA_31t();
79     case k32x: return VRegA_32x();
80     case k35c: return VRegA_35c();
81     case k3rc: return VRegA_3rc();
82     case k51l: return VRegA_51l();
83     default:
84       LOG(FATAL) << "Tried to access vA of instruction " << Name() << " which has no A operand.";
85       exit(EXIT_FAILURE);
86   }
87 }
88 
VRegA_10t(uint16_t inst_data)89 inline int8_t Instruction::VRegA_10t(uint16_t inst_data) const {
90   DCHECK_EQ(FormatOf(Opcode()), k10t);
91   return static_cast<int8_t>(InstAA(inst_data));
92 }
93 
VRegA_10x(uint16_t inst_data)94 inline uint8_t Instruction::VRegA_10x(uint16_t inst_data) const {
95   DCHECK_EQ(FormatOf(Opcode()), k10x);
96   return InstAA(inst_data);
97 }
98 
VRegA_11n(uint16_t inst_data)99 inline uint4_t Instruction::VRegA_11n(uint16_t inst_data) const {
100   DCHECK_EQ(FormatOf(Opcode()), k11n);
101   return InstA(inst_data);
102 }
103 
VRegA_11x(uint16_t inst_data)104 inline uint8_t Instruction::VRegA_11x(uint16_t inst_data) const {
105   DCHECK_EQ(FormatOf(Opcode()), k11x);
106   return InstAA(inst_data);
107 }
108 
VRegA_12x(uint16_t inst_data)109 inline uint4_t Instruction::VRegA_12x(uint16_t inst_data) const {
110   DCHECK_EQ(FormatOf(Opcode()), k12x);
111   return InstA(inst_data);
112 }
113 
VRegA_20t()114 inline int16_t Instruction::VRegA_20t() const {
115   DCHECK_EQ(FormatOf(Opcode()), k20t);
116   return static_cast<int16_t>(Fetch16(1));
117 }
118 
VRegA_21c(uint16_t inst_data)119 inline uint8_t Instruction::VRegA_21c(uint16_t inst_data) const {
120   DCHECK_EQ(FormatOf(Opcode()), k21c);
121   return InstAA(inst_data);
122 }
123 
VRegA_21h(uint16_t inst_data)124 inline uint8_t Instruction::VRegA_21h(uint16_t inst_data) const {
125   DCHECK_EQ(FormatOf(Opcode()), k21h);
126   return InstAA(inst_data);
127 }
128 
VRegA_21s(uint16_t inst_data)129 inline uint8_t Instruction::VRegA_21s(uint16_t inst_data) const {
130   DCHECK_EQ(FormatOf(Opcode()), k21s);
131   return InstAA(inst_data);
132 }
133 
VRegA_21t(uint16_t inst_data)134 inline uint8_t Instruction::VRegA_21t(uint16_t inst_data) const {
135   DCHECK_EQ(FormatOf(Opcode()), k21t);
136   return InstAA(inst_data);
137 }
138 
VRegA_22b(uint16_t inst_data)139 inline uint8_t Instruction::VRegA_22b(uint16_t inst_data) const {
140   DCHECK_EQ(FormatOf(Opcode()), k22b);
141   return InstAA(inst_data);
142 }
143 
VRegA_22c(uint16_t inst_data)144 inline uint4_t Instruction::VRegA_22c(uint16_t inst_data) const {
145   DCHECK_EQ(FormatOf(Opcode()), k22c);
146   return InstA(inst_data);
147 }
148 
VRegA_22s(uint16_t inst_data)149 inline uint4_t Instruction::VRegA_22s(uint16_t inst_data) const {
150   DCHECK_EQ(FormatOf(Opcode()), k22s);
151   return InstA(inst_data);
152 }
153 
VRegA_22t(uint16_t inst_data)154 inline uint4_t Instruction::VRegA_22t(uint16_t inst_data) const {
155   DCHECK_EQ(FormatOf(Opcode()), k22t);
156   return InstA(inst_data);
157 }
158 
VRegA_22x(uint16_t inst_data)159 inline uint8_t Instruction::VRegA_22x(uint16_t inst_data) const {
160   DCHECK_EQ(FormatOf(Opcode()), k22x);
161   return InstAA(inst_data);
162 }
163 
VRegA_23x(uint16_t inst_data)164 inline uint8_t Instruction::VRegA_23x(uint16_t inst_data) const {
165   DCHECK_EQ(FormatOf(Opcode()), k23x);
166   return InstAA(inst_data);
167 }
168 
VRegA_30t()169 inline int32_t Instruction::VRegA_30t() const {
170   DCHECK_EQ(FormatOf(Opcode()), k30t);
171   return static_cast<int32_t>(Fetch32(1));
172 }
173 
VRegA_31c(uint16_t inst_data)174 inline uint8_t Instruction::VRegA_31c(uint16_t inst_data) const {
175   DCHECK_EQ(FormatOf(Opcode()), k31c);
176   return InstAA(inst_data);
177 }
178 
VRegA_31i(uint16_t inst_data)179 inline uint8_t Instruction::VRegA_31i(uint16_t inst_data) const {
180   DCHECK_EQ(FormatOf(Opcode()), k31i);
181   return InstAA(inst_data);
182 }
183 
VRegA_31t(uint16_t inst_data)184 inline uint8_t Instruction::VRegA_31t(uint16_t inst_data) const {
185   DCHECK_EQ(FormatOf(Opcode()), k31t);
186   return InstAA(inst_data);
187 }
188 
VRegA_32x()189 inline uint16_t Instruction::VRegA_32x() const {
190   DCHECK_EQ(FormatOf(Opcode()), k32x);
191   return Fetch16(1);
192 }
193 
VRegA_35c(uint16_t inst_data)194 inline uint4_t Instruction::VRegA_35c(uint16_t inst_data) const {
195   DCHECK_EQ(FormatOf(Opcode()), k35c);
196   return InstB(inst_data);  // This is labeled A in the spec.
197 }
198 
VRegA_3rc(uint16_t inst_data)199 inline uint8_t Instruction::VRegA_3rc(uint16_t inst_data) const {
200   DCHECK_EQ(FormatOf(Opcode()), k3rc);
201   return InstAA(inst_data);
202 }
203 
VRegA_51l(uint16_t inst_data)204 inline uint8_t Instruction::VRegA_51l(uint16_t inst_data) const {
205   DCHECK_EQ(FormatOf(Opcode()), k51l);
206   return InstAA(inst_data);
207 }
208 
209 //------------------------------------------------------------------------------
210 // VRegB
211 //------------------------------------------------------------------------------
HasVRegB()212 inline bool Instruction::HasVRegB() const {
213   switch (FormatOf(Opcode())) {
214     case k11n: return true;
215     case k12x: return true;
216     case k21c: return true;
217     case k21h: return true;
218     case k21s: return true;
219     case k21t: return true;
220     case k22b: return true;
221     case k22c: return true;
222     case k22s: return true;
223     case k22t: return true;
224     case k22x: return true;
225     case k23x: return true;
226     case k31c: return true;
227     case k31i: return true;
228     case k31t: return true;
229     case k32x: return true;
230     case k35c: return true;
231     case k3rc: return true;
232     case k51l: return true;
233     default: return false;
234   }
235 }
236 
HasWideVRegB()237 inline bool Instruction::HasWideVRegB() const {
238   return FormatOf(Opcode()) == k51l;
239 }
240 
VRegB()241 inline int32_t Instruction::VRegB() const {
242   switch (FormatOf(Opcode())) {
243     case k11n: return VRegB_11n();
244     case k12x: return VRegB_12x();
245     case k21c: return VRegB_21c();
246     case k21h: return VRegB_21h();
247     case k21s: return VRegB_21s();
248     case k21t: return VRegB_21t();
249     case k22b: return VRegB_22b();
250     case k22c: return VRegB_22c();
251     case k22s: return VRegB_22s();
252     case k22t: return VRegB_22t();
253     case k22x: return VRegB_22x();
254     case k23x: return VRegB_23x();
255     case k31c: return VRegB_31c();
256     case k31i: return VRegB_31i();
257     case k31t: return VRegB_31t();
258     case k32x: return VRegB_32x();
259     case k35c: return VRegB_35c();
260     case k3rc: return VRegB_3rc();
261     case k51l: return VRegB_51l();
262     default:
263       LOG(FATAL) << "Tried to access vB of instruction " << Name() << " which has no B operand.";
264       exit(EXIT_FAILURE);
265   }
266 }
267 
WideVRegB()268 inline uint64_t Instruction::WideVRegB() const {
269   return VRegB_51l();
270 }
271 
VRegB_11n(uint16_t inst_data)272 inline int4_t Instruction::VRegB_11n(uint16_t inst_data) const {
273   DCHECK_EQ(FormatOf(Opcode()), k11n);
274   return static_cast<int4_t>((InstB(inst_data) << 28) >> 28);
275 }
276 
VRegB_12x(uint16_t inst_data)277 inline uint4_t Instruction::VRegB_12x(uint16_t inst_data) const {
278   DCHECK_EQ(FormatOf(Opcode()), k12x);
279   return InstB(inst_data);
280 }
281 
VRegB_21c()282 inline uint16_t Instruction::VRegB_21c() const {
283   DCHECK_EQ(FormatOf(Opcode()), k21c);
284   return Fetch16(1);
285 }
286 
VRegB_21h()287 inline uint16_t Instruction::VRegB_21h() const {
288   DCHECK_EQ(FormatOf(Opcode()), k21h);
289   return Fetch16(1);
290 }
291 
VRegB_21s()292 inline int16_t Instruction::VRegB_21s() const {
293   DCHECK_EQ(FormatOf(Opcode()), k21s);
294   return static_cast<int16_t>(Fetch16(1));
295 }
296 
VRegB_21t()297 inline int16_t Instruction::VRegB_21t() const {
298   DCHECK_EQ(FormatOf(Opcode()), k21t);
299   return static_cast<int16_t>(Fetch16(1));
300 }
301 
VRegB_22b()302 inline uint8_t Instruction::VRegB_22b() const {
303   DCHECK_EQ(FormatOf(Opcode()), k22b);
304   return static_cast<uint8_t>(Fetch16(1) & 0xff);
305 }
306 
VRegB_22c(uint16_t inst_data)307 inline uint4_t Instruction::VRegB_22c(uint16_t inst_data) const {
308   DCHECK_EQ(FormatOf(Opcode()), k22c);
309   return InstB(inst_data);
310 }
311 
VRegB_22s(uint16_t inst_data)312 inline uint4_t Instruction::VRegB_22s(uint16_t inst_data) const {
313   DCHECK_EQ(FormatOf(Opcode()), k22s);
314   return InstB(inst_data);
315 }
316 
VRegB_22t(uint16_t inst_data)317 inline uint4_t Instruction::VRegB_22t(uint16_t inst_data) const {
318   DCHECK_EQ(FormatOf(Opcode()), k22t);
319   return InstB(inst_data);
320 }
321 
VRegB_22x()322 inline uint16_t Instruction::VRegB_22x() const {
323   DCHECK_EQ(FormatOf(Opcode()), k22x);
324   return Fetch16(1);
325 }
326 
VRegB_23x()327 inline uint8_t Instruction::VRegB_23x() const {
328   DCHECK_EQ(FormatOf(Opcode()), k23x);
329   return static_cast<uint8_t>(Fetch16(1) & 0xff);
330 }
331 
VRegB_31c()332 inline uint32_t Instruction::VRegB_31c() const {
333   DCHECK_EQ(FormatOf(Opcode()), k31c);
334   return Fetch32(1);
335 }
336 
VRegB_31i()337 inline int32_t Instruction::VRegB_31i() const {
338   DCHECK_EQ(FormatOf(Opcode()), k31i);
339   return static_cast<int32_t>(Fetch32(1));
340 }
341 
VRegB_31t()342 inline int32_t Instruction::VRegB_31t() const {
343   DCHECK_EQ(FormatOf(Opcode()), k31t);
344   return static_cast<int32_t>(Fetch32(1));
345 }
346 
VRegB_32x()347 inline uint16_t Instruction::VRegB_32x() const {
348   DCHECK_EQ(FormatOf(Opcode()), k32x);
349   return Fetch16(2);
350 }
351 
VRegB_35c()352 inline uint16_t Instruction::VRegB_35c() const {
353   DCHECK_EQ(FormatOf(Opcode()), k35c);
354   return Fetch16(1);
355 }
356 
VRegB_3rc()357 inline uint16_t Instruction::VRegB_3rc() const {
358   DCHECK_EQ(FormatOf(Opcode()), k3rc);
359   return Fetch16(1);
360 }
361 
VRegB_51l()362 inline uint64_t Instruction::VRegB_51l() const {
363   DCHECK_EQ(FormatOf(Opcode()), k51l);
364   uint64_t vB_wide = Fetch32(1) | ((uint64_t) Fetch32(3) << 32);
365   return vB_wide;
366 }
367 
368 //------------------------------------------------------------------------------
369 // VRegC
370 //------------------------------------------------------------------------------
HasVRegC()371 inline bool Instruction::HasVRegC() const {
372   switch (FormatOf(Opcode())) {
373     case k22b: return true;
374     case k22c: return true;
375     case k22s: return true;
376     case k22t: return true;
377     case k23x: return true;
378     case k35c: return true;
379     case k3rc: return true;
380     default: return false;
381   }
382 }
383 
VRegC()384 inline int32_t Instruction::VRegC() const {
385   switch (FormatOf(Opcode())) {
386     case k22b: return VRegC_22b();
387     case k22c: return VRegC_22c();
388     case k22s: return VRegC_22s();
389     case k22t: return VRegC_22t();
390     case k23x: return VRegC_23x();
391     case k35c: return VRegC_35c();
392     case k3rc: return VRegC_3rc();
393     default:
394       LOG(FATAL) << "Tried to access vC of instruction " << Name() << " which has no C operand.";
395       exit(EXIT_FAILURE);
396   }
397 }
398 
VRegC_22b()399 inline int8_t Instruction::VRegC_22b() const {
400   DCHECK_EQ(FormatOf(Opcode()), k22b);
401   return static_cast<int8_t>(Fetch16(1) >> 8);
402 }
403 
VRegC_22c()404 inline uint16_t Instruction::VRegC_22c() const {
405   DCHECK_EQ(FormatOf(Opcode()), k22c);
406   return Fetch16(1);
407 }
408 
VRegC_22s()409 inline int16_t Instruction::VRegC_22s() const {
410   DCHECK_EQ(FormatOf(Opcode()), k22s);
411   return static_cast<int16_t>(Fetch16(1));
412 }
413 
VRegC_22t()414 inline int16_t Instruction::VRegC_22t() const {
415   DCHECK_EQ(FormatOf(Opcode()), k22t);
416   return static_cast<int16_t>(Fetch16(1));
417 }
418 
VRegC_23x()419 inline uint8_t Instruction::VRegC_23x() const {
420   DCHECK_EQ(FormatOf(Opcode()), k23x);
421   return static_cast<uint8_t>(Fetch16(1) >> 8);
422 }
423 
VRegC_35c()424 inline uint4_t Instruction::VRegC_35c() const {
425   DCHECK_EQ(FormatOf(Opcode()), k35c);
426   return static_cast<uint4_t>(Fetch16(2) & 0x0f);
427 }
428 
VRegC_3rc()429 inline uint16_t Instruction::VRegC_3rc() const {
430   DCHECK_EQ(FormatOf(Opcode()), k3rc);
431   return Fetch16(2);
432 }
433 
HasVarArgs()434 inline bool Instruction::HasVarArgs() const {
435   return FormatOf(Opcode()) == k35c;
436 }
437 
GetVarArgs(uint32_t arg[5],uint16_t inst_data)438 inline void Instruction::GetVarArgs(uint32_t arg[5], uint16_t inst_data) const {
439   DCHECK_EQ(FormatOf(Opcode()), k35c);
440 
441   /*
442    * Note that the fields mentioned in the spec don't appear in
443    * their "usual" positions here compared to most formats. This
444    * was done so that the field names for the argument count and
445    * reference index match between this format and the corresponding
446    * range formats (3rc and friends).
447    *
448    * Bottom line: The argument count is always in vA, and the
449    * method constant (or equivalent) is always in vB.
450    */
451   uint16_t regList = Fetch16(2);
452   uint4_t count = InstB(inst_data);  // This is labeled A in the spec.
453   DCHECK_LE(count, 5U) << "Invalid arg count in 35c (" << count << ")";
454 
455   /*
456    * Copy the argument registers into the arg[] array, and
457    * also copy the first argument (if any) into vC. (The
458    * DecodedInstruction structure doesn't have separate
459    * fields for {vD, vE, vF, vG}, so there's no need to make
460    * copies of those.) Note that cases 5..2 fall through.
461    */
462   switch (count) {
463     case 5:
464       arg[4] = InstA(inst_data);
465       FALLTHROUGH_INTENDED;
466     case 4:
467       arg[3] = (regList >> 12) & 0x0f;
468       FALLTHROUGH_INTENDED;
469     case 3:
470       arg[2] = (regList >> 8) & 0x0f;
471       FALLTHROUGH_INTENDED;
472     case 2:
473       arg[1] = (regList >> 4) & 0x0f;
474       FALLTHROUGH_INTENDED;
475     case 1:
476       arg[0] = regList & 0x0f;
477       break;
478     default:  // case 0
479       break;  // Valid, but no need to do anything.
480   }
481 }
482 
483 }  // namespace art
484 
485 #endif  // ART_RUNTIME_DEX_INSTRUCTION_INL_H_
486