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
22namespace art {
23
24//------------------------------------------------------------------------------
25// VRegA
26//------------------------------------------------------------------------------
27inline 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
59inline 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
93inline 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
98inline uint8_t Instruction::VRegA_10x(uint16_t inst_data) const {
99  DCHECK_EQ(FormatOf(Opcode()), k10x);
100  return InstAA(inst_data);
101}
102
103inline uint4_t Instruction::VRegA_11n(uint16_t inst_data) const {
104  DCHECK_EQ(FormatOf(Opcode()), k11n);
105  return InstA(inst_data);
106}
107
108inline uint8_t Instruction::VRegA_11x(uint16_t inst_data) const {
109  DCHECK_EQ(FormatOf(Opcode()), k11x);
110  return InstAA(inst_data);
111}
112
113inline uint4_t Instruction::VRegA_12x(uint16_t inst_data) const {
114  DCHECK_EQ(FormatOf(Opcode()), k12x);
115  return InstA(inst_data);
116}
117
118inline int16_t Instruction::VRegA_20t() const {
119  DCHECK_EQ(FormatOf(Opcode()), k20t);
120  return static_cast<int16_t>(Fetch16(1));
121}
122
123inline uint8_t Instruction::VRegA_21c(uint16_t inst_data) const {
124  DCHECK_EQ(FormatOf(Opcode()), k21c);
125  return InstAA(inst_data);
126}
127
128inline uint8_t Instruction::VRegA_21h(uint16_t inst_data) const {
129  DCHECK_EQ(FormatOf(Opcode()), k21h);
130  return InstAA(inst_data);
131}
132
133inline uint8_t Instruction::VRegA_21s(uint16_t inst_data) const {
134  DCHECK_EQ(FormatOf(Opcode()), k21s);
135  return InstAA(inst_data);
136}
137
138inline uint8_t Instruction::VRegA_21t(uint16_t inst_data) const {
139  DCHECK_EQ(FormatOf(Opcode()), k21t);
140  return InstAA(inst_data);
141}
142
143inline uint8_t Instruction::VRegA_22b(uint16_t inst_data) const {
144  DCHECK_EQ(FormatOf(Opcode()), k22b);
145  return InstAA(inst_data);
146}
147
148inline uint4_t Instruction::VRegA_22c(uint16_t inst_data) const {
149  DCHECK_EQ(FormatOf(Opcode()), k22c);
150  return InstA(inst_data);
151}
152
153inline uint4_t Instruction::VRegA_22s(uint16_t inst_data) const {
154  DCHECK_EQ(FormatOf(Opcode()), k22s);
155  return InstA(inst_data);
156}
157
158inline uint4_t Instruction::VRegA_22t(uint16_t inst_data) const {
159  DCHECK_EQ(FormatOf(Opcode()), k22t);
160  return InstA(inst_data);
161}
162
163inline uint8_t Instruction::VRegA_22x(uint16_t inst_data) const {
164  DCHECK_EQ(FormatOf(Opcode()), k22x);
165  return InstAA(inst_data);
166}
167
168inline uint8_t Instruction::VRegA_23x(uint16_t inst_data) const {
169  DCHECK_EQ(FormatOf(Opcode()), k23x);
170  return InstAA(inst_data);
171}
172
173inline int32_t Instruction::VRegA_30t() const {
174  DCHECK_EQ(FormatOf(Opcode()), k30t);
175  return static_cast<int32_t>(Fetch32(1));
176}
177
178inline uint8_t Instruction::VRegA_31c(uint16_t inst_data) const {
179  DCHECK_EQ(FormatOf(Opcode()), k31c);
180  return InstAA(inst_data);
181}
182
183inline uint8_t Instruction::VRegA_31i(uint16_t inst_data) const {
184  DCHECK_EQ(FormatOf(Opcode()), k31i);
185  return InstAA(inst_data);
186}
187
188inline uint8_t Instruction::VRegA_31t(uint16_t inst_data) const {
189  DCHECK_EQ(FormatOf(Opcode()), k31t);
190  return InstAA(inst_data);
191}
192
193inline uint16_t Instruction::VRegA_32x() const {
194  DCHECK_EQ(FormatOf(Opcode()), k32x);
195  return Fetch16(1);
196}
197
198inline 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
203inline uint8_t Instruction::VRegA_3rc(uint16_t inst_data) const {
204  DCHECK_EQ(FormatOf(Opcode()), k3rc);
205  return InstAA(inst_data);
206}
207
208inline uint8_t Instruction::VRegA_51l(uint16_t inst_data) const {
209  DCHECK_EQ(FormatOf(Opcode()), k51l);
210  return InstAA(inst_data);
211}
212
213inline 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
218inline 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//------------------------------------------------------------------------------
226inline 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
253inline bool Instruction::HasWideVRegB() const {
254  return FormatOf(Opcode()) == k51l;
255}
256
257inline 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
286inline uint64_t Instruction::WideVRegB() const {
287  return VRegB_51l();
288}
289
290inline 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
295inline uint4_t Instruction::VRegB_12x(uint16_t inst_data) const {
296  DCHECK_EQ(FormatOf(Opcode()), k12x);
297  return InstB(inst_data);
298}
299
300inline uint16_t Instruction::VRegB_21c() const {
301  DCHECK_EQ(FormatOf(Opcode()), k21c);
302  return Fetch16(1);
303}
304
305inline uint16_t Instruction::VRegB_21h() const {
306  DCHECK_EQ(FormatOf(Opcode()), k21h);
307  return Fetch16(1);
308}
309
310inline int16_t Instruction::VRegB_21s() const {
311  DCHECK_EQ(FormatOf(Opcode()), k21s);
312  return static_cast<int16_t>(Fetch16(1));
313}
314
315inline int16_t Instruction::VRegB_21t() const {
316  DCHECK_EQ(FormatOf(Opcode()), k21t);
317  return static_cast<int16_t>(Fetch16(1));
318}
319
320inline uint8_t Instruction::VRegB_22b() const {
321  DCHECK_EQ(FormatOf(Opcode()), k22b);
322  return static_cast<uint8_t>(Fetch16(1) & 0xff);
323}
324
325inline uint4_t Instruction::VRegB_22c(uint16_t inst_data) const {
326  DCHECK_EQ(FormatOf(Opcode()), k22c);
327  return InstB(inst_data);
328}
329
330inline uint4_t Instruction::VRegB_22s(uint16_t inst_data) const {
331  DCHECK_EQ(FormatOf(Opcode()), k22s);
332  return InstB(inst_data);
333}
334
335inline uint4_t Instruction::VRegB_22t(uint16_t inst_data) const {
336  DCHECK_EQ(FormatOf(Opcode()), k22t);
337  return InstB(inst_data);
338}
339
340inline uint16_t Instruction::VRegB_22x() const {
341  DCHECK_EQ(FormatOf(Opcode()), k22x);
342  return Fetch16(1);
343}
344
345inline uint8_t Instruction::VRegB_23x() const {
346  DCHECK_EQ(FormatOf(Opcode()), k23x);
347  return static_cast<uint8_t>(Fetch16(1) & 0xff);
348}
349
350inline uint32_t Instruction::VRegB_31c() const {
351  DCHECK_EQ(FormatOf(Opcode()), k31c);
352  return Fetch32(1);
353}
354
355inline int32_t Instruction::VRegB_31i() const {
356  DCHECK_EQ(FormatOf(Opcode()), k31i);
357  return static_cast<int32_t>(Fetch32(1));
358}
359
360inline int32_t Instruction::VRegB_31t() const {
361  DCHECK_EQ(FormatOf(Opcode()), k31t);
362  return static_cast<int32_t>(Fetch32(1));
363}
364
365inline uint16_t Instruction::VRegB_32x() const {
366  DCHECK_EQ(FormatOf(Opcode()), k32x);
367  return Fetch16(2);
368}
369
370inline uint16_t Instruction::VRegB_35c() const {
371  DCHECK_EQ(FormatOf(Opcode()), k35c);
372  return Fetch16(1);
373}
374
375inline uint16_t Instruction::VRegB_3rc() const {
376  DCHECK_EQ(FormatOf(Opcode()), k3rc);
377  return Fetch16(1);
378}
379
380inline uint16_t Instruction::VRegB_45cc() const {
381  DCHECK_EQ(FormatOf(Opcode()), k45cc);
382  return Fetch16(1);
383}
384
385inline uint16_t Instruction::VRegB_4rcc() const {
386  DCHECK_EQ(FormatOf(Opcode()), k4rcc);
387  return Fetch16(1);
388}
389
390inline 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//------------------------------------------------------------------------------
399inline 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
414inline 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
431inline int8_t Instruction::VRegC_22b() const {
432  DCHECK_EQ(FormatOf(Opcode()), k22b);
433  return static_cast<int8_t>(Fetch16(1) >> 8);
434}
435
436inline uint16_t Instruction::VRegC_22c() const {
437  DCHECK_EQ(FormatOf(Opcode()), k22c);
438  return Fetch16(1);
439}
440
441inline int16_t Instruction::VRegC_22s() const {
442  DCHECK_EQ(FormatOf(Opcode()), k22s);
443  return static_cast<int16_t>(Fetch16(1));
444}
445
446inline int16_t Instruction::VRegC_22t() const {
447  DCHECK_EQ(FormatOf(Opcode()), k22t);
448  return static_cast<int16_t>(Fetch16(1));
449}
450
451inline uint8_t Instruction::VRegC_23x() const {
452  DCHECK_EQ(FormatOf(Opcode()), k23x);
453  return static_cast<uint8_t>(Fetch16(1) >> 8);
454}
455
456inline uint4_t Instruction::VRegC_35c() const {
457  DCHECK_EQ(FormatOf(Opcode()), k35c);
458  return static_cast<uint4_t>(Fetch16(2) & 0x0f);
459}
460
461inline uint16_t Instruction::VRegC_3rc() const {
462  DCHECK_EQ(FormatOf(Opcode()), k3rc);
463  return Fetch16(2);
464}
465
466inline uint4_t Instruction::VRegC_45cc() const {
467  DCHECK_EQ(FormatOf(Opcode()), k45cc);
468  return static_cast<uint4_t>(Fetch16(2) & 0x0f);
469}
470
471inline uint16_t Instruction::VRegC_4rcc() const {
472  DCHECK_EQ(FormatOf(Opcode()), k4rcc);
473  return Fetch16(2);
474}
475
476//------------------------------------------------------------------------------
477// VRegH
478//------------------------------------------------------------------------------
479inline 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
487inline 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
497inline uint16_t Instruction::VRegH_45cc() const {
498  DCHECK_EQ(FormatOf(Opcode()), k45cc);
499  return Fetch16(3);
500}
501
502inline uint16_t Instruction::VRegH_4rcc() const {
503  DCHECK_EQ(FormatOf(Opcode()), k4rcc);
504  return Fetch16(3);
505}
506
507inline bool Instruction::HasVarArgs() const {
508  return (FormatOf(Opcode()) == k35c) || (FormatOf(Opcode()) == k45cc);
509}
510
511inline 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