blob: 4bd91028a7e86bac2fe2fff401f43512fd783a84 [file] [log] [blame]
Andrei Popescu31002712010-02-23 13:46:05 +00001// Copyright 2010 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
29#include "v8.h"
30
31#include "codegen-inl.h"
32#include "jump-target-inl.h"
33#include "register-allocator-inl.h"
Steve Block6ded16b2010-05-10 14:33:55 +010034#include "virtual-frame-inl.h"
Andrei Popescu31002712010-02-23 13:46:05 +000035
36namespace v8 {
37namespace internal {
38
39// -------------------------------------------------------------------------
40// JumpTarget implementation.
41
42#define __ ACCESS_MASM(cgen()->masm())
43
44void JumpTarget::DoJump() {
Steve Block6ded16b2010-05-10 14:33:55 +010045 ASSERT(cgen()->has_valid_frame());
46 // Live non-frame registers are not allowed at unconditional jumps
47 // because we have no way of invalidating the corresponding results
48 // which are still live in the C++ code.
49 ASSERT(cgen()->HasValidEntryRegisters());
50
51 if (is_bound()) {
52 // Backward jump. There already a frame expectation at the target.
53 ASSERT(direction_ == BIDIRECTIONAL);
54 cgen()->frame()->MergeTo(entry_frame_);
55 cgen()->DeleteFrame();
56 } else {
57 // Use the current frame as the expected one at the target if necessary.
58 if (entry_frame_ == NULL) {
59 entry_frame_ = cgen()->frame();
60 RegisterFile empty;
61 cgen()->SetFrame(NULL, &empty);
62 } else {
63 cgen()->frame()->MergeTo(entry_frame_);
64 cgen()->DeleteFrame();
65 }
66
67 // The predicate is_linked() should be made true. Its implementation
68 // detects the presence of a frame pointer in the reaching_frames_ list.
69 if (!is_linked()) {
70 reaching_frames_.Add(NULL);
71 ASSERT(is_linked());
72 }
73 }
74 __ b(&entry_label_);
75 __ nop(); // Branch delay slot nop.
Andrei Popescu31002712010-02-23 13:46:05 +000076}
77
78
79void JumpTarget::DoBranch(Condition cc, Hint ignored) {
80 UNIMPLEMENTED_MIPS();
81}
82
83
84void JumpTarget::Call() {
85 UNIMPLEMENTED_MIPS();
86}
87
88
89void JumpTarget::DoBind() {
Steve Block6ded16b2010-05-10 14:33:55 +010090 ASSERT(!is_bound());
91
92 // Live non-frame registers are not allowed at the start of a basic
93 // block.
94 ASSERT(!cgen()->has_valid_frame() || cgen()->HasValidEntryRegisters());
95
96 if (cgen()->has_valid_frame()) {
97 // If there is a current frame we can use it on the fall through.
98 if (entry_frame_ == NULL) {
99 entry_frame_ = new VirtualFrame(cgen()->frame());
100 } else {
101 ASSERT(cgen()->frame()->Equals(entry_frame_));
102 }
103 } else {
104 // If there is no current frame we must have an entry frame which we can
105 // copy.
106 ASSERT(entry_frame_ != NULL);
107 RegisterFile empty;
108 cgen()->SetFrame(new VirtualFrame(entry_frame_), &empty);
109 }
110
111 // The predicate is_linked() should be made false. Its implementation
112 // detects the presence (or absence) of frame pointers in the
113 // reaching_frames_ list. If we inserted a bogus frame to make
114 // is_linked() true, remove it now.
115 if (is_linked()) {
116 reaching_frames_.Clear();
117 }
118
119 __ bind(&entry_label_);
Andrei Popescu31002712010-02-23 13:46:05 +0000120}
121
122
123void BreakTarget::Jump() {
Steve Block6ded16b2010-05-10 14:33:55 +0100124 // On ARM we do not currently emit merge code for jumps, so we need to do
125 // it explicitly here. The only merging necessary is to drop extra
126 // statement state from the stack.
127 ASSERT(cgen()->has_valid_frame());
128 int count = cgen()->frame()->height() - expected_height_;
129 cgen()->frame()->Drop(count);
130 DoJump();
Andrei Popescu31002712010-02-23 13:46:05 +0000131}
132
133
134void BreakTarget::Jump(Result* arg) {
135 UNIMPLEMENTED_MIPS();
136}
137
138
139void BreakTarget::Bind() {
Steve Block6ded16b2010-05-10 14:33:55 +0100140#ifdef DEBUG
141 // All the forward-reaching frames should have been adjusted at the
142 // jumps to this target.
143 for (int i = 0; i < reaching_frames_.length(); i++) {
144 ASSERT(reaching_frames_[i] == NULL ||
145 reaching_frames_[i]->height() == expected_height_);
146 }
147#endif
148 // Drop leftover statement state from the frame before merging, even
149 // on the fall through. This is so we can bind the return target
150 // with state on the frame.
151 if (cgen()->has_valid_frame()) {
152 int count = cgen()->frame()->height() - expected_height_;
153 // On ARM we do not currently emit merge code at binding sites, so we need
154 // to do it explicitly here. The only merging necessary is to drop extra
155 // statement state from the stack.
156 cgen()->frame()->Drop(count);
157 }
158
159 DoBind();
Andrei Popescu31002712010-02-23 13:46:05 +0000160}
161
162
163void BreakTarget::Bind(Result* arg) {
164 UNIMPLEMENTED_MIPS();
165}
166
167
168#undef __
169
170
171} } // namespace v8::internal
172