• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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