Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(500)

Side by Side Diff: runtime/vm/assembler_arm.cc

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // NOLINT 5 #include "vm/globals.h" // NOLINT
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
11 #include "vm/runtime_entry.h" 11 #include "vm/runtime_entry.h"
12 #include "vm/simulator.h" 12 #include "vm/simulator.h"
13 #include "vm/stack_frame.h" 13 #include "vm/stack_frame.h"
14 #include "vm/stub_code.h" 14 #include "vm/stub_code.h"
15 15
16 // An extra check since we are assuming the existence of /proc/cpuinfo below. 16 // An extra check since we are assuming the existence of /proc/cpuinfo below.
17 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) && \ 17 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) && \
18 !TARGET_OS_IOS 18 !TARGET_OS_IOS
19 #error ARM cross-compile only supported on Linux 19 #error ARM cross-compile only supported on Linux
20 #endif 20 #endif
21 21
22 namespace dart { 22 namespace dart {
23 23
24 DECLARE_FLAG(bool, check_code_pointer); 24 DECLARE_FLAG(bool, check_code_pointer);
25 DECLARE_FLAG(bool, inline_alloc); 25 DECLARE_FLAG(bool, inline_alloc);
26 26
27 uint32_t Address::encoding3() const { 27 uint32_t Address::encoding3() const {
28 if (kind_ == Immediate) { 28 if (kind_ == Immediate) {
29 uint32_t offset = encoding_ & kOffset12Mask; 29 uint32_t offset = encoding_ & kOffset12Mask;
30 ASSERT(offset < 256); 30 ASSERT(offset < 256);
31 return (encoding_ & ~kOffset12Mask) | B22 | 31 return (encoding_ & ~kOffset12Mask) | B22 | ((offset & 0xf0) << 4) |
32 ((offset & 0xf0) << 4) | (offset & 0xf); 32 (offset & 0xf);
33 } 33 }
34 ASSERT(kind_ == IndexRegister); 34 ASSERT(kind_ == IndexRegister);
35 return encoding_; 35 return encoding_;
36 } 36 }
37 37
38 38
39 uint32_t Address::vencoding() const { 39 uint32_t Address::vencoding() const {
40 ASSERT(kind_ == Immediate); 40 ASSERT(kind_ == Immediate);
41 uint32_t offset = encoding_ & kOffset12Mask; 41 uint32_t offset = encoding_ & kOffset12Mask;
42 ASSERT(offset < (1 << 10)); // In the range 0 to +1020. 42 ASSERT(offset < (1 << 10)); // In the range 0 to +1020.
43 ASSERT(Utils::IsAligned(offset, 4)); // Multiple of 4. 43 ASSERT(Utils::IsAligned(offset, 4)); // Multiple of 4.
44 int mode = encoding_ & ((8|4|1) << 21); 44 int mode = encoding_ & ((8 | 4 | 1) << 21);
45 ASSERT((mode == Offset) || (mode == NegOffset)); 45 ASSERT((mode == Offset) || (mode == NegOffset));
46 uint32_t vencoding = (encoding_ & (0xf << kRnShift)) | (offset >> 2); 46 uint32_t vencoding = (encoding_ & (0xf << kRnShift)) | (offset >> 2);
47 if (mode == Offset) { 47 if (mode == Offset) {
48 vencoding |= 1 << 23; 48 vencoding |= 1 << 23;
49 } 49 }
50 return vencoding; 50 return vencoding;
51 } 51 }
52 52
53 53
54 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { 54 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) {
(...skipping 18 matching lines...) Expand all
73 Opcode opcode, 73 Opcode opcode,
74 int set_cc, 74 int set_cc,
75 Register rn, 75 Register rn,
76 Register rd, 76 Register rd,
77 Operand o) { 77 Operand o) {
78 ASSERT(rd != kNoRegister); 78 ASSERT(rd != kNoRegister);
79 ASSERT(cond != kNoCondition); 79 ASSERT(cond != kNoCondition);
80 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 80 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
81 type << kTypeShift | 81 type << kTypeShift |
82 static_cast<int32_t>(opcode) << kOpcodeShift | 82 static_cast<int32_t>(opcode) << kOpcodeShift |
83 set_cc << kSShift | 83 set_cc << kSShift | static_cast<int32_t>(rn) << kRnShift |
84 static_cast<int32_t>(rn) << kRnShift | 84 static_cast<int32_t>(rd) << kRdShift | o.encoding();
85 static_cast<int32_t>(rd) << kRdShift |
86 o.encoding();
87 Emit(encoding); 85 Emit(encoding);
88 } 86 }
89 87
90 88
91 void Assembler::EmitType5(Condition cond, int32_t offset, bool link) { 89 void Assembler::EmitType5(Condition cond, int32_t offset, bool link) {
92 ASSERT(cond != kNoCondition); 90 ASSERT(cond != kNoCondition);
93 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 91 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
94 5 << kTypeShift | 92 5 << kTypeShift | (link ? 1 : 0) << kLinkShift;
95 (link ? 1 : 0) << kLinkShift;
96 Emit(Assembler::EncodeBranchOffset(offset, encoding)); 93 Emit(Assembler::EncodeBranchOffset(offset, encoding));
97 } 94 }
98 95
99 96
100 void Assembler::EmitMemOp(Condition cond, 97 void Assembler::EmitMemOp(Condition cond,
101 bool load, 98 bool load,
102 bool byte, 99 bool byte,
103 Register rd, 100 Register rd,
104 Address ad) { 101 Address ad) {
105 ASSERT(rd != kNoRegister); 102 ASSERT(rd != kNoRegister);
106 ASSERT(cond != kNoCondition); 103 ASSERT(cond != kNoCondition);
107 ASSERT(!ad.has_writeback() || (ad.rn() != rd)); // Unpredictable. 104 ASSERT(!ad.has_writeback() || (ad.rn() != rd)); // Unpredictable.
108 105
109 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 106 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B26 |
110 B26 | (ad.kind() == Address::Immediate ? 0 : B25) | 107 (ad.kind() == Address::Immediate ? 0 : B25) |
111 (load ? L : 0) | 108 (load ? L : 0) | (byte ? B : 0) |
112 (byte ? B : 0) | 109 (static_cast<int32_t>(rd) << kRdShift) | ad.encoding();
113 (static_cast<int32_t>(rd) << kRdShift) |
114 ad.encoding();
115 Emit(encoding); 110 Emit(encoding);
116 } 111 }
117 112
118 113
119 void Assembler::EmitMemOpAddressMode3(Condition cond, 114 void Assembler::EmitMemOpAddressMode3(Condition cond,
120 int32_t mode, 115 int32_t mode,
121 Register rd, 116 Register rd,
122 Address ad) { 117 Address ad) {
123 ASSERT(rd != kNoRegister); 118 ASSERT(rd != kNoRegister);
124 ASSERT(cond != kNoCondition); 119 ASSERT(cond != kNoCondition);
125 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 120 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | mode |
126 mode | 121 (static_cast<int32_t>(rd) << kRdShift) | ad.encoding3();
127 (static_cast<int32_t>(rd) << kRdShift) |
128 ad.encoding3();
129 Emit(encoding); 122 Emit(encoding);
130 } 123 }
131 124
132 125
133 void Assembler::EmitMultiMemOp(Condition cond, 126 void Assembler::EmitMultiMemOp(Condition cond,
134 BlockAddressMode am, 127 BlockAddressMode am,
135 bool load, 128 bool load,
136 Register base, 129 Register base,
137 RegList regs) { 130 RegList regs) {
138 ASSERT(base != kNoRegister); 131 ASSERT(base != kNoRegister);
139 ASSERT(cond != kNoCondition); 132 ASSERT(cond != kNoCondition);
140 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 133 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
141 B27 | 134 am | (load ? L : 0) |
142 am | 135 (static_cast<int32_t>(base) << kRnShift) | regs;
143 (load ? L : 0) |
144 (static_cast<int32_t>(base) << kRnShift) |
145 regs;
146 Emit(encoding); 136 Emit(encoding);
147 } 137 }
148 138
149 139
150 void Assembler::EmitShiftImmediate(Condition cond, 140 void Assembler::EmitShiftImmediate(Condition cond,
151 Shift opcode, 141 Shift opcode,
152 Register rd, 142 Register rd,
153 Register rm, 143 Register rm,
154 Operand o) { 144 Operand o) {
155 ASSERT(cond != kNoCondition); 145 ASSERT(cond != kNoCondition);
156 ASSERT(o.type() == 1); 146 ASSERT(o.type() == 1);
157 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 147 int32_t encoding =
158 static_cast<int32_t>(MOV) << kOpcodeShift | 148 static_cast<int32_t>(cond) << kConditionShift |
159 static_cast<int32_t>(rd) << kRdShift | 149 static_cast<int32_t>(MOV) << kOpcodeShift |
160 o.encoding() << kShiftImmShift | 150 static_cast<int32_t>(rd) << kRdShift | o.encoding() << kShiftImmShift |
161 static_cast<int32_t>(opcode) << kShiftShift | 151 static_cast<int32_t>(opcode) << kShiftShift | static_cast<int32_t>(rm);
162 static_cast<int32_t>(rm);
163 Emit(encoding); 152 Emit(encoding);
164 } 153 }
165 154
166 155
167 void Assembler::EmitShiftRegister(Condition cond, 156 void Assembler::EmitShiftRegister(Condition cond,
168 Shift opcode, 157 Shift opcode,
169 Register rd, 158 Register rd,
170 Register rm, 159 Register rm,
171 Operand o) { 160 Operand o) {
172 ASSERT(cond != kNoCondition); 161 ASSERT(cond != kNoCondition);
173 ASSERT(o.type() == 0); 162 ASSERT(o.type() == 0);
174 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 163 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
175 static_cast<int32_t>(MOV) << kOpcodeShift | 164 static_cast<int32_t>(MOV) << kOpcodeShift |
176 static_cast<int32_t>(rd) << kRdShift | 165 static_cast<int32_t>(rd) << kRdShift |
177 o.encoding() << kShiftRegisterShift | 166 o.encoding() << kShiftRegisterShift |
178 static_cast<int32_t>(opcode) << kShiftShift | 167 static_cast<int32_t>(opcode) << kShiftShift | B4 |
179 B4 |
180 static_cast<int32_t>(rm); 168 static_cast<int32_t>(rm);
181 Emit(encoding); 169 Emit(encoding);
182 } 170 }
183 171
184 172
185 void Assembler::and_(Register rd, Register rn, Operand o, Condition cond) { 173 void Assembler::and_(Register rd, Register rn, Operand o, Condition cond) {
186 EmitType01(cond, o.type(), AND, 0, rn, rd, o); 174 EmitType01(cond, o.type(), AND, 0, rn, rd, o);
187 } 175 }
188 176
189 177
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 EmitType01(cond, o.type(), MVN, 1, R0, rd, o); 292 EmitType01(cond, o.type(), MVN, 1, R0, rd, o);
305 } 293 }
306 294
307 295
308 void Assembler::clz(Register rd, Register rm, Condition cond) { 296 void Assembler::clz(Register rd, Register rm, Condition cond) {
309 ASSERT(rd != kNoRegister); 297 ASSERT(rd != kNoRegister);
310 ASSERT(rm != kNoRegister); 298 ASSERT(rm != kNoRegister);
311 ASSERT(cond != kNoCondition); 299 ASSERT(cond != kNoCondition);
312 ASSERT(rd != PC); 300 ASSERT(rd != PC);
313 ASSERT(rm != PC); 301 ASSERT(rm != PC);
314 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 302 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B24 |
315 B24 | B22 | B21 | (0xf << 16) | 303 B22 | B21 | (0xf << 16) |
316 (static_cast<int32_t>(rd) << kRdShift) | 304 (static_cast<int32_t>(rd) << kRdShift) | (0xf << 8) | B4 |
317 (0xf << 8) | B4 | static_cast<int32_t>(rm); 305 static_cast<int32_t>(rm);
318 Emit(encoding); 306 Emit(encoding);
319 } 307 }
320 308
321 309
322 void Assembler::movw(Register rd, uint16_t imm16, Condition cond) { 310 void Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
323 ASSERT(cond != kNoCondition); 311 ASSERT(cond != kNoCondition);
324 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 312 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | B25 | B24 |
325 B25 | B24 | ((imm16 >> 12) << 16) | 313 ((imm16 >> 12) << 16) |
326 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 314 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
327 Emit(encoding); 315 Emit(encoding);
328 } 316 }
329 317
330 318
331 void Assembler::movt(Register rd, uint16_t imm16, Condition cond) { 319 void Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
332 ASSERT(cond != kNoCondition); 320 ASSERT(cond != kNoCondition);
333 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 321 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | B25 | B24 |
334 B25 | B24 | B22 | ((imm16 >> 12) << 16) | 322 B22 | ((imm16 >> 12) << 16) |
335 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 323 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
336 Emit(encoding); 324 Emit(encoding);
337 } 325 }
338 326
339 327
340 void Assembler::EmitMulOp(Condition cond, int32_t opcode, 328 void Assembler::EmitMulOp(Condition cond,
341 Register rd, Register rn, 329 int32_t opcode,
342 Register rm, Register rs) { 330 Register rd,
331 Register rn,
332 Register rm,
333 Register rs) {
343 ASSERT(rd != kNoRegister); 334 ASSERT(rd != kNoRegister);
344 ASSERT(rn != kNoRegister); 335 ASSERT(rn != kNoRegister);
345 ASSERT(rm != kNoRegister); 336 ASSERT(rm != kNoRegister);
346 ASSERT(rs != kNoRegister); 337 ASSERT(rs != kNoRegister);
347 ASSERT(cond != kNoCondition); 338 ASSERT(cond != kNoCondition);
348 int32_t encoding = opcode | 339 int32_t encoding = opcode | (static_cast<int32_t>(cond) << kConditionShift) |
349 (static_cast<int32_t>(cond) << kConditionShift) | 340 (static_cast<int32_t>(rn) << kRnShift) |
350 (static_cast<int32_t>(rn) << kRnShift) | 341 (static_cast<int32_t>(rd) << kRdShift) |
351 (static_cast<int32_t>(rd) << kRdShift) | 342 (static_cast<int32_t>(rs) << kRsShift) | B7 | B4 |
352 (static_cast<int32_t>(rs) << kRsShift) | 343 (static_cast<int32_t>(rm) << kRmShift);
353 B7 | B4 |
354 (static_cast<int32_t>(rm) << kRmShift);
355 Emit(encoding); 344 Emit(encoding);
356 } 345 }
357 346
358 347
359 void Assembler::mul(Register rd, Register rn, Register rm, Condition cond) { 348 void Assembler::mul(Register rd, Register rn, Register rm, Condition cond) {
360 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 349 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
361 EmitMulOp(cond, 0, R0, rd, rn, rm); 350 EmitMulOp(cond, 0, R0, rd, rn, rm);
362 } 351 }
363 352
364 353
365 // Like mul, but sets condition flags. 354 // Like mul, but sets condition flags.
366 void Assembler::muls(Register rd, Register rn, Register rm, Condition cond) { 355 void Assembler::muls(Register rd, Register rn, Register rm, Condition cond) {
367 EmitMulOp(cond, B20, R0, rd, rn, rm); 356 EmitMulOp(cond, B20, R0, rd, rn, rm);
368 } 357 }
369 358
370 359
371 void Assembler::mla(Register rd, Register rn, 360 void Assembler::mla(Register rd,
372 Register rm, Register ra, Condition cond) { 361 Register rn,
362 Register rm,
363 Register ra,
364 Condition cond) {
373 // rd <- ra + rn * rm. 365 // rd <- ra + rn * rm.
374 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 366 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
375 EmitMulOp(cond, B21, ra, rd, rn, rm); 367 EmitMulOp(cond, B21, ra, rd, rn, rm);
376 } 368 }
377 369
378 370
379 void Assembler::mls(Register rd, Register rn, 371 void Assembler::mls(Register rd,
380 Register rm, Register ra, Condition cond) { 372 Register rn,
373 Register rm,
374 Register ra,
375 Condition cond) {
381 // rd <- ra - rn * rm. 376 // rd <- ra - rn * rm.
382 if (TargetCPUFeatures::arm_version() == ARMv7) { 377 if (TargetCPUFeatures::arm_version() == ARMv7) {
383 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 378 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
384 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); 379 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
385 } else { 380 } else {
386 mul(IP, rn, rm, cond); 381 mul(IP, rn, rm, cond);
387 sub(rd, ra, Operand(IP), cond); 382 sub(rd, ra, Operand(IP), cond);
388 } 383 }
389 } 384 }
390 385
391 386
392 void Assembler::smull(Register rd_lo, Register rd_hi, 387 void Assembler::smull(Register rd_lo,
393 Register rn, Register rm, Condition cond) { 388 Register rd_hi,
389 Register rn,
390 Register rm,
391 Condition cond) {
394 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 392 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
395 EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm); 393 EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm);
396 } 394 }
397 395
398 396
399 void Assembler::umull(Register rd_lo, Register rd_hi, 397 void Assembler::umull(Register rd_lo,
400 Register rn, Register rm, Condition cond) { 398 Register rd_hi,
399 Register rn,
400 Register rm,
401 Condition cond) {
401 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 402 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
402 EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); 403 EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
403 } 404 }
404 405
405 406
406 void Assembler::umlal(Register rd_lo, Register rd_hi, 407 void Assembler::umlal(Register rd_lo,
407 Register rn, Register rm, Condition cond) { 408 Register rd_hi,
409 Register rn,
410 Register rm,
411 Condition cond) {
408 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 412 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
409 EmitMulOp(cond, B23 | B21, rd_lo, rd_hi, rn, rm); 413 EmitMulOp(cond, B23 | B21, rd_lo, rd_hi, rn, rm);
410 } 414 }
411 415
412 416
413 void Assembler::umaal(Register rd_lo, Register rd_hi, 417 void Assembler::umaal(Register rd_lo,
414 Register rn, Register rm) { 418 Register rd_hi,
419 Register rn,
420 Register rm) {
415 ASSERT(rd_lo != IP); 421 ASSERT(rd_lo != IP);
416 ASSERT(rd_hi != IP); 422 ASSERT(rd_hi != IP);
417 ASSERT(rn != IP); 423 ASSERT(rn != IP);
418 ASSERT(rm != IP); 424 ASSERT(rm != IP);
419 if (TargetCPUFeatures::arm_version() != ARMv5TE) { 425 if (TargetCPUFeatures::arm_version() != ARMv5TE) {
420 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 426 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
421 EmitMulOp(AL, B22, rd_lo, rd_hi, rn, rm); 427 EmitMulOp(AL, B22, rd_lo, rd_hi, rn, rm);
422 } else { 428 } else {
423 mov(IP, Operand(0)); 429 mov(IP, Operand(0));
424 umlal(rd_lo, IP, rn, rm); 430 umlal(rd_lo, IP, rn, rm);
425 adds(rd_lo, rd_lo, Operand(rd_hi)); 431 adds(rd_lo, rd_lo, Operand(rd_hi));
426 adc(rd_hi, IP, Operand(0)); 432 adc(rd_hi, IP, Operand(0));
427 } 433 }
428 } 434 }
429 435
430 436
431 void Assembler::EmitDivOp(Condition cond, int32_t opcode, 437 void Assembler::EmitDivOp(Condition cond,
432 Register rd, Register rn, Register rm) { 438 int32_t opcode,
439 Register rd,
440 Register rn,
441 Register rm) {
433 ASSERT(TargetCPUFeatures::integer_division_supported()); 442 ASSERT(TargetCPUFeatures::integer_division_supported());
434 ASSERT(rd != kNoRegister); 443 ASSERT(rd != kNoRegister);
435 ASSERT(rn != kNoRegister); 444 ASSERT(rn != kNoRegister);
436 ASSERT(rm != kNoRegister); 445 ASSERT(rm != kNoRegister);
437 ASSERT(cond != kNoCondition); 446 ASSERT(cond != kNoCondition);
438 int32_t encoding = opcode | 447 int32_t encoding = opcode | (static_cast<int32_t>(cond) << kConditionShift) |
439 (static_cast<int32_t>(cond) << kConditionShift) | 448 (static_cast<int32_t>(rn) << kDivRnShift) |
440 (static_cast<int32_t>(rn) << kDivRnShift) | 449 (static_cast<int32_t>(rd) << kDivRdShift) | B26 | B25 |
441 (static_cast<int32_t>(rd) << kDivRdShift) | 450 B24 | B20 | B4 | (static_cast<int32_t>(rm) << kDivRmShift);
442 B26 | B25 | B24 | B20 | B4 |
443 (static_cast<int32_t>(rm) << kDivRmShift);
444 Emit(encoding); 451 Emit(encoding);
445 } 452 }
446 453
447 454
448 void Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) { 455 void Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) {
449 EmitDivOp(cond, 0, rd, rn, rm); 456 EmitDivOp(cond, 0, rd, rn, rm);
450 } 457 }
451 458
452 459
453 void Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) { 460 void Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) {
454 EmitDivOp(cond, B21 , rd, rn, rm); 461 EmitDivOp(cond, B21, rd, rn, rm);
455 } 462 }
456 463
457 464
458 void Assembler::ldr(Register rd, Address ad, Condition cond) { 465 void Assembler::ldr(Register rd, Address ad, Condition cond) {
459 EmitMemOp(cond, true, false, rd, ad); 466 EmitMemOp(cond, true, false, rd, ad);
460 } 467 }
461 468
462 469
463 void Assembler::str(Register rd, Address ad, Condition cond) { 470 void Assembler::str(Register rd, Address ad, Condition cond) {
464 EmitMemOp(cond, false, false, rd, ad); 471 EmitMemOp(cond, false, false, rd, ad);
(...skipping 23 matching lines...) Expand all
488 void Assembler::ldrsb(Register rd, Address ad, Condition cond) { 495 void Assembler::ldrsb(Register rd, Address ad, Condition cond) {
489 EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad); 496 EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad);
490 } 497 }
491 498
492 499
493 void Assembler::ldrsh(Register rd, Address ad, Condition cond) { 500 void Assembler::ldrsh(Register rd, Address ad, Condition cond) {
494 EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad); 501 EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad);
495 } 502 }
496 503
497 504
498 void Assembler::ldrd(Register rd, Register rd2, Register rn, int32_t offset, 505 void Assembler::ldrd(Register rd,
506 Register rd2,
507 Register rn,
508 int32_t offset,
499 Condition cond) { 509 Condition cond) {
500 ASSERT((rd % 2) == 0); 510 ASSERT((rd % 2) == 0);
501 ASSERT(rd2 == rd + 1); 511 ASSERT(rd2 == rd + 1);
502 if (TargetCPUFeatures::arm_version() == ARMv5TE) { 512 if (TargetCPUFeatures::arm_version() == ARMv5TE) {
503 ldr(rd, Address(rn, offset), cond); 513 ldr(rd, Address(rn, offset), cond);
504 ldr(rd2, Address(rn, offset + kWordSize), cond); 514 ldr(rd2, Address(rn, offset + kWordSize), cond);
505 } else { 515 } else {
506 EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, Address(rn, offset)); 516 EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, Address(rn, offset));
507 } 517 }
508 } 518 }
509 519
510 520
511 void Assembler::strd(Register rd, Register rd2, Register rn, int32_t offset, 521 void Assembler::strd(Register rd,
522 Register rd2,
523 Register rn,
524 int32_t offset,
512 Condition cond) { 525 Condition cond) {
513 ASSERT((rd % 2) == 0); 526 ASSERT((rd % 2) == 0);
514 ASSERT(rd2 == rd + 1); 527 ASSERT(rd2 == rd + 1);
515 if (TargetCPUFeatures::arm_version() == ARMv5TE) { 528 if (TargetCPUFeatures::arm_version() == ARMv5TE) {
516 str(rd, Address(rn, offset), cond); 529 str(rd, Address(rn, offset), cond);
517 str(rd2, Address(rn, offset + kWordSize), cond); 530 str(rd2, Address(rn, offset + kWordSize), cond);
518 } else { 531 } else {
519 EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, Address(rn, offset)); 532 EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, Address(rn, offset));
520 } 533 }
521 } 534 }
522 535
523 536
524 void Assembler::ldm(BlockAddressMode am, Register base, RegList regs, 537 void Assembler::ldm(BlockAddressMode am,
538 Register base,
539 RegList regs,
525 Condition cond) { 540 Condition cond) {
526 ASSERT(regs != 0); 541 ASSERT(regs != 0);
527 EmitMultiMemOp(cond, am, true, base, regs); 542 EmitMultiMemOp(cond, am, true, base, regs);
528 } 543 }
529 544
530 545
531 void Assembler::stm(BlockAddressMode am, Register base, RegList regs, 546 void Assembler::stm(BlockAddressMode am,
547 Register base,
548 RegList regs,
532 Condition cond) { 549 Condition cond) {
533 ASSERT(regs != 0); 550 ASSERT(regs != 0);
534 EmitMultiMemOp(cond, am, false, base, regs); 551 EmitMultiMemOp(cond, am, false, base, regs);
535 } 552 }
536 553
537 554
538 void Assembler::ldrex(Register rt, Register rn, Condition cond) { 555 void Assembler::ldrex(Register rt, Register rn, Condition cond) {
539 ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE); 556 ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE);
540 ASSERT(rn != kNoRegister); 557 ASSERT(rn != kNoRegister);
541 ASSERT(rt != kNoRegister); 558 ASSERT(rt != kNoRegister);
542 ASSERT(cond != kNoCondition); 559 ASSERT(cond != kNoCondition);
543 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 560 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B24 |
544 B24 | 561 B23 | L | (static_cast<int32_t>(rn) << kLdExRnShift) |
545 B23 | 562 (static_cast<int32_t>(rt) << kLdExRtShift) | B11 | B10 |
546 L | 563 B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
547 (static_cast<int32_t>(rn) << kLdExRnShift) |
548 (static_cast<int32_t>(rt) << kLdExRtShift) |
549 B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
550 Emit(encoding); 564 Emit(encoding);
551 } 565 }
552 566
553 567
554 void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) { 568 void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) {
555 ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE); 569 ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE);
556 ASSERT(rn != kNoRegister); 570 ASSERT(rn != kNoRegister);
557 ASSERT(rd != kNoRegister); 571 ASSERT(rd != kNoRegister);
558 ASSERT(rt != kNoRegister); 572 ASSERT(rt != kNoRegister);
559 ASSERT(cond != kNoCondition); 573 ASSERT(cond != kNoCondition);
560 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 574 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B24 |
561 B24 | 575 B23 | (static_cast<int32_t>(rn) << kStrExRnShift) |
562 B23 | 576 (static_cast<int32_t>(rd) << kStrExRdShift) | B11 | B10 |
563 (static_cast<int32_t>(rn) << kStrExRnShift) | 577 B9 | B8 | B7 | B4 |
564 (static_cast<int32_t>(rd) << kStrExRdShift) |
565 B11 | B10 | B9 | B8 | B7 | B4 |
566 (static_cast<int32_t>(rt) << kStrExRtShift); 578 (static_cast<int32_t>(rt) << kStrExRtShift);
567 Emit(encoding); 579 Emit(encoding);
568 } 580 }
569 581
570 582
571 void Assembler::clrex() { 583 void Assembler::clrex() {
572 ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE); 584 ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE);
573 int32_t encoding = (kSpecialCondition << kConditionShift) | 585 int32_t encoding = (kSpecialCondition << kConditionShift) | B26 | B24 | B22 |
574 B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf; 586 B21 | B20 | (0xff << 12) | B4 | 0xf;
575 Emit(encoding); 587 Emit(encoding);
576 } 588 }
577 589
578 590
579 void Assembler::nop(Condition cond) { 591 void Assembler::nop(Condition cond) {
580 ASSERT(cond != kNoCondition); 592 ASSERT(cond != kNoCondition);
581 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 593 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B25 |
582 B25 | B24 | B21 | (0xf << 12); 594 B24 | B21 | (0xf << 12);
583 Emit(encoding); 595 Emit(encoding);
584 } 596 }
585 597
586 598
587 void Assembler::vmovsr(SRegister sn, Register rt, Condition cond) { 599 void Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
588 ASSERT(TargetCPUFeatures::vfp_supported()); 600 ASSERT(TargetCPUFeatures::vfp_supported());
589 ASSERT(sn != kNoSRegister); 601 ASSERT(sn != kNoSRegister);
590 ASSERT(rt != kNoRegister); 602 ASSERT(rt != kNoRegister);
591 ASSERT(rt != SP); 603 ASSERT(rt != SP);
592 ASSERT(rt != PC); 604 ASSERT(rt != PC);
593 ASSERT(cond != kNoCondition); 605 ASSERT(cond != kNoCondition);
594 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 606 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
595 B27 | B26 | B25 | 607 B26 | B25 | ((static_cast<int32_t>(sn) >> 1) * B16) |
596 ((static_cast<int32_t>(sn) >> 1)*B16) | 608 (static_cast<int32_t>(rt) * B12) | B11 | B9 |
597 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 609 ((static_cast<int32_t>(sn) & 1) * B7) | B4;
598 ((static_cast<int32_t>(sn) & 1)*B7) | B4;
599 Emit(encoding); 610 Emit(encoding);
600 } 611 }
601 612
602 613
603 void Assembler::vmovrs(Register rt, SRegister sn, Condition cond) { 614 void Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
604 ASSERT(TargetCPUFeatures::vfp_supported()); 615 ASSERT(TargetCPUFeatures::vfp_supported());
605 ASSERT(sn != kNoSRegister); 616 ASSERT(sn != kNoSRegister);
606 ASSERT(rt != kNoRegister); 617 ASSERT(rt != kNoRegister);
607 ASSERT(rt != SP); 618 ASSERT(rt != SP);
608 ASSERT(rt != PC); 619 ASSERT(rt != PC);
609 ASSERT(cond != kNoCondition); 620 ASSERT(cond != kNoCondition);
610 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 621 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
611 B27 | B26 | B25 | B20 | 622 B26 | B25 | B20 | ((static_cast<int32_t>(sn) >> 1) * B16) |
612 ((static_cast<int32_t>(sn) >> 1)*B16) | 623 (static_cast<int32_t>(rt) * B12) | B11 | B9 |
613 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 624 ((static_cast<int32_t>(sn) & 1) * B7) | B4;
614 ((static_cast<int32_t>(sn) & 1)*B7) | B4;
615 Emit(encoding); 625 Emit(encoding);
616 } 626 }
617 627
618 628
619 void Assembler::vmovsrr(SRegister sm, Register rt, Register rt2, 629 void Assembler::vmovsrr(SRegister sm,
630 Register rt,
631 Register rt2,
620 Condition cond) { 632 Condition cond) {
621 ASSERT(TargetCPUFeatures::vfp_supported()); 633 ASSERT(TargetCPUFeatures::vfp_supported());
622 ASSERT(sm != kNoSRegister); 634 ASSERT(sm != kNoSRegister);
623 ASSERT(sm != S31); 635 ASSERT(sm != S31);
624 ASSERT(rt != kNoRegister); 636 ASSERT(rt != kNoRegister);
625 ASSERT(rt != SP); 637 ASSERT(rt != SP);
626 ASSERT(rt != PC); 638 ASSERT(rt != PC);
627 ASSERT(rt2 != kNoRegister); 639 ASSERT(rt2 != kNoRegister);
628 ASSERT(rt2 != SP); 640 ASSERT(rt2 != SP);
629 ASSERT(rt2 != PC); 641 ASSERT(rt2 != PC);
630 ASSERT(cond != kNoCondition); 642 ASSERT(cond != kNoCondition);
631 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 643 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
632 B27 | B26 | B22 | 644 B26 | B22 | (static_cast<int32_t>(rt2) * B16) |
633 (static_cast<int32_t>(rt2)*B16) | 645 (static_cast<int32_t>(rt) * B12) | B11 | B9 |
634 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 646 ((static_cast<int32_t>(sm) & 1) * B5) | B4 |
635 ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
636 (static_cast<int32_t>(sm) >> 1); 647 (static_cast<int32_t>(sm) >> 1);
637 Emit(encoding); 648 Emit(encoding);
638 } 649 }
639 650
640 651
641 void Assembler::vmovrrs(Register rt, Register rt2, SRegister sm, 652 void Assembler::vmovrrs(Register rt,
653 Register rt2,
654 SRegister sm,
642 Condition cond) { 655 Condition cond) {
643 ASSERT(TargetCPUFeatures::vfp_supported()); 656 ASSERT(TargetCPUFeatures::vfp_supported());
644 ASSERT(sm != kNoSRegister); 657 ASSERT(sm != kNoSRegister);
645 ASSERT(sm != S31); 658 ASSERT(sm != S31);
646 ASSERT(rt != kNoRegister); 659 ASSERT(rt != kNoRegister);
647 ASSERT(rt != SP); 660 ASSERT(rt != SP);
648 ASSERT(rt != PC); 661 ASSERT(rt != PC);
649 ASSERT(rt2 != kNoRegister); 662 ASSERT(rt2 != kNoRegister);
650 ASSERT(rt2 != SP); 663 ASSERT(rt2 != SP);
651 ASSERT(rt2 != PC); 664 ASSERT(rt2 != PC);
652 ASSERT(rt != rt2); 665 ASSERT(rt != rt2);
653 ASSERT(cond != kNoCondition); 666 ASSERT(cond != kNoCondition);
654 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 667 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
655 B27 | B26 | B22 | B20 | 668 B26 | B22 | B20 | (static_cast<int32_t>(rt2) * B16) |
656 (static_cast<int32_t>(rt2)*B16) | 669 (static_cast<int32_t>(rt) * B12) | B11 | B9 |
657 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 670 ((static_cast<int32_t>(sm) & 1) * B5) | B4 |
658 ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
659 (static_cast<int32_t>(sm) >> 1); 671 (static_cast<int32_t>(sm) >> 1);
660 Emit(encoding); 672 Emit(encoding);
661 } 673 }
662 674
663 675
664 void Assembler::vmovdr(DRegister dn, int i, Register rt, Condition cond) { 676 void Assembler::vmovdr(DRegister dn, int i, Register rt, Condition cond) {
665 ASSERT(TargetCPUFeatures::vfp_supported()); 677 ASSERT(TargetCPUFeatures::vfp_supported());
666 ASSERT((i == 0) || (i == 1)); 678 ASSERT((i == 0) || (i == 1));
667 ASSERT(rt != kNoRegister); 679 ASSERT(rt != kNoRegister);
668 ASSERT(rt != SP); 680 ASSERT(rt != SP);
669 ASSERT(rt != PC); 681 ASSERT(rt != PC);
670 ASSERT(dn != kNoDRegister); 682 ASSERT(dn != kNoDRegister);
671 ASSERT(cond != kNoCondition); 683 ASSERT(cond != kNoCondition);
672 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 684 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
673 B27 | B26 | B25 | 685 B26 | B25 | (i * B21) | (static_cast<int32_t>(rt) * B12) |
674 (i*B21) | 686 B11 | B9 | B8 | ((static_cast<int32_t>(dn) >> 4) * B7) |
675 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 687 ((static_cast<int32_t>(dn) & 0xf) * B16) | B4;
676 ((static_cast<int32_t>(dn) >> 4)*B7) |
677 ((static_cast<int32_t>(dn) & 0xf)*B16) | B4;
678 Emit(encoding); 688 Emit(encoding);
679 } 689 }
680 690
681 691
682 void Assembler::vmovdrr(DRegister dm, Register rt, Register rt2, 692 void Assembler::vmovdrr(DRegister dm,
693 Register rt,
694 Register rt2,
683 Condition cond) { 695 Condition cond) {
684 ASSERT(TargetCPUFeatures::vfp_supported()); 696 ASSERT(TargetCPUFeatures::vfp_supported());
685 ASSERT(dm != kNoDRegister); 697 ASSERT(dm != kNoDRegister);
686 ASSERT(rt != kNoRegister); 698 ASSERT(rt != kNoRegister);
687 ASSERT(rt != SP); 699 ASSERT(rt != SP);
688 ASSERT(rt != PC); 700 ASSERT(rt != PC);
689 ASSERT(rt2 != kNoRegister); 701 ASSERT(rt2 != kNoRegister);
690 ASSERT(rt2 != SP); 702 ASSERT(rt2 != SP);
691 ASSERT(rt2 != PC); 703 ASSERT(rt2 != PC);
692 ASSERT(cond != kNoCondition); 704 ASSERT(cond != kNoCondition);
693 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 705 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
694 B27 | B26 | B22 | 706 B26 | B22 | (static_cast<int32_t>(rt2) * B16) |
695 (static_cast<int32_t>(rt2)*B16) | 707 (static_cast<int32_t>(rt) * B12) | B11 | B9 | B8 |
696 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 708 ((static_cast<int32_t>(dm) >> 4) * B5) | B4 |
697 ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
698 (static_cast<int32_t>(dm) & 0xf); 709 (static_cast<int32_t>(dm) & 0xf);
699 Emit(encoding); 710 Emit(encoding);
700 } 711 }
701 712
702 713
703 void Assembler::vmovrrd(Register rt, Register rt2, DRegister dm, 714 void Assembler::vmovrrd(Register rt,
715 Register rt2,
716 DRegister dm,
704 Condition cond) { 717 Condition cond) {
705 ASSERT(TargetCPUFeatures::vfp_supported()); 718 ASSERT(TargetCPUFeatures::vfp_supported());
706 ASSERT(dm != kNoDRegister); 719 ASSERT(dm != kNoDRegister);
707 ASSERT(rt != kNoRegister); 720 ASSERT(rt != kNoRegister);
708 ASSERT(rt != SP); 721 ASSERT(rt != SP);
709 ASSERT(rt != PC); 722 ASSERT(rt != PC);
710 ASSERT(rt2 != kNoRegister); 723 ASSERT(rt2 != kNoRegister);
711 ASSERT(rt2 != SP); 724 ASSERT(rt2 != SP);
712 ASSERT(rt2 != PC); 725 ASSERT(rt2 != PC);
713 ASSERT(rt != rt2); 726 ASSERT(rt != rt2);
714 ASSERT(cond != kNoCondition); 727 ASSERT(cond != kNoCondition);
715 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 728 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
716 B27 | B26 | B22 | B20 | 729 B26 | B22 | B20 | (static_cast<int32_t>(rt2) * B16) |
717 (static_cast<int32_t>(rt2)*B16) | 730 (static_cast<int32_t>(rt) * B12) | B11 | B9 | B8 |
718 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 731 ((static_cast<int32_t>(dm) >> 4) * B5) | B4 |
719 ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
720 (static_cast<int32_t>(dm) & 0xf); 732 (static_cast<int32_t>(dm) & 0xf);
721 Emit(encoding); 733 Emit(encoding);
722 } 734 }
723 735
724 736
725 void Assembler::vldrs(SRegister sd, Address ad, Condition cond) { 737 void Assembler::vldrs(SRegister sd, Address ad, Condition cond) {
726 ASSERT(TargetCPUFeatures::vfp_supported()); 738 ASSERT(TargetCPUFeatures::vfp_supported());
727 ASSERT(sd != kNoSRegister); 739 ASSERT(sd != kNoSRegister);
728 ASSERT(cond != kNoCondition); 740 ASSERT(cond != kNoCondition);
729 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 741 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
730 B27 | B26 | B24 | B20 | 742 B26 | B24 | B20 | ((static_cast<int32_t>(sd) & 1) * B22) |
731 ((static_cast<int32_t>(sd) & 1)*B22) | 743 ((static_cast<int32_t>(sd) >> 1) * B12) | B11 | B9 |
732 ((static_cast<int32_t>(sd) >> 1)*B12) | 744 ad.vencoding();
733 B11 | B9 | ad.vencoding();
734 Emit(encoding); 745 Emit(encoding);
735 } 746 }
736 747
737 748
738 void Assembler::vstrs(SRegister sd, Address ad, Condition cond) { 749 void Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
739 ASSERT(TargetCPUFeatures::vfp_supported()); 750 ASSERT(TargetCPUFeatures::vfp_supported());
740 ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC); 751 ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC);
741 ASSERT(sd != kNoSRegister); 752 ASSERT(sd != kNoSRegister);
742 ASSERT(cond != kNoCondition); 753 ASSERT(cond != kNoCondition);
743 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 754 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
744 B27 | B26 | B24 | 755 B26 | B24 | ((static_cast<int32_t>(sd) & 1) * B22) |
745 ((static_cast<int32_t>(sd) & 1)*B22) | 756 ((static_cast<int32_t>(sd) >> 1) * B12) | B11 | B9 |
746 ((static_cast<int32_t>(sd) >> 1)*B12) | 757 ad.vencoding();
747 B11 | B9 | ad.vencoding();
748 Emit(encoding); 758 Emit(encoding);
749 } 759 }
750 760
751 761
752 void Assembler::vldrd(DRegister dd, Address ad, Condition cond) { 762 void Assembler::vldrd(DRegister dd, Address ad, Condition cond) {
753 ASSERT(TargetCPUFeatures::vfp_supported()); 763 ASSERT(TargetCPUFeatures::vfp_supported());
754 ASSERT(dd != kNoDRegister); 764 ASSERT(dd != kNoDRegister);
755 ASSERT(cond != kNoCondition); 765 ASSERT(cond != kNoCondition);
756 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 766 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
757 B27 | B26 | B24 | B20 | 767 B26 | B24 | B20 | ((static_cast<int32_t>(dd) >> 4) * B22) |
758 ((static_cast<int32_t>(dd) >> 4)*B22) | 768 ((static_cast<int32_t>(dd) & 0xf) * B12) | B11 | B9 | B8 |
759 ((static_cast<int32_t>(dd) & 0xf)*B12) | 769 ad.vencoding();
760 B11 | B9 | B8 | ad.vencoding();
761 Emit(encoding); 770 Emit(encoding);
762 } 771 }
763 772
764 773
765 void Assembler::vstrd(DRegister dd, Address ad, Condition cond) { 774 void Assembler::vstrd(DRegister dd, Address ad, Condition cond) {
766 ASSERT(TargetCPUFeatures::vfp_supported()); 775 ASSERT(TargetCPUFeatures::vfp_supported());
767 ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC); 776 ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC);
768 ASSERT(dd != kNoDRegister); 777 ASSERT(dd != kNoDRegister);
769 ASSERT(cond != kNoCondition); 778 ASSERT(cond != kNoCondition);
770 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 779 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
771 B27 | B26 | B24 | 780 B26 | B24 | ((static_cast<int32_t>(dd) >> 4) * B22) |
772 ((static_cast<int32_t>(dd) >> 4)*B22) | 781 ((static_cast<int32_t>(dd) & 0xf) * B12) | B11 | B9 | B8 |
773 ((static_cast<int32_t>(dd) & 0xf)*B12) | 782 ad.vencoding();
774 B11 | B9 | B8 | ad.vencoding();
775 Emit(encoding); 783 Emit(encoding);
776 } 784 }
777 785
778 void Assembler::EmitMultiVSMemOp(Condition cond, 786 void Assembler::EmitMultiVSMemOp(Condition cond,
779 BlockAddressMode am, 787 BlockAddressMode am,
780 bool load, 788 bool load,
781 Register base, 789 Register base,
782 SRegister start, 790 SRegister start,
783 uint32_t count) { 791 uint32_t count) {
784 ASSERT(TargetCPUFeatures::vfp_supported()); 792 ASSERT(TargetCPUFeatures::vfp_supported());
785 ASSERT(base != kNoRegister); 793 ASSERT(base != kNoRegister);
786 ASSERT(cond != kNoCondition); 794 ASSERT(cond != kNoCondition);
787 ASSERT(start != kNoSRegister); 795 ASSERT(start != kNoSRegister);
788 ASSERT(static_cast<int32_t>(start) + count <= kNumberOfSRegisters); 796 ASSERT(static_cast<int32_t>(start) + count <= kNumberOfSRegisters);
789 797
790 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 798 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
791 B27 | B26 | B11 | B9 | 799 B26 | B11 | B9 | am | (load ? L : 0) |
792 am |
793 (load ? L : 0) |
794 (static_cast<int32_t>(base) << kRnShift) | 800 (static_cast<int32_t>(base) << kRnShift) |
795 ((static_cast<int32_t>(start) & 0x1) ? D : 0) | 801 ((static_cast<int32_t>(start) & 0x1) ? D : 0) |
796 ((static_cast<int32_t>(start) >> 1) << 12) | 802 ((static_cast<int32_t>(start) >> 1) << 12) | count;
797 count;
798 Emit(encoding); 803 Emit(encoding);
799 } 804 }
800 805
801 806
802 void Assembler::EmitMultiVDMemOp(Condition cond, 807 void Assembler::EmitMultiVDMemOp(Condition cond,
803 BlockAddressMode am, 808 BlockAddressMode am,
804 bool load, 809 bool load,
805 Register base, 810 Register base,
806 DRegister start, 811 DRegister start,
807 int32_t count) { 812 int32_t count) {
808 ASSERT(TargetCPUFeatures::vfp_supported()); 813 ASSERT(TargetCPUFeatures::vfp_supported());
809 ASSERT(base != kNoRegister); 814 ASSERT(base != kNoRegister);
810 ASSERT(cond != kNoCondition); 815 ASSERT(cond != kNoCondition);
811 ASSERT(start != kNoDRegister); 816 ASSERT(start != kNoDRegister);
812 ASSERT(static_cast<int32_t>(start) + count <= kNumberOfDRegisters); 817 ASSERT(static_cast<int32_t>(start) + count <= kNumberOfDRegisters);
813 const int armv5te = TargetCPUFeatures::arm_version() == ARMv5TE ? 1 : 0; 818 const int armv5te = TargetCPUFeatures::arm_version() == ARMv5TE ? 1 : 0;
814 819
815 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 820 int32_t encoding =
816 B27 | B26 | B11 | B9 | B8 | 821 (static_cast<int32_t>(cond) << kConditionShift) | B27 | B26 | B11 | B9 |
817 am | 822 B8 | am | (load ? L : 0) | (static_cast<int32_t>(base) << kRnShift) |
818 (load ? L : 0) | 823 ((static_cast<int32_t>(start) & 0x10) ? D : 0) |
819 (static_cast<int32_t>(base) << kRnShift) | 824 ((static_cast<int32_t>(start) & 0xf) << 12) | (count << 1) | armv5te;
820 ((static_cast<int32_t>(start) & 0x10) ? D : 0) |
821 ((static_cast<int32_t>(start) & 0xf) << 12) |
822 (count << 1) | armv5te;
823 Emit(encoding); 825 Emit(encoding);
824 } 826 }
825 827
826 828
827 void Assembler::vldms(BlockAddressMode am, Register base, 829 void Assembler::vldms(BlockAddressMode am,
828 SRegister first, SRegister last, Condition cond) { 830 Register base,
831 SRegister first,
832 SRegister last,
833 Condition cond) {
829 ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); 834 ASSERT((am == IA) || (am == IA_W) || (am == DB_W));
830 ASSERT(last > first); 835 ASSERT(last > first);
831 EmitMultiVSMemOp(cond, am, true, base, first, last - first + 1); 836 EmitMultiVSMemOp(cond, am, true, base, first, last - first + 1);
832 } 837 }
833 838
834 839
835 void Assembler::vstms(BlockAddressMode am, Register base, 840 void Assembler::vstms(BlockAddressMode am,
836 SRegister first, SRegister last, Condition cond) { 841 Register base,
842 SRegister first,
843 SRegister last,
844 Condition cond) {
837 ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); 845 ASSERT((am == IA) || (am == IA_W) || (am == DB_W));
838 ASSERT(last > first); 846 ASSERT(last > first);
839 EmitMultiVSMemOp(cond, am, false, base, first, last - first + 1); 847 EmitMultiVSMemOp(cond, am, false, base, first, last - first + 1);
840 } 848 }
841 849
842 850
843 void Assembler::vldmd(BlockAddressMode am, Register base, 851 void Assembler::vldmd(BlockAddressMode am,
844 DRegister first, intptr_t count, Condition cond) { 852 Register base,
853 DRegister first,
854 intptr_t count,
855 Condition cond) {
845 ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); 856 ASSERT((am == IA) || (am == IA_W) || (am == DB_W));
846 ASSERT(count <= 16); 857 ASSERT(count <= 16);
847 ASSERT(first + count <= kNumberOfDRegisters); 858 ASSERT(first + count <= kNumberOfDRegisters);
848 EmitMultiVDMemOp(cond, am, true, base, first, count); 859 EmitMultiVDMemOp(cond, am, true, base, first, count);
849 } 860 }
850 861
851 862
852 void Assembler::vstmd(BlockAddressMode am, Register base, 863 void Assembler::vstmd(BlockAddressMode am,
853 DRegister first, intptr_t count, Condition cond) { 864 Register base,
865 DRegister first,
866 intptr_t count,
867 Condition cond) {
854 ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); 868 ASSERT((am == IA) || (am == IA_W) || (am == DB_W));
855 ASSERT(count <= 16); 869 ASSERT(count <= 16);
856 ASSERT(first + count <= kNumberOfDRegisters); 870 ASSERT(first + count <= kNumberOfDRegisters);
857 EmitMultiVDMemOp(cond, am, false, base, first, count); 871 EmitMultiVDMemOp(cond, am, false, base, first, count);
858 } 872 }
859 873
860 874
861 void Assembler::EmitVFPsss(Condition cond, int32_t opcode, 875 void Assembler::EmitVFPsss(Condition cond,
862 SRegister sd, SRegister sn, SRegister sm) { 876 int32_t opcode,
877 SRegister sd,
878 SRegister sn,
879 SRegister sm) {
863 ASSERT(TargetCPUFeatures::vfp_supported()); 880 ASSERT(TargetCPUFeatures::vfp_supported());
864 ASSERT(sd != kNoSRegister); 881 ASSERT(sd != kNoSRegister);
865 ASSERT(sn != kNoSRegister); 882 ASSERT(sn != kNoSRegister);
866 ASSERT(sm != kNoSRegister); 883 ASSERT(sm != kNoSRegister);
867 ASSERT(cond != kNoCondition); 884 ASSERT(cond != kNoCondition);
868 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 885 int32_t encoding =
869 B27 | B26 | B25 | B11 | B9 | opcode | 886 (static_cast<int32_t>(cond) << kConditionShift) | B27 | B26 | B25 | B11 |
870 ((static_cast<int32_t>(sd) & 1)*B22) | 887 B9 | opcode | ((static_cast<int32_t>(sd) & 1) * B22) |
871 ((static_cast<int32_t>(sn) >> 1)*B16) | 888 ((static_cast<int32_t>(sn) >> 1) * B16) |
872 ((static_cast<int32_t>(sd) >> 1)*B12) | 889 ((static_cast<int32_t>(sd) >> 1) * B12) |
873 ((static_cast<int32_t>(sn) & 1)*B7) | 890 ((static_cast<int32_t>(sn) & 1) * B7) |
874 ((static_cast<int32_t>(sm) & 1)*B5) | 891 ((static_cast<int32_t>(sm) & 1) * B5) | (static_cast<int32_t>(sm) >> 1);
875 (static_cast<int32_t>(sm) >> 1);
876 Emit(encoding); 892 Emit(encoding);
877 } 893 }
878 894
879 895
880 void Assembler::EmitVFPddd(Condition cond, int32_t opcode, 896 void Assembler::EmitVFPddd(Condition cond,
881 DRegister dd, DRegister dn, DRegister dm) { 897 int32_t opcode,
898 DRegister dd,
899 DRegister dn,
900 DRegister dm) {
882 ASSERT(TargetCPUFeatures::vfp_supported()); 901 ASSERT(TargetCPUFeatures::vfp_supported());
883 ASSERT(dd != kNoDRegister); 902 ASSERT(dd != kNoDRegister);
884 ASSERT(dn != kNoDRegister); 903 ASSERT(dn != kNoDRegister);
885 ASSERT(dm != kNoDRegister); 904 ASSERT(dm != kNoDRegister);
886 ASSERT(cond != kNoCondition); 905 ASSERT(cond != kNoCondition);
887 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 906 int32_t encoding =
888 B27 | B26 | B25 | B11 | B9 | B8 | opcode | 907 (static_cast<int32_t>(cond) << kConditionShift) | B27 | B26 | B25 | B11 |
889 ((static_cast<int32_t>(dd) >> 4)*B22) | 908 B9 | B8 | opcode | ((static_cast<int32_t>(dd) >> 4) * B22) |
890 ((static_cast<int32_t>(dn) & 0xf)*B16) | 909 ((static_cast<int32_t>(dn) & 0xf) * B16) |
891 ((static_cast<int32_t>(dd) & 0xf)*B12) | 910 ((static_cast<int32_t>(dd) & 0xf) * B12) |
892 ((static_cast<int32_t>(dn) >> 4)*B7) | 911 ((static_cast<int32_t>(dn) >> 4) * B7) |
893 ((static_cast<int32_t>(dm) >> 4)*B5) | 912 ((static_cast<int32_t>(dm) >> 4) * B5) | (static_cast<int32_t>(dm) & 0xf);
894 (static_cast<int32_t>(dm) & 0xf);
895 Emit(encoding); 913 Emit(encoding);
896 } 914 }
897 915
898 916
899 void Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) { 917 void Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
900 EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm); 918 EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
901 } 919 }
902 920
903 921
904 void Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) { 922 void Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
905 EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm); 923 EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
906 } 924 }
907 925
908 926
909 bool Assembler::vmovs(SRegister sd, float s_imm, Condition cond) { 927 bool Assembler::vmovs(SRegister sd, float s_imm, Condition cond) {
910 if (TargetCPUFeatures::arm_version() != ARMv7) { 928 if (TargetCPUFeatures::arm_version() != ARMv7) {
911 return false; 929 return false;
912 } 930 }
913 uint32_t imm32 = bit_cast<uint32_t, float>(s_imm); 931 uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
914 if (((imm32 & ((1 << 19) - 1)) == 0) && 932 if (((imm32 & ((1 << 19) - 1)) == 0) &&
915 ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) || 933 ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
916 (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) { 934 (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) - 1)))) {
917 uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) | 935 uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
918 ((imm32 >> 19) & ((1 << 6) -1)); 936 ((imm32 >> 19) & ((1 << 6) - 1));
919 EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf), 937 EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4) * B16) | (imm8 & 0xf), sd,
920 sd, S0, S0); 938 S0, S0);
921 return true; 939 return true;
922 } 940 }
923 return false; 941 return false;
924 } 942 }
925 943
926 944
927 bool Assembler::vmovd(DRegister dd, double d_imm, Condition cond) { 945 bool Assembler::vmovd(DRegister dd, double d_imm, Condition cond) {
928 if (TargetCPUFeatures::arm_version() != ARMv7) { 946 if (TargetCPUFeatures::arm_version() != ARMv7) {
929 return false; 947 return false;
930 } 948 }
931 uint64_t imm64 = bit_cast<uint64_t, double>(d_imm); 949 uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
932 if (((imm64 & ((1LL << 48) - 1)) == 0) && 950 if (((imm64 & ((1LL << 48) - 1)) == 0) &&
933 ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) || 951 ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
934 (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) { 952 (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) - 1)))) {
935 uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) | 953 uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
936 ((imm64 >> 48) & ((1 << 6) -1)); 954 ((imm64 >> 48) & ((1 << 6) - 1));
937 EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf), 955 EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4) * B16) | B8 | (imm8 & 0xf),
938 dd, D0, D0); 956 dd, D0, D0);
939 return true; 957 return true;
940 } 958 }
941 return false; 959 return false;
942 } 960 }
943 961
944 962
945 void Assembler::vadds(SRegister sd, SRegister sn, SRegister sm, 963 void Assembler::vadds(SRegister sd,
964 SRegister sn,
965 SRegister sm,
946 Condition cond) { 966 Condition cond) {
947 EmitVFPsss(cond, B21 | B20, sd, sn, sm); 967 EmitVFPsss(cond, B21 | B20, sd, sn, sm);
948 } 968 }
949 969
950 970
951 void Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm, 971 void Assembler::vaddd(DRegister dd,
972 DRegister dn,
973 DRegister dm,
952 Condition cond) { 974 Condition cond) {
953 EmitVFPddd(cond, B21 | B20, dd, dn, dm); 975 EmitVFPddd(cond, B21 | B20, dd, dn, dm);
954 } 976 }
955 977
956 978
957 void Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm, 979 void Assembler::vsubs(SRegister sd,
980 SRegister sn,
981 SRegister sm,
958 Condition cond) { 982 Condition cond) {
959 EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm); 983 EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
960 } 984 }
961 985
962 986
963 void Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm, 987 void Assembler::vsubd(DRegister dd,
988 DRegister dn,
989 DRegister dm,
964 Condition cond) { 990 Condition cond) {
965 EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm); 991 EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
966 } 992 }
967 993
968 994
969 void Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm, 995 void Assembler::vmuls(SRegister sd,
996 SRegister sn,
997 SRegister sm,
970 Condition cond) { 998 Condition cond) {
971 EmitVFPsss(cond, B21, sd, sn, sm); 999 EmitVFPsss(cond, B21, sd, sn, sm);
972 } 1000 }
973 1001
974 1002
975 void Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm, 1003 void Assembler::vmuld(DRegister dd,
1004 DRegister dn,
1005 DRegister dm,
976 Condition cond) { 1006 Condition cond) {
977 EmitVFPddd(cond, B21, dd, dn, dm); 1007 EmitVFPddd(cond, B21, dd, dn, dm);
978 } 1008 }
979 1009
980 1010
981 void Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm, 1011 void Assembler::vmlas(SRegister sd,
1012 SRegister sn,
1013 SRegister sm,
982 Condition cond) { 1014 Condition cond) {
983 EmitVFPsss(cond, 0, sd, sn, sm); 1015 EmitVFPsss(cond, 0, sd, sn, sm);
984 } 1016 }
985 1017
986 1018
987 void Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm, 1019 void Assembler::vmlad(DRegister dd,
1020 DRegister dn,
1021 DRegister dm,
988 Condition cond) { 1022 Condition cond) {
989 EmitVFPddd(cond, 0, dd, dn, dm); 1023 EmitVFPddd(cond, 0, dd, dn, dm);
990 } 1024 }
991 1025
992 1026
993 void Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm, 1027 void Assembler::vmlss(SRegister sd,
1028 SRegister sn,
1029 SRegister sm,
994 Condition cond) { 1030 Condition cond) {
995 EmitVFPsss(cond, B6, sd, sn, sm); 1031 EmitVFPsss(cond, B6, sd, sn, sm);
996 } 1032 }
997 1033
998 1034
999 void Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm, 1035 void Assembler::vmlsd(DRegister dd,
1036 DRegister dn,
1037 DRegister dm,
1000 Condition cond) { 1038 Condition cond) {
1001 EmitVFPddd(cond, B6, dd, dn, dm); 1039 EmitVFPddd(cond, B6, dd, dn, dm);
1002 } 1040 }
1003 1041
1004 1042
1005 void Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm, 1043 void Assembler::vdivs(SRegister sd,
1044 SRegister sn,
1045 SRegister sm,
1006 Condition cond) { 1046 Condition cond) {
1007 EmitVFPsss(cond, B23, sd, sn, sm); 1047 EmitVFPsss(cond, B23, sd, sn, sm);
1008 } 1048 }
1009 1049
1010 1050
1011 void Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm, 1051 void Assembler::vdivd(DRegister dd,
1052 DRegister dn,
1053 DRegister dm,
1012 Condition cond) { 1054 Condition cond) {
1013 EmitVFPddd(cond, B23, dd, dn, dm); 1055 EmitVFPddd(cond, B23, dd, dn, dm);
1014 } 1056 }
1015 1057
1016 1058
1017 void Assembler::vabss(SRegister sd, SRegister sm, Condition cond) { 1059 void Assembler::vabss(SRegister sd, SRegister sm, Condition cond) {
1018 EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm); 1060 EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
1019 } 1061 }
1020 1062
1021 1063
(...skipping 14 matching lines...) Expand all
1036 1078
1037 void Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) { 1079 void Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
1038 EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm); 1080 EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
1039 } 1081 }
1040 1082
1041 void Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) { 1083 void Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
1042 EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm); 1084 EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
1043 } 1085 }
1044 1086
1045 1087
1046 void Assembler::EmitVFPsd(Condition cond, int32_t opcode, 1088 void Assembler::EmitVFPsd(Condition cond,
1047 SRegister sd, DRegister dm) { 1089 int32_t opcode,
1090 SRegister sd,
1091 DRegister dm) {
1048 ASSERT(TargetCPUFeatures::vfp_supported()); 1092 ASSERT(TargetCPUFeatures::vfp_supported());
1049 ASSERT(sd != kNoSRegister); 1093 ASSERT(sd != kNoSRegister);
1050 ASSERT(dm != kNoDRegister); 1094 ASSERT(dm != kNoDRegister);
1051 ASSERT(cond != kNoCondition); 1095 ASSERT(cond != kNoCondition);
1052 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1096 int32_t encoding =
1053 B27 | B26 | B25 | B11 | B9 | opcode | 1097 (static_cast<int32_t>(cond) << kConditionShift) | B27 | B26 | B25 | B11 |
1054 ((static_cast<int32_t>(sd) & 1)*B22) | 1098 B9 | opcode | ((static_cast<int32_t>(sd) & 1) * B22) |
1055 ((static_cast<int32_t>(sd) >> 1)*B12) | 1099 ((static_cast<int32_t>(sd) >> 1) * B12) |
1056 ((static_cast<int32_t>(dm) >> 4)*B5) | 1100 ((static_cast<int32_t>(dm) >> 4) * B5) | (static_cast<int32_t>(dm) & 0xf);
1057 (static_cast<int32_t>(dm) & 0xf);
1058 Emit(encoding); 1101 Emit(encoding);
1059 } 1102 }
1060 1103
1061 1104
1062 void Assembler::EmitVFPds(Condition cond, int32_t opcode, 1105 void Assembler::EmitVFPds(Condition cond,
1063 DRegister dd, SRegister sm) { 1106 int32_t opcode,
1107 DRegister dd,
1108 SRegister sm) {
1064 ASSERT(TargetCPUFeatures::vfp_supported()); 1109 ASSERT(TargetCPUFeatures::vfp_supported());
1065 ASSERT(dd != kNoDRegister); 1110 ASSERT(dd != kNoDRegister);
1066 ASSERT(sm != kNoSRegister); 1111 ASSERT(sm != kNoSRegister);
1067 ASSERT(cond != kNoCondition); 1112 ASSERT(cond != kNoCondition);
1068 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1113 int32_t encoding =
1069 B27 | B26 | B25 | B11 | B9 | opcode | 1114 (static_cast<int32_t>(cond) << kConditionShift) | B27 | B26 | B25 | B11 |
1070 ((static_cast<int32_t>(dd) >> 4)*B22) | 1115 B9 | opcode | ((static_cast<int32_t>(dd) >> 4) * B22) |
1071 ((static_cast<int32_t>(dd) & 0xf)*B12) | 1116 ((static_cast<int32_t>(dd) & 0xf) * B12) |
1072 ((static_cast<int32_t>(sm) & 1)*B5) | 1117 ((static_cast<int32_t>(sm) & 1) * B5) | (static_cast<int32_t>(sm) >> 1);
1073 (static_cast<int32_t>(sm) >> 1);
1074 Emit(encoding); 1118 Emit(encoding);
1075 } 1119 }
1076 1120
1077 1121
1078 void Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) { 1122 void Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
1079 EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm); 1123 EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
1080 } 1124 }
1081 1125
1082 1126
1083 void Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) { 1127 void Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 1185
1142 1186
1143 void Assembler::vcmpdz(DRegister dd, Condition cond) { 1187 void Assembler::vcmpdz(DRegister dd, Condition cond) {
1144 EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0); 1188 EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
1145 } 1189 }
1146 1190
1147 1191
1148 void Assembler::vmrs(Register rd, Condition cond) { 1192 void Assembler::vmrs(Register rd, Condition cond) {
1149 ASSERT(TargetCPUFeatures::vfp_supported()); 1193 ASSERT(TargetCPUFeatures::vfp_supported());
1150 ASSERT(cond != kNoCondition); 1194 ASSERT(cond != kNoCondition);
1151 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1195 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
1152 B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | 1196 B26 | B25 | B23 | B22 | B21 | B20 | B16 |
1153 (static_cast<int32_t>(rd)*B12) | 1197 (static_cast<int32_t>(rd) * B12) | B11 | B9 | B4;
1154 B11 | B9 | B4;
1155 Emit(encoding); 1198 Emit(encoding);
1156 } 1199 }
1157 1200
1158 1201
1159 void Assembler::vmstat(Condition cond) { 1202 void Assembler::vmstat(Condition cond) {
1160 vmrs(APSR, cond); 1203 vmrs(APSR, cond);
1161 } 1204 }
1162 1205
1163 1206
1164 static inline int ShiftOfOperandSize(OperandSize size) { 1207 static inline int ShiftOfOperandSize(OperandSize size) {
(...skipping 15 matching lines...) Expand all
1180 default: 1223 default:
1181 UNREACHABLE(); 1224 UNREACHABLE();
1182 break; 1225 break;
1183 } 1226 }
1184 1227
1185 UNREACHABLE(); 1228 UNREACHABLE();
1186 return -1; 1229 return -1;
1187 } 1230 }
1188 1231
1189 1232
1190 void Assembler::EmitSIMDqqq(int32_t opcode, OperandSize size, 1233 void Assembler::EmitSIMDqqq(int32_t opcode,
1191 QRegister qd, QRegister qn, QRegister qm) { 1234 OperandSize size,
1235 QRegister qd,
1236 QRegister qn,
1237 QRegister qm) {
1192 ASSERT(TargetCPUFeatures::neon_supported()); 1238 ASSERT(TargetCPUFeatures::neon_supported());
1193 int sz = ShiftOfOperandSize(size); 1239 int sz = ShiftOfOperandSize(size);
1194 int32_t encoding = 1240 int32_t encoding =
1195 (static_cast<int32_t>(kSpecialCondition) << kConditionShift) | 1241 (static_cast<int32_t>(kSpecialCondition) << kConditionShift) | B25 | B6 |
1196 B25 | B6 |
1197 opcode | ((sz & 0x3) * B20) | 1242 opcode | ((sz & 0x3) * B20) |
1198 ((static_cast<int32_t>(qd * 2) >> 4)*B22) | 1243 ((static_cast<int32_t>(qd * 2) >> 4) * B22) |
1199 ((static_cast<int32_t>(qn * 2) & 0xf)*B16) | 1244 ((static_cast<int32_t>(qn * 2) & 0xf) * B16) |
1200 ((static_cast<int32_t>(qd * 2) & 0xf)*B12) | 1245 ((static_cast<int32_t>(qd * 2) & 0xf) * B12) |
1201 ((static_cast<int32_t>(qn * 2) >> 4)*B7) | 1246 ((static_cast<int32_t>(qn * 2) >> 4) * B7) |
1202 ((static_cast<int32_t>(qm * 2) >> 4)*B5) | 1247 ((static_cast<int32_t>(qm * 2) >> 4) * B5) |
1203 (static_cast<int32_t>(qm * 2) & 0xf); 1248 (static_cast<int32_t>(qm * 2) & 0xf);
1204 Emit(encoding); 1249 Emit(encoding);
1205 } 1250 }
1206 1251
1207 1252
1208 void Assembler::EmitSIMDddd(int32_t opcode, OperandSize size, 1253 void Assembler::EmitSIMDddd(int32_t opcode,
1209 DRegister dd, DRegister dn, DRegister dm) { 1254 OperandSize size,
1255 DRegister dd,
1256 DRegister dn,
1257 DRegister dm) {
1210 ASSERT(TargetCPUFeatures::neon_supported()); 1258 ASSERT(TargetCPUFeatures::neon_supported());
1211 int sz = ShiftOfOperandSize(size); 1259 int sz = ShiftOfOperandSize(size);
1212 int32_t encoding = 1260 int32_t encoding =
1213 (static_cast<int32_t>(kSpecialCondition) << kConditionShift) | 1261 (static_cast<int32_t>(kSpecialCondition) << kConditionShift) | B25 |
1214 B25 | 1262 opcode | ((sz & 0x3) * B20) | ((static_cast<int32_t>(dd) >> 4) * B22) |
1215 opcode | ((sz & 0x3) * B20) | 1263 ((static_cast<int32_t>(dn) & 0xf) * B16) |
1216 ((static_cast<int32_t>(dd) >> 4)*B22) | 1264 ((static_cast<int32_t>(dd) & 0xf) * B12) |
1217 ((static_cast<int32_t>(dn) & 0xf)*B16) | 1265 ((static_cast<int32_t>(dn) >> 4) * B7) |
1218 ((static_cast<int32_t>(dd) & 0xf)*B12) | 1266 ((static_cast<int32_t>(dm) >> 4) * B5) | (static_cast<int32_t>(dm) & 0xf);
1219 ((static_cast<int32_t>(dn) >> 4)*B7) |
1220 ((static_cast<int32_t>(dm) >> 4)*B5) |
1221 (static_cast<int32_t>(dm) & 0xf);
1222 Emit(encoding); 1267 Emit(encoding);
1223 } 1268 }
1224 1269
1225 1270
1226 void Assembler::vmovq(QRegister qd, QRegister qm) { 1271 void Assembler::vmovq(QRegister qd, QRegister qm) {
1227 EmitSIMDqqq(B21 | B8 | B4, kByte, qd, qm, qm); 1272 EmitSIMDqqq(B21 | B8 | B4, kByte, qd, qm, qm);
1228 } 1273 }
1229 1274
1230 1275
1231 void Assembler::vaddqi(OperandSize sz, 1276 void Assembler::vaddqi(OperandSize sz,
1232 QRegister qd, QRegister qn, QRegister qm) { 1277 QRegister qd,
1278 QRegister qn,
1279 QRegister qm) {
1233 EmitSIMDqqq(B11, sz, qd, qn, qm); 1280 EmitSIMDqqq(B11, sz, qd, qn, qm);
1234 } 1281 }
1235 1282
1236 1283
1237 void Assembler::vaddqs(QRegister qd, QRegister qn, QRegister qm) { 1284 void Assembler::vaddqs(QRegister qd, QRegister qn, QRegister qm) {
1238 EmitSIMDqqq(B11 | B10 | B8, kSWord, qd, qn, qm); 1285 EmitSIMDqqq(B11 | B10 | B8, kSWord, qd, qn, qm);
1239 } 1286 }
1240 1287
1241 1288
1242 void Assembler::vsubqi(OperandSize sz, 1289 void Assembler::vsubqi(OperandSize sz,
1243 QRegister qd, QRegister qn, QRegister qm) { 1290 QRegister qd,
1291 QRegister qn,
1292 QRegister qm) {
1244 EmitSIMDqqq(B24 | B11, sz, qd, qn, qm); 1293 EmitSIMDqqq(B24 | B11, sz, qd, qn, qm);
1245 } 1294 }
1246 1295
1247 1296
1248 void Assembler::vsubqs(QRegister qd, QRegister qn, QRegister qm) { 1297 void Assembler::vsubqs(QRegister qd, QRegister qn, QRegister qm) {
1249 EmitSIMDqqq(B21 | B11 | B10 | B8, kSWord, qd, qn, qm); 1298 EmitSIMDqqq(B21 | B11 | B10 | B8, kSWord, qd, qn, qm);
1250 } 1299 }
1251 1300
1252 1301
1253 void Assembler::vmulqi(OperandSize sz, 1302 void Assembler::vmulqi(OperandSize sz,
1254 QRegister qd, QRegister qn, QRegister qm) { 1303 QRegister qd,
1304 QRegister qn,
1305 QRegister qm) {
1255 EmitSIMDqqq(B11 | B8 | B4, sz, qd, qn, qm); 1306 EmitSIMDqqq(B11 | B8 | B4, sz, qd, qn, qm);
1256 } 1307 }
1257 1308
1258 1309
1259 void Assembler::vmulqs(QRegister qd, QRegister qn, QRegister qm) { 1310 void Assembler::vmulqs(QRegister qd, QRegister qn, QRegister qm) {
1260 EmitSIMDqqq(B24 | B11 | B10 | B8 | B4, kSWord, qd, qn, qm); 1311 EmitSIMDqqq(B24 | B11 | B10 | B8 | B4, kSWord, qd, qn, qm);
1261 } 1312 }
1262 1313
1263 1314
1264 void Assembler::vshlqi(OperandSize sz, 1315 void Assembler::vshlqi(OperandSize sz,
1265 QRegister qd, QRegister qm, QRegister qn) { 1316 QRegister qd,
1317 QRegister qm,
1318 QRegister qn) {
1266 EmitSIMDqqq(B25 | B10, sz, qd, qn, qm); 1319 EmitSIMDqqq(B25 | B10, sz, qd, qn, qm);
1267 } 1320 }
1268 1321
1269 1322
1270 void Assembler::vshlqu(OperandSize sz, 1323 void Assembler::vshlqu(OperandSize sz,
1271 QRegister qd, QRegister qm, QRegister qn) { 1324 QRegister qd,
1325 QRegister qm,
1326 QRegister qn) {
1272 EmitSIMDqqq(B25 | B24 | B10, sz, qd, qn, qm); 1327 EmitSIMDqqq(B25 | B24 | B10, sz, qd, qn, qm);
1273 } 1328 }
1274 1329
1275 1330
1276 void Assembler::veorq(QRegister qd, QRegister qn, QRegister qm) { 1331 void Assembler::veorq(QRegister qd, QRegister qn, QRegister qm) {
1277 EmitSIMDqqq(B24 | B8 | B4, kByte, qd, qn, qm); 1332 EmitSIMDqqq(B24 | B8 | B4, kByte, qd, qn, qm);
1278 } 1333 }
1279 1334
1280 1335
1281 void Assembler::vorrq(QRegister qd, QRegister qn, QRegister qm) { 1336 void Assembler::vorrq(QRegister qd, QRegister qn, QRegister qm) {
(...skipping 20 matching lines...) Expand all
1302 EmitSIMDqqq(B21 | B11 | B10 | B9 | B8, kSWord, qd, qn, qm); 1357 EmitSIMDqqq(B21 | B11 | B10 | B9 | B8, kSWord, qd, qn, qm);
1303 } 1358 }
1304 1359
1305 1360
1306 void Assembler::vmaxqs(QRegister qd, QRegister qn, QRegister qm) { 1361 void Assembler::vmaxqs(QRegister qd, QRegister qn, QRegister qm) {
1307 EmitSIMDqqq(B11 | B10 | B9 | B8, kSWord, qd, qn, qm); 1362 EmitSIMDqqq(B11 | B10 | B9 | B8, kSWord, qd, qn, qm);
1308 } 1363 }
1309 1364
1310 1365
1311 void Assembler::vabsqs(QRegister qd, QRegister qm) { 1366 void Assembler::vabsqs(QRegister qd, QRegister qm) {
1312 EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B16 | B10 | B9 | B8, kSWord, 1367 EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B16 | B10 | B9 | B8, kSWord, qd, Q0,
1313 qd, Q0, qm); 1368 qm);
1314 } 1369 }
1315 1370
1316 1371
1317 void Assembler::vnegqs(QRegister qd, QRegister qm) { 1372 void Assembler::vnegqs(QRegister qd, QRegister qm) {
1318 EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B16 | B10 | B9 | B8 | B7, kSWord, 1373 EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B16 | B10 | B9 | B8 | B7, kSWord,
1319 qd, Q0, qm); 1374 qd, Q0, qm);
1320 } 1375 }
1321 1376
1322 1377
1323 void Assembler::vrecpeqs(QRegister qd, QRegister qm) { 1378 void Assembler::vrecpeqs(QRegister qd, QRegister qm) {
1324 EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B17 | B16 | B10 | B8, kSWord, 1379 EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B17 | B16 | B10 | B8, kSWord, qd,
1325 qd, Q0, qm); 1380 Q0, qm);
1326 } 1381 }
1327 1382
1328 1383
1329 void Assembler::vrecpsqs(QRegister qd, QRegister qn, QRegister qm) { 1384 void Assembler::vrecpsqs(QRegister qd, QRegister qn, QRegister qm) {
1330 EmitSIMDqqq(B11 | B10 | B9 | B8 | B4, kSWord, qd, qn, qm); 1385 EmitSIMDqqq(B11 | B10 | B9 | B8 | B4, kSWord, qd, qn, qm);
1331 } 1386 }
1332 1387
1333 1388
1334 void Assembler::vrsqrteqs(QRegister qd, QRegister qm) { 1389 void Assembler::vrsqrteqs(QRegister qd, QRegister qm) {
1335 EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B17 | B16 | B10 | B8 | B7, 1390 EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B17 | B16 | B10 | B8 | B7, kSWord,
1336 kSWord, qd, Q0, qm); 1391 qd, Q0, qm);
1337 } 1392 }
1338 1393
1339 1394
1340 void Assembler::vrsqrtsqs(QRegister qd, QRegister qn, QRegister qm) { 1395 void Assembler::vrsqrtsqs(QRegister qd, QRegister qn, QRegister qm) {
1341 EmitSIMDqqq(B21 | B11 | B10 | B9 | B8 | B4, kSWord, qd, qn, qm); 1396 EmitSIMDqqq(B21 | B11 | B10 | B9 | B8 | B4, kSWord, qd, qn, qm);
1342 } 1397 }
1343 1398
1344 1399
1345 void Assembler::vdup(OperandSize sz, QRegister qd, DRegister dm, int idx) { 1400 void Assembler::vdup(OperandSize sz, QRegister qd, DRegister dm, int idx) {
1346 ASSERT((sz != kDWord) && (sz != kSWord) && (sz != kWordPair)); 1401 ASSERT((sz != kDWord) && (sz != kSWord) && (sz != kWordPair));
(...skipping 11 matching lines...) Expand all
1358 ASSERT((idx >= 0) && (idx < 4)); 1413 ASSERT((idx >= 0) && (idx < 4));
1359 code = 2 | (idx << 2); 1414 code = 2 | (idx << 2);
1360 break; 1415 break;
1361 } 1416 }
1362 case kWord: 1417 case kWord:
1363 case kUnsignedWord: { 1418 case kUnsignedWord: {
1364 ASSERT((idx >= 0) && (idx < 2)); 1419 ASSERT((idx >= 0) && (idx < 2));
1365 code = 4 | (idx << 3); 1420 code = 4 | (idx << 3);
1366 break; 1421 break;
1367 } 1422 }
1368 default: { 1423 default: { break; }
1369 break;
1370 }
1371 } 1424 }
1372 1425
1373 EmitSIMDddd(B24 | B23 | B11 | B10 | B6, kWordPair, 1426 EmitSIMDddd(B24 | B23 | B11 | B10 | B6, kWordPair,
1374 static_cast<DRegister>(qd * 2), 1427 static_cast<DRegister>(qd * 2),
1375 static_cast<DRegister>(code & 0xf), 1428 static_cast<DRegister>(code & 0xf), dm);
1376 dm);
1377 } 1429 }
1378 1430
1379 1431
1380 void Assembler::vtbl(DRegister dd, DRegister dn, int len, DRegister dm) { 1432 void Assembler::vtbl(DRegister dd, DRegister dn, int len, DRegister dm) {
1381 ASSERT((len >= 1) && (len <= 4)); 1433 ASSERT((len >= 1) && (len <= 4));
1382 EmitSIMDddd(B24 | B23 | B11 | ((len - 1) * B8), kWordPair, dd, dn, dm); 1434 EmitSIMDddd(B24 | B23 | B11 | ((len - 1) * B8), kWordPair, dd, dn, dm);
1383 } 1435 }
1384 1436
1385 1437
1386 void Assembler::vzipqw(QRegister qd, QRegister qm) { 1438 void Assembler::vzipqw(QRegister qd, QRegister qm) {
1387 EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B17 | B8 | B7, kByte, qd, Q0, qm); 1439 EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B17 | B8 | B7, kByte, qd, Q0, qm);
1388 } 1440 }
1389 1441
1390 1442
1391 void Assembler::vceqqi(OperandSize sz, 1443 void Assembler::vceqqi(OperandSize sz,
1392 QRegister qd, QRegister qn, QRegister qm) { 1444 QRegister qd,
1445 QRegister qn,
1446 QRegister qm) {
1393 EmitSIMDqqq(B24 | B11 | B4, sz, qd, qn, qm); 1447 EmitSIMDqqq(B24 | B11 | B4, sz, qd, qn, qm);
1394 } 1448 }
1395 1449
1396 1450
1397 void Assembler::vceqqs(QRegister qd, QRegister qn, QRegister qm) { 1451 void Assembler::vceqqs(QRegister qd, QRegister qn, QRegister qm) {
1398 EmitSIMDqqq(B11 | B10 | B9, kSWord, qd, qn, qm); 1452 EmitSIMDqqq(B11 | B10 | B9, kSWord, qd, qn, qm);
1399 } 1453 }
1400 1454
1401 1455
1402 void Assembler::vcgeqi(OperandSize sz, 1456 void Assembler::vcgeqi(OperandSize sz,
1403 QRegister qd, QRegister qn, QRegister qm) { 1457 QRegister qd,
1458 QRegister qn,
1459 QRegister qm) {
1404 EmitSIMDqqq(B9 | B8 | B4, sz, qd, qn, qm); 1460 EmitSIMDqqq(B9 | B8 | B4, sz, qd, qn, qm);
1405 } 1461 }
1406 1462
1407 1463
1408 void Assembler::vcugeqi(OperandSize sz, 1464 void Assembler::vcugeqi(OperandSize sz,
1409 QRegister qd, QRegister qn, QRegister qm) { 1465 QRegister qd,
1466 QRegister qn,
1467 QRegister qm) {
1410 EmitSIMDqqq(B24 | B9 | B8 | B4, sz, qd, qn, qm); 1468 EmitSIMDqqq(B24 | B9 | B8 | B4, sz, qd, qn, qm);
1411 } 1469 }
1412 1470
1413 1471
1414 void Assembler::vcgeqs(QRegister qd, QRegister qn, QRegister qm) { 1472 void Assembler::vcgeqs(QRegister qd, QRegister qn, QRegister qm) {
1415 EmitSIMDqqq(B24 | B11 | B10 | B9, kSWord, qd, qn, qm); 1473 EmitSIMDqqq(B24 | B11 | B10 | B9, kSWord, qd, qn, qm);
1416 } 1474 }
1417 1475
1418 1476
1419 void Assembler::vcgtqi(OperandSize sz, 1477 void Assembler::vcgtqi(OperandSize sz,
1420 QRegister qd, QRegister qn, QRegister qm) { 1478 QRegister qd,
1479 QRegister qn,
1480 QRegister qm) {
1421 EmitSIMDqqq(B9 | B8, sz, qd, qn, qm); 1481 EmitSIMDqqq(B9 | B8, sz, qd, qn, qm);
1422 } 1482 }
1423 1483
1424 1484
1425 void Assembler::vcugtqi(OperandSize sz, 1485 void Assembler::vcugtqi(OperandSize sz,
1426 QRegister qd, QRegister qn, QRegister qm) { 1486 QRegister qd,
1487 QRegister qn,
1488 QRegister qm) {
1427 EmitSIMDqqq(B24 | B9 | B8, sz, qd, qn, qm); 1489 EmitSIMDqqq(B24 | B9 | B8, sz, qd, qn, qm);
1428 } 1490 }
1429 1491
1430 1492
1431 void Assembler::vcgtqs(QRegister qd, QRegister qn, QRegister qm) { 1493 void Assembler::vcgtqs(QRegister qd, QRegister qn, QRegister qm) {
1432 EmitSIMDqqq(B24 | B21 | B11 | B10 | B9, kSWord, qd, qn, qm); 1494 EmitSIMDqqq(B24 | B21 | B11 | B10 | B9, kSWord, qd, qn, qm);
1433 } 1495 }
1434 1496
1435 1497
1436 void Assembler::bkpt(uint16_t imm16) { 1498 void Assembler::bkpt(uint16_t imm16) {
1437 Emit(BkptEncoding(imm16)); 1499 Emit(BkptEncoding(imm16));
1438 } 1500 }
1439 1501
1440 1502
1441 void Assembler::b(Label* label, Condition cond) { 1503 void Assembler::b(Label* label, Condition cond) {
1442 EmitBranch(cond, label, false); 1504 EmitBranch(cond, label, false);
1443 } 1505 }
1444 1506
1445 1507
1446 void Assembler::bl(Label* label, Condition cond) { 1508 void Assembler::bl(Label* label, Condition cond) {
1447 EmitBranch(cond, label, true); 1509 EmitBranch(cond, label, true);
1448 } 1510 }
1449 1511
1450 1512
1451 void Assembler::bx(Register rm, Condition cond) { 1513 void Assembler::bx(Register rm, Condition cond) {
1452 ASSERT(rm != kNoRegister); 1514 ASSERT(rm != kNoRegister);
1453 ASSERT(cond != kNoCondition); 1515 ASSERT(cond != kNoCondition);
1454 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1516 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B24 |
1455 B24 | B21 | (0xfff << 8) | B4 | 1517 B21 | (0xfff << 8) | B4 |
1456 (static_cast<int32_t>(rm) << kRmShift); 1518 (static_cast<int32_t>(rm) << kRmShift);
1457 Emit(encoding); 1519 Emit(encoding);
1458 } 1520 }
1459 1521
1460 1522
1461 void Assembler::blx(Register rm, Condition cond) { 1523 void Assembler::blx(Register rm, Condition cond) {
1462 ASSERT(rm != kNoRegister); 1524 ASSERT(rm != kNoRegister);
1463 ASSERT(cond != kNoCondition); 1525 ASSERT(cond != kNoCondition);
1464 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1526 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B24 |
1465 B24 | B21 | (0xfff << 8) | B5 | B4 | 1527 B21 | (0xfff << 8) | B5 | B4 |
1466 (static_cast<int32_t>(rm) << kRmShift); 1528 (static_cast<int32_t>(rm) << kRmShift);
1467 Emit(encoding); 1529 Emit(encoding);
1468 } 1530 }
1469 1531
1470 1532
1471 void Assembler::MarkExceptionHandler(Label* label) { 1533 void Assembler::MarkExceptionHandler(Label* label) {
1472 EmitType01(AL, 1, TST, 1, PC, R0, Operand(0)); 1534 EmitType01(AL, 1, TST, 1, PC, R0, Operand(0));
1473 Label l; 1535 Label l;
1474 b(&l); 1536 b(&l);
1475 EmitBranch(AL, label, false); 1537 EmitBranch(AL, label, false);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 Comment("CheckCodePointer"); 1585 Comment("CheckCodePointer");
1524 Label cid_ok, instructions_ok; 1586 Label cid_ok, instructions_ok;
1525 Push(R0); 1587 Push(R0);
1526 Push(IP); 1588 Push(IP);
1527 CompareClassId(CODE_REG, kCodeCid, R0); 1589 CompareClassId(CODE_REG, kCodeCid, R0);
1528 b(&cid_ok, EQ); 1590 b(&cid_ok, EQ);
1529 bkpt(0); 1591 bkpt(0);
1530 Bind(&cid_ok); 1592 Bind(&cid_ok);
1531 1593
1532 const intptr_t offset = CodeSize() + Instr::kPCReadOffset + 1594 const intptr_t offset = CodeSize() + Instr::kPCReadOffset +
1533 Instructions::HeaderSize() - kHeapObjectTag; 1595 Instructions::HeaderSize() - kHeapObjectTag;
1534 mov(R0, Operand(PC)); 1596 mov(R0, Operand(PC));
1535 AddImmediate(R0, R0, -offset); 1597 AddImmediate(R0, R0, -offset);
1536 ldr(IP, FieldAddress(CODE_REG, Code::saved_instructions_offset())); 1598 ldr(IP, FieldAddress(CODE_REG, Code::saved_instructions_offset()));
1537 cmp(R0, Operand(IP)); 1599 cmp(R0, Operand(IP));
1538 b(&instructions_ok, EQ); 1600 b(&instructions_ok, EQ);
1539 bkpt(1); 1601 bkpt(1);
1540 Bind(&instructions_ok); 1602 Bind(&instructions_ok);
1541 Pop(IP); 1603 Pop(IP);
1542 Pop(R0); 1604 Pop(R0);
1543 #endif 1605 #endif
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 // Load common VM constants from the thread. This works also in places where 1650 // Load common VM constants from the thread. This works also in places where
1589 // no constant pool is set up (e.g. intrinsic code). 1651 // no constant pool is set up (e.g. intrinsic code).
1590 ldr(rd, Address(THR, Thread::OffsetFromThread(object)), cond); 1652 ldr(rd, Address(THR, Thread::OffsetFromThread(object)), cond);
1591 } else if (object.IsSmi()) { 1653 } else if (object.IsSmi()) {
1592 // Relocation doesn't apply to Smis. 1654 // Relocation doesn't apply to Smis.
1593 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); 1655 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond);
1594 } else if (CanLoadFromObjectPool(object)) { 1656 } else if (CanLoadFromObjectPool(object)) {
1595 // Make sure that class CallPattern is able to decode this load from the 1657 // Make sure that class CallPattern is able to decode this load from the
1596 // object pool. 1658 // object pool.
1597 const int32_t offset = ObjectPool::element_offset( 1659 const int32_t offset = ObjectPool::element_offset(
1598 is_unique ? object_pool_wrapper_.AddObject(object) 1660 is_unique ? object_pool_wrapper_.AddObject(object)
1599 : object_pool_wrapper_.FindObject(object)); 1661 : object_pool_wrapper_.FindObject(object));
1600 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, pp, cond); 1662 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, pp, cond);
1601 } else { 1663 } else {
1602 UNREACHABLE(); 1664 UNREACHABLE();
1603 } 1665 }
1604 } 1666 }
1605 1667
1606 1668
1607 void Assembler::LoadObject(Register rd, const Object& object, Condition cond) { 1669 void Assembler::LoadObject(Register rd, const Object& object, Condition cond) {
1608 LoadObjectHelper(rd, object, cond, /* is_unique = */ false, PP); 1670 LoadObjectHelper(rd, object, cond, /* is_unique = */ false, PP);
1609 } 1671 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 ASSERT(reg != FP); 1755 ASSERT(reg != FP);
1694 ASSERT(reg != PC); 1756 ASSERT(reg != PC);
1695 ASSERT((*used & (1 << reg)) == 0); 1757 ASSERT((*used & (1 << reg)) == 0);
1696 *used |= (1 << reg); 1758 *used |= (1 << reg);
1697 return reg; 1759 return reg;
1698 } 1760 }
1699 1761
1700 1762
1701 Register AllocateRegister(RegList* used) { 1763 Register AllocateRegister(RegList* used) {
1702 const RegList free = ~*used; 1764 const RegList free = ~*used;
1703 return (free == 0) ? 1765 return (free == 0)
1704 kNoRegister : 1766 ? kNoRegister
1705 UseRegister(static_cast<Register>(Utils::CountTrailingZeros(free)), used); 1767 : UseRegister(
1768 static_cast<Register>(Utils::CountTrailingZeros(free)),
1769 used);
1706 } 1770 }
1707 1771
1708 1772
1709 void Assembler::StoreIntoObject(Register object, 1773 void Assembler::StoreIntoObject(Register object,
1710 const Address& dest, 1774 const Address& dest,
1711 Register value, 1775 Register value,
1712 bool can_value_be_smi) { 1776 bool can_value_be_smi) {
1713 ASSERT(object != value); 1777 ASSERT(object != value);
1714 str(value, dest); 1778 str(value, dest);
1715 Label done; 1779 Label done;
(...skipping 18 matching lines...) Expand all
1734 Bind(&done); 1798 Bind(&done);
1735 } 1799 }
1736 1800
1737 1801
1738 void Assembler::StoreIntoObjectOffset(Register object, 1802 void Assembler::StoreIntoObjectOffset(Register object,
1739 int32_t offset, 1803 int32_t offset,
1740 Register value, 1804 Register value,
1741 bool can_value_be_smi) { 1805 bool can_value_be_smi) {
1742 int32_t ignored = 0; 1806 int32_t ignored = 0;
1743 if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) { 1807 if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
1744 StoreIntoObject( 1808 StoreIntoObject(object, FieldAddress(object, offset), value,
1745 object, FieldAddress(object, offset), value, can_value_be_smi); 1809 can_value_be_smi);
1746 } else { 1810 } else {
1747 AddImmediate(IP, object, offset - kHeapObjectTag); 1811 AddImmediate(IP, object, offset - kHeapObjectTag);
1748 StoreIntoObject(object, Address(IP), value, can_value_be_smi); 1812 StoreIntoObject(object, Address(IP), value, can_value_be_smi);
1749 } 1813 }
1750 } 1814 }
1751 1815
1752 1816
1753 void Assembler::StoreIntoObjectNoBarrier(Register object, 1817 void Assembler::StoreIntoObjectNoBarrier(Register object,
1754 const Address& dest, 1818 const Address& dest,
1755 Register value) { 1819 Register value) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 void Assembler::InitializeFieldsNoBarrierUnrolled(Register object, 1902 void Assembler::InitializeFieldsNoBarrierUnrolled(Register object,
1839 Register base, 1903 Register base,
1840 intptr_t begin_offset, 1904 intptr_t begin_offset,
1841 intptr_t end_offset, 1905 intptr_t end_offset,
1842 Register value_even, 1906 Register value_even,
1843 Register value_odd) { 1907 Register value_odd) {
1844 ASSERT(value_odd == value_even + 1); 1908 ASSERT(value_odd == value_even + 1);
1845 intptr_t current_offset = begin_offset; 1909 intptr_t current_offset = begin_offset;
1846 while (current_offset + kWordSize < end_offset) { 1910 while (current_offset + kWordSize < end_offset) {
1847 strd(value_even, value_odd, base, current_offset); 1911 strd(value_even, value_odd, base, current_offset);
1848 current_offset += 2*kWordSize; 1912 current_offset += 2 * kWordSize;
1849 } 1913 }
1850 while (current_offset < end_offset) { 1914 while (current_offset < end_offset) {
1851 str(value_even, Address(base, current_offset)); 1915 str(value_even, Address(base, current_offset));
1852 current_offset += kWordSize; 1916 current_offset += kWordSize;
1853 } 1917 }
1854 #if defined(DEBUG) 1918 #if defined(DEBUG)
1855 Label done; 1919 Label done;
1856 StoreIntoObjectFilter(object, value_even, &done); 1920 StoreIntoObjectFilter(object, value_even, &done);
1857 StoreIntoObjectFilter(object, value_odd, &done); 1921 StoreIntoObjectFilter(object, value_odd, &done);
1858 Stop("Store buffer update is required"); 1922 Stop("Store buffer update is required");
(...skipping 11 matching lines...) Expand all
1870 Stop("New value must be Smi."); 1934 Stop("New value must be Smi.");
1871 Bind(&done); 1935 Bind(&done);
1872 #endif // defined(DEBUG) 1936 #endif // defined(DEBUG)
1873 str(value, dest); 1937 str(value, dest);
1874 } 1938 }
1875 1939
1876 1940
1877 void Assembler::LoadClassId(Register result, Register object, Condition cond) { 1941 void Assembler::LoadClassId(Register result, Register object, Condition cond) {
1878 ASSERT(RawObject::kClassIdTagPos == 16); 1942 ASSERT(RawObject::kClassIdTagPos == 16);
1879 ASSERT(RawObject::kClassIdTagSize == 16); 1943 ASSERT(RawObject::kClassIdTagSize == 16);
1880 const intptr_t class_id_offset = Object::tags_offset() + 1944 const intptr_t class_id_offset =
1881 RawObject::kClassIdTagPos / kBitsPerByte; 1945 Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
1882 ldrh(result, FieldAddress(object, class_id_offset), cond); 1946 ldrh(result, FieldAddress(object, class_id_offset), cond);
1883 } 1947 }
1884 1948
1885 1949
1886 void Assembler::LoadClassById(Register result, Register class_id) { 1950 void Assembler::LoadClassById(Register result, Register class_id) {
1887 ASSERT(result != class_id); 1951 ASSERT(result != class_id);
1888 LoadIsolate(result); 1952 LoadIsolate(result);
1889 const intptr_t offset = 1953 const intptr_t offset =
1890 Isolate::class_table_offset() + ClassTable::table_offset(); 1954 Isolate::class_table_offset() + ClassTable::table_offset();
1891 LoadFromOffset(kWord, result, result, offset); 1955 LoadFromOffset(kWord, result, result, offset);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1926 return Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset); 1990 return Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset);
1927 } 1991 }
1928 1992
1929 1993
1930 int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) { 1994 int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) {
1931 // The offset is off by 8 due to the way the ARM CPUs read PC. 1995 // The offset is off by 8 due to the way the ARM CPUs read PC.
1932 offset -= Instr::kPCReadOffset; 1996 offset -= Instr::kPCReadOffset;
1933 1997
1934 if (!CanEncodeBranchOffset(offset)) { 1998 if (!CanEncodeBranchOffset(offset)) {
1935 ASSERT(!use_far_branches()); 1999 ASSERT(!use_far_branches());
1936 Thread::Current()->long_jump_base()->Jump( 2000 Thread::Current()->long_jump_base()->Jump(1, Object::branch_offset_error());
1937 1, Object::branch_offset_error());
1938 } 2001 }
1939 2002
1940 // Properly preserve only the bits supported in the instruction. 2003 // Properly preserve only the bits supported in the instruction.
1941 offset >>= 2; 2004 offset >>= 2;
1942 offset &= kBranchOffsetMask; 2005 offset &= kBranchOffsetMask;
1943 return (inst & ~kBranchOffsetMask) | offset; 2006 return (inst & ~kBranchOffsetMask) | offset;
1944 } 2007 }
1945 2008
1946 2009
1947 int Assembler::DecodeBranchOffset(int32_t inst) { 2010 int Assembler::DecodeBranchOffset(int32_t inst) {
1948 // Sign-extend, left-shift by 2, then add 8. 2011 // Sign-extend, left-shift by 2, then add 8.
1949 return ((((inst & kBranchOffsetMask) << 8) >> 6) + Instr::kPCReadOffset); 2012 return ((((inst & kBranchOffsetMask) << 8) >> 6) + Instr::kPCReadOffset);
1950 } 2013 }
1951 2014
1952 2015
1953 static int32_t DecodeARMv7LoadImmediate(int32_t movt, int32_t movw) { 2016 static int32_t DecodeARMv7LoadImmediate(int32_t movt, int32_t movw) {
1954 int32_t offset = 0; 2017 int32_t offset = 0;
1955 offset |= (movt & 0xf0000) << 12; 2018 offset |= (movt & 0xf0000) << 12;
1956 offset |= (movt & 0xfff) << 16; 2019 offset |= (movt & 0xfff) << 16;
1957 offset |= (movw & 0xf0000) >> 4; 2020 offset |= (movw & 0xf0000) >> 4;
1958 offset |= movw & 0xfff; 2021 offset |= movw & 0xfff;
1959 return offset; 2022 return offset;
1960 } 2023 }
1961 2024
1962 2025
1963 static int32_t DecodeARMv6LoadImmediate(int32_t mov, int32_t or1, 2026 static int32_t DecodeARMv6LoadImmediate(int32_t mov,
1964 int32_t or2, int32_t or3) { 2027 int32_t or1,
2028 int32_t or2,
2029 int32_t or3) {
1965 int32_t offset = 0; 2030 int32_t offset = 0;
1966 offset |= (mov & 0xff) << 24; 2031 offset |= (mov & 0xff) << 24;
1967 offset |= (or1 & 0xff) << 16; 2032 offset |= (or1 & 0xff) << 16;
1968 offset |= (or2 & 0xff) << 8; 2033 offset |= (or2 & 0xff) << 8;
1969 offset |= (or3 & 0xff); 2034 offset |= (or3 & 0xff);
1970 return offset; 2035 return offset;
1971 } 2036 }
1972 2037
1973 2038
1974 class PatchFarBranch : public AssemblerFixup { 2039 class PatchFarBranch : public AssemblerFixup {
1975 public: 2040 public:
1976 PatchFarBranch() {} 2041 PatchFarBranch() {}
1977 2042
1978 void Process(const MemoryRegion& region, intptr_t position) { 2043 void Process(const MemoryRegion& region, intptr_t position) {
1979 const ARMVersion version = TargetCPUFeatures::arm_version(); 2044 const ARMVersion version = TargetCPUFeatures::arm_version();
1980 if ((version == ARMv5TE) || (version == ARMv6)) { 2045 if ((version == ARMv5TE) || (version == ARMv6)) {
1981 ProcessARMv6(region, position); 2046 ProcessARMv6(region, position);
1982 } else { 2047 } else {
1983 ASSERT(version == ARMv7); 2048 ASSERT(version == ARMv7);
1984 ProcessARMv7(region, position); 2049 ProcessARMv7(region, position);
1985 } 2050 }
1986 } 2051 }
1987 2052
1988 private: 2053 private:
1989 void ProcessARMv6(const MemoryRegion& region, intptr_t position) { 2054 void ProcessARMv6(const MemoryRegion& region, intptr_t position) {
1990 const int32_t mov = region.Load<int32_t>(position); 2055 const int32_t mov = region.Load<int32_t>(position);
1991 const int32_t or1 = region.Load<int32_t>(position + 1*Instr::kInstrSize); 2056 const int32_t or1 = region.Load<int32_t>(position + 1 * Instr::kInstrSize);
1992 const int32_t or2 = region.Load<int32_t>(position + 2*Instr::kInstrSize); 2057 const int32_t or2 = region.Load<int32_t>(position + 2 * Instr::kInstrSize);
1993 const int32_t or3 = region.Load<int32_t>(position + 3*Instr::kInstrSize); 2058 const int32_t or3 = region.Load<int32_t>(position + 3 * Instr::kInstrSize);
1994 const int32_t bx = region.Load<int32_t>(position + 4*Instr::kInstrSize); 2059 const int32_t bx = region.Load<int32_t>(position + 4 * Instr::kInstrSize);
1995 2060
1996 if (((mov & 0xffffff00) == 0xe3a0c400) && // mov IP, (byte3 rot 4) 2061 if (((mov & 0xffffff00) == 0xe3a0c400) && // mov IP, (byte3 rot 4)
1997 ((or1 & 0xffffff00) == 0xe38cc800) && // orr IP, IP, (byte2 rot 8) 2062 ((or1 & 0xffffff00) == 0xe38cc800) && // orr IP, IP, (byte2 rot 8)
1998 ((or2 & 0xffffff00) == 0xe38ccc00) && // orr IP, IP, (byte1 rot 12) 2063 ((or2 & 0xffffff00) == 0xe38ccc00) && // orr IP, IP, (byte1 rot 12)
1999 ((or3 & 0xffffff00) == 0xe38cc000)) { // orr IP, IP, byte0 2064 ((or3 & 0xffffff00) == 0xe38cc000)) { // orr IP, IP, byte0
2000 const int32_t offset = DecodeARMv6LoadImmediate(mov, or1, or2, or3); 2065 const int32_t offset = DecodeARMv6LoadImmediate(mov, or1, or2, or3);
2001 const int32_t dest = region.start() + offset; 2066 const int32_t dest = region.start() + offset;
2002 const int32_t dest0 = (dest & 0x000000ff); 2067 const int32_t dest0 = (dest & 0x000000ff);
2003 const int32_t dest1 = (dest & 0x0000ff00) >> 8; 2068 const int32_t dest1 = (dest & 0x0000ff00) >> 8;
2004 const int32_t dest2 = (dest & 0x00ff0000) >> 16; 2069 const int32_t dest2 = (dest & 0x00ff0000) >> 16;
2005 const int32_t dest3 = (dest & 0xff000000) >> 24; 2070 const int32_t dest3 = (dest & 0xff000000) >> 24;
2006 const int32_t patched_mov = 0xe3a0c400 | dest3; 2071 const int32_t patched_mov = 0xe3a0c400 | dest3;
2007 const int32_t patched_or1 = 0xe38cc800 | dest2; 2072 const int32_t patched_or1 = 0xe38cc800 | dest2;
2008 const int32_t patched_or2 = 0xe38ccc00 | dest1; 2073 const int32_t patched_or2 = 0xe38ccc00 | dest1;
2009 const int32_t patched_or3 = 0xe38cc000 | dest0; 2074 const int32_t patched_or3 = 0xe38cc000 | dest0;
2010 2075
2011 region.Store<int32_t>(position + 0 * Instr::kInstrSize, patched_mov); 2076 region.Store<int32_t>(position + 0 * Instr::kInstrSize, patched_mov);
2012 region.Store<int32_t>(position + 1 * Instr::kInstrSize, patched_or1); 2077 region.Store<int32_t>(position + 1 * Instr::kInstrSize, patched_or1);
2013 region.Store<int32_t>(position + 2 * Instr::kInstrSize, patched_or2); 2078 region.Store<int32_t>(position + 2 * Instr::kInstrSize, patched_or2);
2014 region.Store<int32_t>(position + 3 * Instr::kInstrSize, patched_or3); 2079 region.Store<int32_t>(position + 3 * Instr::kInstrSize, patched_or3);
2015 return; 2080 return;
2016 } 2081 }
2017 2082
2018 // If the offset loading instructions aren't there, we must have replaced 2083 // If the offset loading instructions aren't there, we must have replaced
2019 // the far branch with a near one, and so these instructions 2084 // the far branch with a near one, and so these instructions
2020 // should be NOPs. 2085 // should be NOPs.
2021 ASSERT((or1 == Instr::kNopInstruction) && 2086 ASSERT((or1 == Instr::kNopInstruction) && (or2 == Instr::kNopInstruction) &&
2022 (or2 == Instr::kNopInstruction) && 2087 (or3 == Instr::kNopInstruction) && (bx == Instr::kNopInstruction));
2023 (or3 == Instr::kNopInstruction) &&
2024 (bx == Instr::kNopInstruction));
2025 } 2088 }
2026 2089
2027 2090
2028 void ProcessARMv7(const MemoryRegion& region, intptr_t position) { 2091 void ProcessARMv7(const MemoryRegion& region, intptr_t position) {
2029 const int32_t movw = region.Load<int32_t>(position); 2092 const int32_t movw = region.Load<int32_t>(position);
2030 const int32_t movt = region.Load<int32_t>(position + Instr::kInstrSize); 2093 const int32_t movt = region.Load<int32_t>(position + Instr::kInstrSize);
2031 const int32_t bx = region.Load<int32_t>(position + 2 * Instr::kInstrSize); 2094 const int32_t bx = region.Load<int32_t>(position + 2 * Instr::kInstrSize);
2032 2095
2033 if (((movt & 0xfff0f000) == 0xe340c000) && // movt IP, high 2096 if (((movt & 0xfff0f000) == 0xe340c000) && // movt IP, high
2034 ((movw & 0xfff0f000) == 0xe300c000)) { // movw IP, low 2097 ((movw & 0xfff0f000) == 0xe300c000)) { // movw IP, low
2035 const int32_t offset = DecodeARMv7LoadImmediate(movt, movw); 2098 const int32_t offset = DecodeARMv7LoadImmediate(movt, movw);
2036 const int32_t dest = region.start() + offset; 2099 const int32_t dest = region.start() + offset;
2037 const uint16_t dest_high = Utils::High16Bits(dest); 2100 const uint16_t dest_high = Utils::High16Bits(dest);
2038 const uint16_t dest_low = Utils::Low16Bits(dest); 2101 const uint16_t dest_low = Utils::Low16Bits(dest);
2039 const int32_t patched_movt = 2102 const int32_t patched_movt =
2040 0xe340c000 | ((dest_high >> 12) << 16) | (dest_high & 0xfff); 2103 0xe340c000 | ((dest_high >> 12) << 16) | (dest_high & 0xfff);
2041 const int32_t patched_movw = 2104 const int32_t patched_movw =
2042 0xe300c000 | ((dest_low >> 12) << 16) | (dest_low & 0xfff); 2105 0xe300c000 | ((dest_low >> 12) << 16) | (dest_low & 0xfff);
2043 2106
2044 region.Store<int32_t>(position, patched_movw); 2107 region.Store<int32_t>(position, patched_movw);
2045 region.Store<int32_t>(position + Instr::kInstrSize, patched_movt); 2108 region.Store<int32_t>(position + Instr::kInstrSize, patched_movt);
2046 return; 2109 return;
2047 } 2110 }
2048 2111
2049 // If the offset loading instructions aren't there, we must have replaced 2112 // If the offset loading instructions aren't there, we must have replaced
2050 // the far branch with a near one, and so these instructions 2113 // the far branch with a near one, and so these instructions
2051 // should be NOPs. 2114 // should be NOPs.
2052 ASSERT((movt == Instr::kNopInstruction) && 2115 ASSERT((movt == Instr::kNopInstruction) && (bx == Instr::kNopInstruction));
2053 (bx == Instr::kNopInstruction));
2054 } 2116 }
2055 2117
2056 virtual bool IsPointerOffset() const { return false; } 2118 virtual bool IsPointerOffset() const { return false; }
2057 }; 2119 };
2058 2120
2059 2121
2060 void Assembler::EmitFarBranch(Condition cond, int32_t offset, bool link) { 2122 void Assembler::EmitFarBranch(Condition cond, int32_t offset, bool link) {
2061 buffer_.EmitFixup(new PatchFarBranch()); 2123 buffer_.EmitFixup(new PatchFarBranch());
2062 LoadPatchableImmediate(IP, offset); 2124 LoadPatchableImmediate(IP, offset);
2063 if (link) { 2125 if (link) {
(...skipping 29 matching lines...) Expand all
2093 void Assembler::BindARMv6(Label* label) { 2155 void Assembler::BindARMv6(Label* label) {
2094 ASSERT(!label->IsBound()); 2156 ASSERT(!label->IsBound());
2095 intptr_t bound_pc = buffer_.Size(); 2157 intptr_t bound_pc = buffer_.Size();
2096 while (label->IsLinked()) { 2158 while (label->IsLinked()) {
2097 const int32_t position = label->Position(); 2159 const int32_t position = label->Position();
2098 int32_t dest = bound_pc - position; 2160 int32_t dest = bound_pc - position;
2099 if (use_far_branches() && !CanEncodeBranchOffset(dest)) { 2161 if (use_far_branches() && !CanEncodeBranchOffset(dest)) {
2100 // Far branches are enabled and we can't encode the branch offset. 2162 // Far branches are enabled and we can't encode the branch offset.
2101 2163
2102 // Grab instructions that load the offset. 2164 // Grab instructions that load the offset.
2103 const int32_t mov = 2165 const int32_t mov = buffer_.Load<int32_t>(position);
2104 buffer_.Load<int32_t>(position);
2105 const int32_t or1 = 2166 const int32_t or1 =
2106 buffer_.Load<int32_t>(position + 1 * Instr::kInstrSize); 2167 buffer_.Load<int32_t>(position + 1 * Instr::kInstrSize);
2107 const int32_t or2 = 2168 const int32_t or2 =
2108 buffer_.Load<int32_t>(position + 2 * Instr::kInstrSize); 2169 buffer_.Load<int32_t>(position + 2 * Instr::kInstrSize);
2109 const int32_t or3 = 2170 const int32_t or3 =
2110 buffer_.Load<int32_t>(position + 3 * Instr::kInstrSize); 2171 buffer_.Load<int32_t>(position + 3 * Instr::kInstrSize);
2111 2172
2112 // Change from relative to the branch to relative to the assembler 2173 // Change from relative to the branch to relative to the assembler
2113 // buffer. 2174 // buffer.
2114 dest = buffer_.Size(); 2175 dest = buffer_.Size();
2115 const int32_t dest0 = (dest & 0x000000ff); 2176 const int32_t dest0 = (dest & 0x000000ff);
2116 const int32_t dest1 = (dest & 0x0000ff00) >> 8; 2177 const int32_t dest1 = (dest & 0x0000ff00) >> 8;
2117 const int32_t dest2 = (dest & 0x00ff0000) >> 16; 2178 const int32_t dest2 = (dest & 0x00ff0000) >> 16;
2118 const int32_t dest3 = (dest & 0xff000000) >> 24; 2179 const int32_t dest3 = (dest & 0xff000000) >> 24;
2119 const int32_t patched_mov = 0xe3a0c400 | dest3; 2180 const int32_t patched_mov = 0xe3a0c400 | dest3;
2120 const int32_t patched_or1 = 0xe38cc800 | dest2; 2181 const int32_t patched_or1 = 0xe38cc800 | dest2;
2121 const int32_t patched_or2 = 0xe38ccc00 | dest1; 2182 const int32_t patched_or2 = 0xe38ccc00 | dest1;
2122 const int32_t patched_or3 = 0xe38cc000 | dest0; 2183 const int32_t patched_or3 = 0xe38cc000 | dest0;
2123 2184
2124 // Rewrite the instructions. 2185 // Rewrite the instructions.
2125 buffer_.Store<int32_t>(position + 0 * Instr::kInstrSize, patched_mov); 2186 buffer_.Store<int32_t>(position + 0 * Instr::kInstrSize, patched_mov);
2126 buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize, patched_or1); 2187 buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize, patched_or1);
2127 buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize, patched_or2); 2188 buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize, patched_or2);
2128 buffer_.Store<int32_t>(position + 3 * Instr::kInstrSize, patched_or3); 2189 buffer_.Store<int32_t>(position + 3 * Instr::kInstrSize, patched_or3);
2129 label->position_ = DecodeARMv6LoadImmediate(mov, or1, or2, or3); 2190 label->position_ = DecodeARMv6LoadImmediate(mov, or1, or2, or3);
2130 } else if (use_far_branches() && CanEncodeBranchOffset(dest)) { 2191 } else if (use_far_branches() && CanEncodeBranchOffset(dest)) {
2131 // Grab instructions that load the offset, and the branch. 2192 // Grab instructions that load the offset, and the branch.
2132 const int32_t mov = 2193 const int32_t mov = buffer_.Load<int32_t>(position);
2133 buffer_.Load<int32_t>(position);
2134 const int32_t or1 = 2194 const int32_t or1 =
2135 buffer_.Load<int32_t>(position + 1 * Instr::kInstrSize); 2195 buffer_.Load<int32_t>(position + 1 * Instr::kInstrSize);
2136 const int32_t or2 = 2196 const int32_t or2 =
2137 buffer_.Load<int32_t>(position + 2 * Instr::kInstrSize); 2197 buffer_.Load<int32_t>(position + 2 * Instr::kInstrSize);
2138 const int32_t or3 = 2198 const int32_t or3 =
2139 buffer_.Load<int32_t>(position + 3 * Instr::kInstrSize); 2199 buffer_.Load<int32_t>(position + 3 * Instr::kInstrSize);
2140 const int32_t branch = 2200 const int32_t branch =
2141 buffer_.Load<int32_t>(position + 4 * Instr::kInstrSize); 2201 buffer_.Load<int32_t>(position + 4 * Instr::kInstrSize);
2142 2202
2143 // Grab the branch condition, and encode the link bit. 2203 // Grab the branch condition, and encode the link bit.
2144 const int32_t cond = branch & 0xf0000000; 2204 const int32_t cond = branch & 0xf0000000;
2145 const int32_t link = (branch & 0x20) << 19; 2205 const int32_t link = (branch & 0x20) << 19;
2146 2206
2147 // Encode the branch and the offset. 2207 // Encode the branch and the offset.
2148 const int32_t new_branch = cond | link | 0x0a000000; 2208 const int32_t new_branch = cond | link | 0x0a000000;
2149 const int32_t encoded = EncodeBranchOffset(dest, new_branch); 2209 const int32_t encoded = EncodeBranchOffset(dest, new_branch);
2150 2210
2151 // Write the encoded branch instruction followed by two nops. 2211 // Write the encoded branch instruction followed by two nops.
2152 buffer_.Store<int32_t>(position, encoded); 2212 buffer_.Store<int32_t>(position, encoded);
2153 buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize, 2213 buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize,
2154 Instr::kNopInstruction); 2214 Instr::kNopInstruction);
2155 buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize, 2215 buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize,
2156 Instr::kNopInstruction); 2216 Instr::kNopInstruction);
2157 buffer_.Store<int32_t>(position + 3 * Instr::kInstrSize, 2217 buffer_.Store<int32_t>(position + 3 * Instr::kInstrSize,
2158 Instr::kNopInstruction); 2218 Instr::kNopInstruction);
2159 buffer_.Store<int32_t>(position + 4 * Instr::kInstrSize, 2219 buffer_.Store<int32_t>(position + 4 * Instr::kInstrSize,
2160 Instr::kNopInstruction); 2220 Instr::kNopInstruction);
2161 2221
2162 label->position_ = DecodeARMv6LoadImmediate(mov, or1, or2, or3); 2222 label->position_ = DecodeARMv6LoadImmediate(mov, or1, or2, or3);
2163 } else { 2223 } else {
2164 int32_t next = buffer_.Load<int32_t>(position); 2224 int32_t next = buffer_.Load<int32_t>(position);
2165 int32_t encoded = Assembler::EncodeBranchOffset(dest, next); 2225 int32_t encoded = Assembler::EncodeBranchOffset(dest, next);
2166 buffer_.Store<int32_t>(position, encoded); 2226 buffer_.Store<int32_t>(position, encoded);
2167 label->position_ = Assembler::DecodeBranchOffset(next); 2227 label->position_ = Assembler::DecodeBranchOffset(next);
2168 } 2228 }
2169 } 2229 }
2170 label->BindTo(bound_pc); 2230 label->BindTo(bound_pc);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2213 2273
2214 // Grab the branch condition, and encode the link bit. 2274 // Grab the branch condition, and encode the link bit.
2215 const int32_t cond = branch & 0xf0000000; 2275 const int32_t cond = branch & 0xf0000000;
2216 const int32_t link = (branch & 0x20) << 19; 2276 const int32_t link = (branch & 0x20) << 19;
2217 2277
2218 // Encode the branch and the offset. 2278 // Encode the branch and the offset.
2219 const int32_t new_branch = cond | link | 0x0a000000; 2279 const int32_t new_branch = cond | link | 0x0a000000;
2220 const int32_t encoded = EncodeBranchOffset(dest, new_branch); 2280 const int32_t encoded = EncodeBranchOffset(dest, new_branch);
2221 2281
2222 // Write the encoded branch instruction followed by two nops. 2282 // Write the encoded branch instruction followed by two nops.
2223 buffer_.Store<int32_t>(position + 0 * Instr::kInstrSize, 2283 buffer_.Store<int32_t>(position + 0 * Instr::kInstrSize, encoded);
2224 encoded);
2225 buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize, 2284 buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize,
2226 Instr::kNopInstruction); 2285 Instr::kNopInstruction);
2227 buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize, 2286 buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize,
2228 Instr::kNopInstruction); 2287 Instr::kNopInstruction);
2229 2288
2230 label->position_ = DecodeARMv7LoadImmediate(movt, movw); 2289 label->position_ = DecodeARMv7LoadImmediate(movt, movw);
2231 } else { 2290 } else {
2232 int32_t next = buffer_.Load<int32_t>(position); 2291 int32_t next = buffer_.Load<int32_t>(position);
2233 int32_t encoded = Assembler::EncodeBranchOffset(dest, next); 2292 int32_t encoded = Assembler::EncodeBranchOffset(dest, next);
2234 buffer_.Store<int32_t>(position, encoded); 2293 buffer_.Store<int32_t>(position, encoded);
2235 label->position_ = Assembler::DecodeBranchOffset(next); 2294 label->position_ = Assembler::DecodeBranchOffset(next);
2236 } 2295 }
2237 } 2296 }
2238 label->BindTo(bound_pc); 2297 label->BindTo(bound_pc);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2361 return offset == 0; 2420 return offset == 0;
2362 } 2421 }
2363 default: { 2422 default: {
2364 UNREACHABLE(); 2423 UNREACHABLE();
2365 return false; 2424 return false;
2366 } 2425 }
2367 } 2426 }
2368 } 2427 }
2369 2428
2370 2429
2371 bool Address::CanHoldImmediateOffset( 2430 bool Address::CanHoldImmediateOffset(bool is_load,
2372 bool is_load, intptr_t cid, int64_t offset) { 2431 intptr_t cid,
2432 int64_t offset) {
2373 int32_t offset_mask = 0; 2433 int32_t offset_mask = 0;
2374 if (is_load) { 2434 if (is_load) {
2375 return CanHoldLoadOffset(OperandSizeFor(cid), offset, &offset_mask); 2435 return CanHoldLoadOffset(OperandSizeFor(cid), offset, &offset_mask);
2376 } else { 2436 } else {
2377 return CanHoldStoreOffset(OperandSizeFor(cid), offset, &offset_mask); 2437 return CanHoldStoreOffset(OperandSizeFor(cid), offset, &offset_mask);
2378 } 2438 }
2379 } 2439 }
2380 2440
2381 2441
2382 void Assembler::Push(Register rd, Condition cond) { 2442 void Assembler::Push(Register rd, Condition cond) {
(...skipping 16 matching lines...) Expand all
2399 } 2459 }
2400 2460
2401 2461
2402 void Assembler::MoveRegister(Register rd, Register rm, Condition cond) { 2462 void Assembler::MoveRegister(Register rd, Register rm, Condition cond) {
2403 if (rd != rm) { 2463 if (rd != rm) {
2404 mov(rd, Operand(rm), cond); 2464 mov(rd, Operand(rm), cond);
2405 } 2465 }
2406 } 2466 }
2407 2467
2408 2468
2409 void Assembler::Lsl(Register rd, Register rm, const Operand& shift_imm, 2469 void Assembler::Lsl(Register rd,
2470 Register rm,
2471 const Operand& shift_imm,
2410 Condition cond) { 2472 Condition cond) {
2411 ASSERT(shift_imm.type() == 1); 2473 ASSERT(shift_imm.type() == 1);
2412 ASSERT(shift_imm.encoding() != 0); // Do not use Lsl if no shift is wanted. 2474 ASSERT(shift_imm.encoding() != 0); // Do not use Lsl if no shift is wanted.
2413 mov(rd, Operand(rm, LSL, shift_imm.encoding()), cond); 2475 mov(rd, Operand(rm, LSL, shift_imm.encoding()), cond);
2414 } 2476 }
2415 2477
2416 2478
2417 void Assembler::Lsl(Register rd, Register rm, Register rs, Condition cond) { 2479 void Assembler::Lsl(Register rd, Register rm, Register rs, Condition cond) {
2418 mov(rd, Operand(rm, LSL, rs), cond); 2480 mov(rd, Operand(rm, LSL, rs), cond);
2419 } 2481 }
2420 2482
2421 2483
2422 void Assembler::Lsr(Register rd, Register rm, const Operand& shift_imm, 2484 void Assembler::Lsr(Register rd,
2485 Register rm,
2486 const Operand& shift_imm,
2423 Condition cond) { 2487 Condition cond) {
2424 ASSERT(shift_imm.type() == 1); 2488 ASSERT(shift_imm.type() == 1);
2425 uint32_t shift = shift_imm.encoding(); 2489 uint32_t shift = shift_imm.encoding();
2426 ASSERT(shift != 0); // Do not use Lsr if no shift is wanted. 2490 ASSERT(shift != 0); // Do not use Lsr if no shift is wanted.
2427 if (shift == 32) { 2491 if (shift == 32) {
2428 shift = 0; // Comply to UAL syntax. 2492 shift = 0; // Comply to UAL syntax.
2429 } 2493 }
2430 mov(rd, Operand(rm, LSR, shift), cond); 2494 mov(rd, Operand(rm, LSR, shift), cond);
2431 } 2495 }
2432 2496
2433 2497
2434 void Assembler::Lsr(Register rd, Register rm, Register rs, Condition cond) { 2498 void Assembler::Lsr(Register rd, Register rm, Register rs, Condition cond) {
2435 mov(rd, Operand(rm, LSR, rs), cond); 2499 mov(rd, Operand(rm, LSR, rs), cond);
2436 } 2500 }
2437 2501
2438 2502
2439 void Assembler::Asr(Register rd, Register rm, const Operand& shift_imm, 2503 void Assembler::Asr(Register rd,
2504 Register rm,
2505 const Operand& shift_imm,
2440 Condition cond) { 2506 Condition cond) {
2441 ASSERT(shift_imm.type() == 1); 2507 ASSERT(shift_imm.type() == 1);
2442 uint32_t shift = shift_imm.encoding(); 2508 uint32_t shift = shift_imm.encoding();
2443 ASSERT(shift != 0); // Do not use Asr if no shift is wanted. 2509 ASSERT(shift != 0); // Do not use Asr if no shift is wanted.
2444 if (shift == 32) { 2510 if (shift == 32) {
2445 shift = 0; // Comply to UAL syntax. 2511 shift = 0; // Comply to UAL syntax.
2446 } 2512 }
2447 mov(rd, Operand(rm, ASR, shift), cond); 2513 mov(rd, Operand(rm, ASR, shift), cond);
2448 } 2514 }
2449 2515
2450 2516
2451 void Assembler::Asrs(Register rd, Register rm, const Operand& shift_imm, 2517 void Assembler::Asrs(Register rd,
2518 Register rm,
2519 const Operand& shift_imm,
2452 Condition cond) { 2520 Condition cond) {
2453 ASSERT(shift_imm.type() == 1); 2521 ASSERT(shift_imm.type() == 1);
2454 uint32_t shift = shift_imm.encoding(); 2522 uint32_t shift = shift_imm.encoding();
2455 ASSERT(shift != 0); // Do not use Asr if no shift is wanted. 2523 ASSERT(shift != 0); // Do not use Asr if no shift is wanted.
2456 if (shift == 32) { 2524 if (shift == 32) {
2457 shift = 0; // Comply to UAL syntax. 2525 shift = 0; // Comply to UAL syntax.
2458 } 2526 }
2459 movs(rd, Operand(rm, ASR, shift), cond); 2527 movs(rd, Operand(rm, ASR, shift), cond);
2460 } 2528 }
2461 2529
2462 2530
2463 void Assembler::Asr(Register rd, Register rm, Register rs, Condition cond) { 2531 void Assembler::Asr(Register rd, Register rm, Register rs, Condition cond) {
2464 mov(rd, Operand(rm, ASR, rs), cond); 2532 mov(rd, Operand(rm, ASR, rs), cond);
2465 } 2533 }
2466 2534
2467 2535
2468 void Assembler::Ror(Register rd, Register rm, const Operand& shift_imm, 2536 void Assembler::Ror(Register rd,
2537 Register rm,
2538 const Operand& shift_imm,
2469 Condition cond) { 2539 Condition cond) {
2470 ASSERT(shift_imm.type() == 1); 2540 ASSERT(shift_imm.type() == 1);
2471 ASSERT(shift_imm.encoding() != 0); // Use Rrx instruction. 2541 ASSERT(shift_imm.encoding() != 0); // Use Rrx instruction.
2472 mov(rd, Operand(rm, ROR, shift_imm.encoding()), cond); 2542 mov(rd, Operand(rm, ROR, shift_imm.encoding()), cond);
2473 } 2543 }
2474 2544
2475 2545
2476 void Assembler::Ror(Register rd, Register rm, Register rs, Condition cond) { 2546 void Assembler::Ror(Register rd, Register rm, Register rs, Condition cond) {
2477 mov(rd, Operand(rm, ROR, rs), cond); 2547 mov(rd, Operand(rm, ROR, rs), cond);
2478 } 2548 }
(...skipping 24 matching lines...) Expand all
2503 2573
2504 2574
2505 void Assembler::VreciprocalSqrtqs(QRegister qd, QRegister qm) { 2575 void Assembler::VreciprocalSqrtqs(QRegister qd, QRegister qm) {
2506 ASSERT(qm != QTMP); 2576 ASSERT(qm != QTMP);
2507 ASSERT(qd != QTMP); 2577 ASSERT(qd != QTMP);
2508 2578
2509 // Reciprocal square root estimate. 2579 // Reciprocal square root estimate.
2510 vrsqrteqs(qd, qm); 2580 vrsqrteqs(qd, qm);
2511 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. 2581 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2.
2512 // First step. 2582 // First step.
2513 vmulqs(QTMP, qd, qd); // QTMP <- xn^2 2583 vmulqs(QTMP, qd, qd); // QTMP <- xn^2
2514 vrsqrtsqs(QTMP, qm, QTMP); // QTMP <- (3 - Q1*QTMP) / 2. 2584 vrsqrtsqs(QTMP, qm, QTMP); // QTMP <- (3 - Q1*QTMP) / 2.
2515 vmulqs(qd, qd, QTMP); // xn+1 <- xn * QTMP 2585 vmulqs(qd, qd, QTMP); // xn+1 <- xn * QTMP
2516 // Second step. 2586 // Second step.
2517 vmulqs(QTMP, qd, qd); 2587 vmulqs(QTMP, qd, qd);
2518 vrsqrtsqs(QTMP, qm, QTMP); 2588 vrsqrtsqs(QTMP, qm, QTMP);
2519 vmulqs(qd, qd, QTMP); 2589 vmulqs(qd, qd, QTMP);
2520 } 2590 }
2521 2591
2522 2592
2523 void Assembler::Vsqrtqs(QRegister qd, QRegister qm, QRegister temp) { 2593 void Assembler::Vsqrtqs(QRegister qd, QRegister qm, QRegister temp) {
2524 ASSERT(temp != QTMP); 2594 ASSERT(temp != QTMP);
2525 ASSERT(qm != QTMP); 2595 ASSERT(qm != QTMP);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2618 2688
2619 2689
2620 void Assembler::BranchLinkOffset(Register base, int32_t offset) { 2690 void Assembler::BranchLinkOffset(Register base, int32_t offset) {
2621 ASSERT(base != PC); 2691 ASSERT(base != PC);
2622 ASSERT(base != IP); 2692 ASSERT(base != IP);
2623 LoadFromOffset(kWord, IP, base, offset); 2693 LoadFromOffset(kWord, IP, base, offset);
2624 blx(IP); // Use blx instruction so that the return branch prediction works. 2694 blx(IP); // Use blx instruction so that the return branch prediction works.
2625 } 2695 }
2626 2696
2627 2697
2628 void Assembler::LoadPatchableImmediate( 2698 void Assembler::LoadPatchableImmediate(Register rd,
2629 Register rd, int32_t value, Condition cond) { 2699 int32_t value,
2700 Condition cond) {
2630 const ARMVersion version = TargetCPUFeatures::arm_version(); 2701 const ARMVersion version = TargetCPUFeatures::arm_version();
2631 if ((version == ARMv5TE) || (version == ARMv6)) { 2702 if ((version == ARMv5TE) || (version == ARMv6)) {
2632 // This sequence is patched in a few places, and should remain fixed. 2703 // This sequence is patched in a few places, and should remain fixed.
2633 const uint32_t byte0 = (value & 0x000000ff); 2704 const uint32_t byte0 = (value & 0x000000ff);
2634 const uint32_t byte1 = (value & 0x0000ff00) >> 8; 2705 const uint32_t byte1 = (value & 0x0000ff00) >> 8;
2635 const uint32_t byte2 = (value & 0x00ff0000) >> 16; 2706 const uint32_t byte2 = (value & 0x00ff0000) >> 16;
2636 const uint32_t byte3 = (value & 0xff000000) >> 24; 2707 const uint32_t byte3 = (value & 0xff000000) >> 24;
2637 mov(rd, Operand(4, byte3), cond); 2708 mov(rd, Operand(4, byte3), cond);
2638 orr(rd, rd, Operand(8, byte2), cond); 2709 orr(rd, rd, Operand(8, byte2), cond);
2639 orr(rd, rd, Operand(12, byte1), cond); 2710 orr(rd, rd, Operand(12, byte1), cond);
2640 orr(rd, rd, Operand(byte0), cond); 2711 orr(rd, rd, Operand(byte0), cond);
2641 } else { 2712 } else {
2642 ASSERT(version == ARMv7); 2713 ASSERT(version == ARMv7);
2643 const uint16_t value_low = Utils::Low16Bits(value); 2714 const uint16_t value_low = Utils::Low16Bits(value);
2644 const uint16_t value_high = Utils::High16Bits(value); 2715 const uint16_t value_high = Utils::High16Bits(value);
2645 movw(rd, value_low, cond); 2716 movw(rd, value_low, cond);
2646 movt(rd, value_high, cond); 2717 movt(rd, value_high, cond);
2647 } 2718 }
2648 } 2719 }
2649 2720
2650 2721
2651 void Assembler::LoadDecodableImmediate( 2722 void Assembler::LoadDecodableImmediate(Register rd,
2652 Register rd, int32_t value, Condition cond) { 2723 int32_t value,
2724 Condition cond) {
2653 const ARMVersion version = TargetCPUFeatures::arm_version(); 2725 const ARMVersion version = TargetCPUFeatures::arm_version();
2654 if ((version == ARMv5TE) || (version == ARMv6)) { 2726 if ((version == ARMv5TE) || (version == ARMv6)) {
2655 if (constant_pool_allowed()) { 2727 if (constant_pool_allowed()) {
2656 const int32_t offset = Array::element_offset(FindImmediate(value)); 2728 const int32_t offset = Array::element_offset(FindImmediate(value));
2657 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond); 2729 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond);
2658 } else { 2730 } else {
2659 LoadPatchableImmediate(rd, value, cond); 2731 LoadPatchableImmediate(rd, value, cond);
2660 } 2732 }
2661 } else { 2733 } else {
2662 ASSERT(version == ARMv7); 2734 ASSERT(version == ARMv7);
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
2846 void Assembler::StoreMultipleDToOffset(DRegister first, 2918 void Assembler::StoreMultipleDToOffset(DRegister first,
2847 intptr_t count, 2919 intptr_t count,
2848 Register base, 2920 Register base,
2849 int32_t offset) { 2921 int32_t offset) {
2850 ASSERT(base != IP); 2922 ASSERT(base != IP);
2851 AddImmediate(IP, base, offset); 2923 AddImmediate(IP, base, offset);
2852 vstmd(IA, IP, first, count); 2924 vstmd(IA, IP, first, count);
2853 } 2925 }
2854 2926
2855 2927
2856 void Assembler::CopyDoubleField( 2928 void Assembler::CopyDoubleField(Register dst,
2857 Register dst, Register src, Register tmp1, Register tmp2, DRegister dtmp) { 2929 Register src,
2930 Register tmp1,
2931 Register tmp2,
2932 DRegister dtmp) {
2858 if (TargetCPUFeatures::vfp_supported()) { 2933 if (TargetCPUFeatures::vfp_supported()) {
2859 LoadDFromOffset(dtmp, src, Double::value_offset() - kHeapObjectTag); 2934 LoadDFromOffset(dtmp, src, Double::value_offset() - kHeapObjectTag);
2860 StoreDToOffset(dtmp, dst, Double::value_offset() - kHeapObjectTag); 2935 StoreDToOffset(dtmp, dst, Double::value_offset() - kHeapObjectTag);
2861 } else { 2936 } else {
2862 LoadFromOffset(kWord, tmp1, src, 2937 LoadFromOffset(kWord, tmp1, src, Double::value_offset() - kHeapObjectTag);
2863 Double::value_offset() - kHeapObjectTag);
2864 LoadFromOffset(kWord, tmp2, src, 2938 LoadFromOffset(kWord, tmp2, src,
2865 Double::value_offset() + kWordSize - kHeapObjectTag); 2939 Double::value_offset() + kWordSize - kHeapObjectTag);
2866 StoreToOffset(kWord, tmp1, dst, 2940 StoreToOffset(kWord, tmp1, dst, Double::value_offset() - kHeapObjectTag);
2867 Double::value_offset() - kHeapObjectTag);
2868 StoreToOffset(kWord, tmp2, dst, 2941 StoreToOffset(kWord, tmp2, dst,
2869 Double::value_offset() + kWordSize - kHeapObjectTag); 2942 Double::value_offset() + kWordSize - kHeapObjectTag);
2870 } 2943 }
2871 } 2944 }
2872 2945
2873 2946
2874 void Assembler::CopyFloat32x4Field( 2947 void Assembler::CopyFloat32x4Field(Register dst,
2875 Register dst, Register src, Register tmp1, Register tmp2, DRegister dtmp) { 2948 Register src,
2949 Register tmp1,
2950 Register tmp2,
2951 DRegister dtmp) {
2876 if (TargetCPUFeatures::neon_supported()) { 2952 if (TargetCPUFeatures::neon_supported()) {
2877 LoadMultipleDFromOffset(dtmp, 2, src, 2953 LoadMultipleDFromOffset(dtmp, 2, src,
2878 Float32x4::value_offset() - kHeapObjectTag); 2954 Float32x4::value_offset() - kHeapObjectTag);
2879 StoreMultipleDToOffset(dtmp, 2, dst, 2955 StoreMultipleDToOffset(dtmp, 2, dst,
2880 Float32x4::value_offset() - kHeapObjectTag); 2956 Float32x4::value_offset() - kHeapObjectTag);
2881 } else { 2957 } else {
2882 LoadFromOffset(kWord, tmp1, src, 2958 LoadFromOffset(
2959 kWord, tmp1, src,
2883 (Float32x4::value_offset() + 0 * kWordSize) - kHeapObjectTag); 2960 (Float32x4::value_offset() + 0 * kWordSize) - kHeapObjectTag);
2884 LoadFromOffset(kWord, tmp2, src, 2961 LoadFromOffset(
2962 kWord, tmp2, src,
2885 (Float32x4::value_offset() + 1 * kWordSize) - kHeapObjectTag); 2963 (Float32x4::value_offset() + 1 * kWordSize) - kHeapObjectTag);
2886 StoreToOffset(kWord, tmp1, dst, 2964 StoreToOffset(kWord, tmp1, dst,
2887 (Float32x4::value_offset() + 0 * kWordSize) - kHeapObjectTag); 2965 (Float32x4::value_offset() + 0 * kWordSize) - kHeapObjectTag);
2888 StoreToOffset(kWord, tmp2, dst, 2966 StoreToOffset(kWord, tmp2, dst,
2889 (Float32x4::value_offset() + 1 * kWordSize) - kHeapObjectTag); 2967 (Float32x4::value_offset() + 1 * kWordSize) - kHeapObjectTag);
2890 2968
2891 LoadFromOffset(kWord, tmp1, src, 2969 LoadFromOffset(
2970 kWord, tmp1, src,
2892 (Float32x4::value_offset() + 2 * kWordSize) - kHeapObjectTag); 2971 (Float32x4::value_offset() + 2 * kWordSize) - kHeapObjectTag);
2893 LoadFromOffset(kWord, tmp2, src, 2972 LoadFromOffset(
2973 kWord, tmp2, src,
2894 (Float32x4::value_offset() + 3 * kWordSize) - kHeapObjectTag); 2974 (Float32x4::value_offset() + 3 * kWordSize) - kHeapObjectTag);
2895 StoreToOffset(kWord, tmp1, dst, 2975 StoreToOffset(kWord, tmp1, dst,
2896 (Float32x4::value_offset() + 2 * kWordSize) - kHeapObjectTag); 2976 (Float32x4::value_offset() + 2 * kWordSize) - kHeapObjectTag);
2897 StoreToOffset(kWord, tmp2, dst, 2977 StoreToOffset(kWord, tmp2, dst,
2898 (Float32x4::value_offset() + 3 * kWordSize) - kHeapObjectTag); 2978 (Float32x4::value_offset() + 3 * kWordSize) - kHeapObjectTag);
2899 } 2979 }
2900 } 2980 }
2901 2981
2902 2982
2903 void Assembler::CopyFloat64x2Field( 2983 void Assembler::CopyFloat64x2Field(Register dst,
2904 Register dst, Register src, Register tmp1, Register tmp2, DRegister dtmp) { 2984 Register src,
2985 Register tmp1,
2986 Register tmp2,
2987 DRegister dtmp) {
2905 if (TargetCPUFeatures::neon_supported()) { 2988 if (TargetCPUFeatures::neon_supported()) {
2906 LoadMultipleDFromOffset(dtmp, 2, src, 2989 LoadMultipleDFromOffset(dtmp, 2, src,
2907 Float64x2::value_offset() - kHeapObjectTag); 2990 Float64x2::value_offset() - kHeapObjectTag);
2908 StoreMultipleDToOffset(dtmp, 2, dst, 2991 StoreMultipleDToOffset(dtmp, 2, dst,
2909 Float64x2::value_offset() - kHeapObjectTag); 2992 Float64x2::value_offset() - kHeapObjectTag);
2910 } else { 2993 } else {
2911 LoadFromOffset(kWord, tmp1, src, 2994 LoadFromOffset(
2995 kWord, tmp1, src,
2912 (Float64x2::value_offset() + 0 * kWordSize) - kHeapObjectTag); 2996 (Float64x2::value_offset() + 0 * kWordSize) - kHeapObjectTag);
2913 LoadFromOffset(kWord, tmp2, src, 2997 LoadFromOffset(
2998 kWord, tmp2, src,
2914 (Float64x2::value_offset() + 1 * kWordSize) - kHeapObjectTag); 2999 (Float64x2::value_offset() + 1 * kWordSize) - kHeapObjectTag);
2915 StoreToOffset(kWord, tmp1, dst, 3000 StoreToOffset(kWord, tmp1, dst,
2916 (Float64x2::value_offset() + 0 * kWordSize) - kHeapObjectTag); 3001 (Float64x2::value_offset() + 0 * kWordSize) - kHeapObjectTag);
2917 StoreToOffset(kWord, tmp2, dst, 3002 StoreToOffset(kWord, tmp2, dst,
2918 (Float64x2::value_offset() + 1 * kWordSize) - kHeapObjectTag); 3003 (Float64x2::value_offset() + 1 * kWordSize) - kHeapObjectTag);
2919 3004
2920 LoadFromOffset(kWord, tmp1, src, 3005 LoadFromOffset(
3006 kWord, tmp1, src,
2921 (Float64x2::value_offset() + 2 * kWordSize) - kHeapObjectTag); 3007 (Float64x2::value_offset() + 2 * kWordSize) - kHeapObjectTag);
2922 LoadFromOffset(kWord, tmp2, src, 3008 LoadFromOffset(
3009 kWord, tmp2, src,
2923 (Float64x2::value_offset() + 3 * kWordSize) - kHeapObjectTag); 3010 (Float64x2::value_offset() + 3 * kWordSize) - kHeapObjectTag);
2924 StoreToOffset(kWord, tmp1, dst, 3011 StoreToOffset(kWord, tmp1, dst,
2925 (Float64x2::value_offset() + 2 * kWordSize) - kHeapObjectTag); 3012 (Float64x2::value_offset() + 2 * kWordSize) - kHeapObjectTag);
2926 StoreToOffset(kWord, tmp2, dst, 3013 StoreToOffset(kWord, tmp2, dst,
2927 (Float64x2::value_offset() + 3 * kWordSize) - kHeapObjectTag); 3014 (Float64x2::value_offset() + 3 * kWordSize) - kHeapObjectTag);
2928 } 3015 }
2929 } 3016 }
2930 3017
2931 3018
2932 void Assembler::AddImmediate(Register rd, int32_t value, Condition cond) { 3019 void Assembler::AddImmediate(Register rd, int32_t value, Condition cond) {
2933 AddImmediate(rd, rd, value, cond); 3020 AddImmediate(rd, rd, value, cond);
2934 } 3021 }
2935 3022
2936 3023
2937 void Assembler::AddImmediate(Register rd, Register rn, int32_t value, 3024 void Assembler::AddImmediate(Register rd,
3025 Register rn,
3026 int32_t value,
2938 Condition cond) { 3027 Condition cond) {
2939 if (value == 0) { 3028 if (value == 0) {
2940 if (rd != rn) { 3029 if (rd != rn) {
2941 mov(rd, Operand(rn), cond); 3030 mov(rd, Operand(rn), cond);
2942 } 3031 }
2943 return; 3032 return;
2944 } 3033 }
2945 // We prefer to select the shorter code sequence rather than selecting add for 3034 // We prefer to select the shorter code sequence rather than selecting add for
2946 // positive values and sub for negatives ones, which would slightly improve 3035 // positive values and sub for negatives ones, which would slightly improve
2947 // the readability of generated code for some constants. 3036 // the readability of generated code for some constants.
(...skipping 11 matching lines...) Expand all
2959 mvn(IP, o, cond); 3048 mvn(IP, o, cond);
2960 sub(rd, rn, Operand(IP), cond); 3049 sub(rd, rn, Operand(IP), cond);
2961 } else { 3050 } else {
2962 LoadDecodableImmediate(IP, value, cond); 3051 LoadDecodableImmediate(IP, value, cond);
2963 add(rd, rn, Operand(IP), cond); 3052 add(rd, rn, Operand(IP), cond);
2964 } 3053 }
2965 } 3054 }
2966 } 3055 }
2967 3056
2968 3057
2969 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, 3058 void Assembler::AddImmediateSetFlags(Register rd,
3059 Register rn,
3060 int32_t value,
2970 Condition cond) { 3061 Condition cond) {
2971 Operand o; 3062 Operand o;
2972 if (Operand::CanHold(value, &o)) { 3063 if (Operand::CanHold(value, &o)) {
2973 // Handles value == kMinInt32. 3064 // Handles value == kMinInt32.
2974 adds(rd, rn, o, cond); 3065 adds(rd, rn, o, cond);
2975 } else if (Operand::CanHold(-value, &o)) { 3066 } else if (Operand::CanHold(-value, &o)) {
2976 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 3067 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
2977 subs(rd, rn, o, cond); 3068 subs(rd, rn, o, cond);
2978 } else { 3069 } else {
2979 ASSERT(rn != IP); 3070 ASSERT(rn != IP);
2980 if (Operand::CanHold(~value, &o)) { 3071 if (Operand::CanHold(~value, &o)) {
2981 mvn(IP, o, cond); 3072 mvn(IP, o, cond);
2982 adds(rd, rn, Operand(IP), cond); 3073 adds(rd, rn, Operand(IP), cond);
2983 } else if (Operand::CanHold(~(-value), &o)) { 3074 } else if (Operand::CanHold(~(-value), &o)) {
2984 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 3075 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
2985 mvn(IP, o, cond); 3076 mvn(IP, o, cond);
2986 subs(rd, rn, Operand(IP), cond); 3077 subs(rd, rn, Operand(IP), cond);
2987 } else { 3078 } else {
2988 LoadDecodableImmediate(IP, value, cond); 3079 LoadDecodableImmediate(IP, value, cond);
2989 adds(rd, rn, Operand(IP), cond); 3080 adds(rd, rn, Operand(IP), cond);
2990 } 3081 }
2991 } 3082 }
2992 } 3083 }
2993 3084
2994 3085
2995 void Assembler::SubImmediateSetFlags(Register rd, Register rn, int32_t value, 3086 void Assembler::SubImmediateSetFlags(Register rd,
2996 Condition cond) { 3087 Register rn,
3088 int32_t value,
3089 Condition cond) {
2997 Operand o; 3090 Operand o;
2998 if (Operand::CanHold(value, &o)) { 3091 if (Operand::CanHold(value, &o)) {
2999 // Handles value == kMinInt32. 3092 // Handles value == kMinInt32.
3000 subs(rd, rn, o, cond); 3093 subs(rd, rn, o, cond);
3001 } else if (Operand::CanHold(-value, &o)) { 3094 } else if (Operand::CanHold(-value, &o)) {
3002 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 3095 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
3003 adds(rd, rn, o, cond); 3096 adds(rd, rn, o, cond);
3004 } else { 3097 } else {
3005 ASSERT(rn != IP); 3098 ASSERT(rn != IP);
3006 if (Operand::CanHold(~value, &o)) { 3099 if (Operand::CanHold(~value, &o)) {
3007 mvn(IP, o, cond); 3100 mvn(IP, o, cond);
3008 subs(rd, rn, Operand(IP), cond); 3101 subs(rd, rn, Operand(IP), cond);
3009 } else if (Operand::CanHold(~(-value), &o)) { 3102 } else if (Operand::CanHold(~(-value), &o)) {
3010 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 3103 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
3011 mvn(IP, o, cond); 3104 mvn(IP, o, cond);
3012 adds(rd, rn, Operand(IP), cond); 3105 adds(rd, rn, Operand(IP), cond);
3013 } else { 3106 } else {
3014 LoadDecodableImmediate(IP, value, cond); 3107 LoadDecodableImmediate(IP, value, cond);
3015 subs(rd, rn, Operand(IP), cond); 3108 subs(rd, rn, Operand(IP), cond);
3016 } 3109 }
3017 } 3110 }
3018 } 3111 }
3019 3112
3020 3113
3021 void Assembler::AndImmediate(Register rd, Register rs, int32_t imm, 3114 void Assembler::AndImmediate(Register rd,
3115 Register rs,
3116 int32_t imm,
3022 Condition cond) { 3117 Condition cond) {
3023 Operand o; 3118 Operand o;
3024 if (Operand::CanHold(imm, &o)) { 3119 if (Operand::CanHold(imm, &o)) {
3025 and_(rd, rs, Operand(o), cond); 3120 and_(rd, rs, Operand(o), cond);
3026 } else { 3121 } else {
3027 LoadImmediate(TMP, imm, cond); 3122 LoadImmediate(TMP, imm, cond);
3028 and_(rd, rs, Operand(TMP), cond); 3123 and_(rd, rs, Operand(TMP), cond);
3029 } 3124 }
3030 } 3125 }
3031 3126
(...skipping 13 matching lines...) Expand all
3045 void Assembler::TestImmediate(Register rn, int32_t imm, Condition cond) { 3140 void Assembler::TestImmediate(Register rn, int32_t imm, Condition cond) {
3046 Operand o; 3141 Operand o;
3047 if (Operand::CanHold(imm, &o)) { 3142 if (Operand::CanHold(imm, &o)) {
3048 tst(rn, o, cond); 3143 tst(rn, o, cond);
3049 } else { 3144 } else {
3050 LoadImmediate(IP, imm); 3145 LoadImmediate(IP, imm);
3051 tst(rn, Operand(IP), cond); 3146 tst(rn, Operand(IP), cond);
3052 } 3147 }
3053 } 3148 }
3054 3149
3055 void Assembler::IntegerDivide(Register result, Register left, Register right, 3150 void Assembler::IntegerDivide(Register result,
3056 DRegister tmpl, DRegister tmpr) { 3151 Register left,
3152 Register right,
3153 DRegister tmpl,
3154 DRegister tmpr) {
3057 ASSERT(tmpl != tmpr); 3155 ASSERT(tmpl != tmpr);
3058 if (TargetCPUFeatures::integer_division_supported()) { 3156 if (TargetCPUFeatures::integer_division_supported()) {
3059 sdiv(result, left, right); 3157 sdiv(result, left, right);
3060 } else { 3158 } else {
3061 ASSERT(TargetCPUFeatures::vfp_supported()); 3159 ASSERT(TargetCPUFeatures::vfp_supported());
3062 SRegister stmpl = static_cast<SRegister>(2 * tmpl); 3160 SRegister stmpl = static_cast<SRegister>(2 * tmpl);
3063 SRegister stmpr = static_cast<SRegister>(2 * tmpr); 3161 SRegister stmpr = static_cast<SRegister>(2 * tmpr);
3064 vmovsr(stmpl, left); 3162 vmovsr(stmpl, left);
3065 vcvtdi(tmpl, stmpl); // left is in tmpl. 3163 vcvtdi(tmpl, stmpl); // left is in tmpl.
3066 vmovsr(stmpr, right); 3164 vmovsr(stmpr, right);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3144 3242
3145 ReserveAlignedFrameSpace(frame_space); 3243 ReserveAlignedFrameSpace(frame_space);
3146 } 3244 }
3147 3245
3148 3246
3149 void Assembler::LeaveCallRuntimeFrame() { 3247 void Assembler::LeaveCallRuntimeFrame() {
3150 // SP might have been modified to reserve space for arguments 3248 // SP might have been modified to reserve space for arguments
3151 // and ensure proper alignment of the stack frame. 3249 // and ensure proper alignment of the stack frame.
3152 // We need to restore it before restoring registers. 3250 // We need to restore it before restoring registers.
3153 const intptr_t kPushedFpuRegisterSize = 3251 const intptr_t kPushedFpuRegisterSize =
3154 TargetCPUFeatures::vfp_supported() ? 3252 TargetCPUFeatures::vfp_supported()
3155 kDartVolatileFpuRegCount * kFpuRegisterSize : 0; 3253 ? kDartVolatileFpuRegCount * kFpuRegisterSize
3254 : 0;
3156 3255
3157 COMPILE_ASSERT(PP < FP); 3256 COMPILE_ASSERT(PP < FP);
3158 COMPILE_ASSERT((kDartVolatileCpuRegs & (1 << PP)) == 0); 3257 COMPILE_ASSERT((kDartVolatileCpuRegs & (1 << PP)) == 0);
3159 // kVolatileCpuRegCount +1 for PP, -1 because even though LR is volatile, 3258 // kVolatileCpuRegCount +1 for PP, -1 because even though LR is volatile,
3160 // it is pushed ahead of FP. 3259 // it is pushed ahead of FP.
3161 const intptr_t kPushedRegistersSize = 3260 const intptr_t kPushedRegistersSize =
3162 kDartVolatileCpuRegCount * kWordSize + kPushedFpuRegisterSize; 3261 kDartVolatileCpuRegCount * kWordSize + kPushedFpuRegisterSize;
3163 AddImmediate(SP, FP, -kPushedRegistersSize); 3262 AddImmediate(SP, FP, -kPushedRegistersSize);
3164 3263
3165 // Restore all volatile FPU registers. 3264 // Restore all volatile FPU registers.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
3275 Register temp_reg, 3374 Register temp_reg,
3276 Label* trace) { 3375 Label* trace) {
3277 LoadAllocationStatsAddress(temp_reg, cid); 3376 LoadAllocationStatsAddress(temp_reg, cid);
3278 const uword state_offset = ClassHeapStats::state_offset(); 3377 const uword state_offset = ClassHeapStats::state_offset();
3279 ldr(temp_reg, Address(temp_reg, state_offset)); 3378 ldr(temp_reg, Address(temp_reg, state_offset));
3280 tst(temp_reg, Operand(ClassHeapStats::TraceAllocationMask())); 3379 tst(temp_reg, Operand(ClassHeapStats::TraceAllocationMask()));
3281 b(trace, NE); 3380 b(trace, NE);
3282 } 3381 }
3283 3382
3284 3383
3285 void Assembler::LoadAllocationStatsAddress(Register dest, 3384 void Assembler::LoadAllocationStatsAddress(Register dest, intptr_t cid) {
3286 intptr_t cid) {
3287 ASSERT(dest != kNoRegister); 3385 ASSERT(dest != kNoRegister);
3288 ASSERT(dest != TMP); 3386 ASSERT(dest != TMP);
3289 ASSERT(cid > 0); 3387 ASSERT(cid > 0);
3290 const intptr_t class_offset = ClassTable::ClassOffsetFor(cid); 3388 const intptr_t class_offset = ClassTable::ClassOffsetFor(cid);
3291 LoadIsolate(dest); 3389 LoadIsolate(dest);
3292 intptr_t table_offset = 3390 intptr_t table_offset =
3293 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); 3391 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
3294 ldr(dest, Address(dest, table_offset)); 3392 ldr(dest, Address(dest, table_offset));
3295 AddImmediate(dest, class_offset); 3393 AddImmediate(dest, class_offset);
3296 } 3394 }
3297 3395
3298 3396
3299 void Assembler::IncrementAllocationStats(Register stats_addr_reg, 3397 void Assembler::IncrementAllocationStats(Register stats_addr_reg,
3300 intptr_t cid, 3398 intptr_t cid,
3301 Heap::Space space) { 3399 Heap::Space space) {
3302 ASSERT(stats_addr_reg != kNoRegister); 3400 ASSERT(stats_addr_reg != kNoRegister);
3303 ASSERT(stats_addr_reg != TMP); 3401 ASSERT(stats_addr_reg != TMP);
3304 ASSERT(cid > 0); 3402 ASSERT(cid > 0);
3305 const uword count_field_offset = (space == Heap::kNew) ? 3403 const uword count_field_offset =
3306 ClassHeapStats::allocated_since_gc_new_space_offset() : 3404 (space == Heap::kNew)
3307 ClassHeapStats::allocated_since_gc_old_space_offset(); 3405 ? ClassHeapStats::allocated_since_gc_new_space_offset()
3406 : ClassHeapStats::allocated_since_gc_old_space_offset();
3308 const Address& count_address = Address(stats_addr_reg, count_field_offset); 3407 const Address& count_address = Address(stats_addr_reg, count_field_offset);
3309 ldr(TMP, count_address); 3408 ldr(TMP, count_address);
3310 AddImmediate(TMP, 1); 3409 AddImmediate(TMP, 1);
3311 str(TMP, count_address); 3410 str(TMP, count_address);
3312 } 3411 }
3313 3412
3314 3413
3315 void Assembler::IncrementAllocationStatsWithSize(Register stats_addr_reg, 3414 void Assembler::IncrementAllocationStatsWithSize(Register stats_addr_reg,
3316 Register size_reg, 3415 Register size_reg,
3317 Heap::Space space) { 3416 Heap::Space space) {
3318 ASSERT(stats_addr_reg != kNoRegister); 3417 ASSERT(stats_addr_reg != kNoRegister);
3319 ASSERT(stats_addr_reg != TMP); 3418 ASSERT(stats_addr_reg != TMP);
3320 const uword count_field_offset = (space == Heap::kNew) ? 3419 const uword count_field_offset =
3321 ClassHeapStats::allocated_since_gc_new_space_offset() : 3420 (space == Heap::kNew)
3322 ClassHeapStats::allocated_since_gc_old_space_offset(); 3421 ? ClassHeapStats::allocated_since_gc_new_space_offset()
3323 const uword size_field_offset = (space == Heap::kNew) ? 3422 : ClassHeapStats::allocated_since_gc_old_space_offset();
3324 ClassHeapStats::allocated_size_since_gc_new_space_offset() : 3423 const uword size_field_offset =
3325 ClassHeapStats::allocated_size_since_gc_old_space_offset(); 3424 (space == Heap::kNew)
3425 ? ClassHeapStats::allocated_size_since_gc_new_space_offset()
3426 : ClassHeapStats::allocated_size_since_gc_old_space_offset();
3326 const Address& count_address = Address(stats_addr_reg, count_field_offset); 3427 const Address& count_address = Address(stats_addr_reg, count_field_offset);
3327 const Address& size_address = Address(stats_addr_reg, size_field_offset); 3428 const Address& size_address = Address(stats_addr_reg, size_field_offset);
3328 ldr(TMP, count_address); 3429 ldr(TMP, count_address);
3329 AddImmediate(TMP, 1); 3430 AddImmediate(TMP, 1);
3330 str(TMP, count_address); 3431 str(TMP, count_address);
3331 ldr(TMP, size_address); 3432 ldr(TMP, size_address);
3332 add(TMP, TMP, Operand(size_reg)); 3433 add(TMP, TMP, Operand(size_reg));
3333 str(TMP, size_address); 3434 str(TMP, size_address);
3334 } 3435 }
3335 #endif // !PRODUCT 3436 #endif // !PRODUCT
3336 3437
3337 3438
3338 void Assembler::TryAllocate(const Class& cls, 3439 void Assembler::TryAllocate(const Class& cls,
3339 Label* failure, 3440 Label* failure,
3340 Register instance_reg, 3441 Register instance_reg,
3341 Register temp_reg) { 3442 Register temp_reg) {
3342 ASSERT(failure != NULL); 3443 ASSERT(failure != NULL);
3343 if (FLAG_inline_alloc) { 3444 if (FLAG_inline_alloc) {
3344 ASSERT(instance_reg != temp_reg); 3445 ASSERT(instance_reg != temp_reg);
3345 ASSERT(temp_reg != IP); 3446 ASSERT(temp_reg != IP);
3346 const intptr_t instance_size = cls.instance_size(); 3447 const intptr_t instance_size = cls.instance_size();
3347 ASSERT(instance_size != 0); 3448 ASSERT(instance_size != 0);
3348 // If this allocation is traced, program will jump to failure path 3449 // If this allocation is traced, program will jump to failure path
3349 // (i.e. the allocation stub) which will allocate the object and trace the 3450 // (i.e. the allocation stub) which will allocate the object and trace the
3350 // allocation call site. 3451 // allocation call site.
3351 NOT_IN_PRODUCT( 3452 NOT_IN_PRODUCT(MaybeTraceAllocation(cls.id(), temp_reg, failure));
3352 MaybeTraceAllocation(cls.id(), temp_reg, failure));
3353 Heap::Space space = Heap::kNew; 3453 Heap::Space space = Heap::kNew;
3354 ldr(temp_reg, Address(THR, Thread::heap_offset())); 3454 ldr(temp_reg, Address(THR, Thread::heap_offset()));
3355 ldr(instance_reg, Address(temp_reg, Heap::TopOffset(space))); 3455 ldr(instance_reg, Address(temp_reg, Heap::TopOffset(space)));
3356 // TODO(koda): Protect against unsigned overflow here. 3456 // TODO(koda): Protect against unsigned overflow here.
3357 AddImmediateSetFlags(instance_reg, instance_reg, instance_size); 3457 AddImmediateSetFlags(instance_reg, instance_reg, instance_size);
3358 3458
3359 // instance_reg: potential next object start. 3459 // instance_reg: potential next object start.
3360 ldr(IP, Address(temp_reg, Heap::EndOffset(space))); 3460 ldr(IP, Address(temp_reg, Heap::EndOffset(space)));
3361 cmp(IP, Operand(instance_reg)); 3461 cmp(IP, Operand(instance_reg));
3362 // fail if heap end unsigned less than or equal to instance_reg. 3462 // fail if heap end unsigned less than or equal to instance_reg.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3455 3555
3456 Address Assembler::ElementAddressForIntIndex(bool is_load, 3556 Address Assembler::ElementAddressForIntIndex(bool is_load,
3457 bool is_external, 3557 bool is_external,
3458 intptr_t cid, 3558 intptr_t cid,
3459 intptr_t index_scale, 3559 intptr_t index_scale,
3460 Register array, 3560 Register array,
3461 intptr_t index, 3561 intptr_t index,
3462 Register temp) { 3562 Register temp) {
3463 const int64_t offset_base = 3563 const int64_t offset_base =
3464 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag)); 3564 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
3465 const int64_t offset = offset_base + 3565 const int64_t offset =
3466 static_cast<int64_t>(index) * index_scale; 3566 offset_base + static_cast<int64_t>(index) * index_scale;
3467 ASSERT(Utils::IsInt(32, offset)); 3567 ASSERT(Utils::IsInt(32, offset));
3468 3568
3469 if (Address::CanHoldImmediateOffset(is_load, cid, offset)) { 3569 if (Address::CanHoldImmediateOffset(is_load, cid, offset)) {
3470 return Address(array, static_cast<int32_t>(offset)); 3570 return Address(array, static_cast<int32_t>(offset));
3471 } else { 3571 } else {
3472 ASSERT(Address::CanHoldImmediateOffset(is_load, cid, offset - offset_base)); 3572 ASSERT(Address::CanHoldImmediateOffset(is_load, cid, offset - offset_base));
3473 AddImmediate(temp, array, static_cast<int32_t>(offset_base)); 3573 AddImmediate(temp, array, static_cast<int32_t>(offset_base));
3474 return Address(temp, static_cast<int32_t>(offset - offset_base)); 3574 return Address(temp, static_cast<int32_t>(offset - offset_base));
3475 } 3575 }
3476 } 3576 }
3477 3577
3478 3578
3479 void Assembler::LoadElementAddressForIntIndex(Register address, 3579 void Assembler::LoadElementAddressForIntIndex(Register address,
3480 bool is_load, 3580 bool is_load,
3481 bool is_external, 3581 bool is_external,
3482 intptr_t cid, 3582 intptr_t cid,
3483 intptr_t index_scale, 3583 intptr_t index_scale,
3484 Register array, 3584 Register array,
3485 intptr_t index) { 3585 intptr_t index) {
3486 const int64_t offset_base = 3586 const int64_t offset_base =
3487 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag)); 3587 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
3488 const int64_t offset = offset_base + 3588 const int64_t offset =
3489 static_cast<int64_t>(index) * index_scale; 3589 offset_base + static_cast<int64_t>(index) * index_scale;
3490 ASSERT(Utils::IsInt(32, offset)); 3590 ASSERT(Utils::IsInt(32, offset));
3491 AddImmediate(address, array, offset); 3591 AddImmediate(address, array, offset);
3492 } 3592 }
3493 3593
3494 3594
3495 Address Assembler::ElementAddressForRegIndex(bool is_load, 3595 Address Assembler::ElementAddressForRegIndex(bool is_load,
3496 bool is_external, 3596 bool is_external,
3497 intptr_t cid, 3597 intptr_t cid,
3498 intptr_t index_scale, 3598 intptr_t index_scale,
3499 Register array, 3599 Register array,
3500 Register index) { 3600 Register index) {
3501 // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays. 3601 // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
3502 const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift; 3602 const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
3503 int32_t offset = 3603 int32_t offset =
3504 is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); 3604 is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
3505 const OperandSize size = Address::OperandSizeFor(cid); 3605 const OperandSize size = Address::OperandSizeFor(cid);
3506 ASSERT(array != IP); 3606 ASSERT(array != IP);
3507 ASSERT(index != IP); 3607 ASSERT(index != IP);
3508 const Register base = is_load ? IP : index; 3608 const Register base = is_load ? IP : index;
3509 if ((offset != 0) || 3609 if ((offset != 0) || (size == kSWord) || (size == kDWord) ||
3510 (size == kSWord) || (size == kDWord) || (size == kRegList)) { 3610 (size == kRegList)) {
3511 if (shift < 0) { 3611 if (shift < 0) {
3512 ASSERT(shift == -1); 3612 ASSERT(shift == -1);
3513 add(base, array, Operand(index, ASR, 1)); 3613 add(base, array, Operand(index, ASR, 1));
3514 } else { 3614 } else {
3515 add(base, array, Operand(index, LSL, shift)); 3615 add(base, array, Operand(index, LSL, shift));
3516 } 3616 }
3517 } else { 3617 } else {
3518 if (shift < 0) { 3618 if (shift < 0) {
3519 ASSERT(shift == -1); 3619 ASSERT(shift == -1);
3520 return Address(array, index, ASR, 1); 3620 return Address(array, index, ASR, 1);
3521 } else { 3621 } else {
3522 return Address(array, index, LSL, shift); 3622 return Address(array, index, LSL, shift);
3523 } 3623 }
3524 } 3624 }
3525 int32_t offset_mask = 0; 3625 int32_t offset_mask = 0;
3526 if ((is_load && !Address::CanHoldLoadOffset(size, 3626 if ((is_load && !Address::CanHoldLoadOffset(size, offset, &offset_mask)) ||
3527 offset, 3627 (!is_load && !Address::CanHoldStoreOffset(size, offset, &offset_mask))) {
3528 &offset_mask)) ||
3529 (!is_load && !Address::CanHoldStoreOffset(size,
3530 offset,
3531 &offset_mask))) {
3532 AddImmediate(base, offset & ~offset_mask); 3628 AddImmediate(base, offset & ~offset_mask);
3533 offset = offset & offset_mask; 3629 offset = offset & offset_mask;
3534 } 3630 }
3535 return Address(base, offset); 3631 return Address(base, offset);
3536 } 3632 }
3537 3633
3538 3634
3539 void Assembler::LoadElementAddressForRegIndex(Register address, 3635 void Assembler::LoadElementAddressForRegIndex(Register address,
3540 bool is_load, 3636 bool is_load,
3541 bool is_external, 3637 bool is_external,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
3605 Lsr(tmp, src, Operand(8)); 3701 Lsr(tmp, src, Operand(8));
3606 strb(tmp, Address(addr, 1)); 3702 strb(tmp, Address(addr, 1));
3607 Lsr(tmp, src, Operand(16)); 3703 Lsr(tmp, src, Operand(16));
3608 strb(tmp, Address(addr, 2)); 3704 strb(tmp, Address(addr, 2));
3609 Lsr(tmp, src, Operand(24)); 3705 Lsr(tmp, src, Operand(24));
3610 strb(tmp, Address(addr, 3)); 3706 strb(tmp, Address(addr, 3));
3611 } 3707 }
3612 3708
3613 3709
3614 static const char* cpu_reg_names[kNumberOfCpuRegisters] = { 3710 static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
3615 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 3711 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3616 "r8", "ctx", "pp", "fp", "ip", "sp", "lr", "pc", 3712 "r8", "ctx", "pp", "fp", "ip", "sp", "lr", "pc",
3617 }; 3713 };
3618 3714
3619 3715
3620 const char* Assembler::RegisterName(Register reg) { 3716 const char* Assembler::RegisterName(Register reg) {
3621 ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters)); 3717 ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters));
3622 return cpu_reg_names[reg]; 3718 return cpu_reg_names[reg];
3623 } 3719 }
3624 3720
3625 3721
3626 static const char* fpu_reg_names[kNumberOfFpuRegisters] = { 3722 static const char* fpu_reg_names[kNumberOfFpuRegisters] = {
3627 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", 3723 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
3628 #if defined(VFPv3_D32) 3724 #if defined(VFPv3_D32)
3629 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", 3725 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
3630 #endif 3726 #endif
3631 }; 3727 };
3632 3728
3633 3729
3634 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3730 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3635 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 3731 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
3636 return fpu_reg_names[reg]; 3732 return fpu_reg_names[reg];
3637 } 3733 }
3638 3734
3639 } // namespace dart 3735 } // namespace dart
3640 3736
3641 #endif // defined TARGET_ARCH_ARM 3737 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698