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

Side by Side Diff: src/arm/assembler-arm.cc

Issue 6597029: [Isolates] Merge r 6300:6500 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: Created 9 years, 9 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 | « src/arm/assembler-arm.h ('k') | src/arm/builtins-arm.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) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 ASSERT(is_uint5(shift_imm)); 206 ASSERT(is_uint5(shift_imm));
207 rn_ = rn; 207 rn_ = rn;
208 rm_ = rm; 208 rm_ = rm;
209 shift_op_ = shift_op; 209 shift_op_ = shift_op;
210 shift_imm_ = shift_imm & 31; 210 shift_imm_ = shift_imm & 31;
211 am_ = am; 211 am_ = am;
212 } 212 }
213 213
214 214
215 // ----------------------------------------------------------------------------- 215 // -----------------------------------------------------------------------------
216 // Implementation of Assembler. 216 // Specific instructions, constants, and masks.
217
218 // Instruction encoding bits.
219 enum {
220 H = 1 << 5, // halfword (or byte)
221 S6 = 1 << 6, // signed (or unsigned)
222 L = 1 << 20, // load (or store)
223 S = 1 << 20, // set condition code (or leave unchanged)
224 W = 1 << 21, // writeback base register (or leave unchanged)
225 A = 1 << 21, // accumulate in multiply instruction (or not)
226 B = 1 << 22, // unsigned byte (or word)
227 N = 1 << 22, // long (or short)
228 U = 1 << 23, // positive (or negative) offset/index
229 P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing)
230 I = 1 << 25, // immediate shifter operand (or not)
231
232 B4 = 1 << 4,
233 B5 = 1 << 5,
234 B6 = 1 << 6,
235 B7 = 1 << 7,
236 B8 = 1 << 8,
237 B9 = 1 << 9,
238 B12 = 1 << 12,
239 B16 = 1 << 16,
240 B18 = 1 << 18,
241 B19 = 1 << 19,
242 B20 = 1 << 20,
243 B21 = 1 << 21,
244 B22 = 1 << 22,
245 B23 = 1 << 23,
246 B24 = 1 << 24,
247 B25 = 1 << 25,
248 B26 = 1 << 26,
249 B27 = 1 << 27,
250
251 // Instruction bit masks.
252 RdMask = 15 << 12, // in str instruction
253 CondMask = 15 << 28,
254 CoprocessorMask = 15 << 8,
255 OpCodeMask = 15 << 21, // in data-processing instructions
256 Imm24Mask = (1 << 24) - 1,
257 Off12Mask = (1 << 12) - 1,
258 // Reserved condition.
259 nv = 15 << 28
260 };
261
262 217
263 // add(sp, sp, 4) instruction (aka Pop()) 218 // add(sp, sp, 4) instruction (aka Pop())
264 static const Instr kPopInstruction = 219 const Instr kPopInstruction =
265 al | 4 * B21 | 4 | LeaveCC | I | sp.code() * B16 | sp.code() * B12; 220 al | PostIndex | 4 | LeaveCC | I | sp.code() * B16 | sp.code() * B12;
266 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r)) 221 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
267 // register r is not encoded. 222 // register r is not encoded.
268 static const Instr kPushRegPattern = 223 const Instr kPushRegPattern =
269 al | B26 | 4 | NegPreIndex | sp.code() * B16; 224 al | B26 | 4 | NegPreIndex | sp.code() * B16;
270 // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r)) 225 // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))
271 // register r is not encoded. 226 // register r is not encoded.
272 static const Instr kPopRegPattern = 227 const Instr kPopRegPattern =
273 al | B26 | L | 4 | PostIndex | sp.code() * B16; 228 al | B26 | L | 4 | PostIndex | sp.code() * B16;
274 // mov lr, pc 229 // mov lr, pc
275 const Instr kMovLrPc = al | 13*B21 | pc.code() | lr.code() * B12; 230 const Instr kMovLrPc = al | MOV | pc.code() | lr.code() * B12;
276 // ldr rd, [pc, #offset] 231 // ldr rd, [pc, #offset]
277 const Instr kLdrPCMask = CondMask | 15 * B24 | 7 * B20 | 15 * B16; 232 const Instr kLdrPCMask = kCondMask | 15 * B24 | 7 * B20 | 15 * B16;
278 const Instr kLdrPCPattern = al | 5 * B24 | L | pc.code() * B16; 233 const Instr kLdrPCPattern = al | 5 * B24 | L | pc.code() * B16;
279 // blxcc rm 234 // blxcc rm
280 const Instr kBlxRegMask = 235 const Instr kBlxRegMask =
281 15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4; 236 15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4;
282 const Instr kBlxRegPattern = 237 const Instr kBlxRegPattern =
283 B24 | B21 | 15 * B16 | 15 * B12 | 15 * B8 | 3 * B4; 238 B24 | B21 | 15 * B16 | 15 * B12 | 15 * B8 | BLX;
284 const Instr kMovMvnMask = 0x6d * B21 | 0xf * B16; 239 const Instr kMovMvnMask = 0x6d * B21 | 0xf * B16;
285 const Instr kMovMvnPattern = 0xd * B21; 240 const Instr kMovMvnPattern = 0xd * B21;
286 const Instr kMovMvnFlip = B22; 241 const Instr kMovMvnFlip = B22;
287 const Instr kMovLeaveCCMask = 0xdff * B16; 242 const Instr kMovLeaveCCMask = 0xdff * B16;
288 const Instr kMovLeaveCCPattern = 0x1a0 * B16; 243 const Instr kMovLeaveCCPattern = 0x1a0 * B16;
289 const Instr kMovwMask = 0xff * B20; 244 const Instr kMovwMask = 0xff * B20;
290 const Instr kMovwPattern = 0x30 * B20; 245 const Instr kMovwPattern = 0x30 * B20;
291 const Instr kMovwLeaveCCFlip = 0x5 * B21; 246 const Instr kMovwLeaveCCFlip = 0x5 * B21;
292 const Instr kCmpCmnMask = 0xdd * B20 | 0xf * B12; 247 const Instr kCmpCmnMask = 0xdd * B20 | 0xf * B12;
293 const Instr kCmpCmnPattern = 0x15 * B20; 248 const Instr kCmpCmnPattern = 0x15 * B20;
294 const Instr kCmpCmnFlip = B21; 249 const Instr kCmpCmnFlip = B21;
295 const Instr kALUMask = 0x6f * B21;
296 const Instr kAddPattern = 0x4 * B21;
297 const Instr kSubPattern = 0x2 * B21;
298 const Instr kBicPattern = 0xe * B21;
299 const Instr kAndPattern = 0x0 * B21;
300 const Instr kAddSubFlip = 0x6 * B21; 250 const Instr kAddSubFlip = 0x6 * B21;
301 const Instr kAndBicFlip = 0xe * B21; 251 const Instr kAndBicFlip = 0xe * B21;
302 252
303 // A mask for the Rd register for push, pop, ldr, str instructions. 253 // A mask for the Rd register for push, pop, ldr, str instructions.
304 const Instr kRdMask = 0x0000f000; 254 const Instr kLdrRegFpOffsetPattern =
305 static const int kRdShift = 12;
306 static const Instr kLdrRegFpOffsetPattern =
307 al | B26 | L | Offset | fp.code() * B16; 255 al | B26 | L | Offset | fp.code() * B16;
308 static const Instr kStrRegFpOffsetPattern = 256 const Instr kStrRegFpOffsetPattern =
309 al | B26 | Offset | fp.code() * B16; 257 al | B26 | Offset | fp.code() * B16;
310 static const Instr kLdrRegFpNegOffsetPattern = 258 const Instr kLdrRegFpNegOffsetPattern =
311 al | B26 | L | NegOffset | fp.code() * B16; 259 al | B26 | L | NegOffset | fp.code() * B16;
312 static const Instr kStrRegFpNegOffsetPattern = 260 const Instr kStrRegFpNegOffsetPattern =
313 al | B26 | NegOffset | fp.code() * B16; 261 al | B26 | NegOffset | fp.code() * B16;
314 static const Instr kLdrStrInstrTypeMask = 0xffff0000; 262 const Instr kLdrStrInstrTypeMask = 0xffff0000;
315 static const Instr kLdrStrInstrArgumentMask = 0x0000ffff; 263 const Instr kLdrStrInstrArgumentMask = 0x0000ffff;
316 static const Instr kLdrStrOffsetMask = 0x00000fff; 264 const Instr kLdrStrOffsetMask = 0x00000fff;
317 265
266
267 // Spare buffer.
318 static const int kMinimalBufferSize = 4*KB; 268 static const int kMinimalBufferSize = 4*KB;
319 269
270
320 Assembler::Assembler(void* buffer, int buffer_size) 271 Assembler::Assembler(void* buffer, int buffer_size)
321 : positions_recorder_(this), 272 : positions_recorder_(this),
322 allow_peephole_optimization_(false) { 273 allow_peephole_optimization_(false) {
323 Isolate* isolate = Isolate::Current(); 274 Isolate* isolate = Isolate::Current();
324 // BUG(3245989): disable peephole optimization if crankshaft is enabled. 275 // BUG(3245989): disable peephole optimization if crankshaft is enabled.
325 allow_peephole_optimization_ = FLAG_peephole_optimization; 276 allow_peephole_optimization_ = FLAG_peephole_optimization;
326 if (buffer == NULL) { 277 if (buffer == NULL) {
327 // Do our own buffer management. 278 // Do our own buffer management.
328 if (buffer_size <= kMinimalBufferSize) { 279 if (buffer_size <= kMinimalBufferSize) {
329 buffer_size = kMinimalBufferSize; 280 buffer_size = kMinimalBufferSize;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 356
406 bool Assembler::IsBranch(Instr instr) { 357 bool Assembler::IsBranch(Instr instr) {
407 return (instr & (B27 | B25)) == (B27 | B25); 358 return (instr & (B27 | B25)) == (B27 | B25);
408 } 359 }
409 360
410 361
411 int Assembler::GetBranchOffset(Instr instr) { 362 int Assembler::GetBranchOffset(Instr instr) {
412 ASSERT(IsBranch(instr)); 363 ASSERT(IsBranch(instr));
413 // Take the jump offset in the lower 24 bits, sign extend it and multiply it 364 // Take the jump offset in the lower 24 bits, sign extend it and multiply it
414 // with 4 to get the offset in bytes. 365 // with 4 to get the offset in bytes.
415 return ((instr & Imm24Mask) << 8) >> 6; 366 return ((instr & kImm24Mask) << 8) >> 6;
416 } 367 }
417 368
418 369
419 bool Assembler::IsLdrRegisterImmediate(Instr instr) { 370 bool Assembler::IsLdrRegisterImmediate(Instr instr) {
420 return (instr & (B27 | B26 | B25 | B22 | B20)) == (B26 | B20); 371 return (instr & (B27 | B26 | B25 | B22 | B20)) == (B26 | B20);
421 } 372 }
422 373
423 374
424 int Assembler::GetLdrRegisterImmediateOffset(Instr instr) { 375 int Assembler::GetLdrRegisterImmediateOffset(Instr instr) {
425 ASSERT(IsLdrRegisterImmediate(instr)); 376 ASSERT(IsLdrRegisterImmediate(instr));
426 bool positive = (instr & B23) == B23; 377 bool positive = (instr & B23) == B23;
427 int offset = instr & Off12Mask; // Zero extended offset. 378 int offset = instr & kOff12Mask; // Zero extended offset.
428 return positive ? offset : -offset; 379 return positive ? offset : -offset;
429 } 380 }
430 381
431 382
432 Instr Assembler::SetLdrRegisterImmediateOffset(Instr instr, int offset) { 383 Instr Assembler::SetLdrRegisterImmediateOffset(Instr instr, int offset) {
433 ASSERT(IsLdrRegisterImmediate(instr)); 384 ASSERT(IsLdrRegisterImmediate(instr));
434 bool positive = offset >= 0; 385 bool positive = offset >= 0;
435 if (!positive) offset = -offset; 386 if (!positive) offset = -offset;
436 ASSERT(is_uint12(offset)); 387 ASSERT(is_uint12(offset));
437 // Set bit indicating whether the offset should be added. 388 // Set bit indicating whether the offset should be added.
438 instr = (instr & ~B23) | (positive ? B23 : 0); 389 instr = (instr & ~B23) | (positive ? B23 : 0);
439 // Set the actual offset. 390 // Set the actual offset.
440 return (instr & ~Off12Mask) | offset; 391 return (instr & ~kOff12Mask) | offset;
441 } 392 }
442 393
443 394
444 bool Assembler::IsStrRegisterImmediate(Instr instr) { 395 bool Assembler::IsStrRegisterImmediate(Instr instr) {
445 return (instr & (B27 | B26 | B25 | B22 | B20)) == B26; 396 return (instr & (B27 | B26 | B25 | B22 | B20)) == B26;
446 } 397 }
447 398
448 399
449 Instr Assembler::SetStrRegisterImmediateOffset(Instr instr, int offset) { 400 Instr Assembler::SetStrRegisterImmediateOffset(Instr instr, int offset) {
450 ASSERT(IsStrRegisterImmediate(instr)); 401 ASSERT(IsStrRegisterImmediate(instr));
451 bool positive = offset >= 0; 402 bool positive = offset >= 0;
452 if (!positive) offset = -offset; 403 if (!positive) offset = -offset;
453 ASSERT(is_uint12(offset)); 404 ASSERT(is_uint12(offset));
454 // Set bit indicating whether the offset should be added. 405 // Set bit indicating whether the offset should be added.
455 instr = (instr & ~B23) | (positive ? B23 : 0); 406 instr = (instr & ~B23) | (positive ? B23 : 0);
456 // Set the actual offset. 407 // Set the actual offset.
457 return (instr & ~Off12Mask) | offset; 408 return (instr & ~kOff12Mask) | offset;
458 } 409 }
459 410
460 411
461 bool Assembler::IsAddRegisterImmediate(Instr instr) { 412 bool Assembler::IsAddRegisterImmediate(Instr instr) {
462 return (instr & (B27 | B26 | B25 | B24 | B23 | B22 | B21)) == (B25 | B23); 413 return (instr & (B27 | B26 | B25 | B24 | B23 | B22 | B21)) == (B25 | B23);
463 } 414 }
464 415
465 416
466 Instr Assembler::SetAddRegisterImmediateOffset(Instr instr, int offset) { 417 Instr Assembler::SetAddRegisterImmediateOffset(Instr instr, int offset) {
467 ASSERT(IsAddRegisterImmediate(instr)); 418 ASSERT(IsAddRegisterImmediate(instr));
468 ASSERT(offset >= 0); 419 ASSERT(offset >= 0);
469 ASSERT(is_uint12(offset)); 420 ASSERT(is_uint12(offset));
470 // Set the offset. 421 // Set the offset.
471 return (instr & ~Off12Mask) | offset; 422 return (instr & ~kOff12Mask) | offset;
472 } 423 }
473 424
474 425
475 Register Assembler::GetRd(Instr instr) { 426 Register Assembler::GetRd(Instr instr) {
476 Register reg; 427 Register reg;
477 reg.code_ = ((instr & kRdMask) >> kRdShift); 428 reg.code_ = Instruction::RdValue(instr);
478 return reg; 429 return reg;
479 } 430 }
480 431
481 432
482 bool Assembler::IsPush(Instr instr) { 433 bool Assembler::IsPush(Instr instr) {
483 return ((instr & ~kRdMask) == kPushRegPattern); 434 return ((instr & ~kRdMask) == kPushRegPattern);
484 } 435 }
485 436
486 437
487 bool Assembler::IsPop(Instr instr) { 438 bool Assembler::IsPop(Instr instr) {
(...skipping 17 matching lines...) Expand all
505 456
506 457
507 bool Assembler::IsLdrRegFpNegOffset(Instr instr) { 458 bool Assembler::IsLdrRegFpNegOffset(Instr instr) {
508 return ((instr & kLdrStrInstrTypeMask) == kLdrRegFpNegOffsetPattern); 459 return ((instr & kLdrStrInstrTypeMask) == kLdrRegFpNegOffsetPattern);
509 } 460 }
510 461
511 462
512 bool Assembler::IsLdrPcImmediateOffset(Instr instr) { 463 bool Assembler::IsLdrPcImmediateOffset(Instr instr) {
513 // Check the instruction is indeed a 464 // Check the instruction is indeed a
514 // ldr<cond> <Rd>, [pc +/- offset_12]. 465 // ldr<cond> <Rd>, [pc +/- offset_12].
515 return (instr & 0x0f7f0000) == 0x051f0000; 466 return (instr & (kLdrPCMask & ~kCondMask)) == 0x051f0000;
516 } 467 }
517 468
518 469
519 // Labels refer to positions in the (to be) generated code. 470 // Labels refer to positions in the (to be) generated code.
520 // There are bound, linked, and unused labels. 471 // There are bound, linked, and unused labels.
521 // 472 //
522 // Bound labels refer to known positions in the already 473 // Bound labels refer to known positions in the already
523 // generated code. pos() is the position the label refers to. 474 // generated code. pos() is the position the label refers to.
524 // 475 //
525 // Linked labels refer to unknown positions in the code 476 // Linked labels refer to unknown positions in the code
526 // to be generated; pos() is the position of the last 477 // to be generated; pos() is the position of the last
527 // instruction using the label. 478 // instruction using the label.
528 479
529 480
530 // The link chain is terminated by a negative code position (must be aligned) 481 // The link chain is terminated by a negative code position (must be aligned)
531 const int kEndOfChain = -4; 482 const int kEndOfChain = -4;
532 483
533 484
534 int Assembler::target_at(int pos) { 485 int Assembler::target_at(int pos) {
535 Instr instr = instr_at(pos); 486 Instr instr = instr_at(pos);
536 if ((instr & ~Imm24Mask) == 0) { 487 if ((instr & ~kImm24Mask) == 0) {
537 // Emitted label constant, not part of a branch. 488 // Emitted label constant, not part of a branch.
538 return instr - (Code::kHeaderSize - kHeapObjectTag); 489 return instr - (Code::kHeaderSize - kHeapObjectTag);
539 } 490 }
540 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 491 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
541 int imm26 = ((instr & Imm24Mask) << 8) >> 6; 492 int imm26 = ((instr & kImm24Mask) << 8) >> 6;
542 if ((instr & CondMask) == nv && (instr & B24) != 0) { 493 if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
494 ((instr & B24) != 0)) {
543 // blx uses bit 24 to encode bit 2 of imm26 495 // blx uses bit 24 to encode bit 2 of imm26
544 imm26 += 2; 496 imm26 += 2;
545 } 497 }
546 return pos + kPcLoadDelta + imm26; 498 return pos + kPcLoadDelta + imm26;
547 } 499 }
548 500
549 501
550 void Assembler::target_at_put(int pos, int target_pos) { 502 void Assembler::target_at_put(int pos, int target_pos) {
551 Instr instr = instr_at(pos); 503 Instr instr = instr_at(pos);
552 if ((instr & ~Imm24Mask) == 0) { 504 if ((instr & ~kImm24Mask) == 0) {
553 ASSERT(target_pos == kEndOfChain || target_pos >= 0); 505 ASSERT(target_pos == kEndOfChain || target_pos >= 0);
554 // Emitted label constant, not part of a branch. 506 // Emitted label constant, not part of a branch.
555 // Make label relative to Code* of generated Code object. 507 // Make label relative to Code* of generated Code object.
556 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 508 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
557 return; 509 return;
558 } 510 }
559 int imm26 = target_pos - (pos + kPcLoadDelta); 511 int imm26 = target_pos - (pos + kPcLoadDelta);
560 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 512 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
561 if ((instr & CondMask) == nv) { 513 if (Instruction::ConditionField(instr) == kSpecialCondition) {
562 // blx uses bit 24 to encode bit 2 of imm26 514 // blx uses bit 24 to encode bit 2 of imm26
563 ASSERT((imm26 & 1) == 0); 515 ASSERT((imm26 & 1) == 0);
564 instr = (instr & ~(B24 | Imm24Mask)) | ((imm26 & 2) >> 1)*B24; 516 instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24;
565 } else { 517 } else {
566 ASSERT((imm26 & 3) == 0); 518 ASSERT((imm26 & 3) == 0);
567 instr &= ~Imm24Mask; 519 instr &= ~kImm24Mask;
568 } 520 }
569 int imm24 = imm26 >> 2; 521 int imm24 = imm26 >> 2;
570 ASSERT(is_int24(imm24)); 522 ASSERT(is_int24(imm24));
571 instr_at_put(pos, instr | (imm24 & Imm24Mask)); 523 instr_at_put(pos, instr | (imm24 & kImm24Mask));
572 } 524 }
573 525
574 526
575 void Assembler::print(Label* L) { 527 void Assembler::print(Label* L) {
576 if (L->is_unused()) { 528 if (L->is_unused()) {
577 PrintF("unused label\n"); 529 PrintF("unused label\n");
578 } else if (L->is_bound()) { 530 } else if (L->is_bound()) {
579 PrintF("bound label to %d\n", L->pos()); 531 PrintF("bound label to %d\n", L->pos());
580 } else if (L->is_linked()) { 532 } else if (L->is_linked()) {
581 Label l = *L; 533 Label l = *L;
582 PrintF("unbound label"); 534 PrintF("unbound label");
583 while (l.is_linked()) { 535 while (l.is_linked()) {
584 PrintF("@ %d ", l.pos()); 536 PrintF("@ %d ", l.pos());
585 Instr instr = instr_at(l.pos()); 537 Instr instr = instr_at(l.pos());
586 if ((instr & ~Imm24Mask) == 0) { 538 if ((instr & ~kImm24Mask) == 0) {
587 PrintF("value\n"); 539 PrintF("value\n");
588 } else { 540 } else {
589 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx 541 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx
590 int cond = instr & CondMask; 542 Condition cond = Instruction::ConditionField(instr);
591 const char* b; 543 const char* b;
592 const char* c; 544 const char* c;
593 if (cond == nv) { 545 if (cond == kSpecialCondition) {
594 b = "blx"; 546 b = "blx";
595 c = ""; 547 c = "";
596 } else { 548 } else {
597 if ((instr & B24) != 0) 549 if ((instr & B24) != 0)
598 b = "bl"; 550 b = "bl";
599 else 551 else
600 b = "b"; 552 b = "b";
601 553
602 switch (cond) { 554 switch (cond) {
603 case eq: c = "eq"; break; 555 case eq: c = "eq"; break;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 } 677 }
726 } 678 }
727 } 679 }
728 } else if ((*instr & kCmpCmnMask) == kCmpCmnPattern) { 680 } else if ((*instr & kCmpCmnMask) == kCmpCmnPattern) {
729 if (fits_shifter(-imm32, rotate_imm, immed_8, NULL)) { 681 if (fits_shifter(-imm32, rotate_imm, immed_8, NULL)) {
730 *instr ^= kCmpCmnFlip; 682 *instr ^= kCmpCmnFlip;
731 return true; 683 return true;
732 } 684 }
733 } else { 685 } else {
734 Instr alu_insn = (*instr & kALUMask); 686 Instr alu_insn = (*instr & kALUMask);
735 if (alu_insn == kAddPattern || 687 if (alu_insn == ADD ||
736 alu_insn == kSubPattern) { 688 alu_insn == SUB) {
737 if (fits_shifter(-imm32, rotate_imm, immed_8, NULL)) { 689 if (fits_shifter(-imm32, rotate_imm, immed_8, NULL)) {
738 *instr ^= kAddSubFlip; 690 *instr ^= kAddSubFlip;
739 return true; 691 return true;
740 } 692 }
741 } else if (alu_insn == kAndPattern || 693 } else if (alu_insn == AND ||
742 alu_insn == kBicPattern) { 694 alu_insn == BIC) {
743 if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) { 695 if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) {
744 *instr ^= kAndBicFlip; 696 *instr ^= kAndBicFlip;
745 return true; 697 return true;
746 } 698 }
747 } 699 }
748 } 700 }
749 } 701 }
750 return false; 702 return false;
751 } 703 }
752 704
(...skipping 23 matching lines...) Expand all
776 uint32_t dummy1, dummy2; 728 uint32_t dummy1, dummy2;
777 return fits_shifter(imm32_, &dummy1, &dummy2, NULL); 729 return fits_shifter(imm32_, &dummy1, &dummy2, NULL);
778 } 730 }
779 731
780 732
781 void Assembler::addrmod1(Instr instr, 733 void Assembler::addrmod1(Instr instr,
782 Register rn, 734 Register rn,
783 Register rd, 735 Register rd,
784 const Operand& x) { 736 const Operand& x) {
785 CheckBuffer(); 737 CheckBuffer();
786 ASSERT((instr & ~(CondMask | OpCodeMask | S)) == 0); 738 ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
787 if (!x.rm_.is_valid()) { 739 if (!x.rm_.is_valid()) {
788 // Immediate. 740 // Immediate.
789 uint32_t rotate_imm; 741 uint32_t rotate_imm;
790 uint32_t immed_8; 742 uint32_t immed_8;
791 if (x.must_use_constant_pool() || 743 if (x.must_use_constant_pool() ||
792 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { 744 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) {
793 // The immediate operand cannot be encoded as a shifter operand, so load 745 // The immediate operand cannot be encoded as a shifter operand, so load
794 // it first to register ip and change the original instruction to use ip. 746 // it first to register ip and change the original instruction to use ip.
795 // However, if the original instruction is a 'mov rd, x' (not setting the 747 // However, if the original instruction is a 'mov rd, x' (not setting the
796 // condition code), then replace it with a 'ldr rd, [pc]'. 748 // condition code), then replace it with a 'ldr rd, [pc]'.
797 CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed 749 CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed
798 Condition cond = static_cast<Condition>(instr & CondMask); 750 Condition cond = Instruction::ConditionField(instr);
799 if ((instr & ~CondMask) == 13*B21) { // mov, S not set 751 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
800 if (x.must_use_constant_pool() || 752 if (x.must_use_constant_pool() ||
801 !Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { 753 !Isolate::Current()->cpu_features()->IsSupported(ARMv7)) {
802 RecordRelocInfo(x.rmode_, x.imm32_); 754 RecordRelocInfo(x.rmode_, x.imm32_);
803 ldr(rd, MemOperand(pc, 0), cond); 755 ldr(rd, MemOperand(pc, 0), cond);
804 } else { 756 } else {
805 // Will probably use movw, will certainly not use constant pool. 757 // Will probably use movw, will certainly not use constant pool.
806 mov(rd, Operand(x.imm32_ & 0xffff), LeaveCC, cond); 758 mov(rd, Operand(x.imm32_ & 0xffff), LeaveCC, cond);
807 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond); 759 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond);
808 } 760 }
809 } else { 761 } else {
(...skipping 21 matching lines...) Expand all
831 } 783 }
832 emit(instr | rn.code()*B16 | rd.code()*B12); 784 emit(instr | rn.code()*B16 | rd.code()*B12);
833 if (rn.is(pc) || x.rm_.is(pc)) { 785 if (rn.is(pc) || x.rm_.is(pc)) {
834 // Block constant pool emission for one instruction after reading pc. 786 // Block constant pool emission for one instruction after reading pc.
835 BlockConstPoolBefore(pc_offset() + kInstrSize); 787 BlockConstPoolBefore(pc_offset() + kInstrSize);
836 } 788 }
837 } 789 }
838 790
839 791
840 void Assembler::addrmod2(Instr instr, Register rd, const MemOperand& x) { 792 void Assembler::addrmod2(Instr instr, Register rd, const MemOperand& x) {
841 ASSERT((instr & ~(CondMask | B | L)) == B26); 793 ASSERT((instr & ~(kCondMask | B | L)) == B26);
842 int am = x.am_; 794 int am = x.am_;
843 if (!x.rm_.is_valid()) { 795 if (!x.rm_.is_valid()) {
844 // Immediate offset. 796 // Immediate offset.
845 int offset_12 = x.offset_; 797 int offset_12 = x.offset_;
846 if (offset_12 < 0) { 798 if (offset_12 < 0) {
847 offset_12 = -offset_12; 799 offset_12 = -offset_12;
848 am ^= U; 800 am ^= U;
849 } 801 }
850 if (!is_uint12(offset_12)) { 802 if (!is_uint12(offset_12)) {
851 // Immediate offset cannot be encoded, load it first to register ip 803 // Immediate offset cannot be encoded, load it first to register ip
852 // rn (and rd in a load) should never be ip, or will be trashed. 804 // rn (and rd in a load) should never be ip, or will be trashed.
853 ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip))); 805 ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
854 mov(ip, Operand(x.offset_), LeaveCC, 806 mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
855 static_cast<Condition>(instr & CondMask));
856 addrmod2(instr, rd, MemOperand(x.rn_, ip, x.am_)); 807 addrmod2(instr, rd, MemOperand(x.rn_, ip, x.am_));
857 return; 808 return;
858 } 809 }
859 ASSERT(offset_12 >= 0); // no masking needed 810 ASSERT(offset_12 >= 0); // no masking needed
860 instr |= offset_12; 811 instr |= offset_12;
861 } else { 812 } else {
862 // Register offset (shift_imm_ and shift_op_ are 0) or scaled 813 // Register offset (shift_imm_ and shift_op_ are 0) or scaled
863 // register offset the constructors make sure than both shift_imm_ 814 // register offset the constructors make sure than both shift_imm_
864 // and shift_op_ are initialized. 815 // and shift_op_ are initialized.
865 ASSERT(!x.rm_.is(pc)); 816 ASSERT(!x.rm_.is(pc));
866 instr |= B25 | x.shift_imm_*B7 | x.shift_op_ | x.rm_.code(); 817 instr |= B25 | x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
867 } 818 }
868 ASSERT((am & (P|W)) == P || !x.rn_.is(pc)); // no pc base with writeback 819 ASSERT((am & (P|W)) == P || !x.rn_.is(pc)); // no pc base with writeback
869 emit(instr | am | x.rn_.code()*B16 | rd.code()*B12); 820 emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
870 } 821 }
871 822
872 823
873 void Assembler::addrmod3(Instr instr, Register rd, const MemOperand& x) { 824 void Assembler::addrmod3(Instr instr, Register rd, const MemOperand& x) {
874 ASSERT((instr & ~(CondMask | L | S6 | H)) == (B4 | B7)); 825 ASSERT((instr & ~(kCondMask | L | S6 | H)) == (B4 | B7));
875 ASSERT(x.rn_.is_valid()); 826 ASSERT(x.rn_.is_valid());
876 int am = x.am_; 827 int am = x.am_;
877 if (!x.rm_.is_valid()) { 828 if (!x.rm_.is_valid()) {
878 // Immediate offset. 829 // Immediate offset.
879 int offset_8 = x.offset_; 830 int offset_8 = x.offset_;
880 if (offset_8 < 0) { 831 if (offset_8 < 0) {
881 offset_8 = -offset_8; 832 offset_8 = -offset_8;
882 am ^= U; 833 am ^= U;
883 } 834 }
884 if (!is_uint8(offset_8)) { 835 if (!is_uint8(offset_8)) {
885 // Immediate offset cannot be encoded, load it first to register ip 836 // Immediate offset cannot be encoded, load it first to register ip
886 // rn (and rd in a load) should never be ip, or will be trashed. 837 // rn (and rd in a load) should never be ip, or will be trashed.
887 ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip))); 838 ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
888 mov(ip, Operand(x.offset_), LeaveCC, 839 mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
889 static_cast<Condition>(instr & CondMask));
890 addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_)); 840 addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
891 return; 841 return;
892 } 842 }
893 ASSERT(offset_8 >= 0); // no masking needed 843 ASSERT(offset_8 >= 0); // no masking needed
894 instr |= B | (offset_8 >> 4)*B8 | (offset_8 & 0xf); 844 instr |= B | (offset_8 >> 4)*B8 | (offset_8 & 0xf);
895 } else if (x.shift_imm_ != 0) { 845 } else if (x.shift_imm_ != 0) {
896 // Scaled register offset not supported, load index first 846 // Scaled register offset not supported, load index first
897 // rn (and rd in a load) should never be ip, or will be trashed. 847 // rn (and rd in a load) should never be ip, or will be trashed.
898 ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip))); 848 ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
899 mov(ip, Operand(x.rm_, x.shift_op_, x.shift_imm_), LeaveCC, 849 mov(ip, Operand(x.rm_, x.shift_op_, x.shift_imm_), LeaveCC,
900 static_cast<Condition>(instr & CondMask)); 850 Instruction::ConditionField(instr));
901 addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_)); 851 addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
902 return; 852 return;
903 } else { 853 } else {
904 // Register offset. 854 // Register offset.
905 ASSERT((am & (P|W)) == P || !x.rm_.is(pc)); // no pc index with writeback 855 ASSERT((am & (P|W)) == P || !x.rm_.is(pc)); // no pc index with writeback
906 instr |= x.rm_.code(); 856 instr |= x.rm_.code();
907 } 857 }
908 ASSERT((am & (P|W)) == P || !x.rn_.is(pc)); // no pc base with writeback 858 ASSERT((am & (P|W)) == P || !x.rn_.is(pc)); // no pc base with writeback
909 emit(instr | am | x.rn_.code()*B16 | rd.code()*B12); 859 emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
910 } 860 }
911 861
912 862
913 void Assembler::addrmod4(Instr instr, Register rn, RegList rl) { 863 void Assembler::addrmod4(Instr instr, Register rn, RegList rl) {
914 ASSERT((instr & ~(CondMask | P | U | W | L)) == B27); 864 ASSERT((instr & ~(kCondMask | P | U | W | L)) == B27);
915 ASSERT(rl != 0); 865 ASSERT(rl != 0);
916 ASSERT(!rn.is(pc)); 866 ASSERT(!rn.is(pc));
917 emit(instr | rn.code()*B16 | rl); 867 emit(instr | rn.code()*B16 | rl);
918 } 868 }
919 869
920 870
921 void Assembler::addrmod5(Instr instr, CRegister crd, const MemOperand& x) { 871 void Assembler::addrmod5(Instr instr, CRegister crd, const MemOperand& x) {
922 // Unindexed addressing is not encoded by this function. 872 // Unindexed addressing is not encoded by this function.
923 ASSERT_EQ((B27 | B26), 873 ASSERT_EQ((B27 | B26),
924 (instr & ~(CondMask | CoprocessorMask | P | U | N | W | L))); 874 (instr & ~(kCondMask | kCoprocessorMask | P | U | N | W | L)));
925 ASSERT(x.rn_.is_valid() && !x.rm_.is_valid()); 875 ASSERT(x.rn_.is_valid() && !x.rm_.is_valid());
926 int am = x.am_; 876 int am = x.am_;
927 int offset_8 = x.offset_; 877 int offset_8 = x.offset_;
928 ASSERT((offset_8 & 3) == 0); // offset must be an aligned word offset 878 ASSERT((offset_8 & 3) == 0); // offset must be an aligned word offset
929 offset_8 >>= 2; 879 offset_8 >>= 2;
930 if (offset_8 < 0) { 880 if (offset_8 < 0) {
931 offset_8 = -offset_8; 881 offset_8 = -offset_8;
932 am ^= U; 882 am ^= U;
933 } 883 }
934 ASSERT(is_uint8(offset_8)); // unsigned word offset must fit in a byte 884 ASSERT(is_uint8(offset_8)); // unsigned word offset must fit in a byte
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 927 instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
978 } 928 }
979 } 929 }
980 930
981 931
982 // Branch instructions. 932 // Branch instructions.
983 void Assembler::b(int branch_offset, Condition cond) { 933 void Assembler::b(int branch_offset, Condition cond) {
984 ASSERT((branch_offset & 3) == 0); 934 ASSERT((branch_offset & 3) == 0);
985 int imm24 = branch_offset >> 2; 935 int imm24 = branch_offset >> 2;
986 ASSERT(is_int24(imm24)); 936 ASSERT(is_int24(imm24));
987 emit(cond | B27 | B25 | (imm24 & Imm24Mask)); 937 emit(cond | B27 | B25 | (imm24 & kImm24Mask));
988 938
989 if (cond == al) { 939 if (cond == al) {
990 // Dead code is a good location to emit the constant pool. 940 // Dead code is a good location to emit the constant pool.
991 CheckConstPool(false, false); 941 CheckConstPool(false, false);
992 } 942 }
993 } 943 }
994 944
995 945
996 void Assembler::bl(int branch_offset, Condition cond) { 946 void Assembler::bl(int branch_offset, Condition cond) {
997 positions_recorder()->WriteRecordedPositions(); 947 positions_recorder()->WriteRecordedPositions();
998 ASSERT((branch_offset & 3) == 0); 948 ASSERT((branch_offset & 3) == 0);
999 int imm24 = branch_offset >> 2; 949 int imm24 = branch_offset >> 2;
1000 ASSERT(is_int24(imm24)); 950 ASSERT(is_int24(imm24));
1001 emit(cond | B27 | B25 | B24 | (imm24 & Imm24Mask)); 951 emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask));
1002 } 952 }
1003 953
1004 954
1005 void Assembler::blx(int branch_offset) { // v5 and above 955 void Assembler::blx(int branch_offset) { // v5 and above
1006 positions_recorder()->WriteRecordedPositions(); 956 positions_recorder()->WriteRecordedPositions();
1007 ASSERT((branch_offset & 1) == 0); 957 ASSERT((branch_offset & 1) == 0);
1008 int h = ((branch_offset & 2) >> 1)*B24; 958 int h = ((branch_offset & 2) >> 1)*B24;
1009 int imm24 = branch_offset >> 2; 959 int imm24 = branch_offset >> 2;
1010 ASSERT(is_int24(imm24)); 960 ASSERT(is_int24(imm24));
1011 emit(nv | B27 | B25 | h | (imm24 & Imm24Mask)); 961 emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask));
1012 } 962 }
1013 963
1014 964
1015 void Assembler::blx(Register target, Condition cond) { // v5 and above 965 void Assembler::blx(Register target, Condition cond) { // v5 and above
1016 positions_recorder()->WriteRecordedPositions(); 966 positions_recorder()->WriteRecordedPositions();
1017 ASSERT(!target.is(pc)); 967 ASSERT(!target.is(pc));
1018 emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | 3*B4 | target.code()); 968 emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code());
1019 } 969 }
1020 970
1021 971
1022 void Assembler::bx(Register target, Condition cond) { // v5 and above, plus v4t 972 void Assembler::bx(Register target, Condition cond) { // v5 and above, plus v4t
1023 positions_recorder()->WriteRecordedPositions(); 973 positions_recorder()->WriteRecordedPositions();
1024 ASSERT(!target.is(pc)); // use of pc is actually allowed, but discouraged 974 ASSERT(!target.is(pc)); // use of pc is actually allowed, but discouraged
1025 emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | B4 | target.code()); 975 emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code());
1026 } 976 }
1027 977
1028 978
1029 // Data-processing instructions. 979 // Data-processing instructions.
1030 980
1031 void Assembler::and_(Register dst, Register src1, const Operand& src2, 981 void Assembler::and_(Register dst, Register src1, const Operand& src2,
1032 SBit s, Condition cond) { 982 SBit s, Condition cond) {
1033 addrmod1(cond | 0*B21 | s, src1, dst, src2); 983 addrmod1(cond | AND | s, src1, dst, src2);
1034 } 984 }
1035 985
1036 986
1037 void Assembler::eor(Register dst, Register src1, const Operand& src2, 987 void Assembler::eor(Register dst, Register src1, const Operand& src2,
1038 SBit s, Condition cond) { 988 SBit s, Condition cond) {
1039 addrmod1(cond | 1*B21 | s, src1, dst, src2); 989 addrmod1(cond | EOR | s, src1, dst, src2);
1040 } 990 }
1041 991
1042 992
1043 void Assembler::sub(Register dst, Register src1, const Operand& src2, 993 void Assembler::sub(Register dst, Register src1, const Operand& src2,
1044 SBit s, Condition cond) { 994 SBit s, Condition cond) {
1045 addrmod1(cond | 2*B21 | s, src1, dst, src2); 995 addrmod1(cond | SUB | s, src1, dst, src2);
1046 } 996 }
1047 997
1048 998
1049 void Assembler::rsb(Register dst, Register src1, const Operand& src2, 999 void Assembler::rsb(Register dst, Register src1, const Operand& src2,
1050 SBit s, Condition cond) { 1000 SBit s, Condition cond) {
1051 addrmod1(cond | 3*B21 | s, src1, dst, src2); 1001 addrmod1(cond | RSB | s, src1, dst, src2);
1052 } 1002 }
1053 1003
1054 1004
1055 void Assembler::add(Register dst, Register src1, const Operand& src2, 1005 void Assembler::add(Register dst, Register src1, const Operand& src2,
1056 SBit s, Condition cond) { 1006 SBit s, Condition cond) {
1057 addrmod1(cond | 4*B21 | s, src1, dst, src2); 1007 addrmod1(cond | ADD | s, src1, dst, src2);
1058 1008
1059 // Eliminate pattern: push(r), pop() 1009 // Eliminate pattern: push(r), pop()
1060 // str(src, MemOperand(sp, 4, NegPreIndex), al); 1010 // str(src, MemOperand(sp, 4, NegPreIndex), al);
1061 // add(sp, sp, Operand(kPointerSize)); 1011 // add(sp, sp, Operand(kPointerSize));
1062 // Both instructions can be eliminated. 1012 // Both instructions can be eliminated.
1063 if (can_peephole_optimize(2) && 1013 if (can_peephole_optimize(2) &&
1064 // Pattern. 1014 // Pattern.
1065 instr_at(pc_ - 1 * kInstrSize) == kPopInstruction && 1015 instr_at(pc_ - 1 * kInstrSize) == kPopInstruction &&
1066 (instr_at(pc_ - 2 * kInstrSize) & ~RdMask) == kPushRegPattern) { 1016 (instr_at(pc_ - 2 * kInstrSize) & ~kRdMask) == kPushRegPattern) {
1067 pc_ -= 2 * kInstrSize; 1017 pc_ -= 2 * kInstrSize;
1068 if (FLAG_print_peephole_optimization) { 1018 if (FLAG_print_peephole_optimization) {
1069 PrintF("%x push(reg)/pop() eliminated\n", pc_offset()); 1019 PrintF("%x push(reg)/pop() eliminated\n", pc_offset());
1070 } 1020 }
1071 } 1021 }
1072 } 1022 }
1073 1023
1074 1024
1075 void Assembler::adc(Register dst, Register src1, const Operand& src2, 1025 void Assembler::adc(Register dst, Register src1, const Operand& src2,
1076 SBit s, Condition cond) { 1026 SBit s, Condition cond) {
1077 addrmod1(cond | 5*B21 | s, src1, dst, src2); 1027 addrmod1(cond | ADC | s, src1, dst, src2);
1078 } 1028 }
1079 1029
1080 1030
1081 void Assembler::sbc(Register dst, Register src1, const Operand& src2, 1031 void Assembler::sbc(Register dst, Register src1, const Operand& src2,
1082 SBit s, Condition cond) { 1032 SBit s, Condition cond) {
1083 addrmod1(cond | 6*B21 | s, src1, dst, src2); 1033 addrmod1(cond | SBC | s, src1, dst, src2);
1084 } 1034 }
1085 1035
1086 1036
1087 void Assembler::rsc(Register dst, Register src1, const Operand& src2, 1037 void Assembler::rsc(Register dst, Register src1, const Operand& src2,
1088 SBit s, Condition cond) { 1038 SBit s, Condition cond) {
1089 addrmod1(cond | 7*B21 | s, src1, dst, src2); 1039 addrmod1(cond | RSC | s, src1, dst, src2);
1090 } 1040 }
1091 1041
1092 1042
1093 void Assembler::tst(Register src1, const Operand& src2, Condition cond) { 1043 void Assembler::tst(Register src1, const Operand& src2, Condition cond) {
1094 addrmod1(cond | 8*B21 | S, src1, r0, src2); 1044 addrmod1(cond | TST | S, src1, r0, src2);
1095 } 1045 }
1096 1046
1097 1047
1098 void Assembler::teq(Register src1, const Operand& src2, Condition cond) { 1048 void Assembler::teq(Register src1, const Operand& src2, Condition cond) {
1099 addrmod1(cond | 9*B21 | S, src1, r0, src2); 1049 addrmod1(cond | TEQ | S, src1, r0, src2);
1100 } 1050 }
1101 1051
1102 1052
1103 void Assembler::cmp(Register src1, const Operand& src2, Condition cond) { 1053 void Assembler::cmp(Register src1, const Operand& src2, Condition cond) {
1104 addrmod1(cond | 10*B21 | S, src1, r0, src2); 1054 addrmod1(cond | CMP | S, src1, r0, src2);
1105 } 1055 }
1106 1056
1107 1057
1108 void Assembler::cmn(Register src1, const Operand& src2, Condition cond) { 1058 void Assembler::cmn(Register src1, const Operand& src2, Condition cond) {
1109 addrmod1(cond | 11*B21 | S, src1, r0, src2); 1059 addrmod1(cond | CMN | S, src1, r0, src2);
1110 } 1060 }
1111 1061
1112 1062
1113 void Assembler::orr(Register dst, Register src1, const Operand& src2, 1063 void Assembler::orr(Register dst, Register src1, const Operand& src2,
1114 SBit s, Condition cond) { 1064 SBit s, Condition cond) {
1115 addrmod1(cond | 12*B21 | s, src1, dst, src2); 1065 addrmod1(cond | ORR | s, src1, dst, src2);
1116 } 1066 }
1117 1067
1118 1068
1119 void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) { 1069 void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
1120 if (dst.is(pc)) { 1070 if (dst.is(pc)) {
1121 positions_recorder()->WriteRecordedPositions(); 1071 positions_recorder()->WriteRecordedPositions();
1122 } 1072 }
1123 // Don't allow nop instructions in the form mov rn, rn to be generated using 1073 // Don't allow nop instructions in the form mov rn, rn to be generated using
1124 // the mov instruction. They must be generated using nop(int/NopMarkerTypes) 1074 // the mov instruction. They must be generated using nop(int/NopMarkerTypes)
1125 // or MarkCode(int/NopMarkerTypes) pseudo instructions. 1075 // or MarkCode(int/NopMarkerTypes) pseudo instructions.
1126 ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al)); 1076 ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
1127 addrmod1(cond | 13*B21 | s, r0, dst, src); 1077 addrmod1(cond | MOV | s, r0, dst, src);
1128 } 1078 }
1129 1079
1130 1080
1131 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) { 1081 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) {
1132 ASSERT(immediate < 0x10000); 1082 ASSERT(immediate < 0x10000);
1133 mov(reg, Operand(immediate), LeaveCC, cond); 1083 mov(reg, Operand(immediate), LeaveCC, cond);
1134 } 1084 }
1135 1085
1136 1086
1137 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) { 1087 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) {
1138 emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate)); 1088 emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
1139 } 1089 }
1140 1090
1141 1091
1142 void Assembler::bic(Register dst, Register src1, const Operand& src2, 1092 void Assembler::bic(Register dst, Register src1, const Operand& src2,
1143 SBit s, Condition cond) { 1093 SBit s, Condition cond) {
1144 addrmod1(cond | 14*B21 | s, src1, dst, src2); 1094 addrmod1(cond | BIC | s, src1, dst, src2);
1145 } 1095 }
1146 1096
1147 1097
1148 void Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) { 1098 void Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) {
1149 addrmod1(cond | 15*B21 | s, r0, dst, src); 1099 addrmod1(cond | MVN | s, r0, dst, src);
1150 } 1100 }
1151 1101
1152 1102
1153 // Multiply instructions. 1103 // Multiply instructions.
1154 void Assembler::mla(Register dst, Register src1, Register src2, Register srcA, 1104 void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
1155 SBit s, Condition cond) { 1105 SBit s, Condition cond) {
1156 ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc)); 1106 ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
1157 emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 | 1107 emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 |
1158 src2.code()*B8 | B7 | B4 | src1.code()); 1108 src2.code()*B8 | B7 | B4 | src1.code());
1159 } 1109 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1217 emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 | 1167 emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 |
1218 src2.code()*B8 | B7 | B4 | src1.code()); 1168 src2.code()*B8 | B7 | B4 | src1.code());
1219 } 1169 }
1220 1170
1221 1171
1222 // Miscellaneous arithmetic instructions. 1172 // Miscellaneous arithmetic instructions.
1223 void Assembler::clz(Register dst, Register src, Condition cond) { 1173 void Assembler::clz(Register dst, Register src, Condition cond) {
1224 // v5 and above. 1174 // v5 and above.
1225 ASSERT(!dst.is(pc) && !src.is(pc)); 1175 ASSERT(!dst.is(pc) && !src.is(pc));
1226 emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 | 1176 emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 |
1227 15*B8 | B4 | src.code()); 1177 15*B8 | CLZ | src.code());
1228 } 1178 }
1229 1179
1230 1180
1231 // Saturating instructions. 1181 // Saturating instructions.
1232 1182
1233 // Unsigned saturate. 1183 // Unsigned saturate.
1234 void Assembler::usat(Register dst, 1184 void Assembler::usat(Register dst,
1235 int satpos, 1185 int satpos,
1236 const Operand& src, 1186 const Operand& src,
1237 Condition cond) { 1187 Condition cond) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 // str(ry, MemOperand(sp, 4, NegPreIndex), al) 1321 // str(ry, MemOperand(sp, 4, NegPreIndex), al)
1372 // ldr(rx, MemOperand(sp, 4, PostIndex), al) 1322 // ldr(rx, MemOperand(sp, 4, PostIndex), al)
1373 // Both instructions can be eliminated if ry = rx. 1323 // Both instructions can be eliminated if ry = rx.
1374 // If ry != rx, a register copy from ry to rx is inserted 1324 // If ry != rx, a register copy from ry to rx is inserted
1375 // after eliminating the push and the pop instructions. 1325 // after eliminating the push and the pop instructions.
1376 if (can_peephole_optimize(2)) { 1326 if (can_peephole_optimize(2)) {
1377 Instr push_instr = instr_at(pc_ - 2 * kInstrSize); 1327 Instr push_instr = instr_at(pc_ - 2 * kInstrSize);
1378 Instr pop_instr = instr_at(pc_ - 1 * kInstrSize); 1328 Instr pop_instr = instr_at(pc_ - 1 * kInstrSize);
1379 1329
1380 if (IsPush(push_instr) && IsPop(pop_instr)) { 1330 if (IsPush(push_instr) && IsPop(pop_instr)) {
1381 if ((pop_instr & kRdMask) != (push_instr & kRdMask)) { 1331 if (Instruction::RdValue(pop_instr) != Instruction::RdValue(push_instr)) {
1382 // For consecutive push and pop on different registers, 1332 // For consecutive push and pop on different registers,
1383 // we delete both the push & pop and insert a register move. 1333 // we delete both the push & pop and insert a register move.
1384 // push ry, pop rx --> mov rx, ry 1334 // push ry, pop rx --> mov rx, ry
1385 Register reg_pushed, reg_popped; 1335 Register reg_pushed, reg_popped;
1386 reg_pushed = GetRd(push_instr); 1336 reg_pushed = GetRd(push_instr);
1387 reg_popped = GetRd(pop_instr); 1337 reg_popped = GetRd(pop_instr);
1388 pc_ -= 2 * kInstrSize; 1338 pc_ -= 2 * kInstrSize;
1389 // Insert a mov instruction, which is better than a pair of push & pop 1339 // Insert a mov instruction, which is better than a pair of push & pop
1390 mov(reg_popped, reg_pushed); 1340 mov(reg_popped, reg_pushed);
1391 if (FLAG_print_peephole_optimization) { 1341 if (FLAG_print_peephole_optimization) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 } 1402 }
1453 1403
1454 if (can_peephole_optimize(3)) { 1404 if (can_peephole_optimize(3)) {
1455 Instr mem_write_instr = instr_at(pc_ - 3 * kInstrSize); 1405 Instr mem_write_instr = instr_at(pc_ - 3 * kInstrSize);
1456 Instr ldr_instr = instr_at(pc_ - 2 * kInstrSize); 1406 Instr ldr_instr = instr_at(pc_ - 2 * kInstrSize);
1457 Instr mem_read_instr = instr_at(pc_ - 1 * kInstrSize); 1407 Instr mem_read_instr = instr_at(pc_ - 1 * kInstrSize);
1458 if (IsPush(mem_write_instr) && 1408 if (IsPush(mem_write_instr) &&
1459 IsPop(mem_read_instr)) { 1409 IsPop(mem_read_instr)) {
1460 if ((IsLdrRegFpOffset(ldr_instr) || 1410 if ((IsLdrRegFpOffset(ldr_instr) ||
1461 IsLdrRegFpNegOffset(ldr_instr))) { 1411 IsLdrRegFpNegOffset(ldr_instr))) {
1462 if ((mem_write_instr & kRdMask) == 1412 if (Instruction::RdValue(mem_write_instr) ==
1463 (mem_read_instr & kRdMask)) { 1413 Instruction::RdValue(mem_read_instr)) {
1464 // Pattern: push & pop from/to same register, 1414 // Pattern: push & pop from/to same register,
1465 // with a fp+offset ldr in between 1415 // with a fp+offset ldr in between
1466 // 1416 //
1467 // The following: 1417 // The following:
1468 // str rx, [sp, #-4]! 1418 // str rx, [sp, #-4]!
1469 // ldr rz, [fp, #-24] 1419 // ldr rz, [fp, #-24]
1470 // ldr rx, [sp], #+4 1420 // ldr rx, [sp], #+4
1471 // 1421 //
1472 // Becomes: 1422 // Becomes:
1473 // if(rx == rz) 1423 // if(rx == rz)
1474 // delete all 1424 // delete all
1475 // else 1425 // else
1476 // ldr rz, [fp, #-24] 1426 // ldr rz, [fp, #-24]
1477 1427
1478 if ((mem_write_instr & kRdMask) == (ldr_instr & kRdMask)) { 1428 if (Instruction::RdValue(mem_write_instr) ==
1429 Instruction::RdValue(ldr_instr)) {
1479 pc_ -= 3 * kInstrSize; 1430 pc_ -= 3 * kInstrSize;
1480 } else { 1431 } else {
1481 pc_ -= 3 * kInstrSize; 1432 pc_ -= 3 * kInstrSize;
1482 // Reinsert back the ldr rz. 1433 // Reinsert back the ldr rz.
1483 emit(ldr_instr); 1434 emit(ldr_instr);
1484 } 1435 }
1485 if (FLAG_print_peephole_optimization) { 1436 if (FLAG_print_peephole_optimization) {
1486 PrintF("%x push/pop -dead ldr fp+offset in middle\n", pc_offset()); 1437 PrintF("%x push/pop -dead ldr fp+offset in middle\n", pc_offset());
1487 } 1438 }
1488 } else { 1439 } else {
1489 // Pattern: push & pop from/to different registers 1440 // Pattern: push & pop from/to different registers
1490 // with a fp+offset ldr in between 1441 // with a fp+offset ldr in between
1491 // 1442 //
1492 // The following: 1443 // The following:
1493 // str rx, [sp, #-4]! 1444 // str rx, [sp, #-4]!
1494 // ldr rz, [fp, #-24] 1445 // ldr rz, [fp, #-24]
1495 // ldr ry, [sp], #+4 1446 // ldr ry, [sp], #+4
1496 // 1447 //
1497 // Becomes: 1448 // Becomes:
1498 // if(ry == rz) 1449 // if(ry == rz)
1499 // mov ry, rx; 1450 // mov ry, rx;
1500 // else if(rx != rz) 1451 // else if(rx != rz)
1501 // ldr rz, [fp, #-24] 1452 // ldr rz, [fp, #-24]
1502 // mov ry, rx 1453 // mov ry, rx
1503 // else if((ry != rz) || (rx == rz)) becomes: 1454 // else if((ry != rz) || (rx == rz)) becomes:
1504 // mov ry, rx 1455 // mov ry, rx
1505 // ldr rz, [fp, #-24] 1456 // ldr rz, [fp, #-24]
1506 1457
1507 Register reg_pushed, reg_popped; 1458 Register reg_pushed, reg_popped;
1508 if ((mem_read_instr & kRdMask) == (ldr_instr & kRdMask)) { 1459 if (Instruction::RdValue(mem_read_instr) ==
1460 Instruction::RdValue(ldr_instr)) {
1509 reg_pushed = GetRd(mem_write_instr); 1461 reg_pushed = GetRd(mem_write_instr);
1510 reg_popped = GetRd(mem_read_instr); 1462 reg_popped = GetRd(mem_read_instr);
1511 pc_ -= 3 * kInstrSize; 1463 pc_ -= 3 * kInstrSize;
1512 mov(reg_popped, reg_pushed); 1464 mov(reg_popped, reg_pushed);
1513 } else if ((mem_write_instr & kRdMask) 1465 } else if (Instruction::RdValue(mem_write_instr) !=
1514 != (ldr_instr & kRdMask)) { 1466 Instruction::RdValue(ldr_instr)) {
1515 reg_pushed = GetRd(mem_write_instr); 1467 reg_pushed = GetRd(mem_write_instr);
1516 reg_popped = GetRd(mem_read_instr); 1468 reg_popped = GetRd(mem_read_instr);
1517 pc_ -= 3 * kInstrSize; 1469 pc_ -= 3 * kInstrSize;
1518 emit(ldr_instr); 1470 emit(ldr_instr);
1519 mov(reg_popped, reg_pushed); 1471 mov(reg_popped, reg_pushed);
1520 } else if (((mem_read_instr & kRdMask) 1472 } else if ((Instruction::RdValue(mem_read_instr) !=
1521 != (ldr_instr & kRdMask)) || 1473 Instruction::RdValue(ldr_instr)) ||
1522 ((mem_write_instr & kRdMask) 1474 (Instruction::RdValue(mem_write_instr) ==
1523 == (ldr_instr & kRdMask)) ) { 1475 Instruction::RdValue(ldr_instr))) {
1524 reg_pushed = GetRd(mem_write_instr); 1476 reg_pushed = GetRd(mem_write_instr);
1525 reg_popped = GetRd(mem_read_instr); 1477 reg_popped = GetRd(mem_read_instr);
1526 pc_ -= 3 * kInstrSize; 1478 pc_ -= 3 * kInstrSize;
1527 mov(reg_popped, reg_pushed); 1479 mov(reg_popped, reg_pushed);
1528 emit(ldr_instr); 1480 emit(ldr_instr);
1529 } 1481 }
1530 if (FLAG_print_peephole_optimization) { 1482 if (FLAG_print_peephole_optimization) {
1531 PrintF("%x push/pop (ldr fp+off in middle)\n", pc_offset()); 1483 PrintF("%x push/pop (ldr fp+off in middle)\n", pc_offset());
1532 } 1484 }
1533 } 1485 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1635 Condition cond) { 1587 Condition cond) {
1636 addrmod4(cond | B27 | am, base, src); 1588 addrmod4(cond | B27 | am, base, src);
1637 } 1589 }
1638 1590
1639 1591
1640 // Exception-generating instructions and debugging support. 1592 // Exception-generating instructions and debugging support.
1641 // Stops with a non-negative code less than kNumOfWatchedStops support 1593 // Stops with a non-negative code less than kNumOfWatchedStops support
1642 // enabling/disabling and a counter feature. See simulator-arm.h . 1594 // enabling/disabling and a counter feature. See simulator-arm.h .
1643 void Assembler::stop(const char* msg, Condition cond, int32_t code) { 1595 void Assembler::stop(const char* msg, Condition cond, int32_t code) {
1644 #ifndef __arm__ 1596 #ifndef __arm__
1645 // See constants-arm.h SoftwareInterruptCodes. Unluckily the Assembler and
1646 // Simulator do not share constants declaration.
1647 ASSERT(code >= kDefaultStopCode); 1597 ASSERT(code >= kDefaultStopCode);
1648 static const uint32_t kStopInterruptCode = 1 << 23;
1649 static const uint32_t kMaxStopCode = kStopInterruptCode - 1;
1650 // The Simulator will handle the stop instruction and get the message address. 1598 // The Simulator will handle the stop instruction and get the message address.
1651 // It expects to find the address just after the svc instruction. 1599 // It expects to find the address just after the svc instruction.
1652 BlockConstPoolFor(2); 1600 BlockConstPoolFor(2);
1653 if (code >= 0) { 1601 if (code >= 0) {
1654 svc(kStopInterruptCode + code, cond); 1602 svc(kStopCode + code, cond);
1655 } else { 1603 } else {
1656 svc(kStopInterruptCode + kMaxStopCode, cond); 1604 svc(kStopCode + kMaxStopCode, cond);
1657 } 1605 }
1658 emit(reinterpret_cast<Instr>(msg)); 1606 emit(reinterpret_cast<Instr>(msg));
1659 #else // def __arm__ 1607 #else // def __arm__
1660 #ifdef CAN_USE_ARMV5_INSTRUCTIONS 1608 #ifdef CAN_USE_ARMV5_INSTRUCTIONS
1661 ASSERT(cond == al); 1609 if (cond != al) {
1662 bkpt(0); 1610 Label skip;
1611 b(&skip, NegateCondition(cond));
1612 bkpt(0);
1613 bind(&skip);
1614 } else {
1615 bkpt(0);
1616 }
1663 #else // ndef CAN_USE_ARMV5_INSTRUCTIONS 1617 #else // ndef CAN_USE_ARMV5_INSTRUCTIONS
1664 svc(0x9f0001, cond); 1618 svc(0x9f0001, cond);
1665 #endif // ndef CAN_USE_ARMV5_INSTRUCTIONS 1619 #endif // ndef CAN_USE_ARMV5_INSTRUCTIONS
1666 #endif // def __arm__ 1620 #endif // def __arm__
1667 } 1621 }
1668 1622
1669 1623
1670 void Assembler::bkpt(uint32_t imm16) { // v5 and above 1624 void Assembler::bkpt(uint32_t imm16) { // v5 and above
1671 ASSERT(is_uint16(imm16)); 1625 ASSERT(is_uint16(imm16));
1672 emit(al | B24 | B21 | (imm16 >> 4)*B8 | 7*B4 | (imm16 & 0xf)); 1626 emit(al | B24 | B21 | (imm16 >> 4)*B8 | BKPT | (imm16 & 0xf));
1673 } 1627 }
1674 1628
1675 1629
1676 void Assembler::svc(uint32_t imm24, Condition cond) { 1630 void Assembler::svc(uint32_t imm24, Condition cond) {
1677 ASSERT(is_uint24(imm24)); 1631 ASSERT(is_uint24(imm24));
1678 emit(cond | 15*B24 | imm24); 1632 emit(cond | 15*B24 | imm24);
1679 } 1633 }
1680 1634
1681 1635
1682 // Coprocessor instructions. 1636 // Coprocessor instructions.
1683 void Assembler::cdp(Coprocessor coproc, 1637 void Assembler::cdp(Coprocessor coproc,
1684 int opcode_1, 1638 int opcode_1,
1685 CRegister crd, 1639 CRegister crd,
1686 CRegister crn, 1640 CRegister crn,
1687 CRegister crm, 1641 CRegister crm,
1688 int opcode_2, 1642 int opcode_2,
1689 Condition cond) { 1643 Condition cond) {
1690 ASSERT(is_uint4(opcode_1) && is_uint3(opcode_2)); 1644 ASSERT(is_uint4(opcode_1) && is_uint3(opcode_2));
1691 emit(cond | B27 | B26 | B25 | (opcode_1 & 15)*B20 | crn.code()*B16 | 1645 emit(cond | B27 | B26 | B25 | (opcode_1 & 15)*B20 | crn.code()*B16 |
1692 crd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | crm.code()); 1646 crd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | crm.code());
1693 } 1647 }
1694 1648
1695 1649
1696 void Assembler::cdp2(Coprocessor coproc, 1650 void Assembler::cdp2(Coprocessor coproc,
1697 int opcode_1, 1651 int opcode_1,
1698 CRegister crd, 1652 CRegister crd,
1699 CRegister crn, 1653 CRegister crn,
1700 CRegister crm, 1654 CRegister crm,
1701 int opcode_2) { // v5 and above 1655 int opcode_2) { // v5 and above
1702 cdp(coproc, opcode_1, crd, crn, crm, opcode_2, static_cast<Condition>(nv)); 1656 cdp(coproc, opcode_1, crd, crn, crm, opcode_2, kSpecialCondition);
1703 } 1657 }
1704 1658
1705 1659
1706 void Assembler::mcr(Coprocessor coproc, 1660 void Assembler::mcr(Coprocessor coproc,
1707 int opcode_1, 1661 int opcode_1,
1708 Register rd, 1662 Register rd,
1709 CRegister crn, 1663 CRegister crn,
1710 CRegister crm, 1664 CRegister crm,
1711 int opcode_2, 1665 int opcode_2,
1712 Condition cond) { 1666 Condition cond) {
1713 ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2)); 1667 ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2));
1714 emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | crn.code()*B16 | 1668 emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | crn.code()*B16 |
1715 rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code()); 1669 rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
1716 } 1670 }
1717 1671
1718 1672
1719 void Assembler::mcr2(Coprocessor coproc, 1673 void Assembler::mcr2(Coprocessor coproc,
1720 int opcode_1, 1674 int opcode_1,
1721 Register rd, 1675 Register rd,
1722 CRegister crn, 1676 CRegister crn,
1723 CRegister crm, 1677 CRegister crm,
1724 int opcode_2) { // v5 and above 1678 int opcode_2) { // v5 and above
1725 mcr(coproc, opcode_1, rd, crn, crm, opcode_2, static_cast<Condition>(nv)); 1679 mcr(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition);
1726 } 1680 }
1727 1681
1728 1682
1729 void Assembler::mrc(Coprocessor coproc, 1683 void Assembler::mrc(Coprocessor coproc,
1730 int opcode_1, 1684 int opcode_1,
1731 Register rd, 1685 Register rd,
1732 CRegister crn, 1686 CRegister crn,
1733 CRegister crm, 1687 CRegister crm,
1734 int opcode_2, 1688 int opcode_2,
1735 Condition cond) { 1689 Condition cond) {
1736 ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2)); 1690 ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2));
1737 emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | L | crn.code()*B16 | 1691 emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | L | crn.code()*B16 |
1738 rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code()); 1692 rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
1739 } 1693 }
1740 1694
1741 1695
1742 void Assembler::mrc2(Coprocessor coproc, 1696 void Assembler::mrc2(Coprocessor coproc,
1743 int opcode_1, 1697 int opcode_1,
1744 Register rd, 1698 Register rd,
1745 CRegister crn, 1699 CRegister crn,
1746 CRegister crm, 1700 CRegister crm,
1747 int opcode_2) { // v5 and above 1701 int opcode_2) { // v5 and above
1748 mrc(coproc, opcode_1, rd, crn, crm, opcode_2, static_cast<Condition>(nv)); 1702 mrc(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition);
1749 } 1703 }
1750 1704
1751 1705
1752 void Assembler::ldc(Coprocessor coproc, 1706 void Assembler::ldc(Coprocessor coproc,
1753 CRegister crd, 1707 CRegister crd,
1754 const MemOperand& src, 1708 const MemOperand& src,
1755 LFlag l, 1709 LFlag l,
1756 Condition cond) { 1710 Condition cond) {
1757 addrmod5(cond | B27 | B26 | l | L | coproc*B8, crd, src); 1711 addrmod5(cond | B27 | B26 | l | L | coproc*B8, crd, src);
1758 } 1712 }
1759 1713
1760 1714
1761 void Assembler::ldc(Coprocessor coproc, 1715 void Assembler::ldc(Coprocessor coproc,
1762 CRegister crd, 1716 CRegister crd,
1763 Register rn, 1717 Register rn,
1764 int option, 1718 int option,
1765 LFlag l, 1719 LFlag l,
1766 Condition cond) { 1720 Condition cond) {
1767 // Unindexed addressing. 1721 // Unindexed addressing.
1768 ASSERT(is_uint8(option)); 1722 ASSERT(is_uint8(option));
1769 emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 | 1723 emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 |
1770 coproc*B8 | (option & 255)); 1724 coproc*B8 | (option & 255));
1771 } 1725 }
1772 1726
1773 1727
1774 void Assembler::ldc2(Coprocessor coproc, 1728 void Assembler::ldc2(Coprocessor coproc,
1775 CRegister crd, 1729 CRegister crd,
1776 const MemOperand& src, 1730 const MemOperand& src,
1777 LFlag l) { // v5 and above 1731 LFlag l) { // v5 and above
1778 ldc(coproc, crd, src, l, static_cast<Condition>(nv)); 1732 ldc(coproc, crd, src, l, kSpecialCondition);
1779 } 1733 }
1780 1734
1781 1735
1782 void Assembler::ldc2(Coprocessor coproc, 1736 void Assembler::ldc2(Coprocessor coproc,
1783 CRegister crd, 1737 CRegister crd,
1784 Register rn, 1738 Register rn,
1785 int option, 1739 int option,
1786 LFlag l) { // v5 and above 1740 LFlag l) { // v5 and above
1787 ldc(coproc, crd, rn, option, l, static_cast<Condition>(nv)); 1741 ldc(coproc, crd, rn, option, l, kSpecialCondition);
1788 } 1742 }
1789 1743
1790 1744
1791 void Assembler::stc(Coprocessor coproc, 1745 void Assembler::stc(Coprocessor coproc,
1792 CRegister crd, 1746 CRegister crd,
1793 const MemOperand& dst, 1747 const MemOperand& dst,
1794 LFlag l, 1748 LFlag l,
1795 Condition cond) { 1749 Condition cond) {
1796 addrmod5(cond | B27 | B26 | l | coproc*B8, crd, dst); 1750 addrmod5(cond | B27 | B26 | l | coproc*B8, crd, dst);
1797 } 1751 }
1798 1752
1799 1753
1800 void Assembler::stc(Coprocessor coproc, 1754 void Assembler::stc(Coprocessor coproc,
1801 CRegister crd, 1755 CRegister crd,
1802 Register rn, 1756 Register rn,
1803 int option, 1757 int option,
1804 LFlag l, 1758 LFlag l,
1805 Condition cond) { 1759 Condition cond) {
1806 // Unindexed addressing. 1760 // Unindexed addressing.
1807 ASSERT(is_uint8(option)); 1761 ASSERT(is_uint8(option));
1808 emit(cond | B27 | B26 | U | l | rn.code()*B16 | crd.code()*B12 | 1762 emit(cond | B27 | B26 | U | l | rn.code()*B16 | crd.code()*B12 |
1809 coproc*B8 | (option & 255)); 1763 coproc*B8 | (option & 255));
1810 } 1764 }
1811 1765
1812 1766
1813 void Assembler::stc2(Coprocessor 1767 void Assembler::stc2(Coprocessor
1814 coproc, CRegister crd, 1768 coproc, CRegister crd,
1815 const MemOperand& dst, 1769 const MemOperand& dst,
1816 LFlag l) { // v5 and above 1770 LFlag l) { // v5 and above
1817 stc(coproc, crd, dst, l, static_cast<Condition>(nv)); 1771 stc(coproc, crd, dst, l, kSpecialCondition);
1818 } 1772 }
1819 1773
1820 1774
1821 void Assembler::stc2(Coprocessor coproc, 1775 void Assembler::stc2(Coprocessor coproc,
1822 CRegister crd, 1776 CRegister crd,
1823 Register rn, 1777 Register rn,
1824 int option, 1778 int option,
1825 LFlag l) { // v5 and above 1779 LFlag l) { // v5 and above
1826 stc(coproc, crd, rn, option, l, static_cast<Condition>(nv)); 1780 stc(coproc, crd, rn, option, l, kSpecialCondition);
1827 } 1781 }
1828 1782
1829 1783
1830 // Support for VFP. 1784 // Support for VFP.
1831 1785
1832 void Assembler::vldr(const DwVfpRegister dst, 1786 void Assembler::vldr(const DwVfpRegister dst,
1833 const Register base, 1787 const Register base,
1834 int offset, 1788 int offset,
1835 const Condition cond) { 1789 const Condition cond) {
1836 // Ddst = MEM(Rbase + offset). 1790 // Ddst = MEM(Rbase + offset).
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
2490 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && 2444 ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
2491 rinfo.rmode() != RelocInfo::POSITION); 2445 rinfo.rmode() != RelocInfo::POSITION);
2492 if (rinfo.rmode() != RelocInfo::JS_RETURN) { 2446 if (rinfo.rmode() != RelocInfo::JS_RETURN) {
2493 rinfo.set_pc(rinfo.pc() + pc_delta); 2447 rinfo.set_pc(rinfo.pc() + pc_delta);
2494 } 2448 }
2495 } 2449 }
2496 } 2450 }
2497 2451
2498 2452
2499 void Assembler::db(uint8_t data) { 2453 void Assembler::db(uint8_t data) {
2454 // No relocation info should be pending while using db. db is used
2455 // to write pure data with no pointers and the constant pool should
2456 // be emitted before using db.
2457 ASSERT(num_prinfo_ == 0);
2500 CheckBuffer(); 2458 CheckBuffer();
2501 *reinterpret_cast<uint8_t*>(pc_) = data; 2459 *reinterpret_cast<uint8_t*>(pc_) = data;
2502 pc_ += sizeof(uint8_t); 2460 pc_ += sizeof(uint8_t);
2503 } 2461 }
2504 2462
2505 2463
2506 void Assembler::dd(uint32_t data) { 2464 void Assembler::dd(uint32_t data) {
2465 // No relocation info should be pending while using dd. dd is used
2466 // to write pure data with no pointers and the constant pool should
2467 // be emitted before using dd.
2468 ASSERT(num_prinfo_ == 0);
2507 CheckBuffer(); 2469 CheckBuffer();
2508 *reinterpret_cast<uint32_t*>(pc_) = data; 2470 *reinterpret_cast<uint32_t*>(pc_) = data;
2509 pc_ += sizeof(uint32_t); 2471 pc_ += sizeof(uint32_t);
2510 } 2472 }
2511 2473
2512 2474
2513 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2475 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2514 RelocInfo rinfo(pc_, rmode, data); // we do not try to reuse pool constants 2476 RelocInfo rinfo(pc_, rmode, data); // we do not try to reuse pool constants
2515 if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::DEBUG_BREAK_SLOT) { 2477 if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::DEBUG_BREAK_SLOT) {
2516 // Adjust code for new modes. 2478 // Adjust code for new modes.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2618 // Emit constant pool entries. 2580 // Emit constant pool entries.
2619 for (int i = 0; i < num_prinfo_; i++) { 2581 for (int i = 0; i < num_prinfo_; i++) {
2620 RelocInfo& rinfo = prinfo_[i]; 2582 RelocInfo& rinfo = prinfo_[i];
2621 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && 2583 ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
2622 rinfo.rmode() != RelocInfo::POSITION && 2584 rinfo.rmode() != RelocInfo::POSITION &&
2623 rinfo.rmode() != RelocInfo::STATEMENT_POSITION); 2585 rinfo.rmode() != RelocInfo::STATEMENT_POSITION);
2624 Instr instr = instr_at(rinfo.pc()); 2586 Instr instr = instr_at(rinfo.pc());
2625 2587
2626 // Instruction to patch must be a ldr/str [pc, #offset]. 2588 // Instruction to patch must be a ldr/str [pc, #offset].
2627 // P and U set, B and W clear, Rn == pc, offset12 still 0. 2589 // P and U set, B and W clear, Rn == pc, offset12 still 0.
2628 ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) == 2590 ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | kOff12Mask)) ==
2629 (2*B25 | P | U | pc.code()*B16)); 2591 (2*B25 | P | U | pc.code()*B16));
2630 int delta = pc_ - rinfo.pc() - 8; 2592 int delta = pc_ - rinfo.pc() - 8;
2631 ASSERT(delta >= -4); // instr could be ldr pc, [pc, #-4] followed by targ32 2593 ASSERT(delta >= -4); // instr could be ldr pc, [pc, #-4] followed by targ32
2632 if (delta < 0) { 2594 if (delta < 0) {
2633 instr &= ~U; 2595 instr &= ~U;
2634 delta = -delta; 2596 delta = -delta;
2635 } 2597 }
2636 ASSERT(is_uint12(delta)); 2598 ASSERT(is_uint12(delta));
2637 instr_at_put(rinfo.pc(), instr + delta); 2599 instr_at_put(rinfo.pc(), instr + delta);
2638 emit(rinfo.data()); 2600 emit(rinfo.data());
2639 } 2601 }
2640 num_prinfo_ = 0; 2602 num_prinfo_ = 0;
2641 last_const_pool_end_ = pc_offset(); 2603 last_const_pool_end_ = pc_offset();
2642 2604
2643 RecordComment("]"); 2605 RecordComment("]");
2644 2606
2645 if (after_pool.is_linked()) { 2607 if (after_pool.is_linked()) {
2646 bind(&after_pool); 2608 bind(&after_pool);
2647 } 2609 }
2648 2610
2649 // Since a constant pool was just emitted, move the check offset forward by 2611 // Since a constant pool was just emitted, move the check offset forward by
2650 // the standard interval. 2612 // the standard interval.
2651 next_buffer_check_ = pc_offset() + kCheckConstInterval; 2613 next_buffer_check_ = pc_offset() + kCheckConstInterval;
2652 } 2614 }
2653 2615
2654 2616
2655 } } // namespace v8::internal 2617 } } // namespace v8::internal
2656 2618
2657 #endif // V8_TARGET_ARCH_ARM 2619 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/builtins-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698