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_thumb2.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 Thumb2Assembler::and_(Register rd, Register rn, const ShifterOperand& so,
29                            Condition cond) {
30   EmitDataProcessing(cond, AND, 0, rn, rd, so);
31 }
32 
33 
eor(Register rd,Register rn,const ShifterOperand & so,Condition cond)34 void Thumb2Assembler::eor(Register rd, Register rn, const ShifterOperand& so,
35                           Condition cond) {
36   EmitDataProcessing(cond, EOR, 0, rn, rd, so);
37 }
38 
39 
sub(Register rd,Register rn,const ShifterOperand & so,Condition cond)40 void Thumb2Assembler::sub(Register rd, Register rn, const ShifterOperand& so,
41                           Condition cond) {
42   EmitDataProcessing(cond, SUB, 0, rn, rd, so);
43 }
44 
45 
rsb(Register rd,Register rn,const ShifterOperand & so,Condition cond)46 void Thumb2Assembler::rsb(Register rd, Register rn, const ShifterOperand& so,
47                           Condition cond) {
48   EmitDataProcessing(cond, RSB, 0, rn, rd, so);
49 }
50 
51 
rsbs(Register rd,Register rn,const ShifterOperand & so,Condition cond)52 void Thumb2Assembler::rsbs(Register rd, Register rn, const ShifterOperand& so,
53                            Condition cond) {
54   EmitDataProcessing(cond, RSB, 1, rn, rd, so);
55 }
56 
57 
add(Register rd,Register rn,const ShifterOperand & so,Condition cond)58 void Thumb2Assembler::add(Register rd, Register rn, const ShifterOperand& so,
59                           Condition cond) {
60   EmitDataProcessing(cond, ADD, 0, rn, rd, so);
61 }
62 
63 
adds(Register rd,Register rn,const ShifterOperand & so,Condition cond)64 void Thumb2Assembler::adds(Register rd, Register rn, const ShifterOperand& so,
65                            Condition cond) {
66   EmitDataProcessing(cond, ADD, 1, rn, rd, so);
67 }
68 
69 
subs(Register rd,Register rn,const ShifterOperand & so,Condition cond)70 void Thumb2Assembler::subs(Register rd, Register rn, const ShifterOperand& so,
71                            Condition cond) {
72   EmitDataProcessing(cond, SUB, 1, rn, rd, so);
73 }
74 
75 
adc(Register rd,Register rn,const ShifterOperand & so,Condition cond)76 void Thumb2Assembler::adc(Register rd, Register rn, const ShifterOperand& so,
77                           Condition cond) {
78   EmitDataProcessing(cond, ADC, 0, rn, rd, so);
79 }
80 
81 
sbc(Register rd,Register rn,const ShifterOperand & so,Condition cond)82 void Thumb2Assembler::sbc(Register rd, Register rn, const ShifterOperand& so,
83                           Condition cond) {
84   EmitDataProcessing(cond, SBC, 0, rn, rd, so);
85 }
86 
87 
rsc(Register rd,Register rn,const ShifterOperand & so,Condition cond)88 void Thumb2Assembler::rsc(Register rd, Register rn, const ShifterOperand& so,
89                           Condition cond) {
90   EmitDataProcessing(cond, RSC, 0, rn, rd, so);
91 }
92 
93 
tst(Register rn,const ShifterOperand & so,Condition cond)94 void Thumb2Assembler::tst(Register rn, const ShifterOperand& so, Condition cond) {
95   CHECK_NE(rn, PC);  // Reserve tst pc instruction for exception handler marker.
96   EmitDataProcessing(cond, TST, 1, rn, R0, so);
97 }
98 
99 
teq(Register rn,const ShifterOperand & so,Condition cond)100 void Thumb2Assembler::teq(Register rn, const ShifterOperand& so, Condition cond) {
101   CHECK_NE(rn, PC);  // Reserve teq pc instruction for exception handler marker.
102   EmitDataProcessing(cond, TEQ, 1, rn, R0, so);
103 }
104 
105 
cmp(Register rn,const ShifterOperand & so,Condition cond)106 void Thumb2Assembler::cmp(Register rn, const ShifterOperand& so, Condition cond) {
107   EmitDataProcessing(cond, CMP, 1, rn, R0, so);
108 }
109 
110 
cmn(Register rn,const ShifterOperand & so,Condition cond)111 void Thumb2Assembler::cmn(Register rn, const ShifterOperand& so, Condition cond) {
112   EmitDataProcessing(cond, CMN, 1, rn, R0, so);
113 }
114 
115 
orr(Register rd,Register rn,const ShifterOperand & so,Condition cond)116 void Thumb2Assembler::orr(Register rd, Register rn,
117                           const ShifterOperand& so, Condition cond) {
118   EmitDataProcessing(cond, ORR, 0, rn, rd, so);
119 }
120 
121 
orrs(Register rd,Register rn,const ShifterOperand & so,Condition cond)122 void Thumb2Assembler::orrs(Register rd, Register rn,
123                            const ShifterOperand& so, Condition cond) {
124   EmitDataProcessing(cond, ORR, 1, rn, rd, so);
125 }
126 
127 
mov(Register rd,const ShifterOperand & so,Condition cond)128 void Thumb2Assembler::mov(Register rd, const ShifterOperand& so, Condition cond) {
129   EmitDataProcessing(cond, MOV, 0, R0, rd, so);
130 }
131 
132 
movs(Register rd,const ShifterOperand & so,Condition cond)133 void Thumb2Assembler::movs(Register rd, const ShifterOperand& so, Condition cond) {
134   EmitDataProcessing(cond, MOV, 1, R0, rd, so);
135 }
136 
137 
bic(Register rd,Register rn,const ShifterOperand & so,Condition cond)138 void Thumb2Assembler::bic(Register rd, Register rn, const ShifterOperand& so,
139                        Condition cond) {
140   EmitDataProcessing(cond, BIC, 0, rn, rd, so);
141 }
142 
143 
mvn(Register rd,const ShifterOperand & so,Condition cond)144 void Thumb2Assembler::mvn(Register rd, const ShifterOperand& so, Condition cond) {
145   EmitDataProcessing(cond, MVN, 0, R0, rd, so);
146 }
147 
148 
mvns(Register rd,const ShifterOperand & so,Condition cond)149 void Thumb2Assembler::mvns(Register rd, const ShifterOperand& so, Condition cond) {
150   EmitDataProcessing(cond, MVN, 1, R0, rd, so);
151 }
152 
153 
mul(Register rd,Register rn,Register rm,Condition cond)154 void Thumb2Assembler::mul(Register rd, Register rn, Register rm, Condition cond) {
155   if (rd == rm && !IsHighRegister(rd) && !IsHighRegister(rn) && !force_32bit_) {
156     // 16 bit.
157     int16_t encoding = B14 | B9 | B8 | B6 |
158         rn << 3 | rd;
159     Emit16(encoding);
160   } else {
161     // 32 bit.
162     uint32_t op1 = 0b000;
163     uint32_t op2 = 0b00;
164     int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 |
165         op1 << 20 |
166         B15 | B14 | B13 | B12 |
167         op2 << 4 |
168         static_cast<uint32_t>(rd) << 8 |
169         static_cast<uint32_t>(rn) << 16 |
170         static_cast<uint32_t>(rm);
171 
172     Emit32(encoding);
173   }
174 }
175 
176 
mla(Register rd,Register rn,Register rm,Register ra,Condition cond)177 void Thumb2Assembler::mla(Register rd, Register rn, Register rm, Register ra,
178                           Condition cond) {
179   uint32_t op1 = 0b000;
180   uint32_t op2 = 0b00;
181   int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 |
182       op1 << 20 |
183       op2 << 4 |
184       static_cast<uint32_t>(rd) << 8 |
185       static_cast<uint32_t>(ra) << 12 |
186       static_cast<uint32_t>(rn) << 16 |
187       static_cast<uint32_t>(rm);
188 
189   Emit32(encoding);
190 }
191 
192 
mls(Register rd,Register rn,Register rm,Register ra,Condition cond)193 void Thumb2Assembler::mls(Register rd, Register rn, Register rm, Register ra,
194                           Condition cond) {
195   uint32_t op1 = 0b000;
196   uint32_t op2 = 0b01;
197   int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 |
198       op1 << 20 |
199       op2 << 4 |
200       static_cast<uint32_t>(rd) << 8 |
201       static_cast<uint32_t>(ra) << 12 |
202       static_cast<uint32_t>(rn) << 16 |
203       static_cast<uint32_t>(rm);
204 
205   Emit32(encoding);
206 }
207 
208 
umull(Register rd_lo,Register rd_hi,Register rn,Register rm,Condition cond)209 void Thumb2Assembler::umull(Register rd_lo, Register rd_hi, Register rn,
210                             Register rm, Condition cond) {
211   uint32_t op1 = 0b010;
212   uint32_t op2 = 0b0000;
213   int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 |
214       op1 << 20 |
215       op2 << 4 |
216       static_cast<uint32_t>(rd_lo) << 12 |
217       static_cast<uint32_t>(rd_hi) << 8 |
218       static_cast<uint32_t>(rn) << 16 |
219       static_cast<uint32_t>(rm);
220 
221   Emit32(encoding);
222 }
223 
224 
sdiv(Register rd,Register rn,Register rm,Condition cond)225 void Thumb2Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) {
226   uint32_t op1 = 0b001;
227   uint32_t op2 = 0b1111;
228   int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 | B20 |
229       op1 << 20 |
230       op2 << 4 |
231       0xf << 12 |
232       static_cast<uint32_t>(rd) << 8 |
233       static_cast<uint32_t>(rn) << 16 |
234       static_cast<uint32_t>(rm);
235 
236   Emit32(encoding);
237 }
238 
239 
udiv(Register rd,Register rn,Register rm,Condition cond)240 void Thumb2Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) {
241   uint32_t op1 = 0b001;
242   uint32_t op2 = 0b1111;
243   int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 | B21 | B20 |
244       op1 << 20 |
245       op2 << 4 |
246       0xf << 12 |
247       static_cast<uint32_t>(rd) << 8 |
248       static_cast<uint32_t>(rn) << 16 |
249       static_cast<uint32_t>(rm);
250 
251   Emit32(encoding);
252 }
253 
254 
ldr(Register rd,const Address & ad,Condition cond)255 void Thumb2Assembler::ldr(Register rd, const Address& ad, Condition cond) {
256   EmitLoadStore(cond, true, false, false, false, rd, ad);
257 }
258 
259 
str(Register rd,const Address & ad,Condition cond)260 void Thumb2Assembler::str(Register rd, const Address& ad, Condition cond) {
261   EmitLoadStore(cond, false, false, false, false, rd, ad);
262 }
263 
264 
ldrb(Register rd,const Address & ad,Condition cond)265 void Thumb2Assembler::ldrb(Register rd, const Address& ad, Condition cond) {
266   EmitLoadStore(cond, true, true, false, false, rd, ad);
267 }
268 
269 
strb(Register rd,const Address & ad,Condition cond)270 void Thumb2Assembler::strb(Register rd, const Address& ad, Condition cond) {
271   EmitLoadStore(cond, false, true, false, false, rd, ad);
272 }
273 
274 
ldrh(Register rd,const Address & ad,Condition cond)275 void Thumb2Assembler::ldrh(Register rd, const Address& ad, Condition cond) {
276   EmitLoadStore(cond, true, false, true, false, rd, ad);
277 }
278 
279 
strh(Register rd,const Address & ad,Condition cond)280 void Thumb2Assembler::strh(Register rd, const Address& ad, Condition cond) {
281   EmitLoadStore(cond, false, false, true, false, rd, ad);
282 }
283 
284 
ldrsb(Register rd,const Address & ad,Condition cond)285 void Thumb2Assembler::ldrsb(Register rd, const Address& ad, Condition cond) {
286   EmitLoadStore(cond, true, true, false, true, rd, ad);
287 }
288 
289 
ldrsh(Register rd,const Address & ad,Condition cond)290 void Thumb2Assembler::ldrsh(Register rd, const Address& ad, Condition cond) {
291   EmitLoadStore(cond, true, false, true, true, rd, ad);
292 }
293 
294 
ldrd(Register rd,const Address & ad,Condition cond)295 void Thumb2Assembler::ldrd(Register rd, const Address& ad, Condition cond) {
296   CHECK_EQ(rd % 2, 0);
297   // This is different from other loads.  The encoding is like ARM.
298   int32_t encoding = B31 | B30 | B29 | B27 | B22 | B20 |
299       static_cast<int32_t>(rd) << 12 |
300       (static_cast<int32_t>(rd) + 1) << 8 |
301       ad.encodingThumbLdrdStrd();
302   Emit32(encoding);
303 }
304 
305 
strd(Register rd,const Address & ad,Condition cond)306 void Thumb2Assembler::strd(Register rd, const Address& ad, Condition cond) {
307   CHECK_EQ(rd % 2, 0);
308   // This is different from other loads.  The encoding is like ARM.
309   int32_t encoding = B31 | B30 | B29 | B27 | B22 |
310       static_cast<int32_t>(rd) << 12 |
311       (static_cast<int32_t>(rd) + 1) << 8 |
312       ad.encodingThumbLdrdStrd();
313   Emit32(encoding);
314 }
315 
316 
ldm(BlockAddressMode am,Register base,RegList regs,Condition cond)317 void Thumb2Assembler::ldm(BlockAddressMode am,
318                           Register base,
319                           RegList regs,
320                           Condition cond) {
321   if (__builtin_popcount(regs) == 1) {
322     // Thumb doesn't support one reg in the list.
323     // Find the register number.
324     int reg = 0;
325     while (reg < 16) {
326       if ((regs & (1 << reg)) != 0) {
327          break;
328       }
329       ++reg;
330     }
331     CHECK_LT(reg, 16);
332     CHECK(am == DB_W);      // Only writeback is supported.
333     ldr(static_cast<Register>(reg), Address(base, kRegisterSize, Address::PostIndex), cond);
334   } else {
335     EmitMultiMemOp(cond, am, true, base, regs);
336   }
337 }
338 
339 
stm(BlockAddressMode am,Register base,RegList regs,Condition cond)340 void Thumb2Assembler::stm(BlockAddressMode am,
341                           Register base,
342                           RegList regs,
343                           Condition cond) {
344   if (__builtin_popcount(regs) == 1) {
345     // Thumb doesn't support one reg in the list.
346     // Find the register number.
347     int reg = 0;
348     while (reg < 16) {
349       if ((regs & (1 << reg)) != 0) {
350          break;
351       }
352       ++reg;
353     }
354     CHECK_LT(reg, 16);
355     CHECK(am == IA || am == IA_W);
356     Address::Mode strmode = am == IA ? Address::PreIndex : Address::Offset;
357     str(static_cast<Register>(reg), Address(base, -kRegisterSize, strmode), cond);
358   } else {
359     EmitMultiMemOp(cond, am, false, base, regs);
360   }
361 }
362 
363 
vmovs(SRegister sd,float s_imm,Condition cond)364 bool Thumb2Assembler::vmovs(SRegister sd, float s_imm, Condition cond) {
365   uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
366   if (((imm32 & ((1 << 19) - 1)) == 0) &&
367       ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
368        (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
369     uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
370         ((imm32 >> 19) & ((1 << 6) -1));
371     EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
372                sd, S0, S0);
373     return true;
374   }
375   return false;
376 }
377 
378 
vmovd(DRegister dd,double d_imm,Condition cond)379 bool Thumb2Assembler::vmovd(DRegister dd, double d_imm, Condition cond) {
380   uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
381   if (((imm64 & ((1LL << 48) - 1)) == 0) &&
382       ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
383        (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
384     uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
385         ((imm64 >> 48) & ((1 << 6) -1));
386     EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
387                dd, D0, D0);
388     return true;
389   }
390   return false;
391 }
392 
393 
vmovs(SRegister sd,SRegister sm,Condition cond)394 void Thumb2Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
395   EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
396 }
397 
398 
vmovd(DRegister dd,DRegister dm,Condition cond)399 void Thumb2Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
400   EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
401 }
402 
403 
vadds(SRegister sd,SRegister sn,SRegister sm,Condition cond)404 void Thumb2Assembler::vadds(SRegister sd, SRegister sn, SRegister sm,
405                             Condition cond) {
406   EmitVFPsss(cond, B21 | B20, sd, sn, sm);
407 }
408 
409 
vaddd(DRegister dd,DRegister dn,DRegister dm,Condition cond)410 void Thumb2Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
411                             Condition cond) {
412   EmitVFPddd(cond, B21 | B20, dd, dn, dm);
413 }
414 
415 
vsubs(SRegister sd,SRegister sn,SRegister sm,Condition cond)416 void Thumb2Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
417                             Condition cond) {
418   EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
419 }
420 
421 
vsubd(DRegister dd,DRegister dn,DRegister dm,Condition cond)422 void Thumb2Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
423                             Condition cond) {
424   EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
425 }
426 
427 
vmuls(SRegister sd,SRegister sn,SRegister sm,Condition cond)428 void Thumb2Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
429                             Condition cond) {
430   EmitVFPsss(cond, B21, sd, sn, sm);
431 }
432 
433 
vmuld(DRegister dd,DRegister dn,DRegister dm,Condition cond)434 void Thumb2Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
435                             Condition cond) {
436   EmitVFPddd(cond, B21, dd, dn, dm);
437 }
438 
439 
vmlas(SRegister sd,SRegister sn,SRegister sm,Condition cond)440 void Thumb2Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
441                             Condition cond) {
442   EmitVFPsss(cond, 0, sd, sn, sm);
443 }
444 
445 
vmlad(DRegister dd,DRegister dn,DRegister dm,Condition cond)446 void Thumb2Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
447                             Condition cond) {
448   EmitVFPddd(cond, 0, dd, dn, dm);
449 }
450 
451 
vmlss(SRegister sd,SRegister sn,SRegister sm,Condition cond)452 void Thumb2Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
453                             Condition cond) {
454   EmitVFPsss(cond, B6, sd, sn, sm);
455 }
456 
457 
vmlsd(DRegister dd,DRegister dn,DRegister dm,Condition cond)458 void Thumb2Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
459                             Condition cond) {
460   EmitVFPddd(cond, B6, dd, dn, dm);
461 }
462 
463 
vdivs(SRegister sd,SRegister sn,SRegister sm,Condition cond)464 void Thumb2Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
465                             Condition cond) {
466   EmitVFPsss(cond, B23, sd, sn, sm);
467 }
468 
469 
vdivd(DRegister dd,DRegister dn,DRegister dm,Condition cond)470 void Thumb2Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
471                             Condition cond) {
472   EmitVFPddd(cond, B23, dd, dn, dm);
473 }
474 
475 
vabss(SRegister sd,SRegister sm,Condition cond)476 void Thumb2Assembler::vabss(SRegister sd, SRegister sm, Condition cond) {
477   EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
478 }
479 
480 
vabsd(DRegister dd,DRegister dm,Condition cond)481 void Thumb2Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
482   EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
483 }
484 
485 
vnegs(SRegister sd,SRegister sm,Condition cond)486 void Thumb2Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
487   EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
488 }
489 
490 
vnegd(DRegister dd,DRegister dm,Condition cond)491 void Thumb2Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
492   EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
493 }
494 
495 
vsqrts(SRegister sd,SRegister sm,Condition cond)496 void Thumb2Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
497   EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
498 }
499 
vsqrtd(DRegister dd,DRegister dm,Condition cond)500 void Thumb2Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
501   EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
502 }
503 
504 
vcvtsd(SRegister sd,DRegister dm,Condition cond)505 void Thumb2Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
506   EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
507 }
508 
509 
vcvtds(DRegister dd,SRegister sm,Condition cond)510 void Thumb2Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
511   EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
512 }
513 
514 
vcvtis(SRegister sd,SRegister sm,Condition cond)515 void Thumb2Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
516   EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
517 }
518 
519 
vcvtid(SRegister sd,DRegister dm,Condition cond)520 void Thumb2Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
521   EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
522 }
523 
524 
vcvtsi(SRegister sd,SRegister sm,Condition cond)525 void Thumb2Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
526   EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
527 }
528 
529 
vcvtdi(DRegister dd,SRegister sm,Condition cond)530 void Thumb2Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
531   EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
532 }
533 
534 
vcvtus(SRegister sd,SRegister sm,Condition cond)535 void Thumb2Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
536   EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
537 }
538 
539 
vcvtud(SRegister sd,DRegister dm,Condition cond)540 void Thumb2Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
541   EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
542 }
543 
544 
vcvtsu(SRegister sd,SRegister sm,Condition cond)545 void Thumb2Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
546   EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
547 }
548 
549 
vcvtdu(DRegister dd,SRegister sm,Condition cond)550 void Thumb2Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
551   EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
552 }
553 
554 
vcmps(SRegister sd,SRegister sm,Condition cond)555 void Thumb2Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
556   EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
557 }
558 
559 
vcmpd(DRegister dd,DRegister dm,Condition cond)560 void Thumb2Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
561   EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
562 }
563 
564 
vcmpsz(SRegister sd,Condition cond)565 void Thumb2Assembler::vcmpsz(SRegister sd, Condition cond) {
566   EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
567 }
568 
569 
vcmpdz(DRegister dd,Condition cond)570 void Thumb2Assembler::vcmpdz(DRegister dd, Condition cond) {
571   EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
572 }
573 
b(Label * label,Condition cond)574 void Thumb2Assembler::b(Label* label, Condition cond) {
575   EmitBranch(cond, label, false, false);
576 }
577 
578 
bl(Label * label,Condition cond)579 void Thumb2Assembler::bl(Label* label, Condition cond) {
580   CheckCondition(cond);
581   EmitBranch(cond, label, true, false);
582 }
583 
584 
blx(Label * label)585 void Thumb2Assembler::blx(Label* label) {
586   EmitBranch(AL, label, true, true);
587 }
588 
589 
MarkExceptionHandler(Label * label)590 void Thumb2Assembler::MarkExceptionHandler(Label* label) {
591   EmitDataProcessing(AL, TST, 1, PC, R0, ShifterOperand(0));
592   Label l;
593   b(&l);
594   EmitBranch(AL, label, false, false);
595   Bind(&l);
596 }
597 
598 
Emit32(int32_t value)599 void Thumb2Assembler::Emit32(int32_t value) {
600   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
601   buffer_.Emit<int16_t>(value >> 16);
602   buffer_.Emit<int16_t>(value & 0xffff);
603 }
604 
605 
Emit16(int16_t value)606 void Thumb2Assembler::Emit16(int16_t value) {
607   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
608   buffer_.Emit<int16_t>(value);
609 }
610 
611 
Is32BitDataProcessing(Condition cond,Opcode opcode,int set_cc,Register rn,Register rd,const ShifterOperand & so)612 bool Thumb2Assembler::Is32BitDataProcessing(Condition cond,
613                                             Opcode opcode,
614                                             int set_cc,
615                                             Register rn,
616                                             Register rd,
617                                             const ShifterOperand& so) {
618   if (force_32bit_) {
619     return true;
620   }
621 
622   bool can_contain_high_register = (opcode == MOV)
623       || ((opcode == ADD || opcode == SUB) && (rn == rd));
624 
625   if (IsHighRegister(rd) || IsHighRegister(rn)) {
626     if (can_contain_high_register) {
627       // There are high register instructions available for this opcode.
628       // However, there is no RRX available.
629       if (so.IsShift() && so.GetShift() == RRX) {
630         return true;
631       }
632 
633       // Check special case for SP relative ADD and SUB immediate.
634       if ((opcode == ADD || opcode == SUB) && so.IsImmediate()) {
635         // If rn is SP and rd is a high register we need to use a 32 bit encoding.
636          if (rn == SP && rd != SP && IsHighRegister(rd)) {
637            return true;
638          }
639 
640          uint32_t imm = so.GetImmediate();
641          // If the immediates are out of range use 32 bit.
642          if (rd == SP && rn == SP) {
643            if (imm > (1 << 9)) {    // 9 bit immediate.
644              return true;
645            }
646          } else if (opcode == ADD && rd != SP && rn == SP) {   // 10 bit immediate.
647            if (imm > (1 << 10)) {
648              return true;
649            }
650          } else if (opcode == SUB && rd != SP && rn == SP) {
651            // SUB rd, SP, #imm is always 32 bit.
652            return true;
653          }
654       }
655     }
656 
657     // The ADD,SUB and MOV instructions that work with high registers don't have
658     // immediate variants.
659     if (so.IsImmediate()) {
660       return true;
661     }
662 
663     if (!can_contain_high_register) {
664       return true;
665     }
666   }
667 
668   if (so.IsRegister() && IsHighRegister(so.GetRegister()) && !can_contain_high_register) {
669     return true;
670   }
671 
672   // Check for MOV with an ROR.
673   if (opcode == MOV && so.IsRegister() && so.IsShift() && so.GetShift() == ROR) {
674     if (so.GetImmediate() != 0) {
675       return true;
676     }
677   }
678 
679   bool rn_is_valid = true;
680 
681   // Check for single operand instructions and ADD/SUB.
682   switch (opcode) {
683     case CMP:
684     case MOV:
685     case TST:
686     case MVN:
687       rn_is_valid = false;      // There is no Rn for these instructions.
688       break;
689     case TEQ:
690       return true;
691       break;
692     case ADD:
693     case SUB:
694       break;
695     default:
696       if (so.IsRegister() && rd != rn) {
697         return true;
698       }
699   }
700 
701   if (so.IsImmediate()) {
702     if (rn_is_valid && rn != rd) {
703       // The only thumb1 instruction with a register and an immediate are ADD and SUB.  The
704       // immediate must be 3 bits.
705       if (opcode != ADD && opcode != SUB) {
706         return true;
707       } else {
708         // Check that the immediate is 3 bits for ADD and SUB.
709         if (so.GetImmediate() >= 8) {
710           return true;
711         }
712       }
713     } else {
714       // ADD, SUB, CMP and MOV may be thumb1 only if the immediate is 8 bits.
715       if (!(opcode == ADD || opcode == SUB || opcode == MOV || opcode == CMP)) {
716         return true;
717       } else {
718         if (so.GetImmediate() > 255) {
719           return true;
720         }
721       }
722     }
723   }
724 
725   // The instruction can be encoded in 16 bits.
726   return false;
727 }
728 
729 
Emit32BitDataProcessing(Condition cond,Opcode opcode,int set_cc,Register rn,Register rd,const ShifterOperand & so)730 void Thumb2Assembler::Emit32BitDataProcessing(Condition cond,
731                                               Opcode opcode,
732                                               int set_cc,
733                                               Register rn,
734                                               Register rd,
735                                               const ShifterOperand& so) {
736   uint8_t thumb_opcode = 0b11111111;
737   switch (opcode) {
738     case AND: thumb_opcode = 0b0000; break;
739     case EOR: thumb_opcode = 0b0100; break;
740     case SUB: thumb_opcode = 0b1101; break;
741     case RSB: thumb_opcode = 0b1110; break;
742     case ADD: thumb_opcode = 0b1000; break;
743     case ADC: thumb_opcode = 0b1010; break;
744     case SBC: thumb_opcode = 0b1011; break;
745     case RSC: break;
746     case TST: thumb_opcode = 0b0000; set_cc = true; rd = PC; break;
747     case TEQ: thumb_opcode = 0b0100; set_cc = true; rd = PC; break;
748     case CMP: thumb_opcode = 0b1101; set_cc = true; rd = PC; break;
749     case CMN: thumb_opcode = 0b1000; set_cc = true; rd = PC; break;
750     case ORR: thumb_opcode = 0b0010; break;
751     case MOV: thumb_opcode = 0b0010; rn = PC; break;
752     case BIC: thumb_opcode = 0b0001; break;
753     case MVN: thumb_opcode = 0b0011; rn = PC; break;
754     default:
755       break;
756   }
757 
758   if (thumb_opcode == 0b11111111) {
759     LOG(FATAL) << "Invalid thumb2 opcode " << opcode;
760   }
761 
762   int32_t encoding = 0;
763   if (so.IsImmediate()) {
764     // Check special cases.
765     if ((opcode == SUB || opcode == ADD) && (so.GetImmediate() < (1u << 12))) {
766       if (opcode == SUB) {
767         thumb_opcode = 0b0101;
768       } else {
769         thumb_opcode = 0;
770       }
771       uint32_t imm = so.GetImmediate();
772 
773       uint32_t i = (imm >> 11) & 1;
774       uint32_t imm3 = (imm >> 8) & 0b111;
775       uint32_t imm8 = imm & 0xff;
776 
777       encoding = B31 | B30 | B29 | B28 | B25 |
778            thumb_opcode << 21 |
779            rn << 16 |
780            rd << 8 |
781            i << 26 |
782            imm3 << 12 |
783            imm8;
784     } else {
785       // Modified immediate.
786       uint32_t imm = ModifiedImmediate(so.encodingThumb());
787       if (imm == kInvalidModifiedImmediate) {
788         LOG(FATAL) << "Immediate value cannot fit in thumb2 modified immediate";
789       }
790       encoding = B31 | B30 | B29 | B28 |
791           thumb_opcode << 21 |
792           set_cc << 20 |
793           rn << 16 |
794           rd << 8 |
795           imm;
796     }
797   } else if (so.IsRegister()) {
798      // Register (possibly shifted)
799      encoding = B31 | B30 | B29 | B27 | B25 |
800          thumb_opcode << 21 |
801          set_cc << 20 |
802          rn << 16 |
803          rd << 8 |
804          so.encodingThumb();
805   }
806   Emit32(encoding);
807 }
808 
809 
Emit16BitDataProcessing(Condition cond,Opcode opcode,int set_cc,Register rn,Register rd,const ShifterOperand & so)810 void Thumb2Assembler::Emit16BitDataProcessing(Condition cond,
811                                               Opcode opcode,
812                                               int set_cc,
813                                               Register rn,
814                                               Register rd,
815                                               const ShifterOperand& so) {
816   if (opcode == ADD || opcode == SUB) {
817     Emit16BitAddSub(cond, opcode, set_cc, rn, rd, so);
818     return;
819   }
820   uint8_t thumb_opcode = 0b11111111;
821   // Thumb1.
822   uint8_t dp_opcode = 0b01;
823   uint8_t opcode_shift = 6;
824   uint8_t rd_shift = 0;
825   uint8_t rn_shift = 3;
826   uint8_t immediate_shift = 0;
827   bool use_immediate = false;
828   uint8_t immediate = 0;
829 
830   if (opcode == MOV && so.IsRegister() && so.IsShift()) {
831     // Convert shifted mov operand2 into 16 bit opcodes.
832     dp_opcode = 0;
833     opcode_shift = 11;
834 
835     use_immediate = true;
836     immediate = so.GetImmediate();
837     immediate_shift = 6;
838 
839     rn = so.GetRegister();
840 
841     switch (so.GetShift()) {
842     case LSL: thumb_opcode = 0b00; break;
843     case LSR: thumb_opcode = 0b01; break;
844     case ASR: thumb_opcode = 0b10; break;
845     case ROR:
846       // ROR doesn't allow immediates.
847       thumb_opcode = 0b111;
848       dp_opcode = 0b01;
849       opcode_shift = 6;
850       use_immediate = false;
851       break;
852     case RRX: break;
853     default:
854      break;
855     }
856   } else {
857     if (so.IsImmediate()) {
858       use_immediate = true;
859       immediate = so.GetImmediate();
860     }
861 
862     switch (opcode) {
863       case AND: thumb_opcode = 0b0000; break;
864       case EOR: thumb_opcode = 0b0001; break;
865       case SUB: break;
866       case RSB: thumb_opcode = 0b1001; break;
867       case ADD: break;
868       case ADC: thumb_opcode = 0b0101; break;
869       case SBC: thumb_opcode = 0b0110; break;
870       case RSC: break;
871       case TST: thumb_opcode = 0b1000; rn = so.GetRegister(); break;
872       case TEQ: break;
873       case CMP:
874         if (use_immediate) {
875           // T2 encoding.
876            dp_opcode = 0;
877            opcode_shift = 11;
878            thumb_opcode = 0b101;
879            rd_shift = 8;
880            rn_shift = 8;
881         } else {
882           thumb_opcode = 0b1010;
883           rd = rn;
884           rn = so.GetRegister();
885         }
886 
887         break;
888       case CMN: {
889         thumb_opcode = 0b1011;
890         rd = rn;
891         rn = so.GetRegister();
892         break;
893       }
894       case ORR: thumb_opcode = 0b1100; break;
895       case MOV:
896         dp_opcode = 0;
897         if (use_immediate) {
898           // T2 encoding.
899           opcode_shift = 11;
900           thumb_opcode = 0b100;
901           rd_shift = 8;
902           rn_shift = 8;
903         } else {
904           rn = so.GetRegister();
905           if (IsHighRegister(rn) || IsHighRegister(rd)) {
906             // Special mov for high registers.
907             dp_opcode = 0b01;
908             opcode_shift = 7;
909             // Put the top bit of rd into the bottom bit of the opcode.
910             thumb_opcode = 0b0001100 | static_cast<uint32_t>(rd) >> 3;
911             rd = static_cast<Register>(static_cast<uint32_t>(rd) & 0b111);
912           } else {
913             thumb_opcode = 0;
914           }
915         }
916         break;
917       case BIC: thumb_opcode = 0b1110; break;
918       case MVN: thumb_opcode = 0b1111; rn = so.GetRegister(); break;
919       default:
920         break;
921     }
922   }
923 
924   if (thumb_opcode == 0b11111111) {
925     LOG(FATAL) << "Invalid thumb1 opcode " << opcode;
926   }
927 
928   int16_t encoding = dp_opcode << 14 |
929       (thumb_opcode << opcode_shift) |
930       rd << rd_shift |
931       rn << rn_shift |
932       (use_immediate ? (immediate << immediate_shift) : 0);
933 
934   Emit16(encoding);
935 }
936 
937 
938 // ADD and SUB are complex enough to warrant their own emitter.
Emit16BitAddSub(Condition cond,Opcode opcode,int set_cc,Register rn,Register rd,const ShifterOperand & so)939 void Thumb2Assembler::Emit16BitAddSub(Condition cond,
940                                       Opcode opcode,
941                                       int set_cc,
942                                       Register rn,
943                                       Register rd,
944                                       const ShifterOperand& so) {
945   uint8_t dp_opcode = 0;
946   uint8_t opcode_shift = 6;
947   uint8_t rd_shift = 0;
948   uint8_t rn_shift = 3;
949   uint8_t immediate_shift = 0;
950   bool use_immediate = false;
951   uint8_t immediate = 0;
952   uint8_t thumb_opcode;;
953 
954   if (so.IsImmediate()) {
955     use_immediate = true;
956     immediate = so.GetImmediate();
957   }
958 
959   switch (opcode) {
960     case ADD:
961       if (so.IsRegister()) {
962         Register rm = so.GetRegister();
963         if (rn == rd) {
964           // Can use T2 encoding (allows 4 bit registers)
965           dp_opcode = 0b01;
966           opcode_shift = 10;
967           thumb_opcode = 0b0001;
968           // Make Rn also contain the top bit of rd.
969           rn = static_cast<Register>(static_cast<uint32_t>(rm) |
970                                      (static_cast<uint32_t>(rd) & 0b1000) << 1);
971           rd = static_cast<Register>(static_cast<uint32_t>(rd) & 0b111);
972         } else {
973           // T1.
974           opcode_shift = 9;
975           thumb_opcode = 0b01100;
976           immediate = static_cast<uint32_t>(so.GetRegister());
977           use_immediate = true;
978           immediate_shift = 6;
979         }
980       } else {
981         // Immediate.
982         if (rd == SP && rn == SP) {
983           // ADD sp, sp, #imm
984           dp_opcode = 0b10;
985           thumb_opcode = 0b11;
986           opcode_shift = 12;
987           CHECK_LT(immediate, (1 << 9));
988           CHECK_EQ((immediate & 0b11), 0);
989 
990           // Remove rd and rn from instruction by orring it with immed and clearing bits.
991           rn = R0;
992           rd = R0;
993           rd_shift = 0;
994           rn_shift = 0;
995           immediate >>= 2;
996         } else if (rd != SP && rn == SP) {
997           // ADD rd, SP, #imm
998           dp_opcode = 0b10;
999           thumb_opcode = 0b101;
1000           opcode_shift = 11;
1001           CHECK_LT(immediate, (1 << 10));
1002           CHECK_EQ((immediate & 0b11), 0);
1003 
1004           // Remove rn from instruction.
1005           rn = R0;
1006           rn_shift = 0;
1007           rd_shift = 8;
1008           immediate >>= 2;
1009         } else if (rn != rd) {
1010           // Must use T1.
1011           opcode_shift = 9;
1012           thumb_opcode = 0b01110;
1013           immediate_shift = 6;
1014         } else {
1015           // T2 encoding.
1016           opcode_shift = 11;
1017           thumb_opcode = 0b110;
1018           rd_shift = 8;
1019           rn_shift = 8;
1020         }
1021       }
1022       break;
1023 
1024     case SUB:
1025       if (so.IsRegister()) {
1026          // T1.
1027          opcode_shift = 9;
1028          thumb_opcode = 0b01101;
1029          immediate = static_cast<uint32_t>(so.GetRegister());
1030          use_immediate = true;
1031          immediate_shift = 6;
1032        } else {
1033          if (rd == SP && rn == SP) {
1034            // SUB sp, sp, #imm
1035            dp_opcode = 0b10;
1036            thumb_opcode = 0b1100001;
1037            opcode_shift = 7;
1038            CHECK_LT(immediate, (1 << 9));
1039            CHECK_EQ((immediate & 0b11), 0);
1040 
1041            // Remove rd and rn from instruction by orring it with immed and clearing bits.
1042            rn = R0;
1043            rd = R0;
1044            rd_shift = 0;
1045            rn_shift = 0;
1046            immediate >>= 2;
1047          } else if (rn != rd) {
1048            // Must use T1.
1049            opcode_shift = 9;
1050            thumb_opcode = 0b01111;
1051            immediate_shift = 6;
1052          } else {
1053            // T2 encoding.
1054            opcode_shift = 11;
1055            thumb_opcode = 0b111;
1056            rd_shift = 8;
1057            rn_shift = 8;
1058          }
1059        }
1060       break;
1061     default:
1062       LOG(FATAL) << "This opcode is not an ADD or SUB: " << opcode;
1063       return;
1064   }
1065 
1066   int16_t encoding = dp_opcode << 14 |
1067       (thumb_opcode << opcode_shift) |
1068       rd << rd_shift |
1069       rn << rn_shift |
1070       (use_immediate ? (immediate << immediate_shift) : 0);
1071 
1072   Emit16(encoding);
1073 }
1074 
1075 
EmitDataProcessing(Condition cond,Opcode opcode,int set_cc,Register rn,Register rd,const ShifterOperand & so)1076 void Thumb2Assembler::EmitDataProcessing(Condition cond,
1077                                          Opcode opcode,
1078                                          int set_cc,
1079                                          Register rn,
1080                                          Register rd,
1081                                          const ShifterOperand& so) {
1082   CHECK_NE(rd, kNoRegister);
1083   CheckCondition(cond);
1084 
1085   if (Is32BitDataProcessing(cond, opcode, set_cc, rn, rd, so)) {
1086     Emit32BitDataProcessing(cond, opcode, set_cc, rn, rd, so);
1087   } else {
1088     Emit16BitDataProcessing(cond, opcode, set_cc, rn, rd, so);
1089   }
1090 }
1091 
EmitShift(Register rd,Register rm,Shift shift,uint8_t amount,bool setcc)1092 void Thumb2Assembler::EmitShift(Register rd, Register rm, Shift shift, uint8_t amount, bool setcc) {
1093   CHECK_LT(amount, (1 << 5));
1094   if (IsHighRegister(rd) || IsHighRegister(rm) || shift == ROR || shift == RRX) {
1095     uint16_t opcode = 0;
1096     switch (shift) {
1097       case LSL: opcode = 0b00; break;
1098       case LSR: opcode = 0b01; break;
1099       case ASR: opcode = 0b10; break;
1100       case ROR: opcode = 0b11; break;
1101       case RRX: opcode = 0b11; amount = 0; break;
1102       default:
1103         LOG(FATAL) << "Unsupported thumb2 shift opcode";
1104     }
1105     // 32 bit.
1106     int32_t encoding = B31 | B30 | B29 | B27 | B25 | B22 |
1107         0xf << 16 | (setcc ? B20 : 0);
1108     uint32_t imm3 = amount >> 2;
1109     uint32_t imm2 = amount & 0b11;
1110     encoding |= imm3 << 12 | imm2 << 6 | static_cast<int16_t>(rm) |
1111         static_cast<int16_t>(rd) << 8 | opcode << 4;
1112     Emit32(encoding);
1113   } else {
1114     // 16 bit shift
1115     uint16_t opcode = 0;
1116     switch (shift) {
1117       case LSL: opcode = 0b00; break;
1118       case LSR: opcode = 0b01; break;
1119       case ASR: opcode = 0b10; break;
1120       default:
1121          LOG(FATAL) << "Unsupported thumb2 shift opcode";
1122     }
1123     int16_t encoding = opcode << 11 | amount << 6 | static_cast<int16_t>(rm) << 3 |
1124         static_cast<int16_t>(rd);
1125     Emit16(encoding);
1126   }
1127 }
1128 
EmitShift(Register rd,Register rn,Shift shift,Register rm,bool setcc)1129 void Thumb2Assembler::EmitShift(Register rd, Register rn, Shift shift, Register rm, bool setcc) {
1130   CHECK_NE(shift, RRX);
1131   bool must_be_32bit = false;
1132   if (IsHighRegister(rd) || IsHighRegister(rm) || IsHighRegister(rn) || rd != rn) {
1133     must_be_32bit = true;
1134   }
1135 
1136   if (must_be_32bit) {
1137     uint16_t opcode = 0;
1138      switch (shift) {
1139        case LSL: opcode = 0b00; break;
1140        case LSR: opcode = 0b01; break;
1141        case ASR: opcode = 0b10; break;
1142        case ROR: opcode = 0b11; break;
1143        default:
1144          LOG(FATAL) << "Unsupported thumb2 shift opcode";
1145      }
1146      // 32 bit.
1147      int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 |
1148          0xf << 12 | (setcc ? B20 : 0);
1149      encoding |= static_cast<int16_t>(rn) << 16 | static_cast<int16_t>(rm) |
1150          static_cast<int16_t>(rd) << 8 | opcode << 21;
1151      Emit32(encoding);
1152   } else {
1153     uint16_t opcode = 0;
1154     switch (shift) {
1155       case LSL: opcode = 0b0010; break;
1156       case LSR: opcode = 0b0011; break;
1157       case ASR: opcode = 0b0100; break;
1158       default:
1159          LOG(FATAL) << "Unsupported thumb2 shift opcode";
1160     }
1161     int16_t encoding = B14 | opcode << 6 | static_cast<int16_t>(rm) << 3 |
1162         static_cast<int16_t>(rd);
1163     Emit16(encoding);
1164   }
1165 }
1166 
1167 
1168 
Emit(AssemblerBuffer * buffer) const1169 void Thumb2Assembler::Branch::Emit(AssemblerBuffer* buffer) const {
1170   bool link = type_ == kUnconditionalLinkX || type_ == kUnconditionalLink;
1171   bool x = type_ == kUnconditionalX || type_ == kUnconditionalLinkX;
1172   int32_t offset = target_ - location_;
1173 
1174   if (size_ == k32Bit) {
1175     int32_t encoding = B31 | B30 | B29 | B28 | B15;
1176     if (link) {
1177       // BL or BLX immediate.
1178       encoding |= B14;
1179       if (!x) {
1180         encoding |= B12;
1181       } else {
1182         // Bottom bit of offset must be 0.
1183         CHECK_EQ((offset & 1), 0);
1184       }
1185     } else {
1186       if (x) {
1187         LOG(FATAL) << "Invalid use of BX";
1188       } else {
1189         if (cond_ == AL) {
1190           // Can use the T4 encoding allowing a 24 bit offset.
1191           if (!x) {
1192             encoding |= B12;
1193           }
1194         } else {
1195           // Must be T3 encoding with a 20 bit offset.
1196           encoding |= cond_ << 22;
1197         }
1198       }
1199     }
1200     encoding = Thumb2Assembler::EncodeBranchOffset(offset, encoding);
1201     buffer->Store<int16_t>(location_, static_cast<int16_t>(encoding >> 16));
1202     buffer->Store<int16_t>(location_+2, static_cast<int16_t>(encoding & 0xffff));
1203   } else {
1204     if (IsCompareAndBranch()) {
1205       offset -= 4;
1206       uint16_t i = (offset >> 6) & 1;
1207       uint16_t imm5 = (offset >> 1) & 0b11111;
1208       int16_t encoding = B15 | B13 | B12 |
1209             (type_ ==  kCompareAndBranchNonZero ? B11 : 0) |
1210             static_cast<uint32_t>(rn_) |
1211             B8 |
1212             i << 9 |
1213             imm5 << 3;
1214       buffer->Store<int16_t>(location_, encoding);
1215     } else {
1216       offset -= 4;    // Account for PC offset.
1217       int16_t encoding;
1218       // 16 bit.
1219       if (cond_ == AL) {
1220         encoding = B15 | B14 | B13 |
1221             ((offset >> 1) & 0x7ff);
1222       } else {
1223         encoding = B15 | B14 | B12 |
1224             cond_ << 8 | ((offset >> 1) & 0xff);
1225       }
1226       buffer->Store<int16_t>(location_, encoding);
1227     }
1228   }
1229 }
1230 
1231 
EmitCompareAndBranch(Register rn,uint16_t prev,bool n)1232 uint16_t Thumb2Assembler::EmitCompareAndBranch(Register rn, uint16_t prev, bool n) {
1233   uint32_t location = buffer_.Size();
1234 
1235   // This is always unresolved as it must be a forward branch.
1236   Emit16(prev);      // Previous link.
1237   return AddBranch(n ? Branch::kCompareAndBranchNonZero : Branch::kCompareAndBranchZero,
1238       location, rn);
1239 }
1240 
1241 
1242 // NOTE: this only support immediate offsets, not [rx,ry].
1243 // TODO: support [rx,ry] instructions.
EmitLoadStore(Condition cond,bool load,bool byte,bool half,bool is_signed,Register rd,const Address & ad)1244 void Thumb2Assembler::EmitLoadStore(Condition cond,
1245                                     bool load,
1246                                     bool byte,
1247                                     bool half,
1248                                     bool is_signed,
1249                                     Register rd,
1250                                     const Address& ad) {
1251   CHECK_NE(rd, kNoRegister);
1252   CheckCondition(cond);
1253   bool must_be_32bit = force_32bit_;
1254   if (IsHighRegister(rd)) {
1255     must_be_32bit = true;
1256   }
1257 
1258   Register rn = ad.GetRegister();
1259   if (IsHighRegister(rn) && rn != SP && rn != PC) {
1260     must_be_32bit = true;
1261   }
1262 
1263   if (is_signed || ad.GetOffset() < 0 || ad.GetMode() != Address::Offset) {
1264     must_be_32bit = true;
1265   }
1266 
1267   if (ad.IsImmediate()) {
1268     // Immediate offset
1269     int32_t offset = ad.GetOffset();
1270 
1271     // The 16 bit SP relative instruction can only have a 10 bit offset.
1272     if (rn == SP && offset >= (1 << 10)) {
1273       must_be_32bit = true;
1274     }
1275 
1276     if (byte) {
1277       // 5 bit offset, no shift.
1278       if (offset >= (1 << 5)) {
1279         must_be_32bit = true;
1280       }
1281     } else if (half) {
1282       // 6 bit offset, shifted by 1.
1283       if (offset >= (1 << 6)) {
1284         must_be_32bit = true;
1285       }
1286     } else {
1287       // 7 bit offset, shifted by 2.
1288       if (offset >= (1 << 7)) {
1289         must_be_32bit = true;
1290       }
1291     }
1292 
1293     if (must_be_32bit) {
1294       int32_t encoding = B31 | B30 | B29 | B28 | B27 |
1295           (load ? B20 : 0) |
1296           (is_signed ? B24 : 0) |
1297           static_cast<uint32_t>(rd) << 12 |
1298           ad.encodingThumb(true) |
1299           (byte ? 0 : half ? B21 : B22);
1300       Emit32(encoding);
1301     } else {
1302       // 16 bit thumb1.
1303       uint8_t opA = 0;
1304       bool sp_relative = false;
1305 
1306       if (byte) {
1307         opA = 0b0111;
1308       } else if (half) {
1309         opA = 0b1000;
1310       } else {
1311         if (rn == SP) {
1312           opA = 0b1001;
1313           sp_relative = true;
1314         } else {
1315           opA = 0b0110;
1316         }
1317       }
1318       int16_t encoding = opA << 12 |
1319           (load ? B11 : 0);
1320 
1321       CHECK_GE(offset, 0);
1322       if (sp_relative) {
1323         // SP relative, 10 bit offset.
1324         CHECK_LT(offset, (1 << 10));
1325         CHECK_EQ((offset & 0b11), 0);
1326         encoding |= rd << 8 | offset >> 2;
1327       } else {
1328         // No SP relative.  The offset is shifted right depending on
1329         // the size of the load/store.
1330         encoding |= static_cast<uint32_t>(rd);
1331 
1332         if (byte) {
1333           // 5 bit offset, no shift.
1334           CHECK_LT(offset, (1 << 5));
1335         } else if (half) {
1336           // 6 bit offset, shifted by 1.
1337           CHECK_LT(offset, (1 << 6));
1338           CHECK_EQ((offset & 0b1), 0);
1339           offset >>= 1;
1340         } else {
1341           // 7 bit offset, shifted by 2.
1342           CHECK_LT(offset, (1 << 7));
1343           CHECK_EQ((offset & 0b11), 0);
1344           offset >>= 2;
1345         }
1346         encoding |= rn << 3 | offset  << 6;
1347       }
1348 
1349       Emit16(encoding);
1350     }
1351   } else {
1352     // Register shift.
1353     if (ad.GetRegister() == PC) {
1354        // PC relative literal encoding.
1355       int32_t offset = ad.GetOffset();
1356       if (must_be_32bit || offset < 0 || offset >= (1 << 10) || !load) {
1357         int32_t up = B23;
1358         if (offset < 0) {
1359           offset = -offset;
1360           up = 0;
1361         }
1362         CHECK_LT(offset, (1 << 12));
1363         int32_t encoding = 0x1f << 27 | 0xf << 16 | B22 | (load ? B20 : 0) |
1364             offset | up |
1365             static_cast<uint32_t>(rd) << 12;
1366         Emit32(encoding);
1367       } else {
1368         // 16 bit literal load.
1369         CHECK_GE(offset, 0);
1370         CHECK_LT(offset, (1 << 10));
1371         int32_t encoding = B14 | (load ? B11 : 0) | static_cast<uint32_t>(rd) << 8 | offset >> 2;
1372         Emit16(encoding);
1373       }
1374     } else {
1375       if (ad.GetShiftCount() != 0) {
1376         // If there is a shift count this must be 32 bit.
1377         must_be_32bit = true;
1378       } else if (IsHighRegister(ad.GetRegisterOffset())) {
1379         must_be_32bit = true;
1380       }
1381 
1382       if (must_be_32bit) {
1383         int32_t encoding = 0x1f << 27 | (load ? B20 : 0) | static_cast<uint32_t>(rd) << 12 |
1384             ad.encodingThumb(true);
1385         if (half) {
1386           encoding |= B21;
1387         } else if (!byte) {
1388           encoding |= B22;
1389         }
1390         Emit32(encoding);
1391       } else {
1392         // 16 bit register offset.
1393         int32_t encoding = B14 | B12 | (load ? B11 : 0) | static_cast<uint32_t>(rd) |
1394             ad.encodingThumb(false);
1395         if (byte) {
1396           encoding |= B10;
1397         } else if (half) {
1398           encoding |= B9;
1399         }
1400         Emit16(encoding);
1401       }
1402     }
1403   }
1404 }
1405 
1406 
EmitMultiMemOp(Condition cond,BlockAddressMode am,bool load,Register base,RegList regs)1407 void Thumb2Assembler::EmitMultiMemOp(Condition cond,
1408                                      BlockAddressMode am,
1409                                      bool load,
1410                                      Register base,
1411                                      RegList regs) {
1412   CHECK_NE(base, kNoRegister);
1413   CheckCondition(cond);
1414   bool must_be_32bit = force_32bit_;
1415 
1416   if ((regs & 0xff00) != 0) {
1417     must_be_32bit = true;
1418   }
1419 
1420   uint32_t w_bit = am == IA_W || am == DB_W || am == DA_W || am == IB_W;
1421   // 16 bit always uses writeback.
1422   if (!w_bit) {
1423     must_be_32bit = true;
1424   }
1425 
1426   if (must_be_32bit) {
1427     uint32_t op = 0;
1428     switch (am) {
1429       case IA:
1430       case IA_W:
1431         op = 0b01;
1432         break;
1433       case DB:
1434       case DB_W:
1435         op = 0b10;
1436         break;
1437       case DA:
1438       case IB:
1439       case DA_W:
1440       case IB_W:
1441         LOG(FATAL) << "LDM/STM mode not supported on thumb: " << am;
1442     }
1443     if (load) {
1444       // Cannot have SP in the list.
1445       CHECK_EQ((regs & (1 << SP)), 0);
1446     } else {
1447       // Cannot have PC or SP in the list.
1448       CHECK_EQ((regs & (1 << PC | 1 << SP)), 0);
1449     }
1450     int32_t encoding = B31 | B30 | B29 | B27 |
1451                     (op << 23) |
1452                     (load ? B20 : 0) |
1453                     base << 16 |
1454                     regs |
1455                     (w_bit << 21);
1456     Emit32(encoding);
1457   } else {
1458     int16_t encoding = B15 | B14 |
1459                     (load ? B11 : 0) |
1460                     base << 8 |
1461                     regs;
1462     Emit16(encoding);
1463   }
1464 }
1465 
1466 
EmitBranch(Condition cond,Label * label,bool link,bool x)1467 void Thumb2Assembler::EmitBranch(Condition cond, Label* label, bool link, bool x) {
1468   uint32_t pc = buffer_.Size();
1469   Branch::Type branch_type;
1470   if (cond == AL) {
1471     if (link) {
1472       if (x) {
1473         branch_type = Branch::kUnconditionalLinkX;      // BLX.
1474       } else {
1475         branch_type = Branch::kUnconditionalLink;       // BX.
1476       }
1477     } else {
1478       branch_type = Branch::kUnconditional;             // B.
1479     }
1480   } else {
1481     branch_type = Branch::kConditional;                 // B<cond>.
1482   }
1483 
1484   if (label->IsBound()) {
1485     Branch::Size size = AddBranch(branch_type, pc, label->Position(), cond);  // Resolved branch.
1486 
1487     // The branch is to a bound label which means that it's a backwards branch.  We know the
1488     // current size of it so we can emit the appropriate space.  Note that if it's a 16 bit
1489     // branch the size may change if it so happens that other branches change size that change
1490     // the distance to the target and that distance puts this branch over the limit for 16 bits.
1491     if (size == Branch::k16Bit) {
1492       DCHECK(!force_32bit_branches_);
1493       Emit16(0);          // Space for a 16 bit branch.
1494     } else {
1495       Emit32(0);            // Space for a 32 bit branch.
1496     }
1497   } else {
1498     // Branch is to an unbound label.  Emit space for it.
1499     uint16_t branch_id = AddBranch(branch_type, pc, cond);    // Unresolved branch.
1500     if (force_32bit_branches_ || force_32bit_) {
1501       Emit16(static_cast<uint16_t>(label->position_));    // Emit current label link.
1502       Emit16(0);                   // another 16 bits.
1503     } else {
1504       Emit16(static_cast<uint16_t>(label->position_));    // Emit current label link.
1505     }
1506     label->LinkTo(branch_id);           // Link to the branch ID.
1507   }
1508 }
1509 
1510 
clz(Register rd,Register rm,Condition cond)1511 void Thumb2Assembler::clz(Register rd, Register rm, Condition cond) {
1512   CHECK_NE(rd, kNoRegister);
1513   CHECK_NE(rm, kNoRegister);
1514   CheckCondition(cond);
1515   CHECK_NE(rd, PC);
1516   CHECK_NE(rm, PC);
1517   int32_t encoding = B31 | B30 | B29 | B28 | B27 |
1518       B25 | B23 | B21 | B20 |
1519       static_cast<uint32_t>(rm) << 16 |
1520       0xf << 12 |
1521       static_cast<uint32_t>(rd) << 8 |
1522       B7 |
1523       static_cast<uint32_t>(rm);
1524   Emit32(encoding);
1525 }
1526 
1527 
movw(Register rd,uint16_t imm16,Condition cond)1528 void Thumb2Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
1529   CheckCondition(cond);
1530   bool must_be_32bit = force_32bit_;
1531   if (IsHighRegister(rd)|| imm16 >= 256u) {
1532     must_be_32bit = true;
1533   }
1534 
1535   if (must_be_32bit) {
1536     // Use encoding T3.
1537     uint32_t imm4 = (imm16 >> 12) & 0b1111;
1538     uint32_t i = (imm16 >> 11) & 0b1;
1539     uint32_t imm3 = (imm16 >> 8) & 0b111;
1540     uint32_t imm8 = imm16 & 0xff;
1541     int32_t encoding = B31 | B30 | B29 | B28 |
1542                     B25 | B22 |
1543                     static_cast<uint32_t>(rd) << 8 |
1544                     i << 26 |
1545                     imm4 << 16 |
1546                     imm3 << 12 |
1547                     imm8;
1548     Emit32(encoding);
1549   } else {
1550     int16_t encoding = B13 | static_cast<uint16_t>(rd) << 8 |
1551                 imm16;
1552     Emit16(encoding);
1553   }
1554 }
1555 
1556 
movt(Register rd,uint16_t imm16,Condition cond)1557 void Thumb2Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
1558   CheckCondition(cond);
1559   // Always 32 bits.
1560   uint32_t imm4 = (imm16 >> 12) & 0b1111;
1561   uint32_t i = (imm16 >> 11) & 0b1;
1562   uint32_t imm3 = (imm16 >> 8) & 0b111;
1563   uint32_t imm8 = imm16 & 0xff;
1564   int32_t encoding = B31 | B30 | B29 | B28 |
1565                   B25 | B23 | B22 |
1566                   static_cast<uint32_t>(rd) << 8 |
1567                   i << 26 |
1568                   imm4 << 16 |
1569                   imm3 << 12 |
1570                   imm8;
1571   Emit32(encoding);
1572 }
1573 
1574 
ldrex(Register rt,Register rn,uint16_t imm,Condition cond)1575 void Thumb2Assembler::ldrex(Register rt, Register rn, uint16_t imm, Condition cond) {
1576   CHECK_NE(rn, kNoRegister);
1577   CHECK_NE(rt, kNoRegister);
1578   CheckCondition(cond);
1579   CHECK_NE(rn, kNoRegister);
1580   CHECK_NE(rt, kNoRegister);
1581   CheckCondition(cond);
1582   CHECK_LT(imm, (1u << 10));
1583 
1584   int32_t encoding = B31 | B30 | B29 | B27 | B22 | B20 |
1585       static_cast<uint32_t>(rn) << 16 |
1586       static_cast<uint32_t>(rt) << 12 |
1587       0xf << 8 |
1588       imm >> 2;
1589   Emit32(encoding);
1590 }
1591 
1592 
ldrex(Register rt,Register rn,Condition cond)1593 void Thumb2Assembler::ldrex(Register rt, Register rn, Condition cond) {
1594   ldrex(rt, rn, 0, cond);
1595 }
1596 
1597 
strex(Register rd,Register rt,Register rn,uint16_t imm,Condition cond)1598 void Thumb2Assembler::strex(Register rd,
1599                             Register rt,
1600                             Register rn,
1601                             uint16_t imm,
1602                             Condition cond) {
1603   CHECK_NE(rn, kNoRegister);
1604   CHECK_NE(rd, kNoRegister);
1605   CHECK_NE(rt, kNoRegister);
1606   CheckCondition(cond);
1607   CHECK_LT(imm, (1u << 10));
1608 
1609   int32_t encoding = B31 | B30 | B29 | B27 | B22 |
1610       static_cast<uint32_t>(rn) << 16 |
1611       static_cast<uint32_t>(rt) << 12 |
1612       static_cast<uint32_t>(rd) << 8 |
1613       imm >> 2;
1614   Emit32(encoding);
1615 }
1616 
1617 
strex(Register rd,Register rt,Register rn,Condition cond)1618 void Thumb2Assembler::strex(Register rd,
1619                             Register rt,
1620                             Register rn,
1621                             Condition cond) {
1622   strex(rd, rt, rn, 0, cond);
1623 }
1624 
1625 
clrex(Condition cond)1626 void Thumb2Assembler::clrex(Condition cond) {
1627   CheckCondition(cond);
1628   int32_t encoding = B31 | B30 | B29 | B27 | B28 | B25 | B24 | B23 |
1629       B21 | B20 |
1630       0xf << 16 |
1631       B15 |
1632       0xf << 8 |
1633       B5 |
1634       0xf;
1635   Emit32(encoding);
1636 }
1637 
1638 
nop(Condition cond)1639 void Thumb2Assembler::nop(Condition cond) {
1640   CheckCondition(cond);
1641   int16_t encoding = B15 | B13 | B12 |
1642       B11 | B10 | B9 | B8;
1643   Emit16(encoding);
1644 }
1645 
1646 
vmovsr(SRegister sn,Register rt,Condition cond)1647 void Thumb2Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
1648   CHECK_NE(sn, kNoSRegister);
1649   CHECK_NE(rt, kNoRegister);
1650   CHECK_NE(rt, SP);
1651   CHECK_NE(rt, PC);
1652   CheckCondition(cond);
1653   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1654                      B27 | B26 | B25 |
1655                      ((static_cast<int32_t>(sn) >> 1)*B16) |
1656                      (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1657                      ((static_cast<int32_t>(sn) & 1)*B7) | B4;
1658   Emit32(encoding);
1659 }
1660 
1661 
vmovrs(Register rt,SRegister sn,Condition cond)1662 void Thumb2Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
1663   CHECK_NE(sn, kNoSRegister);
1664   CHECK_NE(rt, kNoRegister);
1665   CHECK_NE(rt, SP);
1666   CHECK_NE(rt, PC);
1667   CheckCondition(cond);
1668   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1669                      B27 | B26 | B25 | B20 |
1670                      ((static_cast<int32_t>(sn) >> 1)*B16) |
1671                      (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1672                      ((static_cast<int32_t>(sn) & 1)*B7) | B4;
1673   Emit32(encoding);
1674 }
1675 
1676 
vmovsrr(SRegister sm,Register rt,Register rt2,Condition cond)1677 void Thumb2Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
1678                               Condition cond) {
1679   CHECK_NE(sm, kNoSRegister);
1680   CHECK_NE(sm, S31);
1681   CHECK_NE(rt, kNoRegister);
1682   CHECK_NE(rt, SP);
1683   CHECK_NE(rt, PC);
1684   CHECK_NE(rt2, kNoRegister);
1685   CHECK_NE(rt2, SP);
1686   CHECK_NE(rt2, PC);
1687   CheckCondition(cond);
1688   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1689                      B27 | B26 | B22 |
1690                      (static_cast<int32_t>(rt2)*B16) |
1691                      (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1692                      ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
1693                      (static_cast<int32_t>(sm) >> 1);
1694   Emit32(encoding);
1695 }
1696 
1697 
vmovrrs(Register rt,Register rt2,SRegister sm,Condition cond)1698 void Thumb2Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
1699                               Condition cond) {
1700   CHECK_NE(sm, kNoSRegister);
1701   CHECK_NE(sm, S31);
1702   CHECK_NE(rt, kNoRegister);
1703   CHECK_NE(rt, SP);
1704   CHECK_NE(rt, PC);
1705   CHECK_NE(rt2, kNoRegister);
1706   CHECK_NE(rt2, SP);
1707   CHECK_NE(rt2, PC);
1708   CHECK_NE(rt, rt2);
1709   CheckCondition(cond);
1710   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1711                      B27 | B26 | B22 | B20 |
1712                      (static_cast<int32_t>(rt2)*B16) |
1713                      (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1714                      ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
1715                      (static_cast<int32_t>(sm) >> 1);
1716   Emit32(encoding);
1717 }
1718 
1719 
vmovdrr(DRegister dm,Register rt,Register rt2,Condition cond)1720 void Thumb2Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
1721                               Condition cond) {
1722   CHECK_NE(dm, kNoDRegister);
1723   CHECK_NE(rt, kNoRegister);
1724   CHECK_NE(rt, SP);
1725   CHECK_NE(rt, PC);
1726   CHECK_NE(rt2, kNoRegister);
1727   CHECK_NE(rt2, SP);
1728   CHECK_NE(rt2, PC);
1729   CheckCondition(cond);
1730   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1731                      B27 | B26 | B22 |
1732                      (static_cast<int32_t>(rt2)*B16) |
1733                      (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
1734                      ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
1735                      (static_cast<int32_t>(dm) & 0xf);
1736   Emit32(encoding);
1737 }
1738 
1739 
vmovrrd(Register rt,Register rt2,DRegister dm,Condition cond)1740 void Thumb2Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
1741                               Condition cond) {
1742   CHECK_NE(dm, kNoDRegister);
1743   CHECK_NE(rt, kNoRegister);
1744   CHECK_NE(rt, SP);
1745   CHECK_NE(rt, PC);
1746   CHECK_NE(rt2, kNoRegister);
1747   CHECK_NE(rt2, SP);
1748   CHECK_NE(rt2, PC);
1749   CHECK_NE(rt, rt2);
1750   CheckCondition(cond);
1751   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1752                      B27 | B26 | B22 | B20 |
1753                      (static_cast<int32_t>(rt2)*B16) |
1754                      (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
1755                      ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
1756                      (static_cast<int32_t>(dm) & 0xf);
1757   Emit32(encoding);
1758 }
1759 
1760 
vldrs(SRegister sd,const Address & ad,Condition cond)1761 void Thumb2Assembler::vldrs(SRegister sd, const Address& ad, Condition cond) {
1762   const Address& addr = static_cast<const Address&>(ad);
1763   CHECK_NE(sd, kNoSRegister);
1764   CheckCondition(cond);
1765   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1766                      B27 | B26 | B24 | B20 |
1767                      ((static_cast<int32_t>(sd) & 1)*B22) |
1768                      ((static_cast<int32_t>(sd) >> 1)*B12) |
1769                      B11 | B9 | addr.vencoding();
1770   Emit32(encoding);
1771 }
1772 
1773 
vstrs(SRegister sd,const Address & ad,Condition cond)1774 void Thumb2Assembler::vstrs(SRegister sd, const Address& ad, Condition cond) {
1775   const Address& addr = static_cast<const Address&>(ad);
1776   CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
1777   CHECK_NE(sd, kNoSRegister);
1778   CheckCondition(cond);
1779   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1780                      B27 | B26 | B24 |
1781                      ((static_cast<int32_t>(sd) & 1)*B22) |
1782                      ((static_cast<int32_t>(sd) >> 1)*B12) |
1783                      B11 | B9 | addr.vencoding();
1784   Emit32(encoding);
1785 }
1786 
1787 
vldrd(DRegister dd,const Address & ad,Condition cond)1788 void Thumb2Assembler::vldrd(DRegister dd, const Address& ad, Condition cond) {
1789   const Address& addr = static_cast<const Address&>(ad);
1790   CHECK_NE(dd, kNoDRegister);
1791   CheckCondition(cond);
1792   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1793                      B27 | B26 | B24 | B20 |
1794                      ((static_cast<int32_t>(dd) >> 4)*B22) |
1795                      ((static_cast<int32_t>(dd) & 0xf)*B12) |
1796                      B11 | B9 | B8 | addr.vencoding();
1797   Emit32(encoding);
1798 }
1799 
1800 
vstrd(DRegister dd,const Address & ad,Condition cond)1801 void Thumb2Assembler::vstrd(DRegister dd, const Address& ad, Condition cond) {
1802   const Address& addr = static_cast<const Address&>(ad);
1803   CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
1804   CHECK_NE(dd, kNoDRegister);
1805   CheckCondition(cond);
1806   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1807                      B27 | B26 | B24 |
1808                      ((static_cast<int32_t>(dd) >> 4)*B22) |
1809                      ((static_cast<int32_t>(dd) & 0xf)*B12) |
1810                      B11 | B9 | B8 | addr.vencoding();
1811   Emit32(encoding);
1812 }
1813 
1814 
vpushs(SRegister reg,int nregs,Condition cond)1815 void Thumb2Assembler::vpushs(SRegister reg, int nregs, Condition cond) {
1816   EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, false, cond);
1817 }
1818 
1819 
vpushd(DRegister reg,int nregs,Condition cond)1820 void Thumb2Assembler::vpushd(DRegister reg, int nregs, Condition cond) {
1821   EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, true, cond);
1822 }
1823 
1824 
vpops(SRegister reg,int nregs,Condition cond)1825 void Thumb2Assembler::vpops(SRegister reg, int nregs, Condition cond) {
1826   EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, false, cond);
1827 }
1828 
1829 
vpopd(DRegister reg,int nregs,Condition cond)1830 void Thumb2Assembler::vpopd(DRegister reg, int nregs, Condition cond) {
1831   EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, true, cond);
1832 }
1833 
1834 
EmitVPushPop(uint32_t reg,int nregs,bool push,bool dbl,Condition cond)1835 void Thumb2Assembler::EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond) {
1836   CheckCondition(cond);
1837 
1838   uint32_t D;
1839   uint32_t Vd;
1840   if (dbl) {
1841     // Encoded as D:Vd.
1842     D = (reg >> 4) & 1;
1843     Vd = reg & 0b1111;
1844   } else {
1845     // Encoded as Vd:D.
1846     D = reg & 1;
1847     Vd = (reg >> 1) & 0b1111;
1848   }
1849   int32_t encoding = B27 | B26 | B21 | B19 | B18 | B16 |
1850                     B11 | B9 |
1851         (dbl ? B8 : 0) |
1852         (push ? B24 : (B23 | B20)) |
1853         0b1110 << 28 |
1854         nregs << (dbl ? 1 : 0) |
1855         D << 22 |
1856         Vd << 12;
1857   Emit32(encoding);
1858 }
1859 
1860 
EmitVFPsss(Condition cond,int32_t opcode,SRegister sd,SRegister sn,SRegister sm)1861 void Thumb2Assembler::EmitVFPsss(Condition cond, int32_t opcode,
1862                                  SRegister sd, SRegister sn, SRegister sm) {
1863   CHECK_NE(sd, kNoSRegister);
1864   CHECK_NE(sn, kNoSRegister);
1865   CHECK_NE(sm, kNoSRegister);
1866   CheckCondition(cond);
1867   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1868                      B27 | B26 | B25 | B11 | B9 | opcode |
1869                      ((static_cast<int32_t>(sd) & 1)*B22) |
1870                      ((static_cast<int32_t>(sn) >> 1)*B16) |
1871                      ((static_cast<int32_t>(sd) >> 1)*B12) |
1872                      ((static_cast<int32_t>(sn) & 1)*B7) |
1873                      ((static_cast<int32_t>(sm) & 1)*B5) |
1874                      (static_cast<int32_t>(sm) >> 1);
1875   Emit32(encoding);
1876 }
1877 
1878 
EmitVFPddd(Condition cond,int32_t opcode,DRegister dd,DRegister dn,DRegister dm)1879 void Thumb2Assembler::EmitVFPddd(Condition cond, int32_t opcode,
1880                                  DRegister dd, DRegister dn, DRegister dm) {
1881   CHECK_NE(dd, kNoDRegister);
1882   CHECK_NE(dn, kNoDRegister);
1883   CHECK_NE(dm, kNoDRegister);
1884   CheckCondition(cond);
1885   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1886                      B27 | B26 | B25 | B11 | B9 | B8 | opcode |
1887                      ((static_cast<int32_t>(dd) >> 4)*B22) |
1888                      ((static_cast<int32_t>(dn) & 0xf)*B16) |
1889                      ((static_cast<int32_t>(dd) & 0xf)*B12) |
1890                      ((static_cast<int32_t>(dn) >> 4)*B7) |
1891                      ((static_cast<int32_t>(dm) >> 4)*B5) |
1892                      (static_cast<int32_t>(dm) & 0xf);
1893   Emit32(encoding);
1894 }
1895 
1896 
EmitVFPsd(Condition cond,int32_t opcode,SRegister sd,DRegister dm)1897 void Thumb2Assembler::EmitVFPsd(Condition cond, int32_t opcode,
1898                                 SRegister sd, DRegister dm) {
1899   CHECK_NE(sd, kNoSRegister);
1900   CHECK_NE(dm, kNoDRegister);
1901   CheckCondition(cond);
1902   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1903                      B27 | B26 | B25 | B11 | B9 | opcode |
1904                      ((static_cast<int32_t>(sd) & 1)*B22) |
1905                      ((static_cast<int32_t>(sd) >> 1)*B12) |
1906                      ((static_cast<int32_t>(dm) >> 4)*B5) |
1907                      (static_cast<int32_t>(dm) & 0xf);
1908   Emit32(encoding);
1909 }
1910 
1911 
EmitVFPds(Condition cond,int32_t opcode,DRegister dd,SRegister sm)1912 void Thumb2Assembler::EmitVFPds(Condition cond, int32_t opcode,
1913                                 DRegister dd, SRegister sm) {
1914   CHECK_NE(dd, kNoDRegister);
1915   CHECK_NE(sm, kNoSRegister);
1916   CheckCondition(cond);
1917   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1918                      B27 | B26 | B25 | B11 | B9 | opcode |
1919                      ((static_cast<int32_t>(dd) >> 4)*B22) |
1920                      ((static_cast<int32_t>(dd) & 0xf)*B12) |
1921                      ((static_cast<int32_t>(sm) & 1)*B5) |
1922                      (static_cast<int32_t>(sm) >> 1);
1923   Emit32(encoding);
1924 }
1925 
1926 
vmstat(Condition cond)1927 void Thumb2Assembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR.
1928   CheckCondition(cond);
1929   UNIMPLEMENTED(FATAL) << "Unimplemented thumb instruction";
1930 }
1931 
1932 
svc(uint32_t imm8)1933 void Thumb2Assembler::svc(uint32_t imm8) {
1934   CHECK(IsUint(8, imm8)) << imm8;
1935   int16_t encoding = B15 | B14 | B12 |
1936        B11 | B10 | B9 | B8 |
1937        imm8;
1938   Emit16(encoding);
1939 }
1940 
1941 
bkpt(uint16_t imm8)1942 void Thumb2Assembler::bkpt(uint16_t imm8) {
1943   CHECK(IsUint(8, imm8)) << imm8;
1944   int16_t encoding = B15 | B13 | B12 |
1945       B11 | B10 | B9 |
1946       imm8;
1947   Emit16(encoding);
1948 }
1949 
1950 // Convert the given IT state to a mask bit given bit 0 of the first
1951 // condition and a shift position.
ToItMask(ItState s,uint8_t firstcond0,uint8_t shift)1952 static uint8_t ToItMask(ItState s, uint8_t firstcond0, uint8_t shift) {
1953   switch (s) {
1954   case kItOmitted: return 1 << shift;
1955   case kItThen: return firstcond0 << shift;
1956   case kItElse: return !firstcond0 << shift;
1957   }
1958   return 0;
1959 }
1960 
1961 
1962 // Set the IT condition in the given position for the given state.  This is used
1963 // to check that conditional instructions match the preceding IT statement.
SetItCondition(ItState s,Condition cond,uint8_t index)1964 void Thumb2Assembler::SetItCondition(ItState s, Condition cond, uint8_t index) {
1965   switch (s) {
1966   case kItOmitted: it_conditions_[index] = AL; break;
1967   case kItThen: it_conditions_[index] = cond; break;
1968   case kItElse:
1969     it_conditions_[index] = static_cast<Condition>(static_cast<uint8_t>(cond) ^ 1);
1970     break;
1971   }
1972 }
1973 
1974 
it(Condition firstcond,ItState i1,ItState i2,ItState i3)1975 void Thumb2Assembler::it(Condition firstcond, ItState i1, ItState i2, ItState i3) {
1976   CheckCondition(AL);       // Not allowed in IT block.
1977   uint8_t firstcond0 = static_cast<uint8_t>(firstcond) & 1;
1978 
1979   // All conditions to AL.
1980   for (uint8_t i = 0; i < 4; ++i) {
1981     it_conditions_[i] = AL;
1982   }
1983 
1984   SetItCondition(kItThen, firstcond, 0);
1985   uint8_t mask = ToItMask(i1, firstcond0, 3);
1986   SetItCondition(i1, firstcond, 1);
1987 
1988   if (i1 != kItOmitted) {
1989     mask |= ToItMask(i2, firstcond0, 2);
1990     SetItCondition(i2, firstcond, 2);
1991     if (i2 != kItOmitted) {
1992       mask |= ToItMask(i3, firstcond0, 1);
1993       SetItCondition(i3, firstcond, 3);
1994       if (i3 != kItOmitted) {
1995         mask |= 0b0001;
1996       }
1997     }
1998   }
1999 
2000   // Start at first condition.
2001   it_cond_index_ = 0;
2002   next_condition_ = it_conditions_[0];
2003   uint16_t encoding = B15 | B13 | B12 |
2004         B11 | B10 | B9 | B8 |
2005         firstcond << 4 |
2006         mask;
2007   Emit16(encoding);
2008 }
2009 
2010 
cbz(Register rn,Label * label)2011 void Thumb2Assembler::cbz(Register rn, Label* label) {
2012   CheckCondition(AL);
2013   if (label->IsBound()) {
2014     LOG(FATAL) << "cbz can only be used to branch forwards";
2015   } else {
2016     uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), false);
2017     label->LinkTo(branchid);
2018   }
2019 }
2020 
2021 
cbnz(Register rn,Label * label)2022 void Thumb2Assembler::cbnz(Register rn, Label* label) {
2023   CheckCondition(AL);
2024   if (label->IsBound()) {
2025     LOG(FATAL) << "cbnz can only be used to branch forwards";
2026   } else {
2027     uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), true);
2028     label->LinkTo(branchid);
2029   }
2030 }
2031 
2032 
blx(Register rm,Condition cond)2033 void Thumb2Assembler::blx(Register rm, Condition cond) {
2034   CHECK_NE(rm, kNoRegister);
2035   CheckCondition(cond);
2036   int16_t encoding = B14 | B10 | B9 | B8 | B7 | static_cast<int16_t>(rm) << 3;
2037   Emit16(encoding);
2038 }
2039 
2040 
bx(Register rm,Condition cond)2041 void Thumb2Assembler::bx(Register rm, Condition cond) {
2042   CHECK_NE(rm, kNoRegister);
2043   CheckCondition(cond);
2044   int16_t encoding = B14 | B10 | B9 | B8 | static_cast<int16_t>(rm) << 3;
2045   Emit16(encoding);
2046 }
2047 
2048 
Push(Register rd,Condition cond)2049 void Thumb2Assembler::Push(Register rd, Condition cond) {
2050   str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond);
2051 }
2052 
2053 
Pop(Register rd,Condition cond)2054 void Thumb2Assembler::Pop(Register rd, Condition cond) {
2055   ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond);
2056 }
2057 
2058 
PushList(RegList regs,Condition cond)2059 void Thumb2Assembler::PushList(RegList regs, Condition cond) {
2060   stm(DB_W, SP, regs, cond);
2061 }
2062 
2063 
PopList(RegList regs,Condition cond)2064 void Thumb2Assembler::PopList(RegList regs, Condition cond) {
2065   ldm(IA_W, SP, regs, cond);
2066 }
2067 
2068 
Mov(Register rd,Register rm,Condition cond)2069 void Thumb2Assembler::Mov(Register rd, Register rm, Condition cond) {
2070   if (cond != AL || rd != rm) {
2071     mov(rd, ShifterOperand(rm), cond);
2072   }
2073 }
2074 
2075 
2076 // A branch has changed size.  Make a hole for it.
MakeHoleForBranch(uint32_t location,uint32_t delta)2077 void Thumb2Assembler::MakeHoleForBranch(uint32_t location, uint32_t delta) {
2078   // Move the contents of the buffer using: Move(newposition, oldposition)
2079   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2080   buffer_.Move(location + delta, location);
2081 }
2082 
2083 
Bind(Label * label)2084 void Thumb2Assembler::Bind(Label* label) {
2085   CHECK(!label->IsBound());
2086   uint32_t bound_pc = buffer_.Size();
2087   std::vector<Branch*> changed_branches;
2088 
2089   while (label->IsLinked()) {
2090     uint16_t position = label->Position();                  // Branch id for linked branch.
2091     Branch* branch = GetBranch(position);                   // Get the branch at this id.
2092     bool changed = branch->Resolve(bound_pc);               // Branch can be resolved now.
2093     uint32_t branch_location = branch->GetLocation();
2094     uint16_t next = buffer_.Load<uint16_t>(branch_location);       // Get next in chain.
2095     if (changed) {
2096       DCHECK(!force_32bit_branches_);
2097       MakeHoleForBranch(branch->GetLocation(), 2);
2098       if (branch->IsCompareAndBranch()) {
2099         // A cbz/cbnz instruction has changed size.  There is no valid encoding for
2100         // a 32 bit cbz/cbnz so we need to change this to an instruction pair:
2101         // cmp rn, #0
2102         // b<eq|ne> target
2103         bool n = branch->GetType() == Branch::kCompareAndBranchNonZero;
2104         Condition cond = n ? NE : EQ;
2105         branch->Move(2);      // Move the branch forward by 2 bytes.
2106         branch->ResetTypeAndCondition(Branch::kConditional, cond);
2107         branch->ResetSize(Branch::k16Bit);
2108 
2109         // Now add a compare instruction in the place the branch was.
2110         int16_t cmp = B13 | B11 | static_cast<int16_t>(branch->GetRegister()) << 8;
2111         buffer_.Store<int16_t>(branch_location, cmp);
2112 
2113         // Since have moved made a hole in the code we need to reload the
2114         // current pc.
2115         bound_pc = buffer_.Size();
2116 
2117         // Now resolve the newly added branch.
2118         changed = branch->Resolve(bound_pc);
2119         if (changed) {
2120           MakeHoleForBranch(branch->GetLocation(), 2);
2121           changed_branches.push_back(branch);
2122         }
2123       } else {
2124         changed_branches.push_back(branch);
2125       }
2126     }
2127     label->position_ = next;                                // Move to next.
2128   }
2129   label->BindTo(bound_pc);
2130 
2131   // Now relocate any changed branches.  Do this until there are no more changes.
2132   std::vector<Branch*> branches_to_process = changed_branches;
2133   while (branches_to_process.size() != 0) {
2134     changed_branches.clear();
2135     for (auto& changed_branch : branches_to_process) {
2136       for (auto& branch : branches_) {
2137         bool changed = branch->Relocate(changed_branch->GetLocation(), 2);
2138         if (changed) {
2139           changed_branches.push_back(branch);
2140         }
2141       }
2142       branches_to_process = changed_branches;
2143     }
2144   }
2145 }
2146 
2147 
EmitBranches()2148 void Thumb2Assembler::EmitBranches() {
2149   for (auto& branch : branches_) {
2150     branch->Emit(&buffer_);
2151   }
2152 }
2153 
2154 
Lsl(Register rd,Register rm,uint32_t shift_imm,bool setcc,Condition cond)2155 void Thumb2Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
2156                           bool setcc, Condition cond) {
2157   CHECK_NE(shift_imm, 0u);  // Do not use Lsl if no shift is wanted.
2158   CheckCondition(cond);
2159   EmitShift(rd, rm, LSL, shift_imm, setcc);
2160 }
2161 
2162 
Lsr(Register rd,Register rm,uint32_t shift_imm,bool setcc,Condition cond)2163 void Thumb2Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
2164                           bool setcc, Condition cond) {
2165   CHECK_NE(shift_imm, 0u);  // Do not use Lsr if no shift is wanted.
2166   if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
2167   CheckCondition(cond);
2168   EmitShift(rd, rm, LSR, shift_imm, setcc);
2169 }
2170 
2171 
Asr(Register rd,Register rm,uint32_t shift_imm,bool setcc,Condition cond)2172 void Thumb2Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
2173                           bool setcc, Condition cond) {
2174   CHECK_NE(shift_imm, 0u);  // Do not use Asr if no shift is wanted.
2175   if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
2176   CheckCondition(cond);
2177   EmitShift(rd, rm, ASR, shift_imm, setcc);
2178 }
2179 
2180 
Ror(Register rd,Register rm,uint32_t shift_imm,bool setcc,Condition cond)2181 void Thumb2Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
2182                           bool setcc, Condition cond) {
2183   CHECK_NE(shift_imm, 0u);  // Use Rrx instruction.
2184   CheckCondition(cond);
2185   EmitShift(rd, rm, ROR, shift_imm, setcc);
2186 }
2187 
2188 
Rrx(Register rd,Register rm,bool setcc,Condition cond)2189 void Thumb2Assembler::Rrx(Register rd, Register rm, bool setcc, Condition cond) {
2190   CheckCondition(cond);
2191   EmitShift(rd, rm, RRX, rm, setcc);
2192 }
2193 
2194 
Lsl(Register rd,Register rm,Register rn,bool setcc,Condition cond)2195 void Thumb2Assembler::Lsl(Register rd, Register rm, Register rn,
2196                           bool setcc, Condition cond) {
2197   CheckCondition(cond);
2198   EmitShift(rd, rm, LSL, rn, setcc);
2199 }
2200 
2201 
Lsr(Register rd,Register rm,Register rn,bool setcc,Condition cond)2202 void Thumb2Assembler::Lsr(Register rd, Register rm, Register rn,
2203                           bool setcc, Condition cond) {
2204   CheckCondition(cond);
2205   EmitShift(rd, rm, LSR, rn, setcc);
2206 }
2207 
2208 
Asr(Register rd,Register rm,Register rn,bool setcc,Condition cond)2209 void Thumb2Assembler::Asr(Register rd, Register rm, Register rn,
2210                           bool setcc, Condition cond) {
2211   CheckCondition(cond);
2212   EmitShift(rd, rm, ASR, rn, setcc);
2213 }
2214 
2215 
Ror(Register rd,Register rm,Register rn,bool setcc,Condition cond)2216 void Thumb2Assembler::Ror(Register rd, Register rm, Register rn,
2217                           bool setcc, Condition cond) {
2218   CheckCondition(cond);
2219   EmitShift(rd, rm, ROR, rn, setcc);
2220 }
2221 
2222 
EncodeBranchOffset(int32_t offset,int32_t inst)2223 int32_t Thumb2Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) {
2224   // The offset is off by 4 due to the way the ARM CPUs read PC.
2225   offset -= 4;
2226   offset >>= 1;
2227 
2228   uint32_t value = 0;
2229   // There are two different encodings depending on the value of bit 12.  In one case
2230   // intermediate values are calculated using the sign bit.
2231   if ((inst & B12) == B12) {
2232     // 25 bits of offset.
2233     uint32_t signbit = (offset >> 31) & 0x1;
2234     uint32_t i1 = (offset >> 22) & 0x1;
2235     uint32_t i2 = (offset >> 21) & 0x1;
2236     uint32_t imm10 = (offset >> 11) & 0x03ff;
2237     uint32_t imm11 = offset & 0x07ff;
2238     uint32_t j1 = (i1 ^ signbit) ? 0 : 1;
2239     uint32_t j2 = (i2 ^ signbit) ? 0 : 1;
2240     value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm10 << 16) |
2241                       imm11;
2242     // Remove the offset from the current encoding.
2243     inst &= ~(0x3ff << 16 | 0x7ff);
2244   } else {
2245     uint32_t signbit = (offset >> 31) & 0x1;
2246     uint32_t imm6 = (offset >> 11) & 0x03f;
2247     uint32_t imm11 = offset & 0x07ff;
2248     uint32_t j1 = (offset >> 19) & 1;
2249     uint32_t j2 = (offset >> 17) & 1;
2250     value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm6 << 16) |
2251         imm11;
2252     // Remove the offset from the current encoding.
2253     inst &= ~(0x3f << 16 | 0x7ff);
2254   }
2255   // Mask out offset bits in current instruction.
2256   inst &= ~(B26 | B13 | B11);
2257   inst |= value;
2258   return inst;
2259 }
2260 
2261 
DecodeBranchOffset(int32_t instr)2262 int Thumb2Assembler::DecodeBranchOffset(int32_t instr) {
2263   int32_t imm32;
2264   if ((instr & B12) == B12) {
2265     uint32_t S = (instr >> 26) & 1;
2266     uint32_t J2 = (instr >> 11) & 1;
2267     uint32_t J1 = (instr >> 13) & 1;
2268     uint32_t imm10 = (instr >> 16) & 0x3FF;
2269     uint32_t imm11 = instr & 0x7FF;
2270 
2271     uint32_t I1 = ~(J1 ^ S) & 1;
2272     uint32_t I2 = ~(J2 ^ S) & 1;
2273     imm32 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2274     imm32 = (imm32 << 8) >> 8;  // sign extend 24 bit immediate.
2275   } else {
2276     uint32_t S = (instr >> 26) & 1;
2277     uint32_t J2 = (instr >> 11) & 1;
2278     uint32_t J1 = (instr >> 13) & 1;
2279     uint32_t imm6 = (instr >> 16) & 0x3F;
2280     uint32_t imm11 = instr & 0x7FF;
2281 
2282     imm32 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2283     imm32 = (imm32 << 11) >> 11;  // sign extend 21 bit immediate.
2284   }
2285   imm32 += 4;
2286   return imm32;
2287 }
2288 
2289 
AddConstant(Register rd,int32_t value,Condition cond)2290 void Thumb2Assembler::AddConstant(Register rd, int32_t value, Condition cond) {
2291   AddConstant(rd, rd, value, cond);
2292 }
2293 
2294 
AddConstant(Register rd,Register rn,int32_t value,Condition cond)2295 void Thumb2Assembler::AddConstant(Register rd, Register rn, int32_t value,
2296                                   Condition cond) {
2297   if (value == 0) {
2298     if (rd != rn) {
2299       mov(rd, ShifterOperand(rn), cond);
2300     }
2301     return;
2302   }
2303   // We prefer to select the shorter code sequence rather than selecting add for
2304   // positive values and sub for negatives ones, which would slightly improve
2305   // the readability of generated code for some constants.
2306   ShifterOperand shifter_op;
2307   if (ShifterOperand::CanHoldThumb(rd, rn, ADD, value, &shifter_op)) {
2308     add(rd, rn, shifter_op, cond);
2309   } else if (ShifterOperand::CanHoldThumb(rd, rn, SUB, -value, &shifter_op)) {
2310     sub(rd, rn, shifter_op, cond);
2311   } else {
2312     CHECK(rn != IP);
2313     if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~value, &shifter_op)) {
2314       mvn(IP, shifter_op, cond);
2315       add(rd, rn, ShifterOperand(IP), cond);
2316     } else if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~(-value), &shifter_op)) {
2317       mvn(IP, shifter_op, cond);
2318       sub(rd, rn, ShifterOperand(IP), cond);
2319     } else {
2320       movw(IP, Low16Bits(value), cond);
2321       uint16_t value_high = High16Bits(value);
2322       if (value_high != 0) {
2323         movt(IP, value_high, cond);
2324       }
2325       add(rd, rn, ShifterOperand(IP), cond);
2326     }
2327   }
2328 }
2329 
2330 
AddConstantSetFlags(Register rd,Register rn,int32_t value,Condition cond)2331 void Thumb2Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
2332                                           Condition cond) {
2333   ShifterOperand shifter_op;
2334   if (ShifterOperand::CanHoldThumb(rd, rn, ADD, value, &shifter_op)) {
2335     adds(rd, rn, shifter_op, cond);
2336   } else if (ShifterOperand::CanHoldThumb(rd, rn, ADD, -value, &shifter_op)) {
2337     subs(rd, rn, shifter_op, cond);
2338   } else {
2339     CHECK(rn != IP);
2340     if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~value, &shifter_op)) {
2341       mvn(IP, shifter_op, cond);
2342       adds(rd, rn, ShifterOperand(IP), cond);
2343     } else if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~(-value), &shifter_op)) {
2344       mvn(IP, shifter_op, cond);
2345       subs(rd, rn, ShifterOperand(IP), cond);
2346     } else {
2347       movw(IP, Low16Bits(value), cond);
2348       uint16_t value_high = High16Bits(value);
2349       if (value_high != 0) {
2350         movt(IP, value_high, cond);
2351       }
2352       adds(rd, rn, ShifterOperand(IP), cond);
2353     }
2354   }
2355 }
2356 
2357 
LoadImmediate(Register rd,int32_t value,Condition cond)2358 void Thumb2Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
2359   ShifterOperand shifter_op;
2360   if (ShifterOperand::CanHoldThumb(rd, R0, MOV, value, &shifter_op)) {
2361     mov(rd, shifter_op, cond);
2362   } else if (ShifterOperand::CanHoldThumb(rd, R0, MVN, ~value, &shifter_op)) {
2363     mvn(rd, shifter_op, cond);
2364   } else {
2365     movw(rd, Low16Bits(value), cond);
2366     uint16_t value_high = High16Bits(value);
2367     if (value_high != 0) {
2368       movt(rd, value_high, cond);
2369     }
2370   }
2371 }
2372 
2373 // Implementation note: this method must emit at most one instruction when
2374 // Address::CanHoldLoadOffsetThumb.
LoadFromOffset(LoadOperandType type,Register reg,Register base,int32_t offset,Condition cond)2375 void Thumb2Assembler::LoadFromOffset(LoadOperandType type,
2376                                      Register reg,
2377                                      Register base,
2378                                      int32_t offset,
2379                                      Condition cond) {
2380   if (!Address::CanHoldLoadOffsetThumb(type, offset)) {
2381     CHECK(base != IP);
2382     LoadImmediate(IP, offset, cond);
2383     add(IP, IP, ShifterOperand(base), cond);
2384     base = IP;
2385     offset = 0;
2386   }
2387   CHECK(Address::CanHoldLoadOffsetThumb(type, offset));
2388   switch (type) {
2389     case kLoadSignedByte:
2390       ldrsb(reg, Address(base, offset), cond);
2391       break;
2392     case kLoadUnsignedByte:
2393       ldrb(reg, Address(base, offset), cond);
2394       break;
2395     case kLoadSignedHalfword:
2396       ldrsh(reg, Address(base, offset), cond);
2397       break;
2398     case kLoadUnsignedHalfword:
2399       ldrh(reg, Address(base, offset), cond);
2400       break;
2401     case kLoadWord:
2402       ldr(reg, Address(base, offset), cond);
2403       break;
2404     case kLoadWordPair:
2405       ldrd(reg, Address(base, offset), cond);
2406       break;
2407     default:
2408       LOG(FATAL) << "UNREACHABLE";
2409   }
2410 }
2411 
2412 
2413 // Implementation note: this method must emit at most one instruction when
2414 // Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset.
LoadSFromOffset(SRegister reg,Register base,int32_t offset,Condition cond)2415 void Thumb2Assembler::LoadSFromOffset(SRegister reg,
2416                                       Register base,
2417                                       int32_t offset,
2418                                       Condition cond) {
2419   if (!Address::CanHoldLoadOffsetThumb(kLoadSWord, offset)) {
2420     CHECK_NE(base, IP);
2421     LoadImmediate(IP, offset, cond);
2422     add(IP, IP, ShifterOperand(base), cond);
2423     base = IP;
2424     offset = 0;
2425   }
2426   CHECK(Address::CanHoldLoadOffsetThumb(kLoadSWord, offset));
2427   vldrs(reg, Address(base, offset), cond);
2428 }
2429 
2430 
2431 // Implementation note: this method must emit at most one instruction when
2432 // Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset.
LoadDFromOffset(DRegister reg,Register base,int32_t offset,Condition cond)2433 void Thumb2Assembler::LoadDFromOffset(DRegister reg,
2434                                       Register base,
2435                                       int32_t offset,
2436                                       Condition cond) {
2437   if (!Address::CanHoldLoadOffsetThumb(kLoadDWord, offset)) {
2438     CHECK_NE(base, IP);
2439     LoadImmediate(IP, offset, cond);
2440     add(IP, IP, ShifterOperand(base), cond);
2441     base = IP;
2442     offset = 0;
2443   }
2444   CHECK(Address::CanHoldLoadOffsetThumb(kLoadDWord, offset));
2445   vldrd(reg, Address(base, offset), cond);
2446 }
2447 
2448 
2449 // Implementation note: this method must emit at most one instruction when
2450 // Address::CanHoldStoreOffsetThumb.
StoreToOffset(StoreOperandType type,Register reg,Register base,int32_t offset,Condition cond)2451 void Thumb2Assembler::StoreToOffset(StoreOperandType type,
2452                                     Register reg,
2453                                     Register base,
2454                                     int32_t offset,
2455                                     Condition cond) {
2456   if (!Address::CanHoldStoreOffsetThumb(type, offset)) {
2457     CHECK(reg != IP);
2458     CHECK(base != IP);
2459     LoadImmediate(IP, offset, cond);
2460     add(IP, IP, ShifterOperand(base), cond);
2461     base = IP;
2462     offset = 0;
2463   }
2464   CHECK(Address::CanHoldStoreOffsetThumb(type, offset));
2465   switch (type) {
2466     case kStoreByte:
2467       strb(reg, Address(base, offset), cond);
2468       break;
2469     case kStoreHalfword:
2470       strh(reg, Address(base, offset), cond);
2471       break;
2472     case kStoreWord:
2473       str(reg, Address(base, offset), cond);
2474       break;
2475     case kStoreWordPair:
2476       strd(reg, Address(base, offset), cond);
2477       break;
2478     default:
2479       LOG(FATAL) << "UNREACHABLE";
2480   }
2481 }
2482 
2483 
2484 // Implementation note: this method must emit at most one instruction when
2485 // Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreToOffset.
StoreSToOffset(SRegister reg,Register base,int32_t offset,Condition cond)2486 void Thumb2Assembler::StoreSToOffset(SRegister reg,
2487                                      Register base,
2488                                      int32_t offset,
2489                                      Condition cond) {
2490   if (!Address::CanHoldStoreOffsetThumb(kStoreSWord, offset)) {
2491     CHECK_NE(base, IP);
2492     LoadImmediate(IP, offset, cond);
2493     add(IP, IP, ShifterOperand(base), cond);
2494     base = IP;
2495     offset = 0;
2496   }
2497   CHECK(Address::CanHoldStoreOffsetThumb(kStoreSWord, offset));
2498   vstrs(reg, Address(base, offset), cond);
2499 }
2500 
2501 
2502 // Implementation note: this method must emit at most one instruction when
2503 // Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreSToOffset.
StoreDToOffset(DRegister reg,Register base,int32_t offset,Condition cond)2504 void Thumb2Assembler::StoreDToOffset(DRegister reg,
2505                                      Register base,
2506                                      int32_t offset,
2507                                      Condition cond) {
2508   if (!Address::CanHoldStoreOffsetThumb(kStoreDWord, offset)) {
2509     CHECK_NE(base, IP);
2510     LoadImmediate(IP, offset, cond);
2511     add(IP, IP, ShifterOperand(base), cond);
2512     base = IP;
2513     offset = 0;
2514   }
2515   CHECK(Address::CanHoldStoreOffsetThumb(kStoreDWord, offset));
2516   vstrd(reg, Address(base, offset), cond);
2517 }
2518 
2519 
MemoryBarrier(ManagedRegister mscratch)2520 void Thumb2Assembler::MemoryBarrier(ManagedRegister mscratch) {
2521   CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12);
2522 #if ANDROID_SMP != 0
2523   int32_t encoding = 0xf3bf8f5f;  // dmb in T1 encoding.
2524   Emit32(encoding);
2525 #endif
2526 }
2527 
2528 
CompareAndBranchIfZero(Register r,Label * label)2529 void Thumb2Assembler::CompareAndBranchIfZero(Register r, Label* label) {
2530   if (force_32bit_branches_) {
2531     cmp(r, ShifterOperand(0));
2532     b(label, EQ);
2533   } else {
2534     cbz(r, label);
2535   }
2536 }
2537 
2538 
CompareAndBranchIfNonZero(Register r,Label * label)2539 void Thumb2Assembler::CompareAndBranchIfNonZero(Register r, Label* label) {
2540   if (force_32bit_branches_) {
2541     cmp(r, ShifterOperand(0));
2542     b(label, NE);
2543   } else {
2544     cbnz(r, label);
2545   }
2546 }
2547 }  // namespace arm
2548 }  // namespace art
2549