blob: e160a103d927ce8bb3f07eb88e413cdb17fabedf [file] [log] [blame]
Sebastien Hertz807a2562013-04-15 09:33:39 +02001/*
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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_DEX_INSTRUCTION_INL_H_
18#define ART_RUNTIME_DEX_INSTRUCTION_INL_H_
Sebastien Hertz807a2562013-04-15 09:33:39 +020019
20#include "dex_instruction.h"
21
22namespace art {
23
Sebastien Hertz807a2562013-04-15 09:33:39 +020024//------------------------------------------------------------------------------
25// VRegA
26//------------------------------------------------------------------------------
Ian Rogers29a26482014-05-02 15:27:29 -070027inline 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
Sebastien Hertz3b588e02013-09-11 14:33:18 +020089inline int8_t Instruction::VRegA_10t(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +020090 DCHECK_EQ(FormatOf(Opcode()), k10t);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020091 return static_cast<int8_t>(InstAA(inst_data));
Sebastien Hertz807a2562013-04-15 09:33:39 +020092}
93
Sebastien Hertz3b588e02013-09-11 14:33:18 +020094inline uint8_t Instruction::VRegA_10x(uint16_t inst_data) const {
Sebastien Hertz5243e912013-05-21 10:55:07 +020095 DCHECK_EQ(FormatOf(Opcode()), k10x);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020096 return InstAA(inst_data);
Sebastien Hertz5243e912013-05-21 10:55:07 +020097}
98
Sebastien Hertz3b588e02013-09-11 14:33:18 +020099inline uint4_t Instruction::VRegA_11n(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200100 DCHECK_EQ(FormatOf(Opcode()), k11n);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200101 return InstA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200102}
103
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200104inline uint8_t Instruction::VRegA_11x(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200105 DCHECK_EQ(FormatOf(Opcode()), k11x);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200106 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200107}
108
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200109inline uint4_t Instruction::VRegA_12x(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200110 DCHECK_EQ(FormatOf(Opcode()), k12x);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200111 return InstA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200112}
113
114inline int16_t Instruction::VRegA_20t() const {
115 DCHECK_EQ(FormatOf(Opcode()), k20t);
116 return static_cast<int16_t>(Fetch16(1));
117}
118
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200119inline uint8_t Instruction::VRegA_21c(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200120 DCHECK_EQ(FormatOf(Opcode()), k21c);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200121 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200122}
123
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200124inline uint8_t Instruction::VRegA_21h(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200125 DCHECK_EQ(FormatOf(Opcode()), k21h);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200126 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200127}
128
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200129inline uint8_t Instruction::VRegA_21s(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200130 DCHECK_EQ(FormatOf(Opcode()), k21s);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200131 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200132}
133
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200134inline uint8_t Instruction::VRegA_21t(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200135 DCHECK_EQ(FormatOf(Opcode()), k21t);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200136 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200137}
138
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200139inline uint8_t Instruction::VRegA_22b(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200140 DCHECK_EQ(FormatOf(Opcode()), k22b);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200141 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200142}
143
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200144inline uint4_t Instruction::VRegA_22c(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200145 DCHECK_EQ(FormatOf(Opcode()), k22c);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200146 return InstA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200147}
148
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200149inline uint4_t Instruction::VRegA_22s(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200150 DCHECK_EQ(FormatOf(Opcode()), k22s);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200151 return InstA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200152}
153
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200154inline uint4_t Instruction::VRegA_22t(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200155 DCHECK_EQ(FormatOf(Opcode()), k22t);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200156 return InstA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200157}
158
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200159inline uint8_t Instruction::VRegA_22x(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200160 DCHECK_EQ(FormatOf(Opcode()), k22x);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200161 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200162}
163
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200164inline uint8_t Instruction::VRegA_23x(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200165 DCHECK_EQ(FormatOf(Opcode()), k23x);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200166 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200167}
168
169inline int32_t Instruction::VRegA_30t() const {
170 DCHECK_EQ(FormatOf(Opcode()), k30t);
171 return static_cast<int32_t>(Fetch32(1));
172}
173
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200174inline uint8_t Instruction::VRegA_31c(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200175 DCHECK_EQ(FormatOf(Opcode()), k31c);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200176 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200177}
178
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200179inline uint8_t Instruction::VRegA_31i(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200180 DCHECK_EQ(FormatOf(Opcode()), k31i);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200181 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200182}
183
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200184inline uint8_t Instruction::VRegA_31t(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200185 DCHECK_EQ(FormatOf(Opcode()), k31t);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200186 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200187}
188
189inline uint16_t Instruction::VRegA_32x() const {
190 DCHECK_EQ(FormatOf(Opcode()), k32x);
191 return Fetch16(1);
192}
193
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200194inline uint4_t Instruction::VRegA_35c(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200195 DCHECK_EQ(FormatOf(Opcode()), k35c);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200196 return InstB(inst_data); // This is labeled A in the spec.
Sebastien Hertz807a2562013-04-15 09:33:39 +0200197}
198
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200199inline uint8_t Instruction::VRegA_3rc(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200200 DCHECK_EQ(FormatOf(Opcode()), k3rc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200201 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200202}
203
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200204inline uint8_t Instruction::VRegA_51l(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200205 DCHECK_EQ(FormatOf(Opcode()), k51l);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200206 return InstAA(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200207}
208
209//------------------------------------------------------------------------------
210// VRegB
211//------------------------------------------------------------------------------
Ian Rogers29a26482014-05-02 15:27:29 -0700212inline 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;
Igor Murashkin158f35c2015-06-10 15:55:30 -0700226 case k25x: return true;
Ian Rogers29a26482014-05-02 15:27:29 -0700227 case k31c: return true;
228 case k31i: return true;
229 case k31t: return true;
230 case k32x: return true;
231 case k35c: return true;
232 case k3rc: return true;
233 case k51l: return true;
234 default: return false;
235 }
236}
237
238inline bool Instruction::HasWideVRegB() const {
239 return FormatOf(Opcode()) == k51l;
240}
241
242inline int32_t Instruction::VRegB() const {
243 switch (FormatOf(Opcode())) {
244 case k11n: return VRegB_11n();
245 case k12x: return VRegB_12x();
246 case k21c: return VRegB_21c();
247 case k21h: return VRegB_21h();
248 case k21s: return VRegB_21s();
249 case k21t: return VRegB_21t();
250 case k22b: return VRegB_22b();
251 case k22c: return VRegB_22c();
252 case k22s: return VRegB_22s();
253 case k22t: return VRegB_22t();
254 case k22x: return VRegB_22x();
255 case k23x: return VRegB_23x();
Igor Murashkin158f35c2015-06-10 15:55:30 -0700256 case k25x: return VRegB_25x();
Ian Rogers29a26482014-05-02 15:27:29 -0700257 case k31c: return VRegB_31c();
258 case k31i: return VRegB_31i();
259 case k31t: return VRegB_31t();
260 case k32x: return VRegB_32x();
261 case k35c: return VRegB_35c();
262 case k3rc: return VRegB_3rc();
263 case k51l: return VRegB_51l();
264 default:
265 LOG(FATAL) << "Tried to access vB of instruction " << Name() << " which has no B operand.";
266 exit(EXIT_FAILURE);
267 }
268}
269
270inline uint64_t Instruction::WideVRegB() const {
271 return VRegB_51l();
272}
273
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200274inline int4_t Instruction::VRegB_11n(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200275 DCHECK_EQ(FormatOf(Opcode()), k11n);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200276 return static_cast<int4_t>((InstB(inst_data) << 28) >> 28);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200277}
278
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200279inline uint4_t Instruction::VRegB_12x(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200280 DCHECK_EQ(FormatOf(Opcode()), k12x);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200281 return InstB(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200282}
283
284inline uint16_t Instruction::VRegB_21c() const {
285 DCHECK_EQ(FormatOf(Opcode()), k21c);
286 return Fetch16(1);
287}
288
289inline uint16_t Instruction::VRegB_21h() const {
290 DCHECK_EQ(FormatOf(Opcode()), k21h);
291 return Fetch16(1);
292}
293
294inline int16_t Instruction::VRegB_21s() const {
295 DCHECK_EQ(FormatOf(Opcode()), k21s);
296 return static_cast<int16_t>(Fetch16(1));
297}
298
299inline int16_t Instruction::VRegB_21t() const {
300 DCHECK_EQ(FormatOf(Opcode()), k21t);
301 return static_cast<int16_t>(Fetch16(1));
302}
303
304inline uint8_t Instruction::VRegB_22b() const {
305 DCHECK_EQ(FormatOf(Opcode()), k22b);
306 return static_cast<uint8_t>(Fetch16(1) & 0xff);
307}
308
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200309inline uint4_t Instruction::VRegB_22c(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200310 DCHECK_EQ(FormatOf(Opcode()), k22c);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200311 return InstB(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200312}
313
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200314inline uint4_t Instruction::VRegB_22s(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200315 DCHECK_EQ(FormatOf(Opcode()), k22s);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200316 return InstB(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200317}
318
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200319inline uint4_t Instruction::VRegB_22t(uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200320 DCHECK_EQ(FormatOf(Opcode()), k22t);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200321 return InstB(inst_data);
Sebastien Hertz807a2562013-04-15 09:33:39 +0200322}
323
324inline uint16_t Instruction::VRegB_22x() const {
325 DCHECK_EQ(FormatOf(Opcode()), k22x);
326 return Fetch16(1);
327}
328
329inline uint8_t Instruction::VRegB_23x() const {
330 DCHECK_EQ(FormatOf(Opcode()), k23x);
331 return static_cast<uint8_t>(Fetch16(1) & 0xff);
332}
333
Igor Murashkin158f35c2015-06-10 15:55:30 -0700334// Number of additional registers in this instruction. # of var arg registers = this value + 1.
335inline uint4_t Instruction::VRegB_25x() const {
336 DCHECK_EQ(FormatOf(Opcode()), k25x);
337 return InstB(Fetch16(0));
338}
339
Sebastien Hertz807a2562013-04-15 09:33:39 +0200340inline uint32_t Instruction::VRegB_31c() const {
341 DCHECK_EQ(FormatOf(Opcode()), k31c);
342 return Fetch32(1);
343}
344
345inline int32_t Instruction::VRegB_31i() const {
346 DCHECK_EQ(FormatOf(Opcode()), k31i);
347 return static_cast<int32_t>(Fetch32(1));
348}
349
350inline int32_t Instruction::VRegB_31t() const {
351 DCHECK_EQ(FormatOf(Opcode()), k31t);
352 return static_cast<int32_t>(Fetch32(1));
353}
354
355inline uint16_t Instruction::VRegB_32x() const {
356 DCHECK_EQ(FormatOf(Opcode()), k32x);
357 return Fetch16(2);
358}
359
360inline uint16_t Instruction::VRegB_35c() const {
361 DCHECK_EQ(FormatOf(Opcode()), k35c);
362 return Fetch16(1);
363}
364
365inline uint16_t Instruction::VRegB_3rc() const {
366 DCHECK_EQ(FormatOf(Opcode()), k3rc);
367 return Fetch16(1);
368}
369
370inline uint64_t Instruction::VRegB_51l() const {
371 DCHECK_EQ(FormatOf(Opcode()), k51l);
372 uint64_t vB_wide = Fetch32(1) | ((uint64_t) Fetch32(3) << 32);
373 return vB_wide;
374}
375
376//------------------------------------------------------------------------------
377// VRegC
378//------------------------------------------------------------------------------
Ian Rogers29a26482014-05-02 15:27:29 -0700379inline bool Instruction::HasVRegC() const {
380 switch (FormatOf(Opcode())) {
381 case k22b: return true;
382 case k22c: return true;
383 case k22s: return true;
384 case k22t: return true;
385 case k23x: return true;
Igor Murashkin158f35c2015-06-10 15:55:30 -0700386 case k25x: return true;
Ian Rogers29a26482014-05-02 15:27:29 -0700387 case k35c: return true;
388 case k3rc: return true;
389 default: return false;
390 }
391}
392
393inline int32_t Instruction::VRegC() const {
394 switch (FormatOf(Opcode())) {
395 case k22b: return VRegC_22b();
396 case k22c: return VRegC_22c();
397 case k22s: return VRegC_22s();
398 case k22t: return VRegC_22t();
399 case k23x: return VRegC_23x();
Igor Murashkin158f35c2015-06-10 15:55:30 -0700400 case k25x: return VRegC_25x();
Ian Rogers29a26482014-05-02 15:27:29 -0700401 case k35c: return VRegC_35c();
402 case k3rc: return VRegC_3rc();
403 default:
404 LOG(FATAL) << "Tried to access vC of instruction " << Name() << " which has no C operand.";
405 exit(EXIT_FAILURE);
406 }
407}
408
Sebastien Hertz807a2562013-04-15 09:33:39 +0200409inline int8_t Instruction::VRegC_22b() const {
410 DCHECK_EQ(FormatOf(Opcode()), k22b);
411 return static_cast<int8_t>(Fetch16(1) >> 8);
412}
413
414inline uint16_t Instruction::VRegC_22c() const {
415 DCHECK_EQ(FormatOf(Opcode()), k22c);
416 return Fetch16(1);
417}
418
419inline int16_t Instruction::VRegC_22s() const {
420 DCHECK_EQ(FormatOf(Opcode()), k22s);
421 return static_cast<int16_t>(Fetch16(1));
422}
423
424inline int16_t Instruction::VRegC_22t() const {
425 DCHECK_EQ(FormatOf(Opcode()), k22t);
426 return static_cast<int16_t>(Fetch16(1));
427}
428
429inline uint8_t Instruction::VRegC_23x() const {
430 DCHECK_EQ(FormatOf(Opcode()), k23x);
431 return static_cast<uint8_t>(Fetch16(1) >> 8);
432}
433
Igor Murashkin158f35c2015-06-10 15:55:30 -0700434inline uint4_t Instruction::VRegC_25x() const {
435 DCHECK_EQ(FormatOf(Opcode()), k25x);
436 return static_cast<uint4_t>(Fetch16(1) & 0xf);
437}
438
Sebastien Hertz807a2562013-04-15 09:33:39 +0200439inline uint4_t Instruction::VRegC_35c() const {
440 DCHECK_EQ(FormatOf(Opcode()), k35c);
441 return static_cast<uint4_t>(Fetch16(2) & 0x0f);
442}
443
444inline uint16_t Instruction::VRegC_3rc() const {
445 DCHECK_EQ(FormatOf(Opcode()), k3rc);
446 return Fetch16(2);
447}
448
Igor Murashkin158f35c2015-06-10 15:55:30 -0700449inline bool Instruction::HasVarArgs35c() const {
Ian Rogers29a26482014-05-02 15:27:29 -0700450 return FormatOf(Opcode()) == k35c;
451}
452
Igor Murashkin158f35c2015-06-10 15:55:30 -0700453inline bool Instruction::HasVarArgs25x() const {
454 return FormatOf(Opcode()) == k25x;
455}
456
Igor Murashkin6918bf12015-09-27 19:19:06 -0700457// Copies all of the parameter registers into the arg array. Check the length with VRegB_25x()+2.
458inline void Instruction::GetAllArgs25x(uint32_t (&arg)[kMaxVarArgRegs25x]) const {
Igor Murashkin158f35c2015-06-10 15:55:30 -0700459 DCHECK_EQ(FormatOf(Opcode()), k25x);
460
461 /*
462 * The opcode looks like this:
463 * op vC, {vD, vE, vF, vG}
464 *
465 * and vB is the (implicit) register count (0-4) which denotes how far from vD to vG to read.
466 *
467 * vC is always present, so with "op vC, {}" the register count will be 0 even though vC
468 * is valid.
469 *
470 * The exact semantic meanings of vC:vG is up to the instruction using the format.
471 *
472 * Encoding drawing as a bit stream:
473 * (Note that each uint16 is little endian, and each register takes up 4 bits)
474 *
475 * uint16 ||| uint16
476 * 7-0 15-8 7-0 15-8
477 * |------|-----|||-----|-----|
478 * |opcode|vB|vG|||vD|vC|vF|vE|
479 * |------|-----|||-----|-----|
480 */
481 uint16_t reg_list = Fetch16(1);
482 uint4_t count = VRegB_25x();
483 DCHECK_LE(count, 4U) << "Invalid arg count in 25x (" << count << ")";
484
485 /*
486 * TODO(iam): Change instruction encoding to one of:
487 *
488 * - (X) vA = args count, vB = closure register, {vC..vG} = args (25x)
489 * - (Y) vA = args count, vB = method index, {vC..vG} = args (35x)
490 *
491 * (do this in conjunction with adding verifier support for invoke-lambda)
492 */
493
494 /*
495 * Copy the argument registers into the arg[] array, and
496 * also copy the first argument into vC. (The
497 * DecodedInstruction structure doesn't have separate
498 * fields for {vD, vE, vF, vG}, so there's no need to make
499 * copies of those.) Note that all cases fall-through.
500 */
501 switch (count) {
502 case 4:
Igor Murashkin6918bf12015-09-27 19:19:06 -0700503 arg[5] = (Fetch16(0) >> 8) & 0x0f; // vG
Igor Murashkin158f35c2015-06-10 15:55:30 -0700504 FALLTHROUGH_INTENDED;
505 case 3:
Igor Murashkin6918bf12015-09-27 19:19:06 -0700506 arg[4] = (reg_list >> 12) & 0x0f; // vF
Igor Murashkin158f35c2015-06-10 15:55:30 -0700507 FALLTHROUGH_INTENDED;
508 case 2:
Igor Murashkin6918bf12015-09-27 19:19:06 -0700509 arg[3] = (reg_list >> 8) & 0x0f; // vE
Igor Murashkin158f35c2015-06-10 15:55:30 -0700510 FALLTHROUGH_INTENDED;
511 case 1:
Igor Murashkin6918bf12015-09-27 19:19:06 -0700512 arg[2] = (reg_list >> 4) & 0x0f; // vD
Igor Murashkin158f35c2015-06-10 15:55:30 -0700513 FALLTHROUGH_INTENDED;
514 default: // case 0
Igor Murashkin6918bf12015-09-27 19:19:06 -0700515 // The required lambda 'this' is actually a pair, but the pair is implicit.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700516 arg[0] = VRegC_25x(); // vC
Igor Murashkin6918bf12015-09-27 19:19:06 -0700517 arg[1] = arg[0] + 1; // vC + 1
Igor Murashkin158f35c2015-06-10 15:55:30 -0700518 break;
519 }
520}
521
522inline void Instruction::GetVarArgs(uint32_t arg[kMaxVarArgRegs], uint16_t inst_data) const {
Sebastien Hertz807a2562013-04-15 09:33:39 +0200523 DCHECK_EQ(FormatOf(Opcode()), k35c);
524
525 /*
526 * Note that the fields mentioned in the spec don't appear in
527 * their "usual" positions here compared to most formats. This
528 * was done so that the field names for the argument count and
529 * reference index match between this format and the corresponding
530 * range formats (3rc and friends).
531 *
532 * Bottom line: The argument count is always in vA, and the
533 * method constant (or equivalent) is always in vB.
534 */
535 uint16_t regList = Fetch16(2);
Sebastien Hertzc61124b2013-09-10 11:44:19 +0200536 uint4_t count = InstB(inst_data); // This is labeled A in the spec.
537 DCHECK_LE(count, 5U) << "Invalid arg count in 35c (" << count << ")";
Sebastien Hertz807a2562013-04-15 09:33:39 +0200538
539 /*
540 * Copy the argument registers into the arg[] array, and
541 * also copy the first argument (if any) into vC. (The
542 * DecodedInstruction structure doesn't have separate
543 * fields for {vD, vE, vF, vG}, so there's no need to make
544 * copies of those.) Note that cases 5..2 fall through.
545 */
546 switch (count) {
Ian Rogersfc787ec2014-10-09 21:56:44 -0700547 case 5:
548 arg[4] = InstA(inst_data);
549 FALLTHROUGH_INTENDED;
550 case 4:
551 arg[3] = (regList >> 12) & 0x0f;
552 FALLTHROUGH_INTENDED;
553 case 3:
554 arg[2] = (regList >> 8) & 0x0f;
555 FALLTHROUGH_INTENDED;
556 case 2:
557 arg[1] = (regList >> 4) & 0x0f;
558 FALLTHROUGH_INTENDED;
559 case 1:
560 arg[0] = regList & 0x0f;
561 break;
Sebastien Hertzc61124b2013-09-10 11:44:19 +0200562 default: // case 0
563 break; // Valid, but no need to do anything.
Sebastien Hertz807a2562013-04-15 09:33:39 +0200564 }
565}
566
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700567} // namespace art
Sebastien Hertz807a2562013-04-15 09:33:39 +0200568
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700569#endif // ART_RUNTIME_DEX_INSTRUCTION_INL_H_