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

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: Fix nits 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') | 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 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 #ifdef USE_BLX
758 static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize;
759 #else
760 static const int kPatchDebugBreakSlotReturnOffset = kInstrSize;
761 #endif
762
761 // Difference between address of current opcode and value read from pc 763 // Difference between address of current opcode and value read from pc
762 // register. 764 // register.
763 static const int kPcLoadDelta = 8; 765 static const int kPcLoadDelta = 8;
764 766
765 static const int kJSReturnSequenceInstructions = 4; 767 static const int kJSReturnSequenceInstructions = 4;
766 static const int kDebugBreakSlotInstructions = 3; 768 static const int kDebugBreakSlotInstructions = 3;
767 static const int kDebugBreakSlotLength = 769 static const int kDebugBreakSlotLength =
768 kDebugBreakSlotInstructions * kInstrSize; 770 kDebugBreakSlotInstructions * kInstrSize;
769 771
770 // --------------------------------------------------------------------------- 772 // ---------------------------------------------------------------------------
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 1180
1179 void pop() { 1181 void pop() {
1180 add(sp, sp, Operand(kPointerSize)); 1182 add(sp, sp, Operand(kPointerSize));
1181 } 1183 }
1182 1184
1183 // Jump unconditionally to given label. 1185 // Jump unconditionally to given label.
1184 void jmp(Label* L) { b(L, al); } 1186 void jmp(Label* L) { b(L, al); }
1185 1187
1186 bool predictable_code_size() const { return predictable_code_size_; } 1188 bool predictable_code_size() const { return predictable_code_size_; }
1187 1189
1190 static bool allow_immediate_constant_pool_loads(
1191 const Assembler* assembler) {
1192 return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
1193 (assembler == NULL || !assembler->predictable_code_size());
1194 }
1195
1188 // Check the code size generated from label to here. 1196 // Check the code size generated from label to here.
1189 int SizeOfCodeGeneratedSince(Label* label) { 1197 int SizeOfCodeGeneratedSince(Label* label) {
1190 return pc_offset() - label->pos(); 1198 return pc_offset() - label->pos();
1191 } 1199 }
1192 1200
1193 // Check the number of instructions generated from label to here. 1201 // Check the number of instructions generated from label to here.
1194 int InstructionsGeneratedSince(Label* label) { 1202 int InstructionsGeneratedSince(Label* label) {
1195 return SizeOfCodeGeneratedSince(label) / kInstrSize; 1203 return SizeOfCodeGeneratedSince(label) / kInstrSize;
1196 } 1204 }
1197 1205
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 static bool IsLdrRegFpOffset(Instr instr); 1306 static bool IsLdrRegFpOffset(Instr instr);
1299 static bool IsStrRegFpNegOffset(Instr instr); 1307 static bool IsStrRegFpNegOffset(Instr instr);
1300 static bool IsLdrRegFpNegOffset(Instr instr); 1308 static bool IsLdrRegFpNegOffset(Instr instr);
1301 static bool IsLdrPcImmediateOffset(Instr instr); 1309 static bool IsLdrPcImmediateOffset(Instr instr);
1302 static bool IsTstImmediate(Instr instr); 1310 static bool IsTstImmediate(Instr instr);
1303 static bool IsCmpRegister(Instr instr); 1311 static bool IsCmpRegister(Instr instr);
1304 static bool IsCmpImmediate(Instr instr); 1312 static bool IsCmpImmediate(Instr instr);
1305 static Register GetCmpImmediateRegister(Instr instr); 1313 static Register GetCmpImmediateRegister(Instr instr);
1306 static int GetCmpImmediateRawImmediate(Instr instr); 1314 static int GetCmpImmediateRawImmediate(Instr instr);
1307 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); 1315 static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
1316 static bool IsMovT(Instr instr);
1317 static bool IsMovW(Instr instr);
1308 1318
1309 // Constants in pools are accessed via pc relative addressing, which can 1319 // Constants in pools are accessed via pc relative addressing, which can
1310 // reach +/-4KB thereby defining a maximum distance between the instruction 1320 // reach +/-4KB thereby defining a maximum distance between the instruction
1311 // and the accessed constant. 1321 // and the accessed constant.
1312 static const int kMaxDistToPool = 4*KB; 1322 static const int kMaxDistToPool = 4*KB;
1313 static const int kMaxNumPendingRelocInfo = kMaxDistToPool/kInstrSize; 1323 static const int kMaxNumPendingRelocInfo = kMaxDistToPool/kInstrSize;
1314 1324
1315 // Postpone the generation of the constant pool for the specified number of 1325 // Postpone the generation of the constant pool for the specified number of
1316 // instructions. 1326 // instructions.
1317 void BlockConstPoolFor(int instructions); 1327 void BlockConstPoolFor(int instructions);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1436 int num_pending_reloc_info_; 1446 int num_pending_reloc_info_;
1437 1447
1438 // The bound position, before this we cannot do instruction elimination. 1448 // The bound position, before this we cannot do instruction elimination.
1439 int last_bound_pos_; 1449 int last_bound_pos_;
1440 1450
1441 // Code emission 1451 // Code emission
1442 inline void CheckBuffer(); 1452 inline void CheckBuffer();
1443 void GrowBuffer(); 1453 void GrowBuffer();
1444 inline void emit(Instr x); 1454 inline void emit(Instr x);
1445 1455
1456 // 32-bit immediate values
1457 void move_32_bit_immediate(Condition cond,
1458 Register rd,
1459 SBit s,
1460 const Operand& x);
1461
1446 // Instruction generation 1462 // Instruction generation
1447 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); 1463 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
1448 void addrmod2(Instr instr, Register rd, const MemOperand& x); 1464 void addrmod2(Instr instr, Register rd, const MemOperand& x);
1449 void addrmod3(Instr instr, Register rd, const MemOperand& x); 1465 void addrmod3(Instr instr, Register rd, const MemOperand& x);
1450 void addrmod4(Instr instr, Register rn, RegList rl); 1466 void addrmod4(Instr instr, Register rn, RegList rl);
1451 void addrmod5(Instr instr, CRegister crd, const MemOperand& x); 1467 void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
1452 1468
1453 // Labels 1469 // Labels
1454 void print(Label* L); 1470 void print(Label* L);
1455 void bind_to(Label* L, int pos); 1471 void bind_to(Label* L, int pos);
1456 void link_to(Label* L, Label* appendix); 1472 void link_to(Label* L, Label* appendix);
1457 void next(Label* L); 1473 void next(Label* L);
1458 1474
1475 enum UseConstantPoolMode {
1476 USE_CONSTANT_POOL,
1477 DONT_USE_CONSTANT_POOL
1478 };
1479
1459 // Record reloc info for current pc_ 1480 // Record reloc info for current pc_
1460 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1481 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0,
1482 UseConstantPoolMode mode = USE_CONSTANT_POOL);
1461 1483
1462 friend class RegExpMacroAssemblerARM; 1484 friend class RegExpMacroAssemblerARM;
1463 friend class RelocInfo; 1485 friend class RelocInfo;
1464 friend class CodePatcher; 1486 friend class CodePatcher;
1465 friend class BlockConstPoolScope; 1487 friend class BlockConstPoolScope;
1466 1488
1467 PositionsRecorder positions_recorder_; 1489 PositionsRecorder positions_recorder_;
1468 1490
1469 bool emit_debug_code_; 1491 bool emit_debug_code_;
1470 bool predictable_code_size_; 1492 bool predictable_code_size_;
1471 1493
1472 friend class PositionsRecorder; 1494 friend class PositionsRecorder;
1473 friend class EnsureSpace; 1495 friend class EnsureSpace;
1474 }; 1496 };
1475 1497
1476 1498
1477 class EnsureSpace BASE_EMBEDDED { 1499 class EnsureSpace BASE_EMBEDDED {
1478 public: 1500 public:
1479 explicit EnsureSpace(Assembler* assembler) { 1501 explicit EnsureSpace(Assembler* assembler) {
1480 assembler->CheckBuffer(); 1502 assembler->CheckBuffer();
1481 } 1503 }
1482 }; 1504 };
1483 1505
1484 1506
1507 class PredictableCodeSizeScope {
1508 public:
1509 explicit PredictableCodeSizeScope(Assembler* assembler)
1510 : asm_(assembler) {
1511 old_value_ = assembler->predictable_code_size();
1512 assembler->set_predictable_code_size(true);
1513 }
1514
1515 ~PredictableCodeSizeScope() {
1516 if (!old_value_) {
1517 asm_->set_predictable_code_size(false);
1518 }
1519 }
1520
1521 private:
1522 Assembler* asm_;
1523 bool old_value_;
1524 };
1525
1526
1485 } } // namespace v8::internal 1527 } } // namespace v8::internal
1486 1528
1487 #endif // V8_ARM_ASSEMBLER_ARM_H_ 1529 #endif // V8_ARM_ASSEMBLER_ARM_H_
OLDNEW
« no previous file with comments | « no previous file | src/arm/assembler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698