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