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

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

Issue 11037023: Use movw/movt instead of constant pool on ARMv7 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Set flag properly Created 8 years, 2 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 | « no previous file | src/arm/assembler-arm.cc » ('j') | src/arm/assembler-arm.cc » ('J')
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 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 418
419 // Return true if this is a register operand. 419 // Return true if this is a register operand.
420 INLINE(bool is_reg() const); 420 INLINE(bool is_reg() const);
421 421
422 // Return true if this operand fits in one instruction so that no 422 // Return true if this operand fits in one instruction so that no
423 // 2-instruction solution with a load into the ip register is necessary. If 423 // 2-instruction solution with a load into the ip register is necessary. If
424 // the instruction this operand is used for is a MOV or MVN instruction the 424 // the instruction this operand is used for is a MOV or MVN instruction the
425 // actual instruction to use is required for this calculation. For other 425 // actual instruction to use is required for this calculation. For other
426 // instructions instr is ignored. 426 // instructions instr is ignored.
427 bool is_single_instruction(const Assembler* assembler, Instr instr = 0) const; 427 bool is_single_instruction(const Assembler* assembler, Instr instr = 0) const;
428 bool must_use_constant_pool(const Assembler* assembler) const; 428 bool must_output_reloc_info(const Assembler* assembler) const;
429 429
430 inline int32_t immediate() const { 430 inline int32_t immediate() const {
431 ASSERT(!rm_.is_valid()); 431 ASSERT(!rm_.is_valid());
432 return imm32_; 432 return imm32_;
433 } 433 }
434 434
435 Register rm() const { return rm_; } 435 Register rm() const { return rm_; }
436 Register rs() const { return rs_; } 436 Register rs() const { return rs_; }
437 ShiftOp shift_op() const { return shift_op_; } 437 ShiftOp shift_op() const { return shift_op_; }
438 438
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 // Returns the branch offset to the given label from the current code position 682 // Returns the branch offset to the given label from the current code position
683 // Links the label to the current position if it is still unbound 683 // Links the label to the current position if it is still unbound
684 // Manages the jump elimination optimization if the second parameter is true. 684 // Manages the jump elimination optimization if the second parameter is true.
685 int branch_offset(Label* L, bool jump_elimination_allowed); 685 int branch_offset(Label* L, bool jump_elimination_allowed);
686 686
687 // Puts a labels target address at the given position. 687 // Puts a labels target address at the given position.
688 // The high 8 bits are set to zero. 688 // The high 8 bits are set to zero.
689 void label_at_put(Label* L, int at_offset); 689 void label_at_put(Label* L, int at_offset);
690 690
691 // Return the address in the constant pool of the code target address used by 691 // Return the address in the constant pool of the code target address used by
692 // the branch/call instruction at pc. 692 // the branch/call instruction at pc, or the object in a mov.
693 INLINE(static Address target_address_address_at(Address pc)); 693 INLINE(static Address target_pointer_address_at(Address pc));
694
695 // Read/Modify the pointer in the branch/call/move instruction at pc.
696 INLINE(static Address target_pointer_at(Address pc));
697 INLINE(static void set_target_pointer_at(Address pc, Address target));
694 698
695 // Read/Modify the code target address in the branch/call instruction at pc. 699 // Read/Modify the code target address in the branch/call instruction at pc.
696 INLINE(static Address target_address_at(Address pc)); 700 INLINE(static Address target_address_at(Address pc));
697 INLINE(static void set_target_address_at(Address pc, Address target)); 701 INLINE(static void set_target_address_at(Address pc, Address target));
698 702
703 // Return the code target address at a call site from the return address
704 // of that call in the instruction stream.
705 INLINE(static Address target_address_from_return_address(Address pc));
706
707 // Given the address of the beginning of a call, return the address
708 // in the instruction stream that the call will return from.
709 INLINE(static Address return_address_from_call_start(Address pc));
710
699 // This sets the branch destination (which is in the constant pool on ARM). 711 // This sets the branch destination (which is in the constant pool on ARM).
700 // This is for calls and branches within generated code. 712 // This is for calls and branches within generated code.
701 inline static void deserialization_set_special_target_at( 713 inline static void deserialization_set_special_target_at(
702 Address constant_pool_entry, Address target); 714 Address constant_pool_entry, Address target);
703 715
704 // This sets the branch destination (which is in the constant pool on ARM). 716 // This sets the branch destination (which is in the constant pool on ARM).
705 // This is for calls and branches to runtime code. 717 // This is for calls and branches to runtime code.
706 inline static void set_external_target_at(Address constant_pool_entry, 718 inline static void set_external_target_at(Address constant_pool_entry,
707 Address target); 719 Address target);
708 720
709 // Here we are patching the address in the constant pool, not the actual call 721 // Here we are patching the address in the constant pool, not the actual call
710 // instruction. The address in the constant pool is the same size as a 722 // instruction. The address in the constant pool is the same size as a
711 // pointer. 723 // pointer.
712 static const int kSpecialTargetSize = kPointerSize; 724 static const int kSpecialTargetSize = kPointerSize;
713 725
714 // Size of an instruction. 726 // Size of an instruction.
715 static const int kInstrSize = sizeof(Instr); 727 static const int kInstrSize = sizeof(Instr);
716 728
717 // Distance between the instruction referring to the address of the call
718 // target and the return address.
719 #ifdef USE_BLX
720 // Call sequence is:
721 // ldr ip, [pc, #...] @ call address
722 // blx ip
723 // @ return address
724 static const int kCallTargetAddressOffset = 2 * kInstrSize;
725 #else
726 // Call sequence is:
727 // mov lr, pc
728 // ldr pc, [pc, #...] @ call address
729 // @ return address
730 static const int kCallTargetAddressOffset = kInstrSize;
731 #endif
732
733 // Distance between start of patched return sequence and the emitted address 729 // Distance between start of patched return sequence and the emitted address
734 // to jump to. 730 // to jump to.
735 #ifdef USE_BLX 731 #ifdef USE_BLX
736 // Patched return sequence is: 732 // Patched return sequence is:
737 // ldr ip, [pc, #0] @ emited address and start 733 // ldr ip, [pc, #0] @ emited address and start
738 // blx ip 734 // blx ip
739 static const int kPatchReturnSequenceAddressOffset = 0 * kInstrSize; 735 static const int kPatchReturnSequenceAddressOffset = 0 * kInstrSize;
740 #else 736 #else
741 // Patched return sequence is: 737 // Patched return sequence is:
742 // mov lr, pc @ start of sequence 738 // mov lr, pc @ start of sequence
743 // ldr pc, [pc, #-4] @ emited address 739 // ldr pc, [pc, #-4] @ emited address
744 static const int kPatchReturnSequenceAddressOffset = kInstrSize; 740 static const int kPatchReturnSequenceAddressOffset = kInstrSize;
745 #endif 741 #endif
746 742
747 // Distance between start of patched debug break slot and the emitted address 743 // Distance between start of patched debug break slot and the emitted address
748 // to jump to. 744 // to jump to.
749 #ifdef USE_BLX 745 #ifdef USE_BLX
750 // Patched debug break slot code is: 746 // Patched debug break slot code is:
751 // ldr ip, [pc, #0] @ emited address and start 747 // ldr ip, [pc, #0] @ emited address and start
752 // blx ip 748 // blx ip
753 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; 749 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize;
754 #else 750 #else
755 // Patched debug break slot code is: 751 // Patched debug break slot code is:
756 // mov lr, pc @ start of sequence 752 // mov lr, pc @ start of sequence
757 // ldr pc, [pc, #-4] @ emited address 753 // ldr pc, [pc, #-4] @ emited address
758 static const int kPatchDebugBreakSlotAddressOffset = kInstrSize; 754 static const int kPatchDebugBreakSlotAddressOffset = kInstrSize;
759 #endif 755 #endif
760 756
757 static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize;
ulan 2012/10/18 09:07:53 Is the offset correct when we don't use BLX?
danno 2012/10/18 12:22:10 Done.
758
761 // Difference between address of current opcode and value read from pc 759 // Difference between address of current opcode and value read from pc
762 // register. 760 // register.
763 static const int kPcLoadDelta = 8; 761 static const int kPcLoadDelta = 8;
764 762
765 static const int kJSReturnSequenceInstructions = 4; 763 static const int kJSReturnSequenceInstructions = 4;
766 static const int kDebugBreakSlotInstructions = 3; 764 static const int kDebugBreakSlotInstructions = 3;
767 static const int kDebugBreakSlotLength = 765 static const int kDebugBreakSlotLength =
768 kDebugBreakSlotInstructions * kInstrSize; 766 kDebugBreakSlotInstructions * kInstrSize;
769 767
770 // --------------------------------------------------------------------------- 768 // ---------------------------------------------------------------------------
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 1176
1179 void pop() { 1177 void pop() {
1180 add(sp, sp, Operand(kPointerSize)); 1178 add(sp, sp, Operand(kPointerSize));
1181 } 1179 }
1182 1180
1183 // Jump unconditionally to given label. 1181 // Jump unconditionally to given label.
1184 void jmp(Label* L) { b(L, al); } 1182 void jmp(Label* L) { b(L, al); }
1185 1183
1186 bool predictable_code_size() const { return predictable_code_size_; } 1184 bool predictable_code_size() const { return predictable_code_size_; }
1187 1185
1186 static bool allow_immediate_constant_pool_loads(
1187 const Assembler* assembler) {
1188 return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
1189 (assembler == NULL || !assembler->predictable_code_size());
1190 }
1191
1188 // Check the code size generated from label to here. 1192 // Check the code size generated from label to here.
1189 int SizeOfCodeGeneratedSince(Label* label) { 1193 int SizeOfCodeGeneratedSince(Label* label) {
1190 return pc_offset() - label->pos(); 1194 return pc_offset() - label->pos();
1191 } 1195 }
1192 1196
1193 // Check the number of instructions generated from label to here. 1197 // Check the number of instructions generated from label to here.
1194 int InstructionsGeneratedSince(Label* label) { 1198 int InstructionsGeneratedSince(Label* label) {
1195 return SizeOfCodeGeneratedSince(label) / kInstrSize; 1199 return SizeOfCodeGeneratedSince(label) / kInstrSize;
1196 } 1200 }
1197 1201
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 static bool IsLdrRegFpOffset(Instr instr); 1302 static bool IsLdrRegFpOffset(Instr instr);
1299 static bool IsStrRegFpNegOffset(Instr instr); 1303 static bool IsStrRegFpNegOffset(Instr instr);
1300 static bool IsLdrRegFpNegOffset(Instr instr); 1304 static bool IsLdrRegFpNegOffset(Instr instr);
1301 static bool IsLdrPcImmediateOffset(Instr instr); 1305 static bool IsLdrPcImmediateOffset(Instr instr);
1302 static bool IsTstImmediate(Instr instr); 1306 static bool IsTstImmediate(Instr instr);
1303 static bool IsCmpRegister(Instr instr); 1307 static bool IsCmpRegister(Instr instr);
1304 static bool IsCmpImmediate(Instr instr); 1308 static bool IsCmpImmediate(Instr instr);
1305 static Register GetCmpImmediateRegister(Instr instr); 1309 static Register GetCmpImmediateRegister(Instr instr);
1306 static int GetCmpImmediateRawImmediate(Instr instr); 1310 static int GetCmpImmediateRawImmediate(Instr instr);
1307 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); 1311 static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
1312 static bool IsMovT(Instr instr);
1313 static bool IsMovW(Instr instr);
1308 1314
1309 // Constants in pools are accessed via pc relative addressing, which can 1315 // Constants in pools are accessed via pc relative addressing, which can
1310 // reach +/-4KB thereby defining a maximum distance between the instruction 1316 // reach +/-4KB thereby defining a maximum distance between the instruction
1311 // and the accessed constant. 1317 // and the accessed constant.
1312 static const int kMaxDistToPool = 4*KB; 1318 static const int kMaxDistToPool = 4*KB;
1313 static const int kMaxNumPendingRelocInfo = kMaxDistToPool/kInstrSize; 1319 static const int kMaxNumPendingRelocInfo = kMaxDistToPool/kInstrSize;
1314 1320
1315 // Postpone the generation of the constant pool for the specified number of 1321 // Postpone the generation of the constant pool for the specified number of
1316 // instructions. 1322 // instructions.
1317 void BlockConstPoolFor(int instructions); 1323 void BlockConstPoolFor(int instructions);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1436 int num_pending_reloc_info_; 1442 int num_pending_reloc_info_;
1437 1443
1438 // The bound position, before this we cannot do instruction elimination. 1444 // The bound position, before this we cannot do instruction elimination.
1439 int last_bound_pos_; 1445 int last_bound_pos_;
1440 1446
1441 // Code emission 1447 // Code emission
1442 inline void CheckBuffer(); 1448 inline void CheckBuffer();
1443 void GrowBuffer(); 1449 void GrowBuffer();
1444 inline void emit(Instr x); 1450 inline void emit(Instr x);
1445 1451
1452 // 32-bit immediate values
1453 void move_32_bit_immediate(Condition cond,
1454 Register rd,
1455 SBit s,
1456 const Operand& x);
1457
1446 // Instruction generation 1458 // Instruction generation
1447 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); 1459 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
1448 void addrmod2(Instr instr, Register rd, const MemOperand& x); 1460 void addrmod2(Instr instr, Register rd, const MemOperand& x);
1449 void addrmod3(Instr instr, Register rd, const MemOperand& x); 1461 void addrmod3(Instr instr, Register rd, const MemOperand& x);
1450 void addrmod4(Instr instr, Register rn, RegList rl); 1462 void addrmod4(Instr instr, Register rn, RegList rl);
1451 void addrmod5(Instr instr, CRegister crd, const MemOperand& x); 1463 void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
1452 1464
1453 // Labels 1465 // Labels
1454 void print(Label* L); 1466 void print(Label* L);
1455 void bind_to(Label* L, int pos); 1467 void bind_to(Label* L, int pos);
1456 void link_to(Label* L, Label* appendix); 1468 void link_to(Label* L, Label* appendix);
1457 void next(Label* L); 1469 void next(Label* L);
1458 1470
1471 enum UseConstantPoolMode {
1472 USE_CONSTANT_POOL,
1473 DONT_USE_CONSTANT_POOL
1474 };
1475
1459 // Record reloc info for current pc_ 1476 // Record reloc info for current pc_
1460 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1477 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0,
1478 UseConstantPoolMode mode = USE_CONSTANT_POOL);
1461 1479
1462 friend class RegExpMacroAssemblerARM; 1480 friend class RegExpMacroAssemblerARM;
1463 friend class RelocInfo; 1481 friend class RelocInfo;
1464 friend class CodePatcher; 1482 friend class CodePatcher;
1465 friend class BlockConstPoolScope; 1483 friend class BlockConstPoolScope;
1466 1484
1467 PositionsRecorder positions_recorder_; 1485 PositionsRecorder positions_recorder_;
1468 1486
1469 bool emit_debug_code_; 1487 bool emit_debug_code_;
1470 bool predictable_code_size_; 1488 bool predictable_code_size_;
1471 1489
1472 friend class PositionsRecorder; 1490 friend class PositionsRecorder;
1473 friend class EnsureSpace; 1491 friend class EnsureSpace;
1474 }; 1492 };
1475 1493
1476 1494
1477 class EnsureSpace BASE_EMBEDDED { 1495 class EnsureSpace BASE_EMBEDDED {
1478 public: 1496 public:
1479 explicit EnsureSpace(Assembler* assembler) { 1497 explicit EnsureSpace(Assembler* assembler) {
1480 assembler->CheckBuffer(); 1498 assembler->CheckBuffer();
1481 } 1499 }
1482 }; 1500 };
1483 1501
1484 1502
1503 class PredictableCodeSizeScope {
1504 public:
1505 explicit PredictableCodeSizeScope(Assembler* assembler)
1506 : asm_(assembler) {
1507 old_value_ = assembler->predictable_code_size();
1508 assembler->set_predictable_code_size(true);
1509 }
1510
1511 ~PredictableCodeSizeScope() {
1512 if (!old_value_) {
1513 asm_->set_predictable_code_size(false);
1514 }
1515 }
1516
1517 private:
1518 Assembler* asm_;
1519 bool old_value_;
1520 };
1521
1522
1485 } } // namespace v8::internal 1523 } } // namespace v8::internal
1486 1524
1487 #endif // V8_ARM_ASSEMBLER_ARM_H_ 1525 #endif // V8_ARM_ASSEMBLER_ARM_H_
OLDNEW
« no previous file with comments | « no previous file | src/arm/assembler-arm.cc » ('j') | src/arm/assembler-arm.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698