OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 24 matching lines...) Expand all Loading... |
35 | 35 |
36 namespace v8 { | 36 namespace v8 { |
37 namespace internal { | 37 namespace internal { |
38 | 38 |
39 // ------------------------------------------------------------------------- | 39 // ------------------------------------------------------------------------- |
40 // JumpTarget implementation. | 40 // JumpTarget implementation. |
41 | 41 |
42 #define __ ACCESS_MASM(cgen()->masm()) | 42 #define __ ACCESS_MASM(cgen()->masm()) |
43 | 43 |
44 void JumpTarget::DoJump() { | 44 void JumpTarget::DoJump() { |
45 UNIMPLEMENTED_MIPS(); | 45 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. |
46 } | 76 } |
47 | 77 |
48 | 78 |
49 void JumpTarget::DoBranch(Condition cc, Hint ignored) { | 79 void JumpTarget::DoBranch(Condition cc, Hint ignored) { |
50 UNIMPLEMENTED_MIPS(); | 80 UNIMPLEMENTED_MIPS(); |
51 } | 81 } |
52 | 82 |
53 | 83 |
54 void JumpTarget::Call() { | 84 void JumpTarget::Call() { |
55 UNIMPLEMENTED_MIPS(); | 85 UNIMPLEMENTED_MIPS(); |
56 } | 86 } |
57 | 87 |
58 | 88 |
59 void JumpTarget::DoBind() { | 89 void JumpTarget::DoBind() { |
60 UNIMPLEMENTED_MIPS(); | 90 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_); |
61 } | 120 } |
62 | 121 |
63 | 122 |
64 void BreakTarget::Jump() { | 123 void BreakTarget::Jump() { |
65 UNIMPLEMENTED_MIPS(); | 124 // 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(); |
66 } | 131 } |
67 | 132 |
68 | 133 |
69 void BreakTarget::Jump(Result* arg) { | 134 void BreakTarget::Jump(Result* arg) { |
70 UNIMPLEMENTED_MIPS(); | 135 UNIMPLEMENTED_MIPS(); |
71 } | 136 } |
72 | 137 |
73 | 138 |
74 void BreakTarget::Bind() { | 139 void BreakTarget::Bind() { |
75 UNIMPLEMENTED_MIPS(); | 140 #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(); |
76 } | 160 } |
77 | 161 |
78 | 162 |
79 void BreakTarget::Bind(Result* arg) { | 163 void BreakTarget::Bind(Result* arg) { |
80 UNIMPLEMENTED_MIPS(); | 164 UNIMPLEMENTED_MIPS(); |
81 } | 165 } |
82 | 166 |
83 | 167 |
84 #undef __ | 168 #undef __ |
85 | 169 |
86 | 170 |
87 } } // namespace v8::internal | 171 } } // namespace v8::internal |
88 | 172 |
OLD | NEW |