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

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: More fixes and nit fixes 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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 void label_at_put(Label* L, int at_offset); 686 void label_at_put(Label* L, int at_offset);
687 687
688 // Return the address in the constant pool of the code target address used by 688 // Return the address in the constant pool of the code target address used by
689 // the branch/call instruction at pc. 689 // the branch/call instruction at pc.
690 INLINE(static Address target_address_address_at(Address pc)); 690 INLINE(static Address target_address_address_at(Address pc));
691 691
692 // Read/Modify the code target address in the branch/call instruction at pc. 692 // Read/Modify the code target address in the branch/call instruction at pc.
693 INLINE(static Address target_address_at(Address pc)); 693 INLINE(static Address target_address_at(Address pc));
694 INLINE(static void set_target_address_at(Address pc, Address target)); 694 INLINE(static void set_target_address_at(Address pc, Address target));
695 695
696 INLINE(static Address target_address_from_return_address(Address pc));
Michael Starzinger 2012/10/10 14:19:29 Can we have a one-liner comment of what this metho
danno 2012/10/17 10:04:44 Done.
697 INLINE(static Address return_address_from_call_start(Address pc));
698
696 // This sets the branch destination (which is in the constant pool on ARM). 699 // This sets the branch destination (which is in the constant pool on ARM).
697 // This is for calls and branches within generated code. 700 // This is for calls and branches within generated code.
698 inline static void deserialization_set_special_target_at( 701 inline static void deserialization_set_special_target_at(
699 Address constant_pool_entry, Address target); 702 Address constant_pool_entry, Address target);
700 703
701 // This sets the branch destination (which is in the constant pool on ARM). 704 // This sets the branch destination (which is in the constant pool on ARM).
702 // This is for calls and branches to runtime code. 705 // This is for calls and branches to runtime code.
703 inline static void set_external_target_at(Address constant_pool_entry, 706 inline static void set_external_target_at(Address constant_pool_entry,
704 Address target); 707 Address target);
705 708
706 // Here we are patching the address in the constant pool, not the actual call 709 // Here we are patching the address in the constant pool, not the actual call
707 // instruction. The address in the constant pool is the same size as a 710 // instruction. The address in the constant pool is the same size as a
708 // pointer. 711 // pointer.
709 static const int kSpecialTargetSize = kPointerSize; 712 static const int kSpecialTargetSize = kPointerSize;
710 713
711 // Size of an instruction. 714 // Size of an instruction.
712 static const int kInstrSize = sizeof(Instr); 715 static const int kInstrSize = sizeof(Instr);
713 716
714 // Distance between the instruction referring to the address of the call
715 // target and the return address.
716 #ifdef USE_BLX
717 // Call sequence is:
718 // ldr ip, [pc, #...] @ call address
719 // blx ip
720 // @ return address
721 static const int kCallTargetAddressOffset = 2 * kInstrSize;
722 #else
723 // Call sequence is:
724 // mov lr, pc
725 // ldr pc, [pc, #...] @ call address
726 // @ return address
727 static const int kCallTargetAddressOffset = kInstrSize;
728 #endif
729
730 // Distance between start of patched return sequence and the emitted address 717 // Distance between start of patched return sequence and the emitted address
731 // to jump to. 718 // to jump to.
732 #ifdef USE_BLX 719 #ifdef USE_BLX
733 // Patched return sequence is: 720 // Patched return sequence is:
734 // ldr ip, [pc, #0] @ emited address and start 721 // ldr ip, [pc, #0] @ emited address and start
735 // blx ip 722 // blx ip
736 static const int kPatchReturnSequenceAddressOffset = 0 * kInstrSize; 723 static const int kPatchReturnSequenceAddressOffset = 0 * kInstrSize;
737 #else 724 #else
738 // Patched return sequence is: 725 // Patched return sequence is:
739 // mov lr, pc @ start of sequence 726 // mov lr, pc @ start of sequence
740 // ldr pc, [pc, #-4] @ emited address 727 // ldr pc, [pc, #-4] @ emited address
741 static const int kPatchReturnSequenceAddressOffset = kInstrSize; 728 static const int kPatchReturnSequenceAddressOffset = kInstrSize;
742 #endif 729 #endif
743 730
744 // Distance between start of patched debug break slot and the emitted address 731 // Distance between start of patched debug break slot and the emitted address
745 // to jump to. 732 // to jump to.
746 #ifdef USE_BLX 733 #ifdef USE_BLX
747 // Patched debug break slot code is: 734 // Patched debug break slot code is:
748 // ldr ip, [pc, #0] @ emited address and start 735 // ldr ip, [pc, #0] @ emited address and start
749 // blx ip 736 // blx ip
750 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; 737 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize;
751 #else 738 #else
752 // Patched debug break slot code is: 739 // Patched debug break slot code is:
753 // mov lr, pc @ start of sequence 740 // mov lr, pc @ start of sequence
754 // ldr pc, [pc, #-4] @ emited address 741 // ldr pc, [pc, #-4] @ emited address
755 static const int kPatchDebugBreakSlotAddressOffset = kInstrSize; 742 static const int kPatchDebugBreakSlotAddressOffset = kInstrSize;
756 #endif 743 #endif
757 744
745 static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize;
746
758 // Difference between address of current opcode and value read from pc 747 // Difference between address of current opcode and value read from pc
759 // register. 748 // register.
760 static const int kPcLoadDelta = 8; 749 static const int kPcLoadDelta = 8;
761 750
762 static const int kJSReturnSequenceInstructions = 4; 751 static const int kJSReturnSequenceInstructions = 4;
763 static const int kDebugBreakSlotInstructions = 3; 752 static const int kDebugBreakSlotInstructions = 3;
764 static const int kDebugBreakSlotLength = 753 static const int kDebugBreakSlotLength =
765 kDebugBreakSlotInstructions * kInstrSize; 754 kDebugBreakSlotInstructions * kInstrSize;
766 755
767 // --------------------------------------------------------------------------- 756 // ---------------------------------------------------------------------------
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 1164
1176 void pop() { 1165 void pop() {
1177 add(sp, sp, Operand(kPointerSize)); 1166 add(sp, sp, Operand(kPointerSize));
1178 } 1167 }
1179 1168
1180 // Jump unconditionally to given label. 1169 // Jump unconditionally to given label.
1181 void jmp(Label* L) { b(L, al); } 1170 void jmp(Label* L) { b(L, al); }
1182 1171
1183 bool predictable_code_size() const { return predictable_code_size_; } 1172 bool predictable_code_size() const { return predictable_code_size_; }
1184 1173
1174 static bool allow_immediate_constant_pool_loads(
1175 const Assembler* assembler) {
1176 return CpuFeatures::IsSupported(ARMv7) &&
1177 (assembler == NULL || !assembler->predictable_code_size());
1178 }
1179
1185 // Check the code size generated from label to here. 1180 // Check the code size generated from label to here.
1186 int SizeOfCodeGeneratedSince(Label* label) { 1181 int SizeOfCodeGeneratedSince(Label* label) {
1187 return pc_offset() - label->pos(); 1182 return pc_offset() - label->pos();
1188 } 1183 }
1189 1184
1190 // Check the number of instructions generated from label to here. 1185 // Check the number of instructions generated from label to here.
1191 int InstructionsGeneratedSince(Label* label) { 1186 int InstructionsGeneratedSince(Label* label) {
1192 return SizeOfCodeGeneratedSince(label) / kInstrSize; 1187 return SizeOfCodeGeneratedSince(label) / kInstrSize;
1193 } 1188 }
1194 1189
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 static bool IsLdrRegFpOffset(Instr instr); 1290 static bool IsLdrRegFpOffset(Instr instr);
1296 static bool IsStrRegFpNegOffset(Instr instr); 1291 static bool IsStrRegFpNegOffset(Instr instr);
1297 static bool IsLdrRegFpNegOffset(Instr instr); 1292 static bool IsLdrRegFpNegOffset(Instr instr);
1298 static bool IsLdrPcImmediateOffset(Instr instr); 1293 static bool IsLdrPcImmediateOffset(Instr instr);
1299 static bool IsTstImmediate(Instr instr); 1294 static bool IsTstImmediate(Instr instr);
1300 static bool IsCmpRegister(Instr instr); 1295 static bool IsCmpRegister(Instr instr);
1301 static bool IsCmpImmediate(Instr instr); 1296 static bool IsCmpImmediate(Instr instr);
1302 static Register GetCmpImmediateRegister(Instr instr); 1297 static Register GetCmpImmediateRegister(Instr instr);
1303 static int GetCmpImmediateRawImmediate(Instr instr); 1298 static int GetCmpImmediateRawImmediate(Instr instr);
1304 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); 1299 static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
1300 static bool IsMovT(Instr instr);
1301 static bool IsMovW(Instr instr);
1305 1302
1306 // Constants in pools are accessed via pc relative addressing, which can 1303 // Constants in pools are accessed via pc relative addressing, which can
1307 // reach +/-4KB thereby defining a maximum distance between the instruction 1304 // reach +/-4KB thereby defining a maximum distance between the instruction
1308 // and the accessed constant. 1305 // and the accessed constant.
1309 static const int kMaxDistToPool = 4*KB; 1306 static const int kMaxDistToPool = 4*KB;
1310 static const int kMaxNumPendingRelocInfo = kMaxDistToPool/kInstrSize; 1307 static const int kMaxNumPendingRelocInfo = kMaxDistToPool/kInstrSize;
1311 1308
1312 // Postpone the generation of the constant pool for the specified number of 1309 // Postpone the generation of the constant pool for the specified number of
1313 // instructions. 1310 // instructions.
1314 void BlockConstPoolFor(int instructions); 1311 void BlockConstPoolFor(int instructions);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 int num_pending_reloc_info_; 1430 int num_pending_reloc_info_;
1434 1431
1435 // The bound position, before this we cannot do instruction elimination. 1432 // The bound position, before this we cannot do instruction elimination.
1436 int last_bound_pos_; 1433 int last_bound_pos_;
1437 1434
1438 // Code emission 1435 // Code emission
1439 inline void CheckBuffer(); 1436 inline void CheckBuffer();
1440 void GrowBuffer(); 1437 void GrowBuffer();
1441 inline void emit(Instr x); 1438 inline void emit(Instr x);
1442 1439
1440 // 32-bit immediate values
1441 void move_32_bit_immediate(Condition cond,
1442 Register rd,
1443 SBit s,
1444 const Operand& x);
1445
1443 // Instruction generation 1446 // Instruction generation
1444 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); 1447 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
1445 void addrmod2(Instr instr, Register rd, const MemOperand& x); 1448 void addrmod2(Instr instr, Register rd, const MemOperand& x);
1446 void addrmod3(Instr instr, Register rd, const MemOperand& x); 1449 void addrmod3(Instr instr, Register rd, const MemOperand& x);
1447 void addrmod4(Instr instr, Register rn, RegList rl); 1450 void addrmod4(Instr instr, Register rn, RegList rl);
1448 void addrmod5(Instr instr, CRegister crd, const MemOperand& x); 1451 void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
1449 1452
1450 // Labels 1453 // Labels
1451 void print(Label* L); 1454 void print(Label* L);
1452 void bind_to(Label* L, int pos); 1455 void bind_to(Label* L, int pos);
1453 void link_to(Label* L, Label* appendix); 1456 void link_to(Label* L, Label* appendix);
1454 void next(Label* L); 1457 void next(Label* L);
1455 1458
1459 enum UseConstantPoolMode {
1460 USE_CONSTANT_POOL,
1461 DONT_USE_CONSTANT_POOL
1462 };
1463
1456 // Record reloc info for current pc_ 1464 // Record reloc info for current pc_
1457 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1465 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0,
1466 UseConstantPoolMode mode = USE_CONSTANT_POOL);
1458 1467
1459 friend class RegExpMacroAssemblerARM; 1468 friend class RegExpMacroAssemblerARM;
1460 friend class RelocInfo; 1469 friend class RelocInfo;
1461 friend class CodePatcher; 1470 friend class CodePatcher;
1462 friend class BlockConstPoolScope; 1471 friend class BlockConstPoolScope;
1463 1472
1464 PositionsRecorder positions_recorder_; 1473 PositionsRecorder positions_recorder_;
1465 1474
1466 bool emit_debug_code_; 1475 bool emit_debug_code_;
1467 bool predictable_code_size_; 1476 bool predictable_code_size_;
1468 1477
1469 friend class PositionsRecorder; 1478 friend class PositionsRecorder;
1470 friend class EnsureSpace; 1479 friend class EnsureSpace;
1471 }; 1480 };
1472 1481
1473 1482
1474 class EnsureSpace BASE_EMBEDDED { 1483 class EnsureSpace BASE_EMBEDDED {
1475 public: 1484 public:
1476 explicit EnsureSpace(Assembler* assembler) { 1485 explicit EnsureSpace(Assembler* assembler) {
1477 assembler->CheckBuffer(); 1486 assembler->CheckBuffer();
1478 } 1487 }
1479 }; 1488 };
1480 1489
1481 1490
1491 class ScopedPredictableCodeSize {
Michael Starzinger 2012/10/10 14:19:29 I would call this PredictableCodeSizeScope instead
danno 2012/10/17 10:04:44 Done.
1492 public:
1493 explicit ScopedPredictableCodeSize(Assembler* assembler)
1494 : asm_(assembler) {
1495 old_value_ = assembler->predictable_code_size();
1496 assembler->set_predictable_code_size(true);
1497 }
1498
1499 ~ScopedPredictableCodeSize() {
1500 if (!old_value_) {
1501 asm_->set_predictable_code_size(false);
1502 }
1503 }
1504
1505 private:
1506 Assembler* asm_;
1507 bool old_value_;
1508 };
1509
1510
1482 } } // namespace v8::internal 1511 } } // namespace v8::internal
1483 1512
1484 #endif // V8_ARM_ASSEMBLER_ARM_H_ 1513 #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