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

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

Issue 297163012: Rename ShifterOperand to Operand on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 months 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm_test.cc » ('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" 5 #include "vm/globals.h"
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"
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 buffer_.Emit<int32_t>(value); 108 buffer_.Emit<int32_t>(value);
109 } 109 }
110 110
111 111
112 void Assembler::EmitType01(Condition cond, 112 void Assembler::EmitType01(Condition cond,
113 int type, 113 int type,
114 Opcode opcode, 114 Opcode opcode,
115 int set_cc, 115 int set_cc,
116 Register rn, 116 Register rn,
117 Register rd, 117 Register rd,
118 ShifterOperand so) { 118 Operand o) {
119 ASSERT(rd != kNoRegister); 119 ASSERT(rd != kNoRegister);
120 ASSERT(cond != kNoCondition); 120 ASSERT(cond != kNoCondition);
121 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 121 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
122 type << kTypeShift | 122 type << kTypeShift |
123 static_cast<int32_t>(opcode) << kOpcodeShift | 123 static_cast<int32_t>(opcode) << kOpcodeShift |
124 set_cc << kSShift | 124 set_cc << kSShift |
125 static_cast<int32_t>(rn) << kRnShift | 125 static_cast<int32_t>(rn) << kRnShift |
126 static_cast<int32_t>(rd) << kRdShift | 126 static_cast<int32_t>(rd) << kRdShift |
127 so.encoding(); 127 o.encoding();
128 Emit(encoding); 128 Emit(encoding);
129 } 129 }
130 130
131 131
132 void Assembler::EmitType5(Condition cond, int32_t offset, bool link) { 132 void Assembler::EmitType5(Condition cond, int32_t offset, bool link) {
133 ASSERT(cond != kNoCondition); 133 ASSERT(cond != kNoCondition);
134 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 134 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
135 5 << kTypeShift | 135 5 << kTypeShift |
136 (link ? 1 : 0) << kLinkShift; 136 (link ? 1 : 0) << kLinkShift;
137 Emit(Assembler::EncodeBranchOffset(offset, encoding)); 137 Emit(Assembler::EncodeBranchOffset(offset, encoding));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 (static_cast<int32_t>(base) << kRnShift) | 183 (static_cast<int32_t>(base) << kRnShift) |
184 regs; 184 regs;
185 Emit(encoding); 185 Emit(encoding);
186 } 186 }
187 187
188 188
189 void Assembler::EmitShiftImmediate(Condition cond, 189 void Assembler::EmitShiftImmediate(Condition cond,
190 Shift opcode, 190 Shift opcode,
191 Register rd, 191 Register rd,
192 Register rm, 192 Register rm,
193 ShifterOperand so) { 193 Operand o) {
194 ASSERT(cond != kNoCondition); 194 ASSERT(cond != kNoCondition);
195 ASSERT(so.type() == 1); 195 ASSERT(o.type() == 1);
196 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 196 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
197 static_cast<int32_t>(MOV) << kOpcodeShift | 197 static_cast<int32_t>(MOV) << kOpcodeShift |
198 static_cast<int32_t>(rd) << kRdShift | 198 static_cast<int32_t>(rd) << kRdShift |
199 so.encoding() << kShiftImmShift | 199 o.encoding() << kShiftImmShift |
200 static_cast<int32_t>(opcode) << kShiftShift | 200 static_cast<int32_t>(opcode) << kShiftShift |
201 static_cast<int32_t>(rm); 201 static_cast<int32_t>(rm);
202 Emit(encoding); 202 Emit(encoding);
203 } 203 }
204 204
205 205
206 void Assembler::EmitShiftRegister(Condition cond, 206 void Assembler::EmitShiftRegister(Condition cond,
207 Shift opcode, 207 Shift opcode,
208 Register rd, 208 Register rd,
209 Register rm, 209 Register rm,
210 ShifterOperand so) { 210 Operand o) {
211 ASSERT(cond != kNoCondition); 211 ASSERT(cond != kNoCondition);
212 ASSERT(so.type() == 0); 212 ASSERT(o.type() == 0);
213 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 213 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
214 static_cast<int32_t>(MOV) << kOpcodeShift | 214 static_cast<int32_t>(MOV) << kOpcodeShift |
215 static_cast<int32_t>(rd) << kRdShift | 215 static_cast<int32_t>(rd) << kRdShift |
216 so.encoding() << kShiftRegisterShift | 216 o.encoding() << kShiftRegisterShift |
217 static_cast<int32_t>(opcode) << kShiftShift | 217 static_cast<int32_t>(opcode) << kShiftShift |
218 B4 | 218 B4 |
219 static_cast<int32_t>(rm); 219 static_cast<int32_t>(rm);
220 Emit(encoding); 220 Emit(encoding);
221 } 221 }
222 222
223 223
224 void Assembler::and_(Register rd, Register rn, ShifterOperand so, 224 void Assembler::and_(Register rd, Register rn, Operand o, Condition cond) {
225 Condition cond) { 225 EmitType01(cond, o.type(), AND, 0, rn, rd, o);
226 EmitType01(cond, so.type(), AND, 0, rn, rd, so);
227 } 226 }
228 227
229 228
230 void Assembler::eor(Register rd, Register rn, ShifterOperand so, 229 void Assembler::eor(Register rd, Register rn, Operand o, Condition cond) {
231 Condition cond) { 230 EmitType01(cond, o.type(), EOR, 0, rn, rd, o);
232 EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
233 } 231 }
234 232
235 233
236 void Assembler::sub(Register rd, Register rn, ShifterOperand so, 234 void Assembler::sub(Register rd, Register rn, Operand o, Condition cond) {
237 Condition cond) { 235 EmitType01(cond, o.type(), SUB, 0, rn, rd, o);
238 EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
239 } 236 }
240 237
241 void Assembler::rsb(Register rd, Register rn, ShifterOperand so, 238 void Assembler::rsb(Register rd, Register rn, Operand o, Condition cond) {
242 Condition cond) { 239 EmitType01(cond, o.type(), RSB, 0, rn, rd, o);
243 EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
244 } 240 }
245 241
246 void Assembler::rsbs(Register rd, Register rn, ShifterOperand so, 242 void Assembler::rsbs(Register rd, Register rn, Operand o, Condition cond) {
247 Condition cond) { 243 EmitType01(cond, o.type(), RSB, 1, rn, rd, o);
248 EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
249 } 244 }
250 245
251 246
252 void Assembler::add(Register rd, Register rn, ShifterOperand so, 247 void Assembler::add(Register rd, Register rn, Operand o, Condition cond) {
253 Condition cond) { 248 EmitType01(cond, o.type(), ADD, 0, rn, rd, o);
254 EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
255 } 249 }
256 250
257 251
258 void Assembler::adds(Register rd, Register rn, ShifterOperand so, 252 void Assembler::adds(Register rd, Register rn, Operand o, Condition cond) {
259 Condition cond) { 253 EmitType01(cond, o.type(), ADD, 1, rn, rd, o);
260 EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
261 } 254 }
262 255
263 256
264 void Assembler::subs(Register rd, Register rn, ShifterOperand so, 257 void Assembler::subs(Register rd, Register rn, Operand o, Condition cond) {
265 Condition cond) { 258 EmitType01(cond, o.type(), SUB, 1, rn, rd, o);
266 EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
267 } 259 }
268 260
269 261
270 void Assembler::adc(Register rd, Register rn, ShifterOperand so, 262 void Assembler::adc(Register rd, Register rn, Operand o, Condition cond) {
271 Condition cond) { 263 EmitType01(cond, o.type(), ADC, 0, rn, rd, o);
272 EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
273 } 264 }
274 265
275 266
276 void Assembler::adcs(Register rd, Register rn, ShifterOperand so, 267 void Assembler::adcs(Register rd, Register rn, Operand o, Condition cond) {
277 Condition cond) { 268 EmitType01(cond, o.type(), ADC, 1, rn, rd, o);
278 EmitType01(cond, so.type(), ADC, 1, rn, rd, so);
279 } 269 }
280 270
281 271
282 void Assembler::sbc(Register rd, Register rn, ShifterOperand so, 272 void Assembler::sbc(Register rd, Register rn, Operand o, Condition cond) {
283 Condition cond) { 273 EmitType01(cond, o.type(), SBC, 0, rn, rd, o);
284 EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
285 } 274 }
286 275
287 276
288 void Assembler::sbcs(Register rd, Register rn, ShifterOperand so, 277 void Assembler::sbcs(Register rd, Register rn, Operand o, Condition cond) {
289 Condition cond) { 278 EmitType01(cond, o.type(), SBC, 1, rn, rd, o);
290 EmitType01(cond, so.type(), SBC, 1, rn, rd, so);
291 } 279 }
292 280
293 281
294 void Assembler::rsc(Register rd, Register rn, ShifterOperand so, 282 void Assembler::rsc(Register rd, Register rn, Operand o, Condition cond) {
295 Condition cond) { 283 EmitType01(cond, o.type(), RSC, 0, rn, rd, o);
296 EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
297 } 284 }
298 285
299 286
300 void Assembler::tst(Register rn, ShifterOperand so, Condition cond) { 287 void Assembler::tst(Register rn, Operand o, Condition cond) {
301 EmitType01(cond, so.type(), TST, 1, rn, R0, so); 288 EmitType01(cond, o.type(), TST, 1, rn, R0, o);
302 } 289 }
303 290
304 291
305 void Assembler::teq(Register rn, ShifterOperand so, Condition cond) { 292 void Assembler::teq(Register rn, Operand o, Condition cond) {
306 EmitType01(cond, so.type(), TEQ, 1, rn, R0, so); 293 EmitType01(cond, o.type(), TEQ, 1, rn, R0, o);
307 } 294 }
308 295
309 296
310 void Assembler::cmp(Register rn, ShifterOperand so, Condition cond) { 297 void Assembler::cmp(Register rn, Operand o, Condition cond) {
311 EmitType01(cond, so.type(), CMP, 1, rn, R0, so); 298 EmitType01(cond, o.type(), CMP, 1, rn, R0, o);
312 } 299 }
313 300
314 301
315 void Assembler::cmn(Register rn, ShifterOperand so, Condition cond) { 302 void Assembler::cmn(Register rn, Operand o, Condition cond) {
316 EmitType01(cond, so.type(), CMN, 1, rn, R0, so); 303 EmitType01(cond, o.type(), CMN, 1, rn, R0, o);
317 } 304 }
318 305
319 306
320 void Assembler::orr(Register rd, Register rn, ShifterOperand so, 307 void Assembler::orr(Register rd, Register rn, Operand o, Condition cond) {
321 Condition cond) { 308 EmitType01(cond, o.type(), ORR, 0, rn, rd, o);
322 EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
323 } 309 }
324 310
325 311
326 void Assembler::orrs(Register rd, Register rn, ShifterOperand so, 312 void Assembler::orrs(Register rd, Register rn, Operand o, Condition cond) {
327 Condition cond) { 313 EmitType01(cond, o.type(), ORR, 1, rn, rd, o);
328 EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
329 } 314 }
330 315
331 316
332 void Assembler::mov(Register rd, ShifterOperand so, Condition cond) { 317 void Assembler::mov(Register rd, Operand o, Condition cond) {
333 EmitType01(cond, so.type(), MOV, 0, R0, rd, so); 318 EmitType01(cond, o.type(), MOV, 0, R0, rd, o);
334 } 319 }
335 320
336 321
337 void Assembler::movs(Register rd, ShifterOperand so, Condition cond) { 322 void Assembler::movs(Register rd, Operand o, Condition cond) {
338 EmitType01(cond, so.type(), MOV, 1, R0, rd, so); 323 EmitType01(cond, o.type(), MOV, 1, R0, rd, o);
339 } 324 }
340 325
341 326
342 void Assembler::bic(Register rd, Register rn, ShifterOperand so, 327 void Assembler::bic(Register rd, Register rn, Operand o, Condition cond) {
343 Condition cond) { 328 EmitType01(cond, o.type(), BIC, 0, rn, rd, o);
344 EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
345 } 329 }
346 330
347 331
348 void Assembler::bics(Register rd, Register rn, ShifterOperand so, 332 void Assembler::bics(Register rd, Register rn, Operand o, Condition cond) {
349 Condition cond) { 333 EmitType01(cond, o.type(), BIC, 1, rn, rd, o);
350 EmitType01(cond, so.type(), BIC, 1, rn, rd, so);
351 } 334 }
352 335
353 336
354 void Assembler::mvn(Register rd, ShifterOperand so, Condition cond) { 337 void Assembler::mvn(Register rd, Operand o, Condition cond) {
355 EmitType01(cond, so.type(), MVN, 0, R0, rd, so); 338 EmitType01(cond, o.type(), MVN, 0, R0, rd, o);
356 } 339 }
357 340
358 341
359 void Assembler::mvns(Register rd, ShifterOperand so, Condition cond) { 342 void Assembler::mvns(Register rd, Operand o, Condition cond) {
360 EmitType01(cond, so.type(), MVN, 1, R0, rd, so); 343 EmitType01(cond, o.type(), MVN, 1, R0, rd, o);
361 } 344 }
362 345
363 346
364 void Assembler::clz(Register rd, Register rm, Condition cond) { 347 void Assembler::clz(Register rd, Register rm, Condition cond) {
365 ASSERT(rd != kNoRegister); 348 ASSERT(rd != kNoRegister);
366 ASSERT(rm != kNoRegister); 349 ASSERT(rm != kNoRegister);
367 ASSERT(cond != kNoCondition); 350 ASSERT(cond != kNoCondition);
368 ASSERT(rd != PC); 351 ASSERT(rd != PC);
369 ASSERT(rm != PC); 352 ASSERT(rm != PC);
370 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 353 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 (static_cast<int32_t>(cond) << kConditionShift) | 388 (static_cast<int32_t>(cond) << kConditionShift) |
406 (static_cast<int32_t>(rn) << kRnShift) | 389 (static_cast<int32_t>(rn) << kRnShift) |
407 (static_cast<int32_t>(rd) << kRdShift) | 390 (static_cast<int32_t>(rd) << kRdShift) |
408 (static_cast<int32_t>(rs) << kRsShift) | 391 (static_cast<int32_t>(rs) << kRsShift) |
409 B7 | B4 | 392 B7 | B4 |
410 (static_cast<int32_t>(rm) << kRmShift); 393 (static_cast<int32_t>(rm) << kRmShift);
411 Emit(encoding); 394 Emit(encoding);
412 } 395 }
413 396
414 397
415 void Assembler::mul(Register rd, Register rn, 398 void Assembler::mul(Register rd, Register rn, Register rm, Condition cond) {
416 Register rm, Condition cond) {
417 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 399 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
418 EmitMulOp(cond, 0, R0, rd, rn, rm); 400 EmitMulOp(cond, 0, R0, rd, rn, rm);
419 } 401 }
420 402
421 403
422 // Like mul, but sets condition flags. 404 // Like mul, but sets condition flags.
423 void Assembler::muls(Register rd, Register rn, 405 void Assembler::muls(Register rd, Register rn, Register rm, Condition cond) {
424 Register rm, Condition cond) {
425 EmitMulOp(cond, B20, R0, rd, rn, rm); 406 EmitMulOp(cond, B20, R0, rd, rn, rm);
426 } 407 }
427 408
428 409
429 void Assembler::mla(Register rd, Register rn, 410 void Assembler::mla(Register rd, Register rn,
430 Register rm, Register ra, Condition cond) { 411 Register rm, Register ra, Condition cond) {
431 // rd <- ra + rn * rm. 412 // rd <- ra + rn * rm.
432 if (TargetCPUFeatures::arm_version() == ARMv7) { 413 if (TargetCPUFeatures::arm_version() == ARMv7) {
433 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 414 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
434 EmitMulOp(cond, B21, ra, rd, rn, rm); 415 EmitMulOp(cond, B21, ra, rd, rn, rm);
435 } else { 416 } else {
436 mul(IP, rn, rm, cond); 417 mul(IP, rn, rm, cond);
437 add(rd, ra, ShifterOperand(IP), cond); 418 add(rd, ra, Operand(IP), cond);
438 } 419 }
439 } 420 }
440 421
441 422
442 void Assembler::mls(Register rd, Register rn, 423 void Assembler::mls(Register rd, Register rn,
443 Register rm, Register ra, Condition cond) { 424 Register rm, Register ra, Condition cond) {
444 // rd <- ra - rn * rm. 425 // rd <- ra - rn * rm.
445 if (TargetCPUFeatures::arm_version() == ARMv7) { 426 if (TargetCPUFeatures::arm_version() == ARMv7) {
446 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 427 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
447 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); 428 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
448 } else { 429 } else {
449 mul(IP, rn, rm, cond); 430 mul(IP, rn, rm, cond);
450 sub(rd, ra, ShifterOperand(IP), cond); 431 sub(rd, ra, Operand(IP), cond);
451 } 432 }
452 } 433 }
453 434
454 435
455 void Assembler::smull(Register rd_lo, Register rd_hi, 436 void Assembler::smull(Register rd_lo, Register rd_hi,
456 Register rn, Register rm, Condition cond) { 437 Register rn, Register rm, Condition cond) {
457 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); 438 ASSERT(TargetCPUFeatures::arm_version() == ARMv7);
458 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 439 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
459 EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm); 440 EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm);
460 } 441 }
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after
1492 ASSERT(rm != kNoRegister); 1473 ASSERT(rm != kNoRegister);
1493 ASSERT(cond != kNoCondition); 1474 ASSERT(cond != kNoCondition);
1494 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1475 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1495 B24 | B21 | (0xfff << 8) | B5 | B4 | 1476 B24 | B21 | (0xfff << 8) | B5 | B4 |
1496 (static_cast<int32_t>(rm) << kRmShift); 1477 (static_cast<int32_t>(rm) << kRmShift);
1497 Emit(encoding); 1478 Emit(encoding);
1498 } 1479 }
1499 1480
1500 1481
1501 void Assembler::MarkExceptionHandler(Label* label) { 1482 void Assembler::MarkExceptionHandler(Label* label) {
1502 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); 1483 EmitType01(AL, 1, TST, 1, PC, R0, Operand(0));
1503 Label l; 1484 Label l;
1504 b(&l); 1485 b(&l);
1505 EmitBranch(AL, label, false); 1486 EmitBranch(AL, label, false);
1506 Bind(&l); 1487 Bind(&l);
1507 } 1488 }
1508 1489
1509 1490
1510 void Assembler::Drop(intptr_t stack_elements) { 1491 void Assembler::Drop(intptr_t stack_elements) {
1511 ASSERT(stack_elements >= 0); 1492 ASSERT(stack_elements >= 0);
1512 if (stack_elements > 0) { 1493 if (stack_elements > 0) {
1513 AddImmediate(SP, SP, stack_elements * kWordSize); 1494 AddImmediate(SP, SP, stack_elements * kWordSize);
1514 } 1495 }
1515 } 1496 }
1516 1497
1517 1498
1518 // Uses a code sequence that can easily be decoded. 1499 // Uses a code sequence that can easily be decoded.
1519 void Assembler::LoadWordFromPoolOffset(Register rd, 1500 void Assembler::LoadWordFromPoolOffset(Register rd,
1520 int32_t offset, 1501 int32_t offset,
1521 Condition cond) { 1502 Condition cond) {
1522 ASSERT(rd != PP); 1503 ASSERT(rd != PP);
1523 int32_t offset_mask = 0; 1504 int32_t offset_mask = 0;
1524 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) { 1505 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) {
1525 ldr(rd, Address(PP, offset), cond); 1506 ldr(rd, Address(PP, offset), cond);
1526 } else { 1507 } else {
1527 int32_t offset_hi = offset & ~offset_mask; // signed 1508 int32_t offset_hi = offset & ~offset_mask; // signed
1528 uint32_t offset_lo = offset & offset_mask; // unsigned 1509 uint32_t offset_lo = offset & offset_mask; // unsigned
1529 // Inline a simplified version of AddImmediate(rd, PP, offset_hi). 1510 // Inline a simplified version of AddImmediate(rd, PP, offset_hi).
1530 ShifterOperand shifter_op; 1511 Operand o;
1531 if (ShifterOperand::CanHold(offset_hi, &shifter_op)) { 1512 if (Operand::CanHold(offset_hi, &o)) {
1532 add(rd, PP, shifter_op, cond); 1513 add(rd, PP, o, cond);
1533 } else { 1514 } else {
1534 LoadImmediate(rd, offset_hi, cond); 1515 LoadImmediate(rd, offset_hi, cond);
1535 add(rd, PP, ShifterOperand(LR), cond); 1516 add(rd, PP, Operand(LR), cond);
1536 } 1517 }
1537 ldr(rd, Address(rd, offset_lo), cond); 1518 ldr(rd, Address(rd, offset_lo), cond);
1538 } 1519 }
1539 } 1520 }
1540 1521
1541 1522
1542 void Assembler::LoadPoolPointer() { 1523 void Assembler::LoadPoolPointer() {
1543 const intptr_t object_pool_pc_dist = 1524 const intptr_t object_pool_pc_dist =
1544 Instructions::HeaderSize() - Instructions::object_pool_offset() + 1525 Instructions::HeaderSize() - Instructions::object_pool_offset() +
1545 CodeSize() + Instr::kPCReadOffset; 1526 CodeSize() + Instr::kPCReadOffset;
(...skipping 24 matching lines...) Expand all
1570 Push(IP); 1551 Push(IP);
1571 } 1552 }
1572 1553
1573 1554
1574 void Assembler::CompareObject(Register rn, const Object& object) { 1555 void Assembler::CompareObject(Register rn, const Object& object) {
1575 ASSERT(rn != IP); 1556 ASSERT(rn != IP);
1576 if (object.IsSmi()) { 1557 if (object.IsSmi()) {
1577 CompareImmediate(rn, reinterpret_cast<int32_t>(object.raw())); 1558 CompareImmediate(rn, reinterpret_cast<int32_t>(object.raw()));
1578 } else { 1559 } else {
1579 LoadObject(IP, object); 1560 LoadObject(IP, object);
1580 cmp(rn, ShifterOperand(IP)); 1561 cmp(rn, Operand(IP));
1581 } 1562 }
1582 } 1563 }
1583 1564
1584 1565
1585 // Preserves object and value registers. 1566 // Preserves object and value registers.
1586 void Assembler::StoreIntoObjectFilterNoSmi(Register object, 1567 void Assembler::StoreIntoObjectFilterNoSmi(Register object,
1587 Register value, 1568 Register value,
1588 Label* no_update) { 1569 Label* no_update) {
1589 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && 1570 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
1590 (kOldObjectAlignmentOffset == 0)); 1571 (kOldObjectAlignmentOffset == 0));
1591 1572
1592 // Write-barrier triggers if the value is in the new space (has bit set) and 1573 // Write-barrier triggers if the value is in the new space (has bit set) and
1593 // the object is in the old space (has bit cleared). 1574 // the object is in the old space (has bit cleared).
1594 // To check that, we compute value & ~object and skip the write barrier 1575 // To check that, we compute value & ~object and skip the write barrier
1595 // if the bit is not set. We can't destroy the object. 1576 // if the bit is not set. We can't destroy the object.
1596 bic(IP, value, ShifterOperand(object)); 1577 bic(IP, value, Operand(object));
1597 tst(IP, ShifterOperand(kNewObjectAlignmentOffset)); 1578 tst(IP, Operand(kNewObjectAlignmentOffset));
1598 b(no_update, EQ); 1579 b(no_update, EQ);
1599 } 1580 }
1600 1581
1601 1582
1602 // Preserves object and value registers. 1583 // Preserves object and value registers.
1603 void Assembler::StoreIntoObjectFilter(Register object, 1584 void Assembler::StoreIntoObjectFilter(Register object,
1604 Register value, 1585 Register value,
1605 Label* no_update) { 1586 Label* no_update) {
1606 // For the value we are only interested in the new/old bit and the tag bit. 1587 // For the value we are only interested in the new/old bit and the tag bit.
1607 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi. 1588 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi.
1608 and_(IP, value, ShifterOperand(value, LSL, kObjectAlignmentLog2 - 1)); 1589 and_(IP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1));
1609 // And the result with the negated space bit of the object. 1590 // And the result with the negated space bit of the object.
1610 bic(IP, IP, ShifterOperand(object)); 1591 bic(IP, IP, Operand(object));
1611 tst(IP, ShifterOperand(kNewObjectAlignmentOffset)); 1592 tst(IP, Operand(kNewObjectAlignmentOffset));
1612 b(no_update, EQ); 1593 b(no_update, EQ);
1613 } 1594 }
1614 1595
1615 1596
1616 void Assembler::StoreIntoObject(Register object, 1597 void Assembler::StoreIntoObject(Register object,
1617 const Address& dest, 1598 const Address& dest,
1618 Register value, 1599 Register value,
1619 bool can_value_be_smi) { 1600 bool can_value_be_smi) {
1620 ASSERT(object != value); 1601 ASSERT(object != value);
1621 str(value, dest); 1602 str(value, dest);
1622 Label done; 1603 Label done;
1623 if (can_value_be_smi) { 1604 if (can_value_be_smi) {
1624 StoreIntoObjectFilter(object, value, &done); 1605 StoreIntoObjectFilter(object, value, &done);
1625 } else { 1606 } else {
1626 StoreIntoObjectFilterNoSmi(object, value, &done); 1607 StoreIntoObjectFilterNoSmi(object, value, &done);
1627 } 1608 }
1628 // A store buffer update is required. 1609 // A store buffer update is required.
1629 RegList regs = (1 << LR); 1610 RegList regs = (1 << LR);
1630 if (value != R0) { 1611 if (value != R0) {
1631 regs |= (1 << R0); // Preserve R0. 1612 regs |= (1 << R0); // Preserve R0.
1632 } 1613 }
1633 PushList(regs); 1614 PushList(regs);
1634 if (object != R0) { 1615 if (object != R0) {
1635 mov(R0, ShifterOperand(object)); 1616 mov(R0, Operand(object));
1636 } 1617 }
1637 BranchLink(&StubCode::UpdateStoreBufferLabel()); 1618 BranchLink(&StubCode::UpdateStoreBufferLabel());
1638 PopList(regs); 1619 PopList(regs);
1639 Bind(&done); 1620 Bind(&done);
1640 } 1621 }
1641 1622
1642 1623
1643 void Assembler::StoreIntoObjectNoBarrier(Register object, 1624 void Assembler::StoreIntoObjectNoBarrier(Register object,
1644 const Address& dest, 1625 const Address& dest,
1645 Register value) { 1626 Register value) {
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
2164 } 2145 }
2165 2146
2166 2147
2167 void Assembler::PopList(RegList regs, Condition cond) { 2148 void Assembler::PopList(RegList regs, Condition cond) {
2168 ldm(IA_W, SP, regs, cond); 2149 ldm(IA_W, SP, regs, cond);
2169 } 2150 }
2170 2151
2171 2152
2172 void Assembler::MoveRegister(Register rd, Register rm, Condition cond) { 2153 void Assembler::MoveRegister(Register rd, Register rm, Condition cond) {
2173 if (rd != rm) { 2154 if (rd != rm) {
2174 mov(rd, ShifterOperand(rm), cond); 2155 mov(rd, Operand(rm), cond);
2175 } 2156 }
2176 } 2157 }
2177 2158
2178 2159
2179 void Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm, 2160 void Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
2180 Condition cond) { 2161 Condition cond) {
2181 ASSERT(shift_imm != 0); // Do not use Lsl if no shift is wanted. 2162 ASSERT(shift_imm != 0); // Do not use Lsl if no shift is wanted.
2182 mov(rd, ShifterOperand(rm, LSL, shift_imm), cond); 2163 mov(rd, Operand(rm, LSL, shift_imm), cond);
2183 } 2164 }
2184 2165
2185 2166
2186 void Assembler::Lsl(Register rd, Register rm, Register rs, Condition cond) { 2167 void Assembler::Lsl(Register rd, Register rm, Register rs, Condition cond) {
2187 mov(rd, ShifterOperand(rm, LSL, rs), cond); 2168 mov(rd, Operand(rm, LSL, rs), cond);
2188 } 2169 }
2189 2170
2190 2171
2191 void Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm, 2172 void Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
2192 Condition cond) { 2173 Condition cond) {
2193 ASSERT(shift_imm != 0); // Do not use Lsr if no shift is wanted. 2174 ASSERT(shift_imm != 0); // Do not use Lsr if no shift is wanted.
2194 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. 2175 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax.
2195 mov(rd, ShifterOperand(rm, LSR, shift_imm), cond); 2176 mov(rd, Operand(rm, LSR, shift_imm), cond);
2196 } 2177 }
2197 2178
2198 2179
2199 void Assembler::Lsr(Register rd, Register rm, Register rs, Condition cond) { 2180 void Assembler::Lsr(Register rd, Register rm, Register rs, Condition cond) {
2200 mov(rd, ShifterOperand(rm, LSR, rs), cond); 2181 mov(rd, Operand(rm, LSR, rs), cond);
2201 } 2182 }
2202 2183
2203 2184
2204 void Assembler::Asr(Register rd, Register rm, uint32_t shift_imm, 2185 void Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
2205 Condition cond) { 2186 Condition cond) {
2206 ASSERT(shift_imm != 0); // Do not use Asr if no shift is wanted. 2187 ASSERT(shift_imm != 0); // Do not use Asr if no shift is wanted.
2207 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. 2188 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax.
2208 mov(rd, ShifterOperand(rm, ASR, shift_imm), cond); 2189 mov(rd, Operand(rm, ASR, shift_imm), cond);
2209 } 2190 }
2210 2191
2211 2192
2212 void Assembler::Asr(Register rd, Register rm, Register rs, Condition cond) { 2193 void Assembler::Asr(Register rd, Register rm, Register rs, Condition cond) {
2213 mov(rd, ShifterOperand(rm, ASR, rs), cond); 2194 mov(rd, Operand(rm, ASR, rs), cond);
2214 } 2195 }
2215 2196
2216 2197
2217 void Assembler::Ror(Register rd, Register rm, uint32_t shift_imm, 2198 void Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
2218 Condition cond) { 2199 Condition cond) {
2219 ASSERT(shift_imm != 0); // Use Rrx instruction. 2200 ASSERT(shift_imm != 0); // Use Rrx instruction.
2220 mov(rd, ShifterOperand(rm, ROR, shift_imm), cond); 2201 mov(rd, Operand(rm, ROR, shift_imm), cond);
2221 } 2202 }
2222 2203
2223 2204
2224 void Assembler::Ror(Register rd, Register rm, Register rs, Condition cond) { 2205 void Assembler::Ror(Register rd, Register rm, Register rs, Condition cond) {
2225 mov(rd, ShifterOperand(rm, ROR, rs), cond); 2206 mov(rd, Operand(rm, ROR, rs), cond);
2226 } 2207 }
2227 2208
2228 2209
2229 void Assembler::Rrx(Register rd, Register rm, Condition cond) { 2210 void Assembler::Rrx(Register rd, Register rm, Condition cond) {
2230 mov(rd, ShifterOperand(rm, ROR, 0), cond); 2211 mov(rd, Operand(rm, ROR, 0), cond);
2231 } 2212 }
2232 2213
2233 2214
2234 void Assembler::SignFill(Register rd, Register rm, Condition cond) { 2215 void Assembler::SignFill(Register rd, Register rm, Condition cond) {
2235 Asr(rd, rm, 31, cond); 2216 Asr(rd, rm, 31, cond);
2236 } 2217 }
2237 2218
2238 2219
2239 void Assembler::Vreciprocalqs(QRegister qd, QRegister qm) { 2220 void Assembler::Vreciprocalqs(QRegister qd, QRegister qm) {
2240 ASSERT(qm != QTMP); 2221 ASSERT(qm != QTMP);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2338 2319
2339 void Assembler::LoadPatchableImmediate( 2320 void Assembler::LoadPatchableImmediate(
2340 Register rd, int32_t value, Condition cond) { 2321 Register rd, int32_t value, Condition cond) {
2341 const ARMVersion version = TargetCPUFeatures::arm_version(); 2322 const ARMVersion version = TargetCPUFeatures::arm_version();
2342 if ((version == ARMv5TE) || (version == ARMv6)) { 2323 if ((version == ARMv5TE) || (version == ARMv6)) {
2343 // This sequence is patched in a few places, and should remain fixed. 2324 // This sequence is patched in a few places, and should remain fixed.
2344 const uint32_t byte0 = (value & 0x000000ff); 2325 const uint32_t byte0 = (value & 0x000000ff);
2345 const uint32_t byte1 = (value & 0x0000ff00) >> 8; 2326 const uint32_t byte1 = (value & 0x0000ff00) >> 8;
2346 const uint32_t byte2 = (value & 0x00ff0000) >> 16; 2327 const uint32_t byte2 = (value & 0x00ff0000) >> 16;
2347 const uint32_t byte3 = (value & 0xff000000) >> 24; 2328 const uint32_t byte3 = (value & 0xff000000) >> 24;
2348 mov(rd, ShifterOperand(4, byte3), cond); 2329 mov(rd, Operand(4, byte3), cond);
2349 orr(rd, rd, ShifterOperand(8, byte2), cond); 2330 orr(rd, rd, Operand(8, byte2), cond);
2350 orr(rd, rd, ShifterOperand(12, byte1), cond); 2331 orr(rd, rd, Operand(12, byte1), cond);
2351 orr(rd, rd, ShifterOperand(byte0), cond); 2332 orr(rd, rd, Operand(byte0), cond);
2352 } else { 2333 } else {
2353 ASSERT(version == ARMv7); 2334 ASSERT(version == ARMv7);
2354 const uint16_t value_low = Utils::Low16Bits(value); 2335 const uint16_t value_low = Utils::Low16Bits(value);
2355 const uint16_t value_high = Utils::High16Bits(value); 2336 const uint16_t value_high = Utils::High16Bits(value);
2356 movw(rd, value_low, cond); 2337 movw(rd, value_low, cond);
2357 movt(rd, value_high, cond); 2338 movt(rd, value_high, cond);
2358 } 2339 }
2359 } 2340 }
2360 2341
2361 2342
2362 void Assembler::LoadDecodableImmediate( 2343 void Assembler::LoadDecodableImmediate(
2363 Register rd, int32_t value, Condition cond) { 2344 Register rd, int32_t value, Condition cond) {
2364 const ARMVersion version = TargetCPUFeatures::arm_version(); 2345 const ARMVersion version = TargetCPUFeatures::arm_version();
2365 if ((version == ARMv5TE) || (version == ARMv6)) { 2346 if ((version == ARMv5TE) || (version == ARMv6)) {
2366 LoadPatchableImmediate(rd, value, cond); 2347 LoadPatchableImmediate(rd, value, cond);
2367 } else { 2348 } else {
2368 ASSERT(version == ARMv7); 2349 ASSERT(version == ARMv7);
2369 movw(rd, Utils::Low16Bits(value), cond); 2350 movw(rd, Utils::Low16Bits(value), cond);
2370 const uint16_t value_high = Utils::High16Bits(value); 2351 const uint16_t value_high = Utils::High16Bits(value);
2371 if (value_high != 0) { 2352 if (value_high != 0) {
2372 movt(rd, value_high, cond); 2353 movt(rd, value_high, cond);
2373 } 2354 }
2374 } 2355 }
2375 } 2356 }
2376 2357
2377 2358
2378 void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { 2359 void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
2379 ShifterOperand shifter_op; 2360 Operand o;
2380 if (ShifterOperand::CanHold(value, &shifter_op)) { 2361 if (Operand::CanHold(value, &o)) {
2381 mov(rd, shifter_op, cond); 2362 mov(rd, o, cond);
2382 } else if (ShifterOperand::CanHold(~value, &shifter_op)) { 2363 } else if (Operand::CanHold(~value, &o)) {
2383 mvn(rd, shifter_op, cond); 2364 mvn(rd, o, cond);
2384 } else { 2365 } else {
2385 LoadDecodableImmediate(rd, value, cond); 2366 LoadDecodableImmediate(rd, value, cond);
2386 } 2367 }
2387 } 2368 }
2388 2369
2389 2370
2390 void Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) { 2371 void Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) {
2391 if (!vmovs(sd, value, cond)) { 2372 if (!vmovs(sd, value, cond)) {
2392 LoadImmediate(IP, bit_cast<int32_t, float>(value), cond); 2373 LoadImmediate(IP, bit_cast<int32_t, float>(value), cond);
2393 vmovsr(sd, IP, cond); 2374 vmovsr(sd, IP, cond);
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
2638 2619
2639 void Assembler::AddImmediate(Register rd, int32_t value, Condition cond) { 2620 void Assembler::AddImmediate(Register rd, int32_t value, Condition cond) {
2640 AddImmediate(rd, rd, value, cond); 2621 AddImmediate(rd, rd, value, cond);
2641 } 2622 }
2642 2623
2643 2624
2644 void Assembler::AddImmediate(Register rd, Register rn, int32_t value, 2625 void Assembler::AddImmediate(Register rd, Register rn, int32_t value,
2645 Condition cond) { 2626 Condition cond) {
2646 if (value == 0) { 2627 if (value == 0) {
2647 if (rd != rn) { 2628 if (rd != rn) {
2648 mov(rd, ShifterOperand(rn), cond); 2629 mov(rd, Operand(rn), cond);
2649 } 2630 }
2650 return; 2631 return;
2651 } 2632 }
2652 // We prefer to select the shorter code sequence rather than selecting add for 2633 // We prefer to select the shorter code sequence rather than selecting add for
2653 // positive values and sub for negatives ones, which would slightly improve 2634 // positive values and sub for negatives ones, which would slightly improve
2654 // the readability of generated code for some constants. 2635 // the readability of generated code for some constants.
2655 ShifterOperand shifter_op; 2636 Operand o;
2656 if (ShifterOperand::CanHold(value, &shifter_op)) { 2637 if (Operand::CanHold(value, &o)) {
2657 add(rd, rn, shifter_op, cond); 2638 add(rd, rn, o, cond);
2658 } else if (ShifterOperand::CanHold(-value, &shifter_op)) { 2639 } else if (Operand::CanHold(-value, &o)) {
2659 sub(rd, rn, shifter_op, cond); 2640 sub(rd, rn, o, cond);
2660 } else { 2641 } else {
2661 ASSERT(rn != IP); 2642 ASSERT(rn != IP);
2662 if (ShifterOperand::CanHold(~value, &shifter_op)) { 2643 if (Operand::CanHold(~value, &o)) {
2663 mvn(IP, shifter_op, cond); 2644 mvn(IP, o, cond);
2664 add(rd, rn, ShifterOperand(IP), cond); 2645 add(rd, rn, Operand(IP), cond);
2665 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { 2646 } else if (Operand::CanHold(~(-value), &o)) {
2666 mvn(IP, shifter_op, cond); 2647 mvn(IP, o, cond);
2667 sub(rd, rn, ShifterOperand(IP), cond); 2648 sub(rd, rn, Operand(IP), cond);
2668 } else { 2649 } else {
2669 LoadDecodableImmediate(IP, value, cond); 2650 LoadDecodableImmediate(IP, value, cond);
2670 add(rd, rn, ShifterOperand(IP), cond); 2651 add(rd, rn, Operand(IP), cond);
2671 } 2652 }
2672 } 2653 }
2673 } 2654 }
2674 2655
2675 2656
2676 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, 2657 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value,
2677 Condition cond) { 2658 Condition cond) {
2678 ShifterOperand shifter_op; 2659 Operand o;
2679 if (ShifterOperand::CanHold(value, &shifter_op)) { 2660 if (Operand::CanHold(value, &o)) {
2680 // Handles value == kMinInt32. 2661 // Handles value == kMinInt32.
2681 adds(rd, rn, shifter_op, cond); 2662 adds(rd, rn, o, cond);
2682 } else if (ShifterOperand::CanHold(-value, &shifter_op)) { 2663 } else if (Operand::CanHold(-value, &o)) {
2683 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 2664 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
2684 subs(rd, rn, shifter_op, cond); 2665 subs(rd, rn, o, cond);
2685 } else { 2666 } else {
2686 ASSERT(rn != IP); 2667 ASSERT(rn != IP);
2687 if (ShifterOperand::CanHold(~value, &shifter_op)) { 2668 if (Operand::CanHold(~value, &o)) {
2688 mvn(IP, shifter_op, cond); 2669 mvn(IP, o, cond);
2689 adds(rd, rn, ShifterOperand(IP), cond); 2670 adds(rd, rn, Operand(IP), cond);
2690 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { 2671 } else if (Operand::CanHold(~(-value), &o)) {
2691 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 2672 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
2692 mvn(IP, shifter_op, cond); 2673 mvn(IP, o, cond);
2693 subs(rd, rn, ShifterOperand(IP), cond); 2674 subs(rd, rn, Operand(IP), cond);
2694 } else { 2675 } else {
2695 LoadDecodableImmediate(IP, value, cond); 2676 LoadDecodableImmediate(IP, value, cond);
2696 adds(rd, rn, ShifterOperand(IP), cond); 2677 adds(rd, rn, Operand(IP), cond);
2697 } 2678 }
2698 } 2679 }
2699 } 2680 }
2700 2681
2701 2682
2702 void Assembler::SubImmediateSetFlags(Register rd, Register rn, int32_t value, 2683 void Assembler::SubImmediateSetFlags(Register rd, Register rn, int32_t value,
2703 Condition cond) { 2684 Condition cond) {
2704 ShifterOperand shifter_op; 2685 Operand o;
2705 if (ShifterOperand::CanHold(value, &shifter_op)) { 2686 if (Operand::CanHold(value, &o)) {
2706 // Handles value == kMinInt32. 2687 // Handles value == kMinInt32.
2707 subs(rd, rn, shifter_op, cond); 2688 subs(rd, rn, o, cond);
2708 } else if (ShifterOperand::CanHold(-value, &shifter_op)) { 2689 } else if (Operand::CanHold(-value, &o)) {
2709 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 2690 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
2710 adds(rd, rn, shifter_op, cond); 2691 adds(rd, rn, o, cond);
2711 } else { 2692 } else {
2712 ASSERT(rn != IP); 2693 ASSERT(rn != IP);
2713 if (ShifterOperand::CanHold(~value, &shifter_op)) { 2694 if (Operand::CanHold(~value, &o)) {
2714 mvn(IP, shifter_op, cond); 2695 mvn(IP, o, cond);
2715 subs(rd, rn, ShifterOperand(IP), cond); 2696 subs(rd, rn, Operand(IP), cond);
2716 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { 2697 } else if (Operand::CanHold(~(-value), &o)) {
2717 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 2698 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
2718 mvn(IP, shifter_op, cond); 2699 mvn(IP, o, cond);
2719 adds(rd, rn, ShifterOperand(IP), cond); 2700 adds(rd, rn, Operand(IP), cond);
2720 } else { 2701 } else {
2721 LoadDecodableImmediate(IP, value, cond); 2702 LoadDecodableImmediate(IP, value, cond);
2722 subs(rd, rn, ShifterOperand(IP), cond); 2703 subs(rd, rn, Operand(IP), cond);
2723 } 2704 }
2724 } 2705 }
2725 } 2706 }
2726 2707
2727 2708
2728 void Assembler::AndImmediate(Register rd, Register rs, int32_t imm, 2709 void Assembler::AndImmediate(Register rd, Register rs, int32_t imm,
2729 Condition cond) { 2710 Condition cond) {
2730 ShifterOperand op; 2711 Operand o;
2731 if (ShifterOperand::CanHold(imm, &op)) { 2712 if (Operand::CanHold(imm, &o)) {
2732 and_(rd, rs, ShifterOperand(op), cond); 2713 and_(rd, rs, Operand(o), cond);
2733 } else { 2714 } else {
2734 LoadImmediate(TMP, imm, cond); 2715 LoadImmediate(TMP, imm, cond);
2735 and_(rd, rs, ShifterOperand(TMP), cond); 2716 and_(rd, rs, Operand(TMP), cond);
2736 } 2717 }
2737 } 2718 }
2738 2719
2739 2720
2740 void Assembler::CompareImmediate(Register rn, int32_t value, Condition cond) { 2721 void Assembler::CompareImmediate(Register rn, int32_t value, Condition cond) {
2741 ShifterOperand shifter_op; 2722 Operand o;
2742 if (ShifterOperand::CanHold(value, &shifter_op)) { 2723 if (Operand::CanHold(value, &o)) {
2743 cmp(rn, shifter_op, cond); 2724 cmp(rn, o, cond);
2744 } else { 2725 } else {
2745 ASSERT(rn != IP); 2726 ASSERT(rn != IP);
2746 LoadImmediate(IP, value, cond); 2727 LoadImmediate(IP, value, cond);
2747 cmp(rn, ShifterOperand(IP), cond); 2728 cmp(rn, Operand(IP), cond);
2748 } 2729 }
2749 } 2730 }
2750 2731
2751 2732
2752 void Assembler::TestImmediate(Register rn, int32_t imm, Condition cond) { 2733 void Assembler::TestImmediate(Register rn, int32_t imm, Condition cond) {
2753 ShifterOperand shifter_op; 2734 Operand o;
2754 if (ShifterOperand::CanHold(imm, &shifter_op)) { 2735 if (Operand::CanHold(imm, &o)) {
2755 tst(rn, shifter_op, cond); 2736 tst(rn, o, cond);
2756 } else { 2737 } else {
2757 LoadImmediate(IP, imm); 2738 LoadImmediate(IP, imm);
2758 tst(rn, ShifterOperand(IP), cond); 2739 tst(rn, Operand(IP), cond);
2759 } 2740 }
2760 } 2741 }
2761 2742
2762 void Assembler::IntegerDivide(Register result, Register left, Register right, 2743 void Assembler::IntegerDivide(Register result, Register left, Register right,
2763 DRegister tmpl, DRegister tmpr) { 2744 DRegister tmpl, DRegister tmpr) {
2764 ASSERT(tmpl != tmpr); 2745 ASSERT(tmpl != tmpr);
2765 if (TargetCPUFeatures::integer_division_supported()) { 2746 if (TargetCPUFeatures::integer_division_supported()) {
2766 sdiv(result, left, right); 2747 sdiv(result, left, right);
2767 } else { 2748 } else {
2768 SRegister stmpl = static_cast<SRegister>(2 * tmpl); 2749 SRegister stmpl = static_cast<SRegister>(2 * tmpl);
(...skipping 21 matching lines...) Expand all
2790 CompareImmediate(left, 0); 2771 CompareImmediate(left, 0);
2791 b(&left_neg, LT); 2772 b(&left_neg, LT);
2792 b(&done, EQ); 2773 b(&done, EQ);
2793 CompareImmediate(right, 0); 2774 CompareImmediate(right, 0);
2794 b(&left_pos_right_neg, LT); 2775 b(&left_pos_right_neg, LT);
2795 b(&done, EQ); 2776 b(&done, EQ);
2796 2777
2797 // Both positive. 2778 // Both positive.
2798 LoadImmediate(tmp, INT_MAX); 2779 LoadImmediate(tmp, INT_MAX);
2799 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); 2780 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1);
2800 cmp(tmp, ShifterOperand(right)); 2781 cmp(tmp, Operand(right));
2801 b(overflow, LT); 2782 b(overflow, LT);
2802 b(&done); 2783 b(&done);
2803 2784
2804 // left positive, right non-positive. 2785 // left positive, right non-positive.
2805 Bind(&left_pos_right_neg); 2786 Bind(&left_pos_right_neg);
2806 LoadImmediate(tmp, INT_MIN); 2787 LoadImmediate(tmp, INT_MIN);
2807 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); 2788 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1);
2808 cmp(tmp, ShifterOperand(right)); 2789 cmp(tmp, Operand(right));
2809 b(overflow, GT); 2790 b(overflow, GT);
2810 b(&done); 2791 b(&done);
2811 2792
2812 Bind(&left_neg); 2793 Bind(&left_neg);
2813 CompareImmediate(right, 0); 2794 CompareImmediate(right, 0);
2814 b(&left_neg_right_pos, GT); 2795 b(&left_neg_right_pos, GT);
2815 b(&done, EQ); 2796 b(&done, EQ);
2816 2797
2817 // both negative. 2798 // both negative.
2818 LoadImmediate(tmp, INT_MAX); 2799 LoadImmediate(tmp, INT_MAX);
2819 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); 2800 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1);
2820 cmp(tmp, ShifterOperand(right)); 2801 cmp(tmp, Operand(right));
2821 b(overflow, GT); 2802 b(overflow, GT);
2822 b(&done); 2803 b(&done);
2823 2804
2824 // left non-positive, right positive. 2805 // left non-positive, right positive.
2825 Bind(&left_neg_right_pos); 2806 Bind(&left_neg_right_pos);
2826 LoadImmediate(tmp, INT_MIN); 2807 LoadImmediate(tmp, INT_MIN);
2827 IntegerDivide(tmp, tmp, right, dtmp0, dtmp1); 2808 IntegerDivide(tmp, tmp, right, dtmp0, dtmp1);
2828 cmp(tmp, ShifterOperand(left)); 2809 cmp(tmp, Operand(left));
2829 b(overflow, GT); 2810 b(overflow, GT);
2830 2811
2831 Bind(&done); 2812 Bind(&done);
2832 } 2813 }
2833 2814
2834 2815
2835 static int NumRegsBelowFP(RegList regs) { 2816 static int NumRegsBelowFP(RegList regs) {
2836 int count = 0; 2817 int count = 0;
2837 for (int i = 0; i < FP; i++) { 2818 for (int i = 0; i < FP; i++) {
2838 if ((regs & (1 << i)) != 0) { 2819 if ((regs & (1 << i)) != 0) {
2839 count++; 2820 count++;
2840 } 2821 }
2841 } 2822 }
2842 return count; 2823 return count;
2843 } 2824 }
2844 2825
2845 2826
2846 void Assembler::EnterFrame(RegList regs, intptr_t frame_size) { 2827 void Assembler::EnterFrame(RegList regs, intptr_t frame_size) {
2847 if (prologue_offset_ == -1) { 2828 if (prologue_offset_ == -1) {
2848 prologue_offset_ = CodeSize(); 2829 prologue_offset_ = CodeSize();
2849 } 2830 }
2850 PushList(regs); 2831 PushList(regs);
2851 if ((regs & (1 << FP)) != 0) { 2832 if ((regs & (1 << FP)) != 0) {
2852 // Set FP to the saved previous FP. 2833 // Set FP to the saved previous FP.
2853 add(FP, SP, ShifterOperand(4 * NumRegsBelowFP(regs))); 2834 add(FP, SP, Operand(4 * NumRegsBelowFP(regs)));
2854 } 2835 }
2855 AddImmediate(SP, -frame_size); 2836 AddImmediate(SP, -frame_size);
2856 } 2837 }
2857 2838
2858 2839
2859 void Assembler::LeaveFrame(RegList regs) { 2840 void Assembler::LeaveFrame(RegList regs) {
2860 ASSERT((regs & (1 << PC)) == 0); // Must not pop PC. 2841 ASSERT((regs & (1 << PC)) == 0); // Must not pop PC.
2861 if ((regs & (1 << FP)) != 0) { 2842 if ((regs & (1 << FP)) != 0) {
2862 // Use FP to set SP. 2843 // Use FP to set SP.
2863 sub(SP, FP, ShifterOperand(4 * NumRegsBelowFP(regs))); 2844 sub(SP, FP, Operand(4 * NumRegsBelowFP(regs)));
2864 } 2845 }
2865 PopList(regs); 2846 PopList(regs);
2866 } 2847 }
2867 2848
2868 2849
2869 void Assembler::Ret() { 2850 void Assembler::Ret() {
2870 bx(LR); 2851 bx(LR);
2871 } 2852 }
2872 2853
2873 2854
2874 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { 2855 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
2875 // Reserve space for arguments and align frame before entering 2856 // Reserve space for arguments and align frame before entering
2876 // the C++ world. 2857 // the C++ world.
2877 AddImmediate(SP, -frame_space); 2858 AddImmediate(SP, -frame_space);
2878 if (OS::ActivationFrameAlignment() > 1) { 2859 if (OS::ActivationFrameAlignment() > 1) {
2879 bic(SP, SP, ShifterOperand(OS::ActivationFrameAlignment() - 1)); 2860 bic(SP, SP, Operand(OS::ActivationFrameAlignment() - 1));
2880 } 2861 }
2881 } 2862 }
2882 2863
2883 2864
2884 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { 2865 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
2885 // Preserve volatile CPU registers. 2866 // Preserve volatile CPU registers.
2886 EnterFrame(kDartVolatileCpuRegs | (1 << FP) | (1 << LR), 0); 2867 EnterFrame(kDartVolatileCpuRegs | (1 << FP) | (1 << LR), 0);
2887 2868
2888 // Preserve all volatile FPU registers. 2869 // Preserve all volatile FPU registers.
2889 if (TargetCPUFeatures::vfp_supported()) { 2870 if (TargetCPUFeatures::vfp_supported()) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2963 2944
2964 // On entry to a function compiled for OSR, the caller's frame pointer, the 2945 // On entry to a function compiled for OSR, the caller's frame pointer, the
2965 // stack locals, and any copied parameters are already in place. The frame 2946 // stack locals, and any copied parameters are already in place. The frame
2966 // pointer is already set up. The PC marker is not correct for the 2947 // pointer is already set up. The PC marker is not correct for the
2967 // optimized function and there may be extra space for spill slots to 2948 // optimized function and there may be extra space for spill slots to
2968 // allocate. We must also set up the pool pointer for the function. 2949 // allocate. We must also set up the pool pointer for the function.
2969 void Assembler::EnterOsrFrame(intptr_t extra_size) { 2950 void Assembler::EnterOsrFrame(intptr_t extra_size) {
2970 const intptr_t offset = CodeSize(); 2951 const intptr_t offset = CodeSize();
2971 2952
2972 Comment("EnterOsrFrame"); 2953 Comment("EnterOsrFrame");
2973 mov(IP, ShifterOperand(PC)); 2954 mov(IP, Operand(PC));
2974 2955
2975 AddImmediate(IP, -offset); 2956 AddImmediate(IP, -offset);
2976 str(IP, Address(FP, kPcMarkerSlotFromFp * kWordSize)); 2957 str(IP, Address(FP, kPcMarkerSlotFromFp * kWordSize));
2977 2958
2978 // Setup pool pointer for this dart function. 2959 // Setup pool pointer for this dart function.
2979 LoadPoolPointer(); 2960 LoadPoolPointer();
2980 2961
2981 AddImmediate(SP, -extra_size); 2962 AddImmediate(SP, -extra_size);
2982 } 2963 }
2983 2964
2984 2965
2985 void Assembler::LeaveDartFrame() { 2966 void Assembler::LeaveDartFrame() {
2986 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); 2967 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR));
2987 // Adjust SP for PC pushed in EnterDartFrame. 2968 // Adjust SP for PC pushed in EnterDartFrame.
2988 AddImmediate(SP, kWordSize); 2969 AddImmediate(SP, kWordSize);
2989 } 2970 }
2990 2971
2991 2972
2992 void Assembler::EnterStubFrame(bool load_pp) { 2973 void Assembler::EnterStubFrame(bool load_pp) {
2993 // Push 0 as saved PC for stub frames. 2974 // Push 0 as saved PC for stub frames.
2994 mov(IP, ShifterOperand(LR)); 2975 mov(IP, Operand(LR));
2995 mov(LR, ShifterOperand(0)); 2976 mov(LR, Operand(0));
2996 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR); 2977 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR);
2997 EnterFrame(regs, 0); 2978 EnterFrame(regs, 0);
2998 if (load_pp) { 2979 if (load_pp) {
2999 // Setup pool pointer for this stub. 2980 // Setup pool pointer for this stub.
3000 LoadPoolPointer(); 2981 LoadPoolPointer();
3001 } 2982 }
3002 } 2983 }
3003 2984
3004 2985
3005 void Assembler::LeaveStubFrame() { 2986 void Assembler::LeaveStubFrame() {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3064 const uword size_field_offset = (space == Heap::kNew) ? 3045 const uword size_field_offset = (space == Heap::kNew) ?
3065 ClassHeapStats::allocated_size_since_gc_new_space_offset() : 3046 ClassHeapStats::allocated_size_since_gc_new_space_offset() :
3066 ClassHeapStats::allocated_size_since_gc_old_space_offset(); 3047 ClassHeapStats::allocated_size_since_gc_old_space_offset();
3067 LoadImmediate(temp_reg, class_heap_stats_table_address + class_offset); 3048 LoadImmediate(temp_reg, class_heap_stats_table_address + class_offset);
3068 const Address& count_address = Address(temp_reg, count_field_offset); 3049 const Address& count_address = Address(temp_reg, count_field_offset);
3069 const Address& size_address = Address(temp_reg, size_field_offset); 3050 const Address& size_address = Address(temp_reg, size_field_offset);
3070 ldr(TMP, count_address); 3051 ldr(TMP, count_address);
3071 AddImmediate(TMP, 1); 3052 AddImmediate(TMP, 1);
3072 str(TMP, count_address); 3053 str(TMP, count_address);
3073 ldr(TMP, size_address); 3054 ldr(TMP, size_address);
3074 add(TMP, TMP, ShifterOperand(size_reg)); 3055 add(TMP, TMP, Operand(size_reg));
3075 str(TMP, size_address); 3056 str(TMP, size_address);
3076 } else { 3057 } else {
3077 ASSERT(temp_reg != kNoRegister); 3058 ASSERT(temp_reg != kNoRegister);
3078 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT 3059 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT
3079 const uword count_field_offset = (space == Heap::kNew) ? 3060 const uword count_field_offset = (space == Heap::kNew) ?
3080 ClassHeapStats::allocated_since_gc_new_space_offset() : 3061 ClassHeapStats::allocated_since_gc_new_space_offset() :
3081 ClassHeapStats::allocated_since_gc_old_space_offset(); 3062 ClassHeapStats::allocated_since_gc_old_space_offset();
3082 const uword size_field_offset = (space == Heap::kNew) ? 3063 const uword size_field_offset = (space == Heap::kNew) ?
3083 ClassHeapStats::allocated_size_since_gc_new_space_offset() : 3064 ClassHeapStats::allocated_size_since_gc_new_space_offset() :
3084 ClassHeapStats::allocated_size_since_gc_old_space_offset(); 3065 ClassHeapStats::allocated_size_since_gc_old_space_offset();
3085 LoadImmediate(temp_reg, class_table->ClassStatsTableAddress()); 3066 LoadImmediate(temp_reg, class_table->ClassStatsTableAddress());
3086 ldr(temp_reg, Address(temp_reg, 0)); 3067 ldr(temp_reg, Address(temp_reg, 0));
3087 AddImmediate(temp_reg, class_offset); 3068 AddImmediate(temp_reg, class_offset);
3088 ldr(TMP, Address(temp_reg, count_field_offset)); 3069 ldr(TMP, Address(temp_reg, count_field_offset));
3089 AddImmediate(TMP, 1); 3070 AddImmediate(TMP, 1);
3090 str(TMP, Address(temp_reg, count_field_offset)); 3071 str(TMP, Address(temp_reg, count_field_offset));
3091 ldr(TMP, Address(temp_reg, size_field_offset)); 3072 ldr(TMP, Address(temp_reg, size_field_offset));
3092 add(TMP, TMP, ShifterOperand(size_reg)); 3073 add(TMP, TMP, Operand(size_reg));
3093 str(TMP, Address(temp_reg, size_field_offset)); 3074 str(TMP, Address(temp_reg, size_field_offset));
3094 } 3075 }
3095 } 3076 }
3096 3077
3097 3078
3098 void Assembler::TryAllocate(const Class& cls, 3079 void Assembler::TryAllocate(const Class& cls,
3099 Label* failure, 3080 Label* failure,
3100 Register instance_reg, 3081 Register instance_reg,
3101 Register temp_reg) { 3082 Register temp_reg) {
3102 ASSERT(failure != NULL); 3083 ASSERT(failure != NULL);
3103 if (FLAG_inline_alloc) { 3084 if (FLAG_inline_alloc) {
3104 Heap* heap = Isolate::Current()->heap(); 3085 Heap* heap = Isolate::Current()->heap();
3105 const intptr_t instance_size = cls.instance_size(); 3086 const intptr_t instance_size = cls.instance_size();
3106 LoadImmediate(instance_reg, heap->TopAddress()); 3087 LoadImmediate(instance_reg, heap->TopAddress());
3107 ldr(instance_reg, Address(instance_reg, 0)); 3088 ldr(instance_reg, Address(instance_reg, 0));
3108 AddImmediate(instance_reg, instance_size); 3089 AddImmediate(instance_reg, instance_size);
3109 3090
3110 // instance_reg: potential next object start. 3091 // instance_reg: potential next object start.
3111 LoadImmediate(IP, heap->EndAddress()); 3092 LoadImmediate(IP, heap->EndAddress());
3112 ldr(IP, Address(IP, 0)); 3093 ldr(IP, Address(IP, 0));
3113 cmp(IP, ShifterOperand(instance_reg)); 3094 cmp(IP, Operand(instance_reg));
3114 // fail if heap end unsigned less than or equal to instance_reg. 3095 // fail if heap end unsigned less than or equal to instance_reg.
3115 b(failure, LS); 3096 b(failure, LS);
3116 3097
3117 // Successfully allocated the object, now update top to point to 3098 // Successfully allocated the object, now update top to point to
3118 // next object start and store the class in the class field of object. 3099 // next object start and store the class in the class field of object.
3119 LoadImmediate(IP, heap->TopAddress()); 3100 LoadImmediate(IP, heap->TopAddress());
3120 str(instance_reg, Address(IP, 0)); 3101 str(instance_reg, Address(IP, 0));
3121 3102
3122 ASSERT(instance_size >= kHeapObjectTag); 3103 ASSERT(instance_size >= kHeapObjectTag);
3123 AddImmediate(instance_reg, -instance_size + kHeapObjectTag); 3104 AddImmediate(instance_reg, -instance_size + kHeapObjectTag);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3210 3191
3211 3192
3212 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3193 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3213 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 3194 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
3214 return fpu_reg_names[reg]; 3195 return fpu_reg_names[reg];
3215 } 3196 }
3216 3197
3217 } // namespace dart 3198 } // namespace dart
3218 3199
3219 #endif // defined TARGET_ARCH_ARM 3200 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698