blob: 408f75e79ab93aea0a69a0171dfb1ea6cf2f38a7 [file] [log] [blame]
ager@chromium.org5c838252010-02-19 08:53:10 +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
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +000031#if defined(V8_TARGET_ARCH_MIPS)
32
ager@chromium.org5c838252010-02-19 08:53:10 +000033#include "codegen-inl.h"
34#include "jump-target-inl.h"
35#include "register-allocator-inl.h"
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000036#include "virtual-frame-inl.h"
ager@chromium.org5c838252010-02-19 08:53:10 +000037
38namespace v8 {
39namespace internal {
40
41// -------------------------------------------------------------------------
42// JumpTarget implementation.
43
44#define __ ACCESS_MASM(cgen()->masm())
45
46void JumpTarget::DoJump() {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +000047 ASSERT(cgen()->has_valid_frame());
48 // Live non-frame registers are not allowed at unconditional jumps
49 // because we have no way of invalidating the corresponding results
50 // which are still live in the C++ code.
51 ASSERT(cgen()->HasValidEntryRegisters());
52
53 if (is_bound()) {
54 // Backward jump. There already a frame expectation at the target.
55 ASSERT(direction_ == BIDIRECTIONAL);
56 cgen()->frame()->MergeTo(entry_frame_);
57 cgen()->DeleteFrame();
58 } else {
59 // Use the current frame as the expected one at the target if necessary.
60 if (entry_frame_ == NULL) {
61 entry_frame_ = cgen()->frame();
62 RegisterFile empty;
63 cgen()->SetFrame(NULL, &empty);
64 } else {
65 cgen()->frame()->MergeTo(entry_frame_);
66 cgen()->DeleteFrame();
67 }
68
69 // The predicate is_linked() should be made true. Its implementation
70 // detects the presence of a frame pointer in the reaching_frames_ list.
71 if (!is_linked()) {
72 reaching_frames_.Add(NULL);
73 ASSERT(is_linked());
74 }
75 }
76 __ b(&entry_label_);
77 __ nop(); // Branch delay slot nop.
ager@chromium.org5c838252010-02-19 08:53:10 +000078}
79
80
81void JumpTarget::DoBranch(Condition cc, Hint ignored) {
82 UNIMPLEMENTED_MIPS();
83}
84
85
86void JumpTarget::Call() {
87 UNIMPLEMENTED_MIPS();
88}
89
90
91void JumpTarget::DoBind() {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +000092 ASSERT(!is_bound());
93
94 // Live non-frame registers are not allowed at the start of a basic
95 // block.
96 ASSERT(!cgen()->has_valid_frame() || cgen()->HasValidEntryRegisters());
97
98 if (cgen()->has_valid_frame()) {
99 // If there is a current frame we can use it on the fall through.
100 if (entry_frame_ == NULL) {
101 entry_frame_ = new VirtualFrame(cgen()->frame());
102 } else {
103 ASSERT(cgen()->frame()->Equals(entry_frame_));
104 }
105 } else {
106 // If there is no current frame we must have an entry frame which we can
107 // copy.
108 ASSERT(entry_frame_ != NULL);
109 RegisterFile empty;
110 cgen()->SetFrame(new VirtualFrame(entry_frame_), &empty);
111 }
112
113 // The predicate is_linked() should be made false. Its implementation
114 // detects the presence (or absence) of frame pointers in the
115 // reaching_frames_ list. If we inserted a bogus frame to make
116 // is_linked() true, remove it now.
117 if (is_linked()) {
118 reaching_frames_.Clear();
119 }
120
121 __ bind(&entry_label_);
ager@chromium.org5c838252010-02-19 08:53:10 +0000122}
123
124
125void BreakTarget::Jump() {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000126 // On ARM we do not currently emit merge code for jumps, so we need to do
127 // it explicitly here. The only merging necessary is to drop extra
128 // statement state from the stack.
129 ASSERT(cgen()->has_valid_frame());
130 int count = cgen()->frame()->height() - expected_height_;
131 cgen()->frame()->Drop(count);
132 DoJump();
ager@chromium.org5c838252010-02-19 08:53:10 +0000133}
134
135
136void BreakTarget::Jump(Result* arg) {
137 UNIMPLEMENTED_MIPS();
138}
139
140
141void BreakTarget::Bind() {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000142#ifdef DEBUG
143 // All the forward-reaching frames should have been adjusted at the
144 // jumps to this target.
145 for (int i = 0; i < reaching_frames_.length(); i++) {
146 ASSERT(reaching_frames_[i] == NULL ||
147 reaching_frames_[i]->height() == expected_height_);
148 }
149#endif
150 // Drop leftover statement state from the frame before merging, even
151 // on the fall through. This is so we can bind the return target
152 // with state on the frame.
153 if (cgen()->has_valid_frame()) {
154 int count = cgen()->frame()->height() - expected_height_;
155 // On ARM we do not currently emit merge code at binding sites, so we need
156 // to do it explicitly here. The only merging necessary is to drop extra
157 // statement state from the stack.
158 cgen()->frame()->Drop(count);
159 }
160
161 DoBind();
ager@chromium.org5c838252010-02-19 08:53:10 +0000162}
163
164
165void BreakTarget::Bind(Result* arg) {
166 UNIMPLEMENTED_MIPS();
167}
168
169
170#undef __
171
172
173} } // namespace v8::internal
174
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000175#endif // V8_TARGET_ARCH_MIPS