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 k51l: return true;
53    default: return false;
54  }
55}
56
57inline 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
89inline 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
94inline uint8_t Instruction::VRegA_10x(uint16_t inst_data) const {
95  DCHECK_EQ(FormatOf(Opcode()), k10x);
96  return InstAA(inst_data);
97}
98
99inline uint4_t Instruction::VRegA_11n(uint16_t inst_data) const {
100  DCHECK_EQ(FormatOf(Opcode()), k11n);
101  return InstA(inst_data);
102}
103
104inline uint8_t Instruction::VRegA_11x(uint16_t inst_data) const {
105  DCHECK_EQ(FormatOf(Opcode()), k11x);
106  return InstAA(inst_data);
107}
108
109inline uint4_t Instruction::VRegA_12x(uint16_t inst_data) const {
110  DCHECK_EQ(FormatOf(Opcode()), k12x);
111  return InstA(inst_data);
112}
113
114inline int16_t Instruction::VRegA_20t() const {
115  DCHECK_EQ(FormatOf(Opcode()), k20t);
116  return static_cast<int16_t>(Fetch16(1));
117}
118
119inline uint8_t Instruction::VRegA_21c(uint16_t inst_data) const {
120  DCHECK_EQ(FormatOf(Opcode()), k21c);
121  return InstAA(inst_data);
122}
123
124inline uint8_t Instruction::VRegA_21h(uint16_t inst_data) const {
125  DCHECK_EQ(FormatOf(Opcode()), k21h);
126  return InstAA(inst_data);
127}
128
129inline uint8_t Instruction::VRegA_21s(uint16_t inst_data) const {
130  DCHECK_EQ(FormatOf(Opcode()), k21s);
131  return InstAA(inst_data);
132}
133
134inline uint8_t Instruction::VRegA_21t(uint16_t inst_data) const {
135  DCHECK_EQ(FormatOf(Opcode()), k21t);
136  return InstAA(inst_data);
137}
138
139inline uint8_t Instruction::VRegA_22b(uint16_t inst_data) const {
140  DCHECK_EQ(FormatOf(Opcode()), k22b);
141  return InstAA(inst_data);
142}
143
144inline uint4_t Instruction::VRegA_22c(uint16_t inst_data) const {
145  DCHECK_EQ(FormatOf(Opcode()), k22c);
146  return InstA(inst_data);
147}
148
149inline uint4_t Instruction::VRegA_22s(uint16_t inst_data) const {
150  DCHECK_EQ(FormatOf(Opcode()), k22s);
151  return InstA(inst_data);
152}
153
154inline uint4_t Instruction::VRegA_22t(uint16_t inst_data) const {
155  DCHECK_EQ(FormatOf(Opcode()), k22t);
156  return InstA(inst_data);
157}
158
159inline uint8_t Instruction::VRegA_22x(uint16_t inst_data) const {
160  DCHECK_EQ(FormatOf(Opcode()), k22x);
161  return InstAA(inst_data);
162}
163
164inline uint8_t Instruction::VRegA_23x(uint16_t inst_data) const {
165  DCHECK_EQ(FormatOf(Opcode()), k23x);
166  return InstAA(inst_data);
167}
168
169inline int32_t Instruction::VRegA_30t() const {
170  DCHECK_EQ(FormatOf(Opcode()), k30t);
171  return static_cast<int32_t>(Fetch32(1));
172}
173
174inline uint8_t Instruction::VRegA_31c(uint16_t inst_data) const {
175  DCHECK_EQ(FormatOf(Opcode()), k31c);
176  return InstAA(inst_data);
177}
178
179inline uint8_t Instruction::VRegA_31i(uint16_t inst_data) const {
180  DCHECK_EQ(FormatOf(Opcode()), k31i);
181  return InstAA(inst_data);
182}
183
184inline uint8_t Instruction::VRegA_31t(uint16_t inst_data) const {
185  DCHECK_EQ(FormatOf(Opcode()), k31t);
186  return InstAA(inst_data);
187}
188
189inline uint16_t Instruction::VRegA_32x() const {
190  DCHECK_EQ(FormatOf(Opcode()), k32x);
191  return Fetch16(1);
192}
193
194inline 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
199inline uint8_t Instruction::VRegA_3rc(uint16_t inst_data) const {
200  DCHECK_EQ(FormatOf(Opcode()), k3rc);
201  return InstAA(inst_data);
202}
203
204inline 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//------------------------------------------------------------------------------
212inline 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
237inline bool Instruction::HasWideVRegB() const {
238  return FormatOf(Opcode()) == k51l;
239}
240
241inline 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
268inline uint64_t Instruction::WideVRegB() const {
269  return VRegB_51l();
270}
271
272inline 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
277inline uint4_t Instruction::VRegB_12x(uint16_t inst_data) const {
278  DCHECK_EQ(FormatOf(Opcode()), k12x);
279  return InstB(inst_data);
280}
281
282inline uint16_t Instruction::VRegB_21c() const {
283  DCHECK_EQ(FormatOf(Opcode()), k21c);
284  return Fetch16(1);
285}
286
287inline uint16_t Instruction::VRegB_21h() const {
288  DCHECK_EQ(FormatOf(Opcode()), k21h);
289  return Fetch16(1);
290}
291
292inline int16_t Instruction::VRegB_21s() const {
293  DCHECK_EQ(FormatOf(Opcode()), k21s);
294  return static_cast<int16_t>(Fetch16(1));
295}
296
297inline int16_t Instruction::VRegB_21t() const {
298  DCHECK_EQ(FormatOf(Opcode()), k21t);
299  return static_cast<int16_t>(Fetch16(1));
300}
301
302inline uint8_t Instruction::VRegB_22b() const {
303  DCHECK_EQ(FormatOf(Opcode()), k22b);
304  return static_cast<uint8_t>(Fetch16(1) & 0xff);
305}
306
307inline uint4_t Instruction::VRegB_22c(uint16_t inst_data) const {
308  DCHECK_EQ(FormatOf(Opcode()), k22c);
309  return InstB(inst_data);
310}
311
312inline uint4_t Instruction::VRegB_22s(uint16_t inst_data) const {
313  DCHECK_EQ(FormatOf(Opcode()), k22s);
314  return InstB(inst_data);
315}
316
317inline uint4_t Instruction::VRegB_22t(uint16_t inst_data) const {
318  DCHECK_EQ(FormatOf(Opcode()), k22t);
319  return InstB(inst_data);
320}
321
322inline uint16_t Instruction::VRegB_22x() const {
323  DCHECK_EQ(FormatOf(Opcode()), k22x);
324  return Fetch16(1);
325}
326
327inline uint8_t Instruction::VRegB_23x() const {
328  DCHECK_EQ(FormatOf(Opcode()), k23x);
329  return static_cast<uint8_t>(Fetch16(1) & 0xff);
330}
331
332inline uint32_t Instruction::VRegB_31c() const {
333  DCHECK_EQ(FormatOf(Opcode()), k31c);
334  return Fetch32(1);
335}
336
337inline int32_t Instruction::VRegB_31i() const {
338  DCHECK_EQ(FormatOf(Opcode()), k31i);
339  return static_cast<int32_t>(Fetch32(1));
340}
341
342inline int32_t Instruction::VRegB_31t() const {
343  DCHECK_EQ(FormatOf(Opcode()), k31t);
344  return static_cast<int32_t>(Fetch32(1));
345}
346
347inline uint16_t Instruction::VRegB_32x() const {
348  DCHECK_EQ(FormatOf(Opcode()), k32x);
349  return Fetch16(2);
350}
351
352inline uint16_t Instruction::VRegB_35c() const {
353  DCHECK_EQ(FormatOf(Opcode()), k35c);
354  return Fetch16(1);
355}
356
357inline uint16_t Instruction::VRegB_3rc() const {
358  DCHECK_EQ(FormatOf(Opcode()), k3rc);
359  return Fetch16(1);
360}
361
362inline 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//------------------------------------------------------------------------------
371inline 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
384inline 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
399inline int8_t Instruction::VRegC_22b() const {
400  DCHECK_EQ(FormatOf(Opcode()), k22b);
401  return static_cast<int8_t>(Fetch16(1) >> 8);
402}
403
404inline uint16_t Instruction::VRegC_22c() const {
405  DCHECK_EQ(FormatOf(Opcode()), k22c);
406  return Fetch16(1);
407}
408
409inline int16_t Instruction::VRegC_22s() const {
410  DCHECK_EQ(FormatOf(Opcode()), k22s);
411  return static_cast<int16_t>(Fetch16(1));
412}
413
414inline int16_t Instruction::VRegC_22t() const {
415  DCHECK_EQ(FormatOf(Opcode()), k22t);
416  return static_cast<int16_t>(Fetch16(1));
417}
418
419inline uint8_t Instruction::VRegC_23x() const {
420  DCHECK_EQ(FormatOf(Opcode()), k23x);
421  return static_cast<uint8_t>(Fetch16(1) >> 8);
422}
423
424inline uint4_t Instruction::VRegC_35c() const {
425  DCHECK_EQ(FormatOf(Opcode()), k35c);
426  return static_cast<uint4_t>(Fetch16(2) & 0x0f);
427}
428
429inline uint16_t Instruction::VRegC_3rc() const {
430  DCHECK_EQ(FormatOf(Opcode()), k3rc);
431  return Fetch16(2);
432}
433
434inline bool Instruction::HasVarArgs() const {
435  return FormatOf(Opcode()) == k35c;
436}
437
438inline 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