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 //------------------------------------------------------------------------------
VRegA_10t()27 inline int8_t Instruction::VRegA_10t() const {
28 DCHECK_EQ(FormatOf(Opcode()), k10t);
29 return static_cast<int8_t>(InstAA());
30 }
31
VRegA_10x()32 inline uint8_t Instruction::VRegA_10x() const {
33 DCHECK_EQ(FormatOf(Opcode()), k10x);
34 return InstAA();
35 }
36
VRegA_11n()37 inline uint4_t Instruction::VRegA_11n() const {
38 DCHECK_EQ(FormatOf(Opcode()), k11n);
39 return InstA();
40 }
41
VRegA_11x()42 inline uint8_t Instruction::VRegA_11x() const {
43 DCHECK_EQ(FormatOf(Opcode()), k11x);
44 return InstAA();
45 }
46
VRegA_12x()47 inline uint4_t Instruction::VRegA_12x() const {
48 DCHECK_EQ(FormatOf(Opcode()), k12x);
49 return InstA();
50 }
51
VRegA_20t()52 inline int16_t Instruction::VRegA_20t() const {
53 DCHECK_EQ(FormatOf(Opcode()), k20t);
54 return static_cast<int16_t>(Fetch16(1));
55 }
56
VRegA_21c()57 inline uint8_t Instruction::VRegA_21c() const {
58 DCHECK_EQ(FormatOf(Opcode()), k21c);
59 return InstAA();
60 }
61
VRegA_21h()62 inline uint8_t Instruction::VRegA_21h() const {
63 DCHECK_EQ(FormatOf(Opcode()), k21h);
64 return InstAA();
65 }
66
VRegA_21s()67 inline uint8_t Instruction::VRegA_21s() const {
68 DCHECK_EQ(FormatOf(Opcode()), k21s);
69 return InstAA();
70 }
71
VRegA_21t()72 inline uint8_t Instruction::VRegA_21t() const {
73 DCHECK_EQ(FormatOf(Opcode()), k21t);
74 return InstAA();
75 }
76
VRegA_22b()77 inline uint8_t Instruction::VRegA_22b() const {
78 DCHECK_EQ(FormatOf(Opcode()), k22b);
79 return InstAA();
80 }
81
VRegA_22c()82 inline uint4_t Instruction::VRegA_22c() const {
83 DCHECK_EQ(FormatOf(Opcode()), k22c);
84 return InstA();
85 }
86
VRegA_22s()87 inline uint4_t Instruction::VRegA_22s() const {
88 DCHECK_EQ(FormatOf(Opcode()), k22s);
89 return InstA();
90 }
91
VRegA_22t()92 inline uint4_t Instruction::VRegA_22t() const {
93 DCHECK_EQ(FormatOf(Opcode()), k22t);
94 return InstA();
95 }
96
VRegA_22x()97 inline uint8_t Instruction::VRegA_22x() const {
98 DCHECK_EQ(FormatOf(Opcode()), k22x);
99 return InstAA();
100 }
101
VRegA_23x()102 inline uint8_t Instruction::VRegA_23x() const {
103 DCHECK_EQ(FormatOf(Opcode()), k23x);
104 return InstAA();
105 }
106
VRegA_30t()107 inline int32_t Instruction::VRegA_30t() const {
108 DCHECK_EQ(FormatOf(Opcode()), k30t);
109 return static_cast<int32_t>(Fetch32(1));
110 }
111
VRegA_31c()112 inline uint8_t Instruction::VRegA_31c() const {
113 DCHECK_EQ(FormatOf(Opcode()), k31c);
114 return InstAA();
115 }
116
VRegA_31i()117 inline uint8_t Instruction::VRegA_31i() const {
118 DCHECK_EQ(FormatOf(Opcode()), k31i);
119 return InstAA();
120 }
121
VRegA_31t()122 inline uint8_t Instruction::VRegA_31t() const {
123 DCHECK_EQ(FormatOf(Opcode()), k31t);
124 return InstAA();
125 }
126
VRegA_32x()127 inline uint16_t Instruction::VRegA_32x() const {
128 DCHECK_EQ(FormatOf(Opcode()), k32x);
129 return Fetch16(1);
130 }
131
VRegA_35c()132 inline uint4_t Instruction::VRegA_35c() const {
133 DCHECK_EQ(FormatOf(Opcode()), k35c);
134 return InstB(); // This is labeled A in the spec.
135 }
136
VRegA_3rc()137 inline uint8_t Instruction::VRegA_3rc() const {
138 DCHECK_EQ(FormatOf(Opcode()), k3rc);
139 return InstAA();
140 }
141
VRegA_51l()142 inline uint8_t Instruction::VRegA_51l() const {
143 DCHECK_EQ(FormatOf(Opcode()), k51l);
144 return InstAA();
145 }
146
147 //------------------------------------------------------------------------------
148 // VRegB
149 //------------------------------------------------------------------------------
VRegB_11n()150 inline int4_t Instruction::VRegB_11n() const {
151 DCHECK_EQ(FormatOf(Opcode()), k11n);
152 return static_cast<int4_t>((InstB() << 28) >> 28);
153 }
154
VRegB_12x()155 inline uint4_t Instruction::VRegB_12x() const {
156 DCHECK_EQ(FormatOf(Opcode()), k12x);
157 return InstB();
158 }
159
VRegB_21c()160 inline uint16_t Instruction::VRegB_21c() const {
161 DCHECK_EQ(FormatOf(Opcode()), k21c);
162 return Fetch16(1);
163 }
164
VRegB_21h()165 inline uint16_t Instruction::VRegB_21h() const {
166 DCHECK_EQ(FormatOf(Opcode()), k21h);
167 return Fetch16(1);
168 }
169
VRegB_21s()170 inline int16_t Instruction::VRegB_21s() const {
171 DCHECK_EQ(FormatOf(Opcode()), k21s);
172 return static_cast<int16_t>(Fetch16(1));
173 }
174
VRegB_21t()175 inline int16_t Instruction::VRegB_21t() const {
176 DCHECK_EQ(FormatOf(Opcode()), k21t);
177 return static_cast<int16_t>(Fetch16(1));
178 }
179
VRegB_22b()180 inline uint8_t Instruction::VRegB_22b() const {
181 DCHECK_EQ(FormatOf(Opcode()), k22b);
182 return static_cast<uint8_t>(Fetch16(1) & 0xff);
183 }
184
VRegB_22c()185 inline uint4_t Instruction::VRegB_22c() const {
186 DCHECK_EQ(FormatOf(Opcode()), k22c);
187 return InstB();
188 }
189
VRegB_22s()190 inline uint4_t Instruction::VRegB_22s() const {
191 DCHECK_EQ(FormatOf(Opcode()), k22s);
192 return InstB();
193 }
194
VRegB_22t()195 inline uint4_t Instruction::VRegB_22t() const {
196 DCHECK_EQ(FormatOf(Opcode()), k22t);
197 return InstB();
198 }
199
VRegB_22x()200 inline uint16_t Instruction::VRegB_22x() const {
201 DCHECK_EQ(FormatOf(Opcode()), k22x);
202 return Fetch16(1);
203 }
204
VRegB_23x()205 inline uint8_t Instruction::VRegB_23x() const {
206 DCHECK_EQ(FormatOf(Opcode()), k23x);
207 return static_cast<uint8_t>(Fetch16(1) & 0xff);
208 }
209
VRegB_31c()210 inline uint32_t Instruction::VRegB_31c() const {
211 DCHECK_EQ(FormatOf(Opcode()), k31c);
212 return Fetch32(1);
213 }
214
VRegB_31i()215 inline int32_t Instruction::VRegB_31i() const {
216 DCHECK_EQ(FormatOf(Opcode()), k31i);
217 return static_cast<int32_t>(Fetch32(1));
218 }
219
VRegB_31t()220 inline int32_t Instruction::VRegB_31t() const {
221 DCHECK_EQ(FormatOf(Opcode()), k31t);
222 return static_cast<int32_t>(Fetch32(1));
223 }
224
VRegB_32x()225 inline uint16_t Instruction::VRegB_32x() const {
226 DCHECK_EQ(FormatOf(Opcode()), k32x);
227 return Fetch16(2);
228 }
229
VRegB_35c()230 inline uint16_t Instruction::VRegB_35c() const {
231 DCHECK_EQ(FormatOf(Opcode()), k35c);
232 return Fetch16(1);
233 }
234
VRegB_3rc()235 inline uint16_t Instruction::VRegB_3rc() const {
236 DCHECK_EQ(FormatOf(Opcode()), k3rc);
237 return Fetch16(1);
238 }
239
VRegB_51l()240 inline uint64_t Instruction::VRegB_51l() const {
241 DCHECK_EQ(FormatOf(Opcode()), k51l);
242 uint64_t vB_wide = Fetch32(1) | ((uint64_t) Fetch32(3) << 32);
243 return vB_wide;
244 }
245
246 //------------------------------------------------------------------------------
247 // VRegC
248 //------------------------------------------------------------------------------
VRegC_22b()249 inline int8_t Instruction::VRegC_22b() const {
250 DCHECK_EQ(FormatOf(Opcode()), k22b);
251 return static_cast<int8_t>(Fetch16(1) >> 8);
252 }
253
VRegC_22c()254 inline uint16_t Instruction::VRegC_22c() const {
255 DCHECK_EQ(FormatOf(Opcode()), k22c);
256 return Fetch16(1);
257 }
258
VRegC_22s()259 inline int16_t Instruction::VRegC_22s() const {
260 DCHECK_EQ(FormatOf(Opcode()), k22s);
261 return static_cast<int16_t>(Fetch16(1));
262 }
263
VRegC_22t()264 inline int16_t Instruction::VRegC_22t() const {
265 DCHECK_EQ(FormatOf(Opcode()), k22t);
266 return static_cast<int16_t>(Fetch16(1));
267 }
268
VRegC_23x()269 inline uint8_t Instruction::VRegC_23x() const {
270 DCHECK_EQ(FormatOf(Opcode()), k23x);
271 return static_cast<uint8_t>(Fetch16(1) >> 8);
272 }
273
VRegC_35c()274 inline uint4_t Instruction::VRegC_35c() const {
275 DCHECK_EQ(FormatOf(Opcode()), k35c);
276 return static_cast<uint4_t>(Fetch16(2) & 0x0f);
277 }
278
VRegC_3rc()279 inline uint16_t Instruction::VRegC_3rc() const {
280 DCHECK_EQ(FormatOf(Opcode()), k3rc);
281 return Fetch16(2);
282 }
283
GetArgs(uint32_t arg[5])284 inline void Instruction::GetArgs(uint32_t arg[5]) const {
285 DCHECK_EQ(FormatOf(Opcode()), k35c);
286
287 /*
288 * Note that the fields mentioned in the spec don't appear in
289 * their "usual" positions here compared to most formats. This
290 * was done so that the field names for the argument count and
291 * reference index match between this format and the corresponding
292 * range formats (3rc and friends).
293 *
294 * Bottom line: The argument count is always in vA, and the
295 * method constant (or equivalent) is always in vB.
296 */
297 uint16_t regList = Fetch16(2);
298 uint4_t count = InstB(); // This is labeled A in the spec.
299
300 /*
301 * Copy the argument registers into the arg[] array, and
302 * also copy the first argument (if any) into vC. (The
303 * DecodedInstruction structure doesn't have separate
304 * fields for {vD, vE, vF, vG}, so there's no need to make
305 * copies of those.) Note that cases 5..2 fall through.
306 */
307 switch (count) {
308 case 5: arg[4] = InstA();
309 case 4: arg[3] = (regList >> 12) & 0x0f;
310 case 3: arg[2] = (regList >> 8) & 0x0f;
311 case 2: arg[1] = (regList >> 4) & 0x0f;
312 case 1: arg[0] = regList & 0x0f; break;
313 case 0: break; // Valid, but no need to do anything.
314 default:
315 LOG(ERROR) << "Invalid arg count in 35c (" << count << ")";
316 return;
317 }
318 }
319
320 } // namespace art
321
322 #endif // ART_RUNTIME_DEX_INSTRUCTION_INL_H_
323