1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/backend/ppc/unwinding-info-writer-ppc.h"
6 #include "src/compiler/backend/instruction.h"
7
8 namespace v8 {
9 namespace internal {
10 namespace compiler {
BeginInstructionBlock(int pc_offset,const InstructionBlock * block)11 void UnwindingInfoWriter::BeginInstructionBlock(int pc_offset,
12 const InstructionBlock* block) {
13 if (!enabled()) return;
14
15 block_will_exit_ = false;
16
17 DCHECK_LT(block->rpo_number().ToInt(),
18 static_cast<int>(block_initial_states_.size()));
19 const BlockInitialState* initial_state =
20 block_initial_states_[block->rpo_number().ToInt()];
21 if (!initial_state) return;
22 if (initial_state->saved_lr_ != saved_lr_) {
23 eh_frame_writer_.AdvanceLocation(pc_offset);
24 if (initial_state->saved_lr_) {
25 eh_frame_writer_.RecordRegisterSavedToStack(kLrDwarfCode,
26 kSystemPointerSize);
27 eh_frame_writer_.RecordRegisterSavedToStack(fp, 0);
28 } else {
29 eh_frame_writer_.RecordRegisterFollowsInitialRule(kLrDwarfCode);
30 }
31 saved_lr_ = initial_state->saved_lr_;
32 }
33 }
34
EndInstructionBlock(const InstructionBlock * block)35 void UnwindingInfoWriter::EndInstructionBlock(const InstructionBlock* block) {
36 if (!enabled() || block_will_exit_) return;
37
38 for (const RpoNumber& successor : block->successors()) {
39 int successor_index = successor.ToInt();
40 DCHECK_LT(successor_index, static_cast<int>(block_initial_states_.size()));
41 const BlockInitialState* existing_state =
42 block_initial_states_[successor_index];
43
44 // If we already had an entry for this BB, check that the values are the
45 // same we are trying to insert.
46 if (existing_state) {
47 DCHECK_EQ(existing_state->saved_lr_, saved_lr_);
48 } else {
49 block_initial_states_[successor_index] =
50 zone_->New<BlockInitialState>(saved_lr_);
51 }
52 }
53 }
54
MarkFrameConstructed(int at_pc)55 void UnwindingInfoWriter::MarkFrameConstructed(int at_pc) {
56 if (!enabled()) return;
57
58 // Regardless of the type of frame constructed, the relevant part of the
59 // layout is always the one in the diagram:
60 //
61 // | .... | higher addresses
62 // +----------+ ^
63 // | LR | | |
64 // +----------+ | |
65 // | saved FP | | |
66 // +----------+ <-- FP v
67 // | .... | stack growth
68 //
69 // The LR is pushed on the stack, and we can record this fact at the end of
70 // the construction, since the LR itself is not modified in the process.
71 eh_frame_writer_.AdvanceLocation(at_pc);
72 eh_frame_writer_.RecordRegisterSavedToStack(kLrDwarfCode,
73 kSystemPointerSize);
74 eh_frame_writer_.RecordRegisterSavedToStack(fp, 0);
75 saved_lr_ = true;
76 }
77
MarkFrameDeconstructed(int at_pc)78 void UnwindingInfoWriter::MarkFrameDeconstructed(int at_pc) {
79 if (!enabled()) return;
80
81 // The lr is restored by the last operation in LeaveFrame().
82 eh_frame_writer_.AdvanceLocation(at_pc);
83 eh_frame_writer_.RecordRegisterFollowsInitialRule(kLrDwarfCode);
84 saved_lr_ = false;
85 }
86
MarkLinkRegisterOnTopOfStack(int pc_offset)87 void UnwindingInfoWriter::MarkLinkRegisterOnTopOfStack(int pc_offset) {
88 if (!enabled()) return;
89
90 eh_frame_writer_.AdvanceLocation(pc_offset);
91 eh_frame_writer_.SetBaseAddressRegisterAndOffset(sp, 0);
92 eh_frame_writer_.RecordRegisterSavedToStack(kLrDwarfCode, 0);
93 }
94
MarkPopLinkRegisterFromTopOfStack(int pc_offset)95 void UnwindingInfoWriter::MarkPopLinkRegisterFromTopOfStack(int pc_offset) {
96 if (!enabled()) return;
97
98 eh_frame_writer_.AdvanceLocation(pc_offset);
99 eh_frame_writer_.SetBaseAddressRegisterAndOffset(fp, 0);
100 eh_frame_writer_.RecordRegisterFollowsInitialRule(kLrDwarfCode);
101 }
102
103 } // namespace compiler
104 } // namespace internal
105 } // namespace v8
106