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

Unified Diff: src/arm64/delayed-masm-arm64.h

Issue 268673003: ARM64: Optimize generated code for gaps (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: reset scratch register value when acquired Created 6 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm64/assembler-arm64.cc ('k') | src/arm64/delayed-masm-arm64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm64/delayed-masm-arm64.h
diff --git a/src/arm64/delayed-masm-arm64.h b/src/arm64/delayed-masm-arm64.h
new file mode 100644
index 0000000000000000000000000000000000000000..a8782c3dd7a5f832603ceb24e17dc37275e2a06c
--- /dev/null
+++ b/src/arm64/delayed-masm-arm64.h
@@ -0,0 +1,164 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_ARM64_DELAYED_MASM_ARM64_H_
+#define V8_ARM64_DELAYED_MASM_ARM64_H_
+
+#include "src/lithium.h"
+
+namespace v8 {
+namespace internal {
+
+class LCodeGen;
+
+// This class delays the generation of some instructions. This way, we have a
+// chance to merge two instructions in one (with load/store pair).
+// Each instruction must either:
+// - merge with the pending instruction and generate just one instruction.
+// - emit the pending instruction and then generate the instruction (or set the
+// pending instruction).
+class DelayedMasm BASE_EMBEDDED {
+ public:
+ DelayedMasm(LCodeGen* owner,
+ MacroAssembler* masm,
+ const Register& scratch_register)
+ : cgen_(owner), masm_(masm), scratch_register_(scratch_register),
+ scratch_register_used_(false), pending_(kNone), saved_value_(0) {
+#ifdef DEBUG
+ pending_register_ = no_reg;
+ pending_value_ = 0;
+ pending_pc_ = 0;
+ scratch_register_acquired_ = false;
+#endif
+ }
+ ~DelayedMasm() {
+ ASSERT(!scratch_register_acquired_);
+ ASSERT(!scratch_register_used_);
+ ASSERT(!pending());
+ }
+ inline void EndDelayedUse();
+
+ const Register& ScratchRegister() {
+ scratch_register_used_ = true;
+ return scratch_register_;
+ }
+ bool IsScratchRegister(const CPURegister& reg) {
+ return reg.Is(scratch_register_);
+ }
+ bool scratch_register_used() const { return scratch_register_used_; }
+ void reset_scratch_register_used() { scratch_register_used_ = false; }
+ // Acquire/Release scratch register for use outside this class.
+ void AcquireScratchRegister() {
+ EmitPending();
+ ResetSavedValue();
+#ifdef DEBUG
+ ASSERT(!scratch_register_acquired_);
+ scratch_register_acquired_ = true;
+#endif
+ }
+ void ReleaseScratchRegister() {
+#ifdef DEBUG
+ ASSERT(scratch_register_acquired_);
+ scratch_register_acquired_ = false;
+#endif
+ }
+ bool pending() { return pending_ != kNone; }
+
+ // Extra layer over the macro-assembler instructions (which emits the
+ // potential pending instruction).
+ inline void Mov(const Register& rd,
+ const Operand& operand,
+ DiscardMoveMode discard_mode = kDontDiscardForSameWReg);
+ inline void Fmov(FPRegister fd, FPRegister fn);
+ inline void Fmov(FPRegister fd, double imm);
+ inline void LoadObject(Register result, Handle<Object> object);
+ // Instructions which try to merge which the pending instructions.
+ void StackSlotMove(LOperand* src, LOperand* dst);
+ // StoreConstant can only be used if the scratch register is not acquired.
+ void StoreConstant(uint64_t value, const MemOperand& operand);
+ void Load(const CPURegister& rd, const MemOperand& operand);
+ void Store(const CPURegister& rd, const MemOperand& operand);
+ // Emit the potential pending instruction.
+ void EmitPending();
+ // Reset the pending state.
+ void ResetPending() {
+ pending_ = kNone;
+#ifdef DEBUG
+ pending_register_ = no_reg;
+ MemOperand tmp;
+ pending_address_src_ = tmp;
+ pending_address_dst_ = tmp;
+ pending_value_ = 0;
+ pending_pc_ = 0;
+#endif
+ }
+ void InitializeRootRegister() {
+ masm_->InitializeRootRegister();
+ }
+
+ private:
+ // Set the saved value and load the ScratchRegister with it.
+ void SetSavedValue(uint64_t saved_value) {
+ ASSERT(saved_value != 0);
+ if (saved_value_ != saved_value) {
+ masm_->Mov(ScratchRegister(), saved_value);
+ saved_value_ = saved_value;
+ }
+ }
+ // Reset the saved value (i.e. the value of ScratchRegister is no longer
+ // known).
+ void ResetSavedValue() {
+ saved_value_ = 0;
+ }
+
+ LCodeGen* cgen_;
+ MacroAssembler* masm_;
+
+ // Register used to store a constant.
+ Register scratch_register_;
+ bool scratch_register_used_;
+
+ // Sometimes we store or load two values in two contiguous stack slots.
+ // In this case, we try to use the ldp/stp instructions to reduce code size.
+ // To be able to do that, instead of generating directly the instructions,
+ // we register with the following fields that an instruction needs to be
+ // generated. Then with the next instruction, if the instruction is
+ // consistent with the pending one for stp/ldp we generate ldp/stp. Else,
+ // if they are not consistent, we generate the pending instruction and we
+ // register the new instruction (which becomes pending).
+
+ // Enumeration of instructions which can be pending.
+ enum Pending {
+ kNone,
+ kStoreConstant,
+ kLoad, kStore,
+ kStackSlotMove
+ };
+ // The pending instruction.
+ Pending pending_;
+ // For kLoad, kStore: register which must be loaded/stored.
+ CPURegister pending_register_;
+ // For kLoad, kStackSlotMove: address of the load.
+ MemOperand pending_address_src_;
+ // For kStoreConstant, kStore, kStackSlotMove: address of the store.
+ MemOperand pending_address_dst_;
+ // For kStoreConstant: value to be stored.
+ uint64_t pending_value_;
+ // Value held into the ScratchRegister if the saved_value_ is not 0.
+ // For 0, we use xzr.
+ uint64_t saved_value_;
+#ifdef DEBUG
+ // Address where the pending instruction must be generated. It's only used to
+ // check that nothing else has been generated since we set the pending
+ // instruction.
+ int pending_pc_;
+ // If true, the scratch register has been acquired outside this class. The
+ // scratch register can no longer be used for constants.
+ bool scratch_register_acquired_;
+#endif
+};
+
+} } // namespace v8::internal
+
+#endif // V8_ARM64_DELAYED_MASM_ARM64_H_
« no previous file with comments | « src/arm64/assembler-arm64.cc ('k') | src/arm64/delayed-masm-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698