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/s390/unwinding-info-writer-s390.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(r14, kSystemPointerSize);
26 eh_frame_writer_.RecordRegisterSavedToStack(fp, 0);
27 } else {
28 eh_frame_writer_.RecordRegisterFollowsInitialRule(r14);
29 }
30 saved_lr_ = initial_state->saved_lr_;
31 }
32 }
33
EndInstructionBlock(const InstructionBlock * block)34 void UnwindingInfoWriter::EndInstructionBlock(const InstructionBlock* block) {
35 if (!enabled() || block_will_exit_) return;
36
37 for (const RpoNumber& successor : block->successors()) {
38 int successor_index = successor.ToInt();
39 DCHECK_LT(successor_index, static_cast<int>(block_initial_states_.size()));
40 const BlockInitialState* existing_state =
41 block_initial_states_[successor_index];
42
43 // If we already had an entry for this BB, check that the values are the
44 // same we are trying to insert.
45 if (existing_state) {
46 DCHECK_EQ(existing_state->saved_lr_, saved_lr_);
47 } else {
48 block_initial_states_[successor_index] =
49 zone_->New<BlockInitialState>(saved_lr_);
50 }
51 }
52 }
53
MarkFrameConstructed(int at_pc)54 void UnwindingInfoWriter::MarkFrameConstructed(int at_pc) {
55 if (!enabled()) return;
56
57 // Regardless of the type of frame constructed, the relevant part of the
58 // layout is always the one in the diagram:
59 //
60 // | .... | higher addresses
61 // +----------+ ^
62 // | LR | | |
63 // +----------+ | |
64 // | saved FP | | |
65 // +----------+ <-- FP v
66 // | .... | stack growth
67 //
68 // The LR is pushed on the stack, and we can record this fact at the end of
69 // the construction, since the LR itself is not modified in the process.
70 eh_frame_writer_.AdvanceLocation(at_pc);
71 eh_frame_writer_.RecordRegisterSavedToStack(r14, kSystemPointerSize);
72 eh_frame_writer_.RecordRegisterSavedToStack(fp, 0);
73 saved_lr_ = true;
74 }
75
MarkFrameDeconstructed(int at_pc)76 void UnwindingInfoWriter::MarkFrameDeconstructed(int at_pc) {
77 if (!enabled()) return;
78
79 // The lr is restored by the last operation in LeaveFrame().
80 eh_frame_writer_.AdvanceLocation(at_pc);
81 eh_frame_writer_.RecordRegisterFollowsInitialRule(r14);
82 saved_lr_ = false;
83 }
84
MarkLinkRegisterOnTopOfStack(int pc_offset)85 void UnwindingInfoWriter::MarkLinkRegisterOnTopOfStack(int pc_offset) {
86 if (!enabled()) return;
87
88 eh_frame_writer_.AdvanceLocation(pc_offset);
89 eh_frame_writer_.SetBaseAddressRegisterAndOffset(sp, 0);
90 eh_frame_writer_.RecordRegisterSavedToStack(r14, 0);
91 }
92
MarkPopLinkRegisterFromTopOfStack(int pc_offset)93 void UnwindingInfoWriter::MarkPopLinkRegisterFromTopOfStack(int pc_offset) {
94 if (!enabled()) return;
95
96 eh_frame_writer_.AdvanceLocation(pc_offset);
97 eh_frame_writer_.SetBaseAddressRegisterAndOffset(fp, 0);
98 eh_frame_writer_.RecordRegisterFollowsInitialRule(r14);
99 }
100
101 } // namespace compiler
102 } // namespace internal
103 } // namespace v8
104