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 |