Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 // to be generated; pos() is the position of the last | 322 // to be generated; pos() is the position of the last |
| 323 // instruction using the label. | 323 // instruction using the label. |
| 324 | 324 |
| 325 | 325 |
| 326 // The link chain is terminated by a negative code position (must be aligned) | 326 // The link chain is terminated by a negative code position (must be aligned) |
| 327 const int kEndOfChain = -4; | 327 const int kEndOfChain = -4; |
| 328 | 328 |
| 329 | 329 |
| 330 int Assembler::target_at(int pos) { | 330 int Assembler::target_at(int pos) { |
| 331 Instr instr = instr_at(pos); | 331 Instr instr = instr_at(pos); |
| 332 if ((instr & ~Imm24Mask) == 0) { | |
| 333 // Emitted label constant, not part of a branch. | |
| 334 return instr - (Code::kHeaderSize - kHeapObjectTag); | |
| 335 } | |
| 332 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 | 336 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 |
| 333 int imm26 = ((instr & Imm24Mask) << 8) >> 6; | 337 int imm26 = ((instr & Imm24Mask) << 8) >> 6; |
| 334 if ((instr & CondMask) == nv && (instr & B24) != 0) | 338 if ((instr & CondMask) == nv && (instr & B24) != 0) |
| 335 // blx uses bit 24 to encode bit 2 of imm26 | 339 // blx uses bit 24 to encode bit 2 of imm26 |
| 336 imm26 += 2; | 340 imm26 += 2; |
| 337 | 341 |
| 338 return pos + 8 + imm26; | 342 return pos + 8 + imm26; |
|
Erik Corry
2009/08/27 14:43:05
This isn't your code, but I wonder what this '8' r
Lasse Reichstein
2009/08/28 09:15:17
Changed to a constant, kPcLoadDelta. It's the diff
| |
| 339 } | 343 } |
| 340 | 344 |
| 341 | 345 |
| 342 void Assembler::target_at_put(int pos, int target_pos) { | 346 void Assembler::target_at_put(int pos, int target_pos) { |
| 347 Instr instr = instr_at(pos); | |
| 348 if ((instr & ~Imm24Mask) == 0) { | |
| 349 ASSERT(target_pos == kEndOfChain || target_pos >= 0); | |
| 350 // Emitted label constant, not part of a branch. | |
| 351 // Make label relative to Code* of generated Code object. | |
| 352 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); | |
| 353 return; | |
| 354 } | |
| 343 int imm26 = target_pos - pos - 8; | 355 int imm26 = target_pos - pos - 8; |
|
Erik Corry
2009/08/27 14:43:05
And this one.
Lasse Reichstein
2009/08/28 09:15:17
Ditto.
| |
| 344 Instr instr = instr_at(pos); | |
| 345 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 | 356 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 |
| 346 if ((instr & CondMask) == nv) { | 357 if ((instr & CondMask) == nv) { |
| 347 // blx uses bit 24 to encode bit 2 of imm26 | 358 // blx uses bit 24 to encode bit 2 of imm26 |
| 348 ASSERT((imm26 & 1) == 0); | 359 ASSERT((imm26 & 1) == 0); |
| 349 instr = (instr & ~(B24 | Imm24Mask)) | ((imm26 & 2) >> 1)*B24; | 360 instr = (instr & ~(B24 | Imm24Mask)) | ((imm26 & 2) >> 1)*B24; |
| 350 } else { | 361 } else { |
| 351 ASSERT((imm26 & 3) == 0); | 362 ASSERT((imm26 & 3) == 0); |
| 352 instr &= ~Imm24Mask; | 363 instr &= ~Imm24Mask; |
| 353 } | 364 } |
| 354 int imm24 = imm26 >> 2; | 365 int imm24 = imm26 >> 2; |
| 355 ASSERT(is_int24(imm24)); | 366 ASSERT(is_int24(imm24)); |
| 356 instr_at_put(pos, instr | (imm24 & Imm24Mask)); | 367 instr_at_put(pos, instr | (imm24 & Imm24Mask)); |
| 357 } | 368 } |
| 358 | 369 |
| 359 | 370 |
| 360 void Assembler::print(Label* L) { | 371 void Assembler::print(Label* L) { |
| 361 if (L->is_unused()) { | 372 if (L->is_unused()) { |
| 362 PrintF("unused label\n"); | 373 PrintF("unused label\n"); |
| 363 } else if (L->is_bound()) { | 374 } else if (L->is_bound()) { |
| 364 PrintF("bound label to %d\n", L->pos()); | 375 PrintF("bound label to %d\n", L->pos()); |
| 365 } else if (L->is_linked()) { | 376 } else if (L->is_linked()) { |
| 366 Label l = *L; | 377 Label l = *L; |
| 367 PrintF("unbound label"); | 378 PrintF("unbound label"); |
| 368 while (l.is_linked()) { | 379 while (l.is_linked()) { |
| 369 PrintF("@ %d ", l.pos()); | 380 PrintF("@ %d ", l.pos()); |
| 370 Instr instr = instr_at(l.pos()); | 381 Instr instr = instr_at(l.pos()); |
| 371 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx | 382 if ((instr & ~Imm24Mask) == 0) { |
| 372 int cond = instr & CondMask; | 383 PrintF("value"); |
|
Erik Corry
2009/08/27 14:43:05
Seems like this should print what the value is and
Lasse Reichstein
2009/08/28 09:15:17
It does need a newline. It can't really print a va
| |
| 373 const char* b; | |
| 374 const char* c; | |
| 375 if (cond == nv) { | |
| 376 b = "blx"; | |
| 377 c = ""; | |
| 378 } else { | 384 } else { |
| 379 if ((instr & B24) != 0) | 385 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx |
| 380 b = "bl"; | 386 int cond = instr & CondMask; |
| 381 else | 387 const char* b; |
| 382 b = "b"; | 388 const char* c; |
| 389 if (cond == nv) { | |
| 390 b = "blx"; | |
| 391 c = ""; | |
| 392 } else { | |
| 393 if ((instr & B24) != 0) | |
| 394 b = "bl"; | |
| 395 else | |
| 396 b = "b"; | |
| 383 | 397 |
| 384 switch (cond) { | 398 switch (cond) { |
| 385 case eq: c = "eq"; break; | 399 case eq: c = "eq"; break; |
| 386 case ne: c = "ne"; break; | 400 case ne: c = "ne"; break; |
| 387 case hs: c = "hs"; break; | 401 case hs: c = "hs"; break; |
| 388 case lo: c = "lo"; break; | 402 case lo: c = "lo"; break; |
| 389 case mi: c = "mi"; break; | 403 case mi: c = "mi"; break; |
| 390 case pl: c = "pl"; break; | 404 case pl: c = "pl"; break; |
| 391 case vs: c = "vs"; break; | 405 case vs: c = "vs"; break; |
| 392 case vc: c = "vc"; break; | 406 case vc: c = "vc"; break; |
| 393 case hi: c = "hi"; break; | 407 case hi: c = "hi"; break; |
| 394 case ls: c = "ls"; break; | 408 case ls: c = "ls"; break; |
| 395 case ge: c = "ge"; break; | 409 case ge: c = "ge"; break; |
| 396 case lt: c = "lt"; break; | 410 case lt: c = "lt"; break; |
| 397 case gt: c = "gt"; break; | 411 case gt: c = "gt"; break; |
| 398 case le: c = "le"; break; | 412 case le: c = "le"; break; |
| 399 case al: c = ""; break; | 413 case al: c = ""; break; |
| 400 default: | 414 default: |
| 401 c = ""; | 415 c = ""; |
| 402 UNREACHABLE(); | 416 UNREACHABLE(); |
| 417 } | |
| 403 } | 418 } |
| 419 PrintF("%s%s\n", b, c); | |
| 404 } | 420 } |
| 405 PrintF("%s%s\n", b, c); | |
| 406 next(&l); | 421 next(&l); |
| 407 } | 422 } |
| 408 } else { | 423 } else { |
| 409 PrintF("label in inconsistent state (pos = %d)\n", L->pos_); | 424 PrintF("label in inconsistent state (pos = %d)\n", L->pos_); |
| 410 } | 425 } |
| 411 } | 426 } |
| 412 | 427 |
| 413 | 428 |
| 414 void Assembler::bind_to(Label* L, int pos) { | 429 void Assembler::bind_to(Label* L, int pos) { |
| 415 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position | 430 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 663 target_pos = L->pos(); // L's link | 678 target_pos = L->pos(); // L's link |
| 664 } else { | 679 } else { |
| 665 target_pos = kEndOfChain; | 680 target_pos = kEndOfChain; |
| 666 } | 681 } |
| 667 L->link_to(pc_offset()); | 682 L->link_to(pc_offset()); |
| 668 } | 683 } |
| 669 | 684 |
| 670 // Block the emission of the constant pool, since the branch instruction must | 685 // Block the emission of the constant pool, since the branch instruction must |
| 671 // be emitted at the pc offset recorded by the label | 686 // be emitted at the pc offset recorded by the label |
| 672 BlockConstPoolBefore(pc_offset() + kInstrSize); | 687 BlockConstPoolBefore(pc_offset() + kInstrSize); |
| 688 return target_pos - pc_offset() - 8; | |
|
Erik Corry
2009/08/27 14:43:05
And this one!
Lasse Reichstein
2009/08/28 09:15:17
And this one, too.
| |
| 689 } | |
| 673 | 690 |
| 674 return target_pos - pc_offset() - 8; | 691 |
| 692 void Assembler::label_at_put(Label* L, int at_offset) { | |
| 693 int target_pos; | |
| 694 if (L->is_bound()) { | |
| 695 target_pos = L->pos(); | |
| 696 } else { | |
| 697 if (L->is_linked()) { | |
| 698 target_pos = L->pos(); // L's link | |
| 699 } else { | |
| 700 target_pos = kEndOfChain; | |
| 701 } | |
| 702 L->link_to(at_offset); | |
| 703 instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag)); | |
| 704 } | |
| 675 } | 705 } |
| 676 | 706 |
| 677 | 707 |
| 678 // Branch instructions | 708 // Branch instructions |
| 679 void Assembler::b(int branch_offset, Condition cond) { | 709 void Assembler::b(int branch_offset, Condition cond) { |
| 680 ASSERT((branch_offset & 3) == 0); | 710 ASSERT((branch_offset & 3) == 0); |
| 681 int imm24 = branch_offset >> 2; | 711 int imm24 = branch_offset >> 2; |
| 682 ASSERT(is_int24(imm24)); | 712 ASSERT(is_int24(imm24)); |
| 683 emit(cond | B27 | B25 | (imm24 & Imm24Mask)); | 713 emit(cond | B27 | B25 | (imm24 & Imm24Mask)); |
| 684 | 714 |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1483 bind(&after_pool); | 1513 bind(&after_pool); |
| 1484 } | 1514 } |
| 1485 | 1515 |
| 1486 // Since a constant pool was just emitted, move the check offset forward by | 1516 // Since a constant pool was just emitted, move the check offset forward by |
| 1487 // the standard interval. | 1517 // the standard interval. |
| 1488 next_buffer_check_ = pc_offset() + kCheckConstInterval; | 1518 next_buffer_check_ = pc_offset() + kCheckConstInterval; |
| 1489 } | 1519 } |
| 1490 | 1520 |
| 1491 | 1521 |
| 1492 } } // namespace v8::internal | 1522 } } // namespace v8::internal |
| OLD | NEW |