1 /*
2 * Copyright (C) 2014 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 #include "assembler_arm32.h"
18
19 #include "base/logging.h"
20 #include "entrypoints/quick/quick_entrypoints.h"
21 #include "offsets.h"
22 #include "thread.h"
23 #include "utils.h"
24
25 namespace art {
26 namespace arm {
27
and_(Register rd,Register rn,const ShifterOperand & so,Condition cond)28 void Arm32Assembler::and_(Register rd, Register rn, const ShifterOperand& so,
29 Condition cond) {
30 EmitType01(cond, so.type(), AND, 0, rn, rd, so);
31 }
32
33
eor(Register rd,Register rn,const ShifterOperand & so,Condition cond)34 void Arm32Assembler::eor(Register rd, Register rn, const ShifterOperand& so,
35 Condition cond) {
36 EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
37 }
38
39
sub(Register rd,Register rn,const ShifterOperand & so,Condition cond)40 void Arm32Assembler::sub(Register rd, Register rn, const ShifterOperand& so,
41 Condition cond) {
42 EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
43 }
44
rsb(Register rd,Register rn,const ShifterOperand & so,Condition cond)45 void Arm32Assembler::rsb(Register rd, Register rn, const ShifterOperand& so,
46 Condition cond) {
47 EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
48 }
49
rsbs(Register rd,Register rn,const ShifterOperand & so,Condition cond)50 void Arm32Assembler::rsbs(Register rd, Register rn, const ShifterOperand& so,
51 Condition cond) {
52 EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
53 }
54
55
add(Register rd,Register rn,const ShifterOperand & so,Condition cond)56 void Arm32Assembler::add(Register rd, Register rn, const ShifterOperand& so,
57 Condition cond) {
58 EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
59 }
60
61
adds(Register rd,Register rn,const ShifterOperand & so,Condition cond)62 void Arm32Assembler::adds(Register rd, Register rn, const ShifterOperand& so,
63 Condition cond) {
64 EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
65 }
66
67
subs(Register rd,Register rn,const ShifterOperand & so,Condition cond)68 void Arm32Assembler::subs(Register rd, Register rn, const ShifterOperand& so,
69 Condition cond) {
70 EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
71 }
72
73
adc(Register rd,Register rn,const ShifterOperand & so,Condition cond)74 void Arm32Assembler::adc(Register rd, Register rn, const ShifterOperand& so,
75 Condition cond) {
76 EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
77 }
78
79
sbc(Register rd,Register rn,const ShifterOperand & so,Condition cond)80 void Arm32Assembler::sbc(Register rd, Register rn, const ShifterOperand& so,
81 Condition cond) {
82 EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
83 }
84
85
rsc(Register rd,Register rn,const ShifterOperand & so,Condition cond)86 void Arm32Assembler::rsc(Register rd, Register rn, const ShifterOperand& so,
87 Condition cond) {
88 EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
89 }
90
91
tst(Register rn,const ShifterOperand & so,Condition cond)92 void Arm32Assembler::tst(Register rn, const ShifterOperand& so, Condition cond) {
93 CHECK_NE(rn, PC); // Reserve tst pc instruction for exception handler marker.
94 EmitType01(cond, so.type(), TST, 1, rn, R0, so);
95 }
96
97
teq(Register rn,const ShifterOperand & so,Condition cond)98 void Arm32Assembler::teq(Register rn, const ShifterOperand& so, Condition cond) {
99 CHECK_NE(rn, PC); // Reserve teq pc instruction for exception handler marker.
100 EmitType01(cond, so.type(), TEQ, 1, rn, R0, so);
101 }
102
103
cmp(Register rn,const ShifterOperand & so,Condition cond)104 void Arm32Assembler::cmp(Register rn, const ShifterOperand& so, Condition cond) {
105 EmitType01(cond, so.type(), CMP, 1, rn, R0, so);
106 }
107
108
cmn(Register rn,const ShifterOperand & so,Condition cond)109 void Arm32Assembler::cmn(Register rn, const ShifterOperand& so, Condition cond) {
110 EmitType01(cond, so.type(), CMN, 1, rn, R0, so);
111 }
112
113
orr(Register rd,Register rn,const ShifterOperand & so,Condition cond)114 void Arm32Assembler::orr(Register rd, Register rn,
115 const ShifterOperand& so, Condition cond) {
116 EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
117 }
118
119
orrs(Register rd,Register rn,const ShifterOperand & so,Condition cond)120 void Arm32Assembler::orrs(Register rd, Register rn,
121 const ShifterOperand& so, Condition cond) {
122 EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
123 }
124
125
mov(Register rd,const ShifterOperand & so,Condition cond)126 void Arm32Assembler::mov(Register rd, const ShifterOperand& so, Condition cond) {
127 EmitType01(cond, so.type(), MOV, 0, R0, rd, so);
128 }
129
130
movs(Register rd,const ShifterOperand & so,Condition cond)131 void Arm32Assembler::movs(Register rd, const ShifterOperand& so, Condition cond) {
132 EmitType01(cond, so.type(), MOV, 1, R0, rd, so);
133 }
134
135
bic(Register rd,Register rn,const ShifterOperand & so,Condition cond)136 void Arm32Assembler::bic(Register rd, Register rn, const ShifterOperand& so,
137 Condition cond) {
138 EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
139 }
140
141
mvn(Register rd,const ShifterOperand & so,Condition cond)142 void Arm32Assembler::mvn(Register rd, const ShifterOperand& so, Condition cond) {
143 EmitType01(cond, so.type(), MVN, 0, R0, rd, so);
144 }
145
146
mvns(Register rd,const ShifterOperand & so,Condition cond)147 void Arm32Assembler::mvns(Register rd, const ShifterOperand& so, Condition cond) {
148 EmitType01(cond, so.type(), MVN, 1, R0, rd, so);
149 }
150
151
mul(Register rd,Register rn,Register rm,Condition cond)152 void Arm32Assembler::mul(Register rd, Register rn, Register rm, Condition cond) {
153 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
154 EmitMulOp(cond, 0, R0, rd, rn, rm);
155 }
156
157
mla(Register rd,Register rn,Register rm,Register ra,Condition cond)158 void Arm32Assembler::mla(Register rd, Register rn, Register rm, Register ra,
159 Condition cond) {
160 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
161 EmitMulOp(cond, B21, ra, rd, rn, rm);
162 }
163
164
mls(Register rd,Register rn,Register rm,Register ra,Condition cond)165 void Arm32Assembler::mls(Register rd, Register rn, Register rm, Register ra,
166 Condition cond) {
167 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
168 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
169 }
170
171
umull(Register rd_lo,Register rd_hi,Register rn,Register rm,Condition cond)172 void Arm32Assembler::umull(Register rd_lo, Register rd_hi, Register rn,
173 Register rm, Condition cond) {
174 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
175 EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
176 }
177
178
sdiv(Register rd,Register rn,Register rm,Condition cond)179 void Arm32Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) {
180 CHECK_NE(rd, kNoRegister);
181 CHECK_NE(rn, kNoRegister);
182 CHECK_NE(rm, kNoRegister);
183 CHECK_NE(cond, kNoCondition);
184 int32_t encoding = B26 | B25 | B24 | B20 |
185 B15 | B14 | B13 | B12 |
186 (static_cast<int32_t>(cond) << kConditionShift) |
187 (static_cast<int32_t>(rn) << 0) |
188 (static_cast<int32_t>(rd) << 16) |
189 (static_cast<int32_t>(rm) << 8) |
190 B4;
191 Emit(encoding);
192 }
193
194
udiv(Register rd,Register rn,Register rm,Condition cond)195 void Arm32Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) {
196 CHECK_NE(rd, kNoRegister);
197 CHECK_NE(rn, kNoRegister);
198 CHECK_NE(rm, kNoRegister);
199 CHECK_NE(cond, kNoCondition);
200 int32_t encoding = B26 | B25 | B24 | B21 | B20 |
201 B15 | B14 | B13 | B12 |
202 (static_cast<int32_t>(cond) << kConditionShift) |
203 (static_cast<int32_t>(rn) << 0) |
204 (static_cast<int32_t>(rd) << 16) |
205 (static_cast<int32_t>(rm) << 8) |
206 B4;
207 Emit(encoding);
208 }
209
210
ldr(Register rd,const Address & ad,Condition cond)211 void Arm32Assembler::ldr(Register rd, const Address& ad, Condition cond) {
212 EmitMemOp(cond, true, false, rd, ad);
213 }
214
215
str(Register rd,const Address & ad,Condition cond)216 void Arm32Assembler::str(Register rd, const Address& ad, Condition cond) {
217 EmitMemOp(cond, false, false, rd, ad);
218 }
219
220
ldrb(Register rd,const Address & ad,Condition cond)221 void Arm32Assembler::ldrb(Register rd, const Address& ad, Condition cond) {
222 EmitMemOp(cond, true, true, rd, ad);
223 }
224
225
strb(Register rd,const Address & ad,Condition cond)226 void Arm32Assembler::strb(Register rd, const Address& ad, Condition cond) {
227 EmitMemOp(cond, false, true, rd, ad);
228 }
229
230
ldrh(Register rd,const Address & ad,Condition cond)231 void Arm32Assembler::ldrh(Register rd, const Address& ad, Condition cond) {
232 EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad);
233 }
234
235
strh(Register rd,const Address & ad,Condition cond)236 void Arm32Assembler::strh(Register rd, const Address& ad, Condition cond) {
237 EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad);
238 }
239
240
ldrsb(Register rd,const Address & ad,Condition cond)241 void Arm32Assembler::ldrsb(Register rd, const Address& ad, Condition cond) {
242 EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad);
243 }
244
245
ldrsh(Register rd,const Address & ad,Condition cond)246 void Arm32Assembler::ldrsh(Register rd, const Address& ad, Condition cond) {
247 EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad);
248 }
249
250
ldrd(Register rd,const Address & ad,Condition cond)251 void Arm32Assembler::ldrd(Register rd, const Address& ad, Condition cond) {
252 CHECK_EQ(rd % 2, 0);
253 EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad);
254 }
255
256
strd(Register rd,const Address & ad,Condition cond)257 void Arm32Assembler::strd(Register rd, const Address& ad, Condition cond) {
258 CHECK_EQ(rd % 2, 0);
259 EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad);
260 }
261
262
ldm(BlockAddressMode am,Register base,RegList regs,Condition cond)263 void Arm32Assembler::ldm(BlockAddressMode am,
264 Register base,
265 RegList regs,
266 Condition cond) {
267 EmitMultiMemOp(cond, am, true, base, regs);
268 }
269
270
stm(BlockAddressMode am,Register base,RegList regs,Condition cond)271 void Arm32Assembler::stm(BlockAddressMode am,
272 Register base,
273 RegList regs,
274 Condition cond) {
275 EmitMultiMemOp(cond, am, false, base, regs);
276 }
277
278
vmovs(SRegister sd,SRegister sm,Condition cond)279 void Arm32Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
280 EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
281 }
282
283
vmovd(DRegister dd,DRegister dm,Condition cond)284 void Arm32Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
285 EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
286 }
287
288
vmovs(SRegister sd,float s_imm,Condition cond)289 bool Arm32Assembler::vmovs(SRegister sd, float s_imm, Condition cond) {
290 uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
291 if (((imm32 & ((1 << 19) - 1)) == 0) &&
292 ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
293 (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
294 uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
295 ((imm32 >> 19) & ((1 << 6) -1));
296 EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
297 sd, S0, S0);
298 return true;
299 }
300 return false;
301 }
302
303
vmovd(DRegister dd,double d_imm,Condition cond)304 bool Arm32Assembler::vmovd(DRegister dd, double d_imm, Condition cond) {
305 uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
306 if (((imm64 & ((1LL << 48) - 1)) == 0) &&
307 ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
308 (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
309 uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
310 ((imm64 >> 48) & ((1 << 6) -1));
311 EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
312 dd, D0, D0);
313 return true;
314 }
315 return false;
316 }
317
318
vadds(SRegister sd,SRegister sn,SRegister sm,Condition cond)319 void Arm32Assembler::vadds(SRegister sd, SRegister sn, SRegister sm,
320 Condition cond) {
321 EmitVFPsss(cond, B21 | B20, sd, sn, sm);
322 }
323
324
vaddd(DRegister dd,DRegister dn,DRegister dm,Condition cond)325 void Arm32Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
326 Condition cond) {
327 EmitVFPddd(cond, B21 | B20, dd, dn, dm);
328 }
329
330
vsubs(SRegister sd,SRegister sn,SRegister sm,Condition cond)331 void Arm32Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
332 Condition cond) {
333 EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
334 }
335
336
vsubd(DRegister dd,DRegister dn,DRegister dm,Condition cond)337 void Arm32Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
338 Condition cond) {
339 EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
340 }
341
342
vmuls(SRegister sd,SRegister sn,SRegister sm,Condition cond)343 void Arm32Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
344 Condition cond) {
345 EmitVFPsss(cond, B21, sd, sn, sm);
346 }
347
348
vmuld(DRegister dd,DRegister dn,DRegister dm,Condition cond)349 void Arm32Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
350 Condition cond) {
351 EmitVFPddd(cond, B21, dd, dn, dm);
352 }
353
354
vmlas(SRegister sd,SRegister sn,SRegister sm,Condition cond)355 void Arm32Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
356 Condition cond) {
357 EmitVFPsss(cond, 0, sd, sn, sm);
358 }
359
360
vmlad(DRegister dd,DRegister dn,DRegister dm,Condition cond)361 void Arm32Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
362 Condition cond) {
363 EmitVFPddd(cond, 0, dd, dn, dm);
364 }
365
366
vmlss(SRegister sd,SRegister sn,SRegister sm,Condition cond)367 void Arm32Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
368 Condition cond) {
369 EmitVFPsss(cond, B6, sd, sn, sm);
370 }
371
372
vmlsd(DRegister dd,DRegister dn,DRegister dm,Condition cond)373 void Arm32Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
374 Condition cond) {
375 EmitVFPddd(cond, B6, dd, dn, dm);
376 }
377
378
vdivs(SRegister sd,SRegister sn,SRegister sm,Condition cond)379 void Arm32Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
380 Condition cond) {
381 EmitVFPsss(cond, B23, sd, sn, sm);
382 }
383
384
vdivd(DRegister dd,DRegister dn,DRegister dm,Condition cond)385 void Arm32Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
386 Condition cond) {
387 EmitVFPddd(cond, B23, dd, dn, dm);
388 }
389
390
vabss(SRegister sd,SRegister sm,Condition cond)391 void Arm32Assembler::vabss(SRegister sd, SRegister sm, Condition cond) {
392 EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
393 }
394
395
vabsd(DRegister dd,DRegister dm,Condition cond)396 void Arm32Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
397 EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
398 }
399
400
vnegs(SRegister sd,SRegister sm,Condition cond)401 void Arm32Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
402 EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
403 }
404
405
vnegd(DRegister dd,DRegister dm,Condition cond)406 void Arm32Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
407 EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
408 }
409
410
vsqrts(SRegister sd,SRegister sm,Condition cond)411 void Arm32Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
412 EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
413 }
414
vsqrtd(DRegister dd,DRegister dm,Condition cond)415 void Arm32Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
416 EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
417 }
418
419
vcvtsd(SRegister sd,DRegister dm,Condition cond)420 void Arm32Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
421 EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
422 }
423
424
vcvtds(DRegister dd,SRegister sm,Condition cond)425 void Arm32Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
426 EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
427 }
428
429
vcvtis(SRegister sd,SRegister sm,Condition cond)430 void Arm32Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
431 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
432 }
433
434
vcvtid(SRegister sd,DRegister dm,Condition cond)435 void Arm32Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
436 EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
437 }
438
439
vcvtsi(SRegister sd,SRegister sm,Condition cond)440 void Arm32Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
441 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
442 }
443
444
vcvtdi(DRegister dd,SRegister sm,Condition cond)445 void Arm32Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
446 EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
447 }
448
449
vcvtus(SRegister sd,SRegister sm,Condition cond)450 void Arm32Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
451 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
452 }
453
454
vcvtud(SRegister sd,DRegister dm,Condition cond)455 void Arm32Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
456 EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
457 }
458
459
vcvtsu(SRegister sd,SRegister sm,Condition cond)460 void Arm32Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
461 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
462 }
463
464
vcvtdu(DRegister dd,SRegister sm,Condition cond)465 void Arm32Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
466 EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
467 }
468
469
vcmps(SRegister sd,SRegister sm,Condition cond)470 void Arm32Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
471 EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
472 }
473
474
vcmpd(DRegister dd,DRegister dm,Condition cond)475 void Arm32Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
476 EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
477 }
478
479
vcmpsz(SRegister sd,Condition cond)480 void Arm32Assembler::vcmpsz(SRegister sd, Condition cond) {
481 EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
482 }
483
484
vcmpdz(DRegister dd,Condition cond)485 void Arm32Assembler::vcmpdz(DRegister dd, Condition cond) {
486 EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
487 }
488
b(Label * label,Condition cond)489 void Arm32Assembler::b(Label* label, Condition cond) {
490 EmitBranch(cond, label, false);
491 }
492
493
bl(Label * label,Condition cond)494 void Arm32Assembler::bl(Label* label, Condition cond) {
495 EmitBranch(cond, label, true);
496 }
497
498
MarkExceptionHandler(Label * label)499 void Arm32Assembler::MarkExceptionHandler(Label* label) {
500 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
501 Label l;
502 b(&l);
503 EmitBranch(AL, label, false);
504 Bind(&l);
505 }
506
507
Emit(int32_t value)508 void Arm32Assembler::Emit(int32_t value) {
509 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
510 buffer_.Emit<int32_t>(value);
511 }
512
513
EmitType01(Condition cond,int type,Opcode opcode,int set_cc,Register rn,Register rd,const ShifterOperand & so)514 void Arm32Assembler::EmitType01(Condition cond,
515 int type,
516 Opcode opcode,
517 int set_cc,
518 Register rn,
519 Register rd,
520 const ShifterOperand& so) {
521 CHECK_NE(rd, kNoRegister);
522 CHECK_NE(cond, kNoCondition);
523 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
524 type << kTypeShift |
525 static_cast<int32_t>(opcode) << kOpcodeShift |
526 set_cc << kSShift |
527 static_cast<int32_t>(rn) << kRnShift |
528 static_cast<int32_t>(rd) << kRdShift |
529 so.encodingArm();
530 Emit(encoding);
531 }
532
533
EmitType5(Condition cond,int offset,bool link)534 void Arm32Assembler::EmitType5(Condition cond, int offset, bool link) {
535 CHECK_NE(cond, kNoCondition);
536 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
537 5 << kTypeShift |
538 (link ? 1 : 0) << kLinkShift;
539 Emit(Arm32Assembler::EncodeBranchOffset(offset, encoding));
540 }
541
542
EmitMemOp(Condition cond,bool load,bool byte,Register rd,const Address & ad)543 void Arm32Assembler::EmitMemOp(Condition cond,
544 bool load,
545 bool byte,
546 Register rd,
547 const Address& ad) {
548 CHECK_NE(rd, kNoRegister);
549 CHECK_NE(cond, kNoCondition);
550 const Address& addr = static_cast<const Address&>(ad);
551
552 int32_t encoding = 0;
553 if (!ad.IsImmediate() && ad.GetRegisterOffset() == PC) {
554 // PC relative LDR(literal)
555 int32_t offset = ad.GetOffset();
556 int32_t u = B23;
557 if (offset < 0) {
558 offset = -offset;
559 u = 0;
560 }
561 CHECK_LT(offset, (1 << 12));
562 encoding = (static_cast<int32_t>(cond) << kConditionShift) |
563 B26 | B24 | u | B20 |
564 (load ? L : 0) |
565 (byte ? B : 0) |
566 (static_cast<int32_t>(rd) << kRdShift) |
567 0xf << 16 |
568 (offset & 0xfff);
569
570 } else {
571 encoding = (static_cast<int32_t>(cond) << kConditionShift) |
572 B26 |
573 (load ? L : 0) |
574 (byte ? B : 0) |
575 (static_cast<int32_t>(rd) << kRdShift) |
576 addr.encodingArm();
577 }
578 Emit(encoding);
579 }
580
581
EmitMemOpAddressMode3(Condition cond,int32_t mode,Register rd,const Address & ad)582 void Arm32Assembler::EmitMemOpAddressMode3(Condition cond,
583 int32_t mode,
584 Register rd,
585 const Address& ad) {
586 CHECK_NE(rd, kNoRegister);
587 CHECK_NE(cond, kNoCondition);
588 const Address& addr = static_cast<const Address&>(ad);
589 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
590 B22 |
591 mode |
592 (static_cast<int32_t>(rd) << kRdShift) |
593 addr.encoding3();
594 Emit(encoding);
595 }
596
597
EmitMultiMemOp(Condition cond,BlockAddressMode am,bool load,Register base,RegList regs)598 void Arm32Assembler::EmitMultiMemOp(Condition cond,
599 BlockAddressMode am,
600 bool load,
601 Register base,
602 RegList regs) {
603 CHECK_NE(base, kNoRegister);
604 CHECK_NE(cond, kNoCondition);
605 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
606 B27 |
607 am |
608 (load ? L : 0) |
609 (static_cast<int32_t>(base) << kRnShift) |
610 regs;
611 Emit(encoding);
612 }
613
614
EmitShiftImmediate(Condition cond,Shift opcode,Register rd,Register rm,const ShifterOperand & so)615 void Arm32Assembler::EmitShiftImmediate(Condition cond,
616 Shift opcode,
617 Register rd,
618 Register rm,
619 const ShifterOperand& so) {
620 CHECK_NE(cond, kNoCondition);
621 CHECK(so.IsImmediate());
622 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
623 static_cast<int32_t>(MOV) << kOpcodeShift |
624 static_cast<int32_t>(rd) << kRdShift |
625 so.encodingArm() << kShiftImmShift |
626 static_cast<int32_t>(opcode) << kShiftShift |
627 static_cast<int32_t>(rm);
628 Emit(encoding);
629 }
630
631
EmitShiftRegister(Condition cond,Shift opcode,Register rd,Register rm,const ShifterOperand & so)632 void Arm32Assembler::EmitShiftRegister(Condition cond,
633 Shift opcode,
634 Register rd,
635 Register rm,
636 const ShifterOperand& so) {
637 CHECK_NE(cond, kNoCondition);
638 CHECK(so.IsRegister());
639 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
640 static_cast<int32_t>(MOV) << kOpcodeShift |
641 static_cast<int32_t>(rd) << kRdShift |
642 so.encodingArm() << kShiftRegisterShift |
643 static_cast<int32_t>(opcode) << kShiftShift |
644 B4 |
645 static_cast<int32_t>(rm);
646 Emit(encoding);
647 }
648
649
EmitBranch(Condition cond,Label * label,bool link)650 void Arm32Assembler::EmitBranch(Condition cond, Label* label, bool link) {
651 if (label->IsBound()) {
652 EmitType5(cond, label->Position() - buffer_.Size(), link);
653 } else {
654 int position = buffer_.Size();
655 // Use the offset field of the branch instruction for linking the sites.
656 EmitType5(cond, label->position_, link);
657 label->LinkTo(position);
658 }
659 }
660
661
clz(Register rd,Register rm,Condition cond)662 void Arm32Assembler::clz(Register rd, Register rm, Condition cond) {
663 CHECK_NE(rd, kNoRegister);
664 CHECK_NE(rm, kNoRegister);
665 CHECK_NE(cond, kNoCondition);
666 CHECK_NE(rd, PC);
667 CHECK_NE(rm, PC);
668 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
669 B24 | B22 | B21 | (0xf << 16) |
670 (static_cast<int32_t>(rd) << kRdShift) |
671 (0xf << 8) | B4 | static_cast<int32_t>(rm);
672 Emit(encoding);
673 }
674
675
movw(Register rd,uint16_t imm16,Condition cond)676 void Arm32Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
677 CHECK_NE(cond, kNoCondition);
678 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
679 B25 | B24 | ((imm16 >> 12) << 16) |
680 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
681 Emit(encoding);
682 }
683
684
movt(Register rd,uint16_t imm16,Condition cond)685 void Arm32Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
686 CHECK_NE(cond, kNoCondition);
687 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
688 B25 | B24 | B22 | ((imm16 >> 12) << 16) |
689 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
690 Emit(encoding);
691 }
692
693
EmitMulOp(Condition cond,int32_t opcode,Register rd,Register rn,Register rm,Register rs)694 void Arm32Assembler::EmitMulOp(Condition cond, int32_t opcode,
695 Register rd, Register rn,
696 Register rm, Register rs) {
697 CHECK_NE(rd, kNoRegister);
698 CHECK_NE(rn, kNoRegister);
699 CHECK_NE(rm, kNoRegister);
700 CHECK_NE(rs, kNoRegister);
701 CHECK_NE(cond, kNoCondition);
702 int32_t encoding = opcode |
703 (static_cast<int32_t>(cond) << kConditionShift) |
704 (static_cast<int32_t>(rn) << kRnShift) |
705 (static_cast<int32_t>(rd) << kRdShift) |
706 (static_cast<int32_t>(rs) << kRsShift) |
707 B7 | B4 |
708 (static_cast<int32_t>(rm) << kRmShift);
709 Emit(encoding);
710 }
711
ldrex(Register rt,Register rn,Condition cond)712 void Arm32Assembler::ldrex(Register rt, Register rn, Condition cond) {
713 CHECK_NE(rn, kNoRegister);
714 CHECK_NE(rt, kNoRegister);
715 CHECK_NE(cond, kNoCondition);
716 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
717 B24 |
718 B23 |
719 L |
720 (static_cast<int32_t>(rn) << kLdExRnShift) |
721 (static_cast<int32_t>(rt) << kLdExRtShift) |
722 B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
723 Emit(encoding);
724 }
725
726
strex(Register rd,Register rt,Register rn,Condition cond)727 void Arm32Assembler::strex(Register rd,
728 Register rt,
729 Register rn,
730 Condition cond) {
731 CHECK_NE(rn, kNoRegister);
732 CHECK_NE(rd, kNoRegister);
733 CHECK_NE(rt, kNoRegister);
734 CHECK_NE(cond, kNoCondition);
735 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
736 B24 |
737 B23 |
738 (static_cast<int32_t>(rn) << kStrExRnShift) |
739 (static_cast<int32_t>(rd) << kStrExRdShift) |
740 B11 | B10 | B9 | B8 | B7 | B4 |
741 (static_cast<int32_t>(rt) << kStrExRtShift);
742 Emit(encoding);
743 }
744
745
clrex(Condition cond)746 void Arm32Assembler::clrex(Condition cond) {
747 CHECK_EQ(cond, AL); // This cannot be conditional on ARM.
748 int32_t encoding = (kSpecialCondition << kConditionShift) |
749 B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf;
750 Emit(encoding);
751 }
752
753
nop(Condition cond)754 void Arm32Assembler::nop(Condition cond) {
755 CHECK_NE(cond, kNoCondition);
756 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
757 B25 | B24 | B21 | (0xf << 12);
758 Emit(encoding);
759 }
760
761
vmovsr(SRegister sn,Register rt,Condition cond)762 void Arm32Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
763 CHECK_NE(sn, kNoSRegister);
764 CHECK_NE(rt, kNoRegister);
765 CHECK_NE(rt, SP);
766 CHECK_NE(rt, PC);
767 CHECK_NE(cond, kNoCondition);
768 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
769 B27 | B26 | B25 |
770 ((static_cast<int32_t>(sn) >> 1)*B16) |
771 (static_cast<int32_t>(rt)*B12) | B11 | B9 |
772 ((static_cast<int32_t>(sn) & 1)*B7) | B4;
773 Emit(encoding);
774 }
775
776
vmovrs(Register rt,SRegister sn,Condition cond)777 void Arm32Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
778 CHECK_NE(sn, kNoSRegister);
779 CHECK_NE(rt, kNoRegister);
780 CHECK_NE(rt, SP);
781 CHECK_NE(rt, PC);
782 CHECK_NE(cond, kNoCondition);
783 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
784 B27 | B26 | B25 | B20 |
785 ((static_cast<int32_t>(sn) >> 1)*B16) |
786 (static_cast<int32_t>(rt)*B12) | B11 | B9 |
787 ((static_cast<int32_t>(sn) & 1)*B7) | B4;
788 Emit(encoding);
789 }
790
791
vmovsrr(SRegister sm,Register rt,Register rt2,Condition cond)792 void Arm32Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
793 Condition cond) {
794 CHECK_NE(sm, kNoSRegister);
795 CHECK_NE(sm, S31);
796 CHECK_NE(rt, kNoRegister);
797 CHECK_NE(rt, SP);
798 CHECK_NE(rt, PC);
799 CHECK_NE(rt2, kNoRegister);
800 CHECK_NE(rt2, SP);
801 CHECK_NE(rt2, PC);
802 CHECK_NE(cond, kNoCondition);
803 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
804 B27 | B26 | B22 |
805 (static_cast<int32_t>(rt2)*B16) |
806 (static_cast<int32_t>(rt)*B12) | B11 | B9 |
807 ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
808 (static_cast<int32_t>(sm) >> 1);
809 Emit(encoding);
810 }
811
812
vmovrrs(Register rt,Register rt2,SRegister sm,Condition cond)813 void Arm32Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
814 Condition cond) {
815 CHECK_NE(sm, kNoSRegister);
816 CHECK_NE(sm, S31);
817 CHECK_NE(rt, kNoRegister);
818 CHECK_NE(rt, SP);
819 CHECK_NE(rt, PC);
820 CHECK_NE(rt2, kNoRegister);
821 CHECK_NE(rt2, SP);
822 CHECK_NE(rt2, PC);
823 CHECK_NE(rt, rt2);
824 CHECK_NE(cond, kNoCondition);
825 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
826 B27 | B26 | B22 | B20 |
827 (static_cast<int32_t>(rt2)*B16) |
828 (static_cast<int32_t>(rt)*B12) | B11 | B9 |
829 ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
830 (static_cast<int32_t>(sm) >> 1);
831 Emit(encoding);
832 }
833
834
vmovdrr(DRegister dm,Register rt,Register rt2,Condition cond)835 void Arm32Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
836 Condition cond) {
837 CHECK_NE(dm, kNoDRegister);
838 CHECK_NE(rt, kNoRegister);
839 CHECK_NE(rt, SP);
840 CHECK_NE(rt, PC);
841 CHECK_NE(rt2, kNoRegister);
842 CHECK_NE(rt2, SP);
843 CHECK_NE(rt2, PC);
844 CHECK_NE(cond, kNoCondition);
845 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
846 B27 | B26 | B22 |
847 (static_cast<int32_t>(rt2)*B16) |
848 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
849 ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
850 (static_cast<int32_t>(dm) & 0xf);
851 Emit(encoding);
852 }
853
854
vmovrrd(Register rt,Register rt2,DRegister dm,Condition cond)855 void Arm32Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
856 Condition cond) {
857 CHECK_NE(dm, kNoDRegister);
858 CHECK_NE(rt, kNoRegister);
859 CHECK_NE(rt, SP);
860 CHECK_NE(rt, PC);
861 CHECK_NE(rt2, kNoRegister);
862 CHECK_NE(rt2, SP);
863 CHECK_NE(rt2, PC);
864 CHECK_NE(rt, rt2);
865 CHECK_NE(cond, kNoCondition);
866 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
867 B27 | B26 | B22 | B20 |
868 (static_cast<int32_t>(rt2)*B16) |
869 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
870 ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
871 (static_cast<int32_t>(dm) & 0xf);
872 Emit(encoding);
873 }
874
875
vldrs(SRegister sd,const Address & ad,Condition cond)876 void Arm32Assembler::vldrs(SRegister sd, const Address& ad, Condition cond) {
877 const Address& addr = static_cast<const Address&>(ad);
878 CHECK_NE(sd, kNoSRegister);
879 CHECK_NE(cond, kNoCondition);
880 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
881 B27 | B26 | B24 | B20 |
882 ((static_cast<int32_t>(sd) & 1)*B22) |
883 ((static_cast<int32_t>(sd) >> 1)*B12) |
884 B11 | B9 | addr.vencoding();
885 Emit(encoding);
886 }
887
888
vstrs(SRegister sd,const Address & ad,Condition cond)889 void Arm32Assembler::vstrs(SRegister sd, const Address& ad, Condition cond) {
890 const Address& addr = static_cast<const Address&>(ad);
891 CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
892 CHECK_NE(sd, kNoSRegister);
893 CHECK_NE(cond, kNoCondition);
894 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
895 B27 | B26 | B24 |
896 ((static_cast<int32_t>(sd) & 1)*B22) |
897 ((static_cast<int32_t>(sd) >> 1)*B12) |
898 B11 | B9 | addr.vencoding();
899 Emit(encoding);
900 }
901
902
vldrd(DRegister dd,const Address & ad,Condition cond)903 void Arm32Assembler::vldrd(DRegister dd, const Address& ad, Condition cond) {
904 const Address& addr = static_cast<const Address&>(ad);
905 CHECK_NE(dd, kNoDRegister);
906 CHECK_NE(cond, kNoCondition);
907 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
908 B27 | B26 | B24 | B20 |
909 ((static_cast<int32_t>(dd) >> 4)*B22) |
910 ((static_cast<int32_t>(dd) & 0xf)*B12) |
911 B11 | B9 | B8 | addr.vencoding();
912 Emit(encoding);
913 }
914
915
vstrd(DRegister dd,const Address & ad,Condition cond)916 void Arm32Assembler::vstrd(DRegister dd, const Address& ad, Condition cond) {
917 const Address& addr = static_cast<const Address&>(ad);
918 CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
919 CHECK_NE(dd, kNoDRegister);
920 CHECK_NE(cond, kNoCondition);
921 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
922 B27 | B26 | B24 |
923 ((static_cast<int32_t>(dd) >> 4)*B22) |
924 ((static_cast<int32_t>(dd) & 0xf)*B12) |
925 B11 | B9 | B8 | addr.vencoding();
926 Emit(encoding);
927 }
928
929
vpushs(SRegister reg,int nregs,Condition cond)930 void Arm32Assembler::vpushs(SRegister reg, int nregs, Condition cond) {
931 EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, false, cond);
932 }
933
934
vpushd(DRegister reg,int nregs,Condition cond)935 void Arm32Assembler::vpushd(DRegister reg, int nregs, Condition cond) {
936 EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, true, cond);
937 }
938
939
vpops(SRegister reg,int nregs,Condition cond)940 void Arm32Assembler::vpops(SRegister reg, int nregs, Condition cond) {
941 EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, false, cond);
942 }
943
944
vpopd(DRegister reg,int nregs,Condition cond)945 void Arm32Assembler::vpopd(DRegister reg, int nregs, Condition cond) {
946 EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, true, cond);
947 }
948
949
EmitVPushPop(uint32_t reg,int nregs,bool push,bool dbl,Condition cond)950 void Arm32Assembler::EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond) {
951 CHECK_NE(cond, kNoCondition);
952 CHECK_GT(nregs, 0);
953 uint32_t D;
954 uint32_t Vd;
955 if (dbl) {
956 // Encoded as D:Vd.
957 D = (reg >> 4) & 1;
958 Vd = reg & 0b1111;
959 } else {
960 // Encoded as Vd:D.
961 D = reg & 1;
962 Vd = (reg >> 1) & 0b1111;
963 }
964 int32_t encoding = B27 | B26 | B21 | B19 | B18 | B16 |
965 B11 | B9 |
966 (dbl ? B8 : 0) |
967 (push ? B24 : (B23 | B20)) |
968 static_cast<int32_t>(cond) << kConditionShift |
969 nregs << (dbl ? 1 : 0) |
970 D << 22 |
971 Vd << 12;
972 Emit(encoding);
973 }
974
975
EmitVFPsss(Condition cond,int32_t opcode,SRegister sd,SRegister sn,SRegister sm)976 void Arm32Assembler::EmitVFPsss(Condition cond, int32_t opcode,
977 SRegister sd, SRegister sn, SRegister sm) {
978 CHECK_NE(sd, kNoSRegister);
979 CHECK_NE(sn, kNoSRegister);
980 CHECK_NE(sm, kNoSRegister);
981 CHECK_NE(cond, kNoCondition);
982 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
983 B27 | B26 | B25 | B11 | B9 | opcode |
984 ((static_cast<int32_t>(sd) & 1)*B22) |
985 ((static_cast<int32_t>(sn) >> 1)*B16) |
986 ((static_cast<int32_t>(sd) >> 1)*B12) |
987 ((static_cast<int32_t>(sn) & 1)*B7) |
988 ((static_cast<int32_t>(sm) & 1)*B5) |
989 (static_cast<int32_t>(sm) >> 1);
990 Emit(encoding);
991 }
992
993
EmitVFPddd(Condition cond,int32_t opcode,DRegister dd,DRegister dn,DRegister dm)994 void Arm32Assembler::EmitVFPddd(Condition cond, int32_t opcode,
995 DRegister dd, DRegister dn, DRegister dm) {
996 CHECK_NE(dd, kNoDRegister);
997 CHECK_NE(dn, kNoDRegister);
998 CHECK_NE(dm, kNoDRegister);
999 CHECK_NE(cond, kNoCondition);
1000 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1001 B27 | B26 | B25 | B11 | B9 | B8 | opcode |
1002 ((static_cast<int32_t>(dd) >> 4)*B22) |
1003 ((static_cast<int32_t>(dn) & 0xf)*B16) |
1004 ((static_cast<int32_t>(dd) & 0xf)*B12) |
1005 ((static_cast<int32_t>(dn) >> 4)*B7) |
1006 ((static_cast<int32_t>(dm) >> 4)*B5) |
1007 (static_cast<int32_t>(dm) & 0xf);
1008 Emit(encoding);
1009 }
1010
1011
EmitVFPsd(Condition cond,int32_t opcode,SRegister sd,DRegister dm)1012 void Arm32Assembler::EmitVFPsd(Condition cond, int32_t opcode,
1013 SRegister sd, DRegister dm) {
1014 CHECK_NE(sd, kNoSRegister);
1015 CHECK_NE(dm, kNoDRegister);
1016 CHECK_NE(cond, kNoCondition);
1017 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1018 B27 | B26 | B25 | B11 | B9 | opcode |
1019 ((static_cast<int32_t>(sd) & 1)*B22) |
1020 ((static_cast<int32_t>(sd) >> 1)*B12) |
1021 ((static_cast<int32_t>(dm) >> 4)*B5) |
1022 (static_cast<int32_t>(dm) & 0xf);
1023 Emit(encoding);
1024 }
1025
1026
EmitVFPds(Condition cond,int32_t opcode,DRegister dd,SRegister sm)1027 void Arm32Assembler::EmitVFPds(Condition cond, int32_t opcode,
1028 DRegister dd, SRegister sm) {
1029 CHECK_NE(dd, kNoDRegister);
1030 CHECK_NE(sm, kNoSRegister);
1031 CHECK_NE(cond, kNoCondition);
1032 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1033 B27 | B26 | B25 | B11 | B9 | opcode |
1034 ((static_cast<int32_t>(dd) >> 4)*B22) |
1035 ((static_cast<int32_t>(dd) & 0xf)*B12) |
1036 ((static_cast<int32_t>(sm) & 1)*B5) |
1037 (static_cast<int32_t>(sm) >> 1);
1038 Emit(encoding);
1039 }
1040
1041
Lsl(Register rd,Register rm,uint32_t shift_imm,bool setcc,Condition cond)1042 void Arm32Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
1043 bool setcc, Condition cond) {
1044 CHECK_NE(shift_imm, 0u); // Do not use Lsl if no shift is wanted.
1045 if (setcc) {
1046 movs(rd, ShifterOperand(rm, LSL, shift_imm), cond);
1047 } else {
1048 mov(rd, ShifterOperand(rm, LSL, shift_imm), cond);
1049 }
1050 }
1051
1052
Lsr(Register rd,Register rm,uint32_t shift_imm,bool setcc,Condition cond)1053 void Arm32Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
1054 bool setcc, Condition cond) {
1055 CHECK_NE(shift_imm, 0u); // Do not use Lsr if no shift is wanted.
1056 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax.
1057 if (setcc) {
1058 movs(rd, ShifterOperand(rm, LSR, shift_imm), cond);
1059 } else {
1060 mov(rd, ShifterOperand(rm, LSR, shift_imm), cond);
1061 }
1062 }
1063
1064
Asr(Register rd,Register rm,uint32_t shift_imm,bool setcc,Condition cond)1065 void Arm32Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
1066 bool setcc, Condition cond) {
1067 CHECK_NE(shift_imm, 0u); // Do not use Asr if no shift is wanted.
1068 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax.
1069 if (setcc) {
1070 movs(rd, ShifterOperand(rm, ASR, shift_imm), cond);
1071 } else {
1072 mov(rd, ShifterOperand(rm, ASR, shift_imm), cond);
1073 }
1074 }
1075
1076
Ror(Register rd,Register rm,uint32_t shift_imm,bool setcc,Condition cond)1077 void Arm32Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
1078 bool setcc, Condition cond) {
1079 CHECK_NE(shift_imm, 0u); // Use Rrx instruction.
1080 if (setcc) {
1081 movs(rd, ShifterOperand(rm, ROR, shift_imm), cond);
1082 } else {
1083 mov(rd, ShifterOperand(rm, ROR, shift_imm), cond);
1084 }
1085 }
1086
Rrx(Register rd,Register rm,bool setcc,Condition cond)1087 void Arm32Assembler::Rrx(Register rd, Register rm, bool setcc, Condition cond) {
1088 if (setcc) {
1089 movs(rd, ShifterOperand(rm, ROR, 0), cond);
1090 } else {
1091 mov(rd, ShifterOperand(rm, ROR, 0), cond);
1092 }
1093 }
1094
1095
Lsl(Register rd,Register rm,Register rn,bool setcc,Condition cond)1096 void Arm32Assembler::Lsl(Register rd, Register rm, Register rn,
1097 bool setcc, Condition cond) {
1098 if (setcc) {
1099 movs(rd, ShifterOperand(rm, LSL, rn), cond);
1100 } else {
1101 mov(rd, ShifterOperand(rm, LSL, rn), cond);
1102 }
1103 }
1104
1105
Lsr(Register rd,Register rm,Register rn,bool setcc,Condition cond)1106 void Arm32Assembler::Lsr(Register rd, Register rm, Register rn,
1107 bool setcc, Condition cond) {
1108 if (setcc) {
1109 movs(rd, ShifterOperand(rm, LSR, rn), cond);
1110 } else {
1111 mov(rd, ShifterOperand(rm, LSR, rn), cond);
1112 }
1113 }
1114
1115
Asr(Register rd,Register rm,Register rn,bool setcc,Condition cond)1116 void Arm32Assembler::Asr(Register rd, Register rm, Register rn,
1117 bool setcc, Condition cond) {
1118 if (setcc) {
1119 movs(rd, ShifterOperand(rm, ASR, rn), cond);
1120 } else {
1121 mov(rd, ShifterOperand(rm, ASR, rn), cond);
1122 }
1123 }
1124
1125
Ror(Register rd,Register rm,Register rn,bool setcc,Condition cond)1126 void Arm32Assembler::Ror(Register rd, Register rm, Register rn,
1127 bool setcc, Condition cond) {
1128 if (setcc) {
1129 movs(rd, ShifterOperand(rm, ROR, rn), cond);
1130 } else {
1131 mov(rd, ShifterOperand(rm, ROR, rn), cond);
1132 }
1133 }
1134
vmstat(Condition cond)1135 void Arm32Assembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR
1136 CHECK_NE(cond, kNoCondition);
1137 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1138 B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 |
1139 (static_cast<int32_t>(PC)*B12) |
1140 B11 | B9 | B4;
1141 Emit(encoding);
1142 }
1143
1144
svc(uint32_t imm24)1145 void Arm32Assembler::svc(uint32_t imm24) {
1146 CHECK(IsUint(24, imm24)) << imm24;
1147 int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24;
1148 Emit(encoding);
1149 }
1150
1151
bkpt(uint16_t imm16)1152 void Arm32Assembler::bkpt(uint16_t imm16) {
1153 int32_t encoding = (AL << kConditionShift) | B24 | B21 |
1154 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
1155 Emit(encoding);
1156 }
1157
1158
blx(Register rm,Condition cond)1159 void Arm32Assembler::blx(Register rm, Condition cond) {
1160 CHECK_NE(rm, kNoRegister);
1161 CHECK_NE(cond, kNoCondition);
1162 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1163 B24 | B21 | (0xfff << 8) | B5 | B4 |
1164 (static_cast<int32_t>(rm) << kRmShift);
1165 Emit(encoding);
1166 }
1167
1168
bx(Register rm,Condition cond)1169 void Arm32Assembler::bx(Register rm, Condition cond) {
1170 CHECK_NE(rm, kNoRegister);
1171 CHECK_NE(cond, kNoCondition);
1172 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1173 B24 | B21 | (0xfff << 8) | B4 |
1174 (static_cast<int32_t>(rm) << kRmShift);
1175 Emit(encoding);
1176 }
1177
1178
Push(Register rd,Condition cond)1179 void Arm32Assembler::Push(Register rd, Condition cond) {
1180 str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond);
1181 }
1182
1183
Pop(Register rd,Condition cond)1184 void Arm32Assembler::Pop(Register rd, Condition cond) {
1185 ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond);
1186 }
1187
1188
PushList(RegList regs,Condition cond)1189 void Arm32Assembler::PushList(RegList regs, Condition cond) {
1190 stm(DB_W, SP, regs, cond);
1191 }
1192
1193
PopList(RegList regs,Condition cond)1194 void Arm32Assembler::PopList(RegList regs, Condition cond) {
1195 ldm(IA_W, SP, regs, cond);
1196 }
1197
1198
Mov(Register rd,Register rm,Condition cond)1199 void Arm32Assembler::Mov(Register rd, Register rm, Condition cond) {
1200 if (rd != rm) {
1201 mov(rd, ShifterOperand(rm), cond);
1202 }
1203 }
1204
1205
Bind(Label * label)1206 void Arm32Assembler::Bind(Label* label) {
1207 CHECK(!label->IsBound());
1208 int bound_pc = buffer_.Size();
1209 while (label->IsLinked()) {
1210 int32_t position = label->Position();
1211 int32_t next = buffer_.Load<int32_t>(position);
1212 int32_t encoded = Arm32Assembler::EncodeBranchOffset(bound_pc - position, next);
1213 buffer_.Store<int32_t>(position, encoded);
1214 label->position_ = Arm32Assembler::DecodeBranchOffset(next);
1215 }
1216 label->BindTo(bound_pc);
1217 }
1218
1219
EncodeBranchOffset(int offset,int32_t inst)1220 int32_t Arm32Assembler::EncodeBranchOffset(int offset, int32_t inst) {
1221 // The offset is off by 8 due to the way the ARM CPUs read PC.
1222 offset -= 8;
1223 CHECK_ALIGNED(offset, 4);
1224 CHECK(IsInt(POPCOUNT(kBranchOffsetMask), offset)) << offset;
1225
1226 // Properly preserve only the bits supported in the instruction.
1227 offset >>= 2;
1228 offset &= kBranchOffsetMask;
1229 return (inst & ~kBranchOffsetMask) | offset;
1230 }
1231
1232
DecodeBranchOffset(int32_t inst)1233 int Arm32Assembler::DecodeBranchOffset(int32_t inst) {
1234 // Sign-extend, left-shift by 2, then add 8.
1235 return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
1236 }
1237
1238
AddConstant(Register rd,int32_t value,Condition cond)1239 void Arm32Assembler::AddConstant(Register rd, int32_t value, Condition cond) {
1240 AddConstant(rd, rd, value, cond);
1241 }
1242
1243
AddConstant(Register rd,Register rn,int32_t value,Condition cond)1244 void Arm32Assembler::AddConstant(Register rd, Register rn, int32_t value,
1245 Condition cond) {
1246 if (value == 0) {
1247 if (rd != rn) {
1248 mov(rd, ShifterOperand(rn), cond);
1249 }
1250 return;
1251 }
1252 // We prefer to select the shorter code sequence rather than selecting add for
1253 // positive values and sub for negatives ones, which would slightly improve
1254 // the readability of generated code for some constants.
1255 ShifterOperand shifter_op;
1256 if (ShifterOperand::CanHoldArm(value, &shifter_op)) {
1257 add(rd, rn, shifter_op, cond);
1258 } else if (ShifterOperand::CanHoldArm(-value, &shifter_op)) {
1259 sub(rd, rn, shifter_op, cond);
1260 } else {
1261 CHECK(rn != IP);
1262 if (ShifterOperand::CanHoldArm(~value, &shifter_op)) {
1263 mvn(IP, shifter_op, cond);
1264 add(rd, rn, ShifterOperand(IP), cond);
1265 } else if (ShifterOperand::CanHoldArm(~(-value), &shifter_op)) {
1266 mvn(IP, shifter_op, cond);
1267 sub(rd, rn, ShifterOperand(IP), cond);
1268 } else {
1269 movw(IP, Low16Bits(value), cond);
1270 uint16_t value_high = High16Bits(value);
1271 if (value_high != 0) {
1272 movt(IP, value_high, cond);
1273 }
1274 add(rd, rn, ShifterOperand(IP), cond);
1275 }
1276 }
1277 }
1278
1279
AddConstantSetFlags(Register rd,Register rn,int32_t value,Condition cond)1280 void Arm32Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
1281 Condition cond) {
1282 ShifterOperand shifter_op;
1283 if (ShifterOperand::CanHoldArm(value, &shifter_op)) {
1284 adds(rd, rn, shifter_op, cond);
1285 } else if (ShifterOperand::CanHoldArm(-value, &shifter_op)) {
1286 subs(rd, rn, shifter_op, cond);
1287 } else {
1288 CHECK(rn != IP);
1289 if (ShifterOperand::CanHoldArm(~value, &shifter_op)) {
1290 mvn(IP, shifter_op, cond);
1291 adds(rd, rn, ShifterOperand(IP), cond);
1292 } else if (ShifterOperand::CanHoldArm(~(-value), &shifter_op)) {
1293 mvn(IP, shifter_op, cond);
1294 subs(rd, rn, ShifterOperand(IP), cond);
1295 } else {
1296 movw(IP, Low16Bits(value), cond);
1297 uint16_t value_high = High16Bits(value);
1298 if (value_high != 0) {
1299 movt(IP, value_high, cond);
1300 }
1301 adds(rd, rn, ShifterOperand(IP), cond);
1302 }
1303 }
1304 }
1305
1306
LoadImmediate(Register rd,int32_t value,Condition cond)1307 void Arm32Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
1308 ShifterOperand shifter_op;
1309 if (ShifterOperand::CanHoldArm(value, &shifter_op)) {
1310 mov(rd, shifter_op, cond);
1311 } else if (ShifterOperand::CanHoldArm(~value, &shifter_op)) {
1312 mvn(rd, shifter_op, cond);
1313 } else {
1314 movw(rd, Low16Bits(value), cond);
1315 uint16_t value_high = High16Bits(value);
1316 if (value_high != 0) {
1317 movt(rd, value_high, cond);
1318 }
1319 }
1320 }
1321
1322
1323 // Implementation note: this method must emit at most one instruction when
1324 // Address::CanHoldLoadOffsetArm.
LoadFromOffset(LoadOperandType type,Register reg,Register base,int32_t offset,Condition cond)1325 void Arm32Assembler::LoadFromOffset(LoadOperandType type,
1326 Register reg,
1327 Register base,
1328 int32_t offset,
1329 Condition cond) {
1330 if (!Address::CanHoldLoadOffsetArm(type, offset)) {
1331 CHECK(base != IP);
1332 LoadImmediate(IP, offset, cond);
1333 add(IP, IP, ShifterOperand(base), cond);
1334 base = IP;
1335 offset = 0;
1336 }
1337 CHECK(Address::CanHoldLoadOffsetArm(type, offset));
1338 switch (type) {
1339 case kLoadSignedByte:
1340 ldrsb(reg, Address(base, offset), cond);
1341 break;
1342 case kLoadUnsignedByte:
1343 ldrb(reg, Address(base, offset), cond);
1344 break;
1345 case kLoadSignedHalfword:
1346 ldrsh(reg, Address(base, offset), cond);
1347 break;
1348 case kLoadUnsignedHalfword:
1349 ldrh(reg, Address(base, offset), cond);
1350 break;
1351 case kLoadWord:
1352 ldr(reg, Address(base, offset), cond);
1353 break;
1354 case kLoadWordPair:
1355 ldrd(reg, Address(base, offset), cond);
1356 break;
1357 default:
1358 LOG(FATAL) << "UNREACHABLE";
1359 }
1360 }
1361
1362
1363 // Implementation note: this method must emit at most one instruction when
1364 // Address::CanHoldLoadOffsetArm, as expected by JIT::GuardedLoadFromOffset.
LoadSFromOffset(SRegister reg,Register base,int32_t offset,Condition cond)1365 void Arm32Assembler::LoadSFromOffset(SRegister reg,
1366 Register base,
1367 int32_t offset,
1368 Condition cond) {
1369 if (!Address::CanHoldLoadOffsetArm(kLoadSWord, offset)) {
1370 CHECK_NE(base, IP);
1371 LoadImmediate(IP, offset, cond);
1372 add(IP, IP, ShifterOperand(base), cond);
1373 base = IP;
1374 offset = 0;
1375 }
1376 CHECK(Address::CanHoldLoadOffsetArm(kLoadSWord, offset));
1377 vldrs(reg, Address(base, offset), cond);
1378 }
1379
1380
1381 // Implementation note: this method must emit at most one instruction when
1382 // Address::CanHoldLoadOffsetArm, as expected by JIT::GuardedLoadFromOffset.
LoadDFromOffset(DRegister reg,Register base,int32_t offset,Condition cond)1383 void Arm32Assembler::LoadDFromOffset(DRegister reg,
1384 Register base,
1385 int32_t offset,
1386 Condition cond) {
1387 if (!Address::CanHoldLoadOffsetArm(kLoadDWord, offset)) {
1388 CHECK_NE(base, IP);
1389 LoadImmediate(IP, offset, cond);
1390 add(IP, IP, ShifterOperand(base), cond);
1391 base = IP;
1392 offset = 0;
1393 }
1394 CHECK(Address::CanHoldLoadOffsetArm(kLoadDWord, offset));
1395 vldrd(reg, Address(base, offset), cond);
1396 }
1397
1398
1399 // Implementation note: this method must emit at most one instruction when
1400 // Address::CanHoldStoreOffsetArm.
StoreToOffset(StoreOperandType type,Register reg,Register base,int32_t offset,Condition cond)1401 void Arm32Assembler::StoreToOffset(StoreOperandType type,
1402 Register reg,
1403 Register base,
1404 int32_t offset,
1405 Condition cond) {
1406 if (!Address::CanHoldStoreOffsetArm(type, offset)) {
1407 CHECK(reg != IP);
1408 CHECK(base != IP);
1409 LoadImmediate(IP, offset, cond);
1410 add(IP, IP, ShifterOperand(base), cond);
1411 base = IP;
1412 offset = 0;
1413 }
1414 CHECK(Address::CanHoldStoreOffsetArm(type, offset));
1415 switch (type) {
1416 case kStoreByte:
1417 strb(reg, Address(base, offset), cond);
1418 break;
1419 case kStoreHalfword:
1420 strh(reg, Address(base, offset), cond);
1421 break;
1422 case kStoreWord:
1423 str(reg, Address(base, offset), cond);
1424 break;
1425 case kStoreWordPair:
1426 strd(reg, Address(base, offset), cond);
1427 break;
1428 default:
1429 LOG(FATAL) << "UNREACHABLE";
1430 }
1431 }
1432
1433
1434 // Implementation note: this method must emit at most one instruction when
1435 // Address::CanHoldStoreOffsetArm, as expected by JIT::GuardedStoreToOffset.
StoreSToOffset(SRegister reg,Register base,int32_t offset,Condition cond)1436 void Arm32Assembler::StoreSToOffset(SRegister reg,
1437 Register base,
1438 int32_t offset,
1439 Condition cond) {
1440 if (!Address::CanHoldStoreOffsetArm(kStoreSWord, offset)) {
1441 CHECK_NE(base, IP);
1442 LoadImmediate(IP, offset, cond);
1443 add(IP, IP, ShifterOperand(base), cond);
1444 base = IP;
1445 offset = 0;
1446 }
1447 CHECK(Address::CanHoldStoreOffsetArm(kStoreSWord, offset));
1448 vstrs(reg, Address(base, offset), cond);
1449 }
1450
1451
1452 // Implementation note: this method must emit at most one instruction when
1453 // Address::CanHoldStoreOffsetArm, as expected by JIT::GuardedStoreSToOffset.
StoreDToOffset(DRegister reg,Register base,int32_t offset,Condition cond)1454 void Arm32Assembler::StoreDToOffset(DRegister reg,
1455 Register base,
1456 int32_t offset,
1457 Condition cond) {
1458 if (!Address::CanHoldStoreOffsetArm(kStoreDWord, offset)) {
1459 CHECK_NE(base, IP);
1460 LoadImmediate(IP, offset, cond);
1461 add(IP, IP, ShifterOperand(base), cond);
1462 base = IP;
1463 offset = 0;
1464 }
1465 CHECK(Address::CanHoldStoreOffsetArm(kStoreDWord, offset));
1466 vstrd(reg, Address(base, offset), cond);
1467 }
1468
1469
MemoryBarrier(ManagedRegister mscratch)1470 void Arm32Assembler::MemoryBarrier(ManagedRegister mscratch) {
1471 CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12);
1472 #if ANDROID_SMP != 0
1473 int32_t encoding = 0xf57ff05f; // dmb
1474 Emit(encoding);
1475 #endif
1476 }
1477
1478
cbz(Register rn,Label * target)1479 void Arm32Assembler::cbz(Register rn, Label* target) {
1480 LOG(FATAL) << "cbz is not supported on ARM32";
1481 }
1482
1483
cbnz(Register rn,Label * target)1484 void Arm32Assembler::cbnz(Register rn, Label* target) {
1485 LOG(FATAL) << "cbnz is not supported on ARM32";
1486 }
1487
1488
CompareAndBranchIfZero(Register r,Label * label)1489 void Arm32Assembler::CompareAndBranchIfZero(Register r, Label* label) {
1490 cmp(r, ShifterOperand(0));
1491 b(label, EQ);
1492 }
1493
1494
CompareAndBranchIfNonZero(Register r,Label * label)1495 void Arm32Assembler::CompareAndBranchIfNonZero(Register r, Label* label) {
1496 cmp(r, ShifterOperand(0));
1497 b(label, NE);
1498 }
1499
1500
1501 } // namespace arm
1502 } // namespace art
1503