Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(327)

Side by Side Diff: src/mips/codegen-mips.cc

Issue 6709022: Re-establish mips basic infrastructure. (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 28
29 #include "v8.h" 29 #include "v8.h"
30 30
31 #if defined(V8_TARGET_ARCH_MIPS) 31 #if defined(V8_TARGET_ARCH_MIPS)
32 32
33 #include "bootstrapper.h" 33 #include "bootstrapper.h"
34 #include "code-stubs.h"
34 #include "codegen-inl.h" 35 #include "codegen-inl.h"
35 #include "compiler.h" 36 #include "compiler.h"
36 #include "debug.h" 37 #include "debug.h"
37 #include "ic-inl.h" 38 #include "ic-inl.h"
39 #include "jsregexp.h"
40 #include "jump-target-inl.h"
38 #include "parser.h" 41 #include "parser.h"
42 #include "regexp-macro-assembler.h"
43 #include "regexp-stack.h"
39 #include "register-allocator-inl.h" 44 #include "register-allocator-inl.h"
40 #include "runtime.h" 45 #include "runtime.h"
41 #include "scopes.h" 46 #include "scopes.h"
47 #include "stub-cache.h"
42 #include "virtual-frame-inl.h" 48 #include "virtual-frame-inl.h"
43 49 #include "virtual-frame-mips-inl.h"
44
45 50
46 namespace v8 { 51 namespace v8 {
47 namespace internal { 52 namespace internal {
48 53
54
49 #define __ ACCESS_MASM(masm_) 55 #define __ ACCESS_MASM(masm_)
50 56
51 57 // -------------------------------------------------------------------------
52
53 // -----------------------------------------------------------------------------
54 // Platform-specific DeferredCode functions. 58 // Platform-specific DeferredCode functions.
55 59
56
57 void DeferredCode::SaveRegisters() { 60 void DeferredCode::SaveRegisters() {
58 UNIMPLEMENTED_MIPS(); 61 // On MIPS you either have a completely spilled frame or you
62 // handle it yourself, but at the moment there's no automation
63 // of registers and deferred code.
59 } 64 }
60 65
61 66
62 void DeferredCode::RestoreRegisters() { 67 void DeferredCode::RestoreRegisters() {
63 UNIMPLEMENTED_MIPS();
64 } 68 }
65 69
66 70
71 // -------------------------------------------------------------------------
72 // Platform-specific RuntimeCallHelper functions.
73
74 void VirtualFrameRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
75 frame_state_->frame()->AssertIsSpilled();
76 }
77
78
79 void VirtualFrameRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
80 }
81
82
83 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
84 masm->EnterInternalFrame();
85 }
86
87
88 void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
89 masm->LeaveInternalFrame();
90 }
91
92
67 // ----------------------------------------------------------------------------- 93 // -----------------------------------------------------------------------------
68 // CodeGenState implementation. 94 // CodeGenState implementation.
69 95
70 CodeGenState::CodeGenState(CodeGenerator* owner) 96 CodeGenState::CodeGenState(CodeGenerator* owner)
71 : owner_(owner), 97 : owner_(owner),
72 true_target_(NULL), 98 previous_(owner->state()) {
73 false_target_(NULL), 99 owner->set_state(this);
74 previous_(NULL) {
75 owner_->set_state(this);
76 } 100 }
77 101
78 102
79 CodeGenState::CodeGenState(CodeGenerator* owner, 103 ConditionCodeGenState::ConditionCodeGenState(CodeGenerator* owner,
80 JumpTarget* true_target, 104 JumpTarget* true_target,
81 JumpTarget* false_target) 105 JumpTarget* false_target)
82 : owner_(owner), 106 : CodeGenState(owner),
83 true_target_(true_target), 107 true_target_(true_target),
84 false_target_(false_target), 108 false_target_(false_target) {
85 previous_(owner->state()) { 109 owner->set_state(this);
86 owner_->set_state(this);
87 } 110 }
88 111
89 112
113 TypeInfoCodeGenState::TypeInfoCodeGenState(CodeGenerator* owner,
114 Slot* slot,
115 TypeInfo type_info)
116 : CodeGenState(owner),
117 slot_(slot) {
118 owner->set_state(this);
119 old_type_info_ = owner->set_type_info(slot, type_info);
120 }
121
122
90 CodeGenState::~CodeGenState() { 123 CodeGenState::~CodeGenState() {
91 ASSERT(owner_->state() == this); 124 ASSERT(owner_->state() == this);
92 owner_->set_state(previous_); 125 owner_->set_state(previous_);
93 } 126 }
94 127
95 128
129 TypeInfoCodeGenState::~TypeInfoCodeGenState() {
130 owner()->set_type_info(slot_, old_type_info_);
131 }
132
133
96 // ----------------------------------------------------------------------------- 134 // -----------------------------------------------------------------------------
97 // CodeGenerator implementation 135 // CodeGenerator implementation.
136
137 int CodeGenerator::inlined_write_barrier_size_ = -1;
98 138
99 CodeGenerator::CodeGenerator(MacroAssembler* masm) 139 CodeGenerator::CodeGenerator(MacroAssembler* masm)
100 : deferred_(8), 140 : deferred_(8),
101 masm_(masm), 141 masm_(masm),
142 info_(NULL),
102 frame_(NULL), 143 frame_(NULL),
103 allocator_(NULL), 144 allocator_(NULL),
104 cc_reg_(cc_always), 145 cc_reg_(cc_always),
105 state_(NULL), 146 state_(NULL),
147 loop_nesting_(0),
148 type_info_(NULL),
149 function_return_(JumpTarget::BIDIRECTIONAL),
106 function_return_is_shadowed_(false) { 150 function_return_is_shadowed_(false) {
107 } 151 }
108 152
109 153
110 // Calling conventions: 154 // Calling conventions:
111 // fp: caller's frame pointer 155 // fp: caller's frame pointer
112 // sp: stack pointer 156 // sp: stack pointer
113 // a1: called JS function 157 // a1: called JS function
114 // cp: callee's context 158 // cp: callee's context
115 159
116 void CodeGenerator::Generate(CompilationInfo* info) { 160 void CodeGenerator::Generate(CompilationInfo* info) {
117 // Record the position for debugging purposes. 161 UNIMPLEMENTED_MIPS();
118 CodeForFunctionPosition(info->function()); 162 }
119 163
120 // Initialize state. 164
121 info_ = info; 165 int CodeGenerator::NumberOfSlot(Slot* slot) {
122 ASSERT(allocator_ == NULL); 166 UNIMPLEMENTED_MIPS();
123 RegisterAllocator register_allocator(this); 167 return 0;
124 allocator_ = &register_allocator;
125 ASSERT(frame_ == NULL);
126 frame_ = new VirtualFrame();
127 cc_reg_ = cc_always;
128
129 {
130 CodeGenState state(this);
131
132 // Registers:
133 // a1: called JS function
134 // ra: return address
135 // fp: caller's frame pointer
136 // sp: stack pointer
137 // cp: callee's context
138 //
139 // Stack:
140 // arguments
141 // receiver
142
143 frame_->Enter();
144
145 // Allocate space for locals and initialize them.
146 frame_->AllocateStackSlots();
147
148 // Initialize the function return target.
149 function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
150 function_return_is_shadowed_ = false;
151
152 VirtualFrame::SpilledScope spilled_scope;
153 if (scope()->num_heap_slots() > 0) {
154 UNIMPLEMENTED_MIPS();
155 }
156
157 {
158 Comment cmnt2(masm_, "[ copy context parameters into .context");
159
160 // Note that iteration order is relevant here! If we have the same
161 // parameter twice (e.g., function (x, y, x)), and that parameter
162 // needs to be copied into the context, it must be the last argument
163 // passed to the parameter that needs to be copied. This is a rare
164 // case so we don't check for it, instead we rely on the copying
165 // order: such a parameter is copied repeatedly into the same
166 // context location and thus the last value is what is seen inside
167 // the function.
168 for (int i = 0; i < scope()->num_parameters(); i++) {
169 UNIMPLEMENTED_MIPS();
170 }
171 }
172
173 // Store the arguments object. This must happen after context
174 // initialization because the arguments object may be stored in the
175 // context.
176 if (scope()->arguments() != NULL) {
177 UNIMPLEMENTED_MIPS();
178 }
179
180 // Generate code to 'execute' declarations and initialize functions
181 // (source elements). In case of an illegal redeclaration we need to
182 // handle that instead of processing the declarations.
183 if (scope()->HasIllegalRedeclaration()) {
184 Comment cmnt(masm_, "[ illegal redeclarations");
185 scope()->VisitIllegalRedeclaration(this);
186 } else {
187 Comment cmnt(masm_, "[ declarations");
188 ProcessDeclarations(scope()->declarations());
189 // Bail out if a stack-overflow exception occurred when processing
190 // declarations.
191 if (HasStackOverflow()) return;
192 }
193
194 if (FLAG_trace) {
195 UNIMPLEMENTED_MIPS();
196 }
197
198 // Compile the body of the function in a vanilla state. Don't
199 // bother compiling all the code if the scope has an illegal
200 // redeclaration.
201 if (!scope()->HasIllegalRedeclaration()) {
202 Comment cmnt(masm_, "[ function body");
203 #ifdef DEBUG
204 bool is_builtin = Bootstrapper::IsActive();
205 bool should_trace =
206 is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls;
207 if (should_trace) {
208 UNIMPLEMENTED_MIPS();
209 }
210 #endif
211 VisitStatementsAndSpill(info->function()->body());
212 }
213 }
214
215 if (has_valid_frame() || function_return_.is_linked()) {
216 if (!function_return_.is_linked()) {
217 CodeForReturnPosition(info->function());
218 }
219 // Registers:
220 // v0: result
221 // sp: stack pointer
222 // fp: frame pointer
223 // cp: callee's context
224
225 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
226
227 function_return_.Bind();
228 if (FLAG_trace) {
229 UNIMPLEMENTED_MIPS();
230 }
231
232 // Add a label for checking the size of the code used for returning.
233 Label check_exit_codesize;
234 masm_->bind(&check_exit_codesize);
235
236 masm_->mov(sp, fp);
237 masm_->lw(fp, MemOperand(sp, 0));
238 masm_->lw(ra, MemOperand(sp, 4));
239 masm_->addiu(sp, sp, 8);
240
241 // Here we use masm_-> instead of the __ macro to avoid the code coverage
242 // tool from instrumenting as we rely on the code size here.
243 // TODO(MIPS): Should we be able to use more than 0x1ffe parameters?
244 masm_->addiu(sp, sp, (scope()->num_parameters() + 1) * kPointerSize);
245 masm_->Jump(ra);
246 // The Jump automatically generates a nop in the branch delay slot.
247
248 // Check that the size of the code used for returning matches what is
249 // expected by the debugger.
250 ASSERT_EQ(kJSReturnSequenceLength,
251 masm_->InstructionsGeneratedSince(&check_exit_codesize));
252 }
253
254 // Code generation state must be reset.
255 ASSERT(!has_cc());
256 ASSERT(state_ == NULL);
257 ASSERT(!function_return_is_shadowed_);
258 function_return_.Unuse();
259 DeleteFrame();
260
261 // Process any deferred code using the register allocator.
262 if (!HasStackOverflow()) {
263 ProcessDeferred();
264 }
265
266 allocator_ = NULL;
267 }
268
269
270 void CodeGenerator::LoadReference(Reference* ref) {
271 VirtualFrame::SpilledScope spilled_scope;
272 Comment cmnt(masm_, "[ LoadReference");
273 Expression* e = ref->expression();
274 Property* property = e->AsProperty();
275 Variable* var = e->AsVariableProxy()->AsVariable();
276
277 if (property != NULL) {
278 UNIMPLEMENTED_MIPS();
279 } else if (var != NULL) {
280 // The expression is a variable proxy that does not rewrite to a
281 // property. Global variables are treated as named property references.
282 if (var->is_global()) {
283 LoadGlobal();
284 ref->set_type(Reference::NAMED);
285 } else {
286 ASSERT(var->slot() != NULL);
287 ref->set_type(Reference::SLOT);
288 }
289 } else {
290 UNIMPLEMENTED_MIPS();
291 }
292 }
293
294
295 void CodeGenerator::UnloadReference(Reference* ref) {
296 VirtualFrame::SpilledScope spilled_scope;
297 // Pop a reference from the stack while preserving TOS.
298 Comment cmnt(masm_, "[ UnloadReference");
299 int size = ref->size();
300 if (size > 0) {
301 frame_->EmitPop(a0);
302 frame_->Drop(size);
303 frame_->EmitPush(a0);
304 }
305 ref->set_unloaded();
306 } 168 }
307 169
308 170
309 MemOperand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { 171 MemOperand CodeGenerator::SlotOperand(Slot* slot, Register tmp) {
310 // Currently, this assertion will fail if we try to assign to 172 UNIMPLEMENTED_MIPS();
311 // a constant variable that is constant because it is read-only 173 return MemOperand(zero_reg, 0);
312 // (such as the variable referring to a named function expression). 174 }
313 // We need to implement assignments to read-only variables. 175
314 // Ideally, we should do this during AST generation (by converting 176
315 // such assignments into expression statements); however, in general 177 MemOperand CodeGenerator::ContextSlotOperandCheckExtensions(
316 // we may not be able to make the decision until past AST generation, 178 Slot* slot,
317 // that is when the entire program is known. 179 Register tmp,
318 ASSERT(slot != NULL); 180 Register tmp2,
319 int index = slot->index(); 181 JumpTarget* slow) {
320 switch (slot->type()) { 182 UNIMPLEMENTED_MIPS();
321 case Slot::PARAMETER: 183 return MemOperand(zero_reg, 0);
322 UNIMPLEMENTED_MIPS(); 184 }
323 return MemOperand(no_reg, 0); 185
324 186
325 case Slot::LOCAL:
326 return frame_->LocalAt(index);
327
328 case Slot::CONTEXT: {
329 UNIMPLEMENTED_MIPS();
330 return MemOperand(no_reg, 0);
331 }
332
333 default:
334 UNREACHABLE();
335 return MemOperand(no_reg, 0);
336 }
337 }
338
339
340 // Loads a value on TOS. If it is a boolean value, the result may have been
341 // (partially) translated into branches, or it may have set the condition
342 // code register. If force_cc is set, the value is forced to set the
343 // condition code register and no value is pushed. If the condition code
344 // register was set, has_cc() is true and cc_reg_ contains the condition to
345 // test for 'true'.
346 void CodeGenerator::LoadCondition(Expression* x, 187 void CodeGenerator::LoadCondition(Expression* x,
347 JumpTarget* true_target, 188 JumpTarget* true_target,
348 JumpTarget* false_target, 189 JumpTarget* false_target,
349 bool force_cc) { 190 bool force_cc) {
350 ASSERT(!has_cc()); 191 UNIMPLEMENTED_MIPS();
351 int original_height = frame_->height(); 192 }
352 193
353 { CodeGenState new_state(this, true_target, false_target); 194
354 Visit(x); 195 void CodeGenerator::Load(Expression* x) {
355 196 UNIMPLEMENTED_MIPS();
356 // If we hit a stack overflow, we may not have actually visited 197 }
357 // the expression. In that case, we ensure that we have a 198
358 // valid-looking frame state because we will continue to generate 199
359 // code as we unwind the C++ stack. 200 void CodeGenerator::LoadGlobal() {
360 // 201 UNIMPLEMENTED_MIPS();
361 // It's possible to have both a stack overflow and a valid frame 202 }
362 // state (eg, a subexpression overflowed, visiting it returned 203
363 // with a dummied frame state, and visiting this expression 204
364 // returned with a normal-looking state). 205 void CodeGenerator::LoadGlobalReceiver(Register scratch) {
365 if (HasStackOverflow() && 206 UNIMPLEMENTED_MIPS();
366 has_valid_frame() && 207 }
367 !has_cc() && 208
368 frame_->height() == original_height) { 209
369 true_target->Jump(); 210 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() {
370 } 211 UNIMPLEMENTED_MIPS();
212 return EAGER_ARGUMENTS_ALLOCATION;
213 }
214
215
216 void CodeGenerator::StoreArgumentsObject(bool initial) {
217 UNIMPLEMENTED_MIPS();
218 }
219
220
221 void CodeGenerator::LoadTypeofExpression(Expression* x) {
222 UNIMPLEMENTED_MIPS();
223 }
224
225
226 Reference::Reference(CodeGenerator* cgen,
227 Expression* expression,
228 bool persist_after_get)
229 : cgen_(cgen),
230 expression_(expression),
231 type_(ILLEGAL),
232 persist_after_get_(persist_after_get) {
233 UNIMPLEMENTED_MIPS();
234 }
235
236
237 Reference::~Reference() {
238 UNIMPLEMENTED_MIPS();
239 }
240
241
242 void CodeGenerator::LoadReference(Reference* ref) {
243 UNIMPLEMENTED_MIPS();
244 }
245
246
247 void CodeGenerator::UnloadReference(Reference* ref) {
248 UNIMPLEMENTED_MIPS();
249 }
250
251
252 // ECMA-262, section 9.2, page 30: ToBoolean(). Convert the given
253 // register to a boolean in the condition code register. The code
254 // may jump to 'false_target' in case the register converts to 'false'.
255 void CodeGenerator::ToBoolean(JumpTarget* true_target,
256 JumpTarget* false_target) {
257 UNIMPLEMENTED_MIPS();
258 }
259
260
261 void CodeGenerator::GenericBinaryOperation(Token::Value op,
262 OverwriteMode overwrite_mode,
263 GenerateInlineSmi inline_smi,
264 int constant_rhs) {
265 UNIMPLEMENTED_MIPS();
266 }
267
268
269 class DeferredInlineSmiOperation: public DeferredCode {
270 public:
271 DeferredInlineSmiOperation(Token::Value op,
272 int value,
273 bool reversed,
274 OverwriteMode overwrite_mode,
275 Register tos)
276 : op_(op),
277 value_(value),
278 reversed_(reversed),
279 overwrite_mode_(overwrite_mode),
280 tos_register_(tos) {
281 set_comment("[ DeferredInlinedSmiOperation");
371 } 282 }
372 if (force_cc && frame_ != NULL && !has_cc()) { 283
373 // Convert the TOS value to a boolean in the condition code register. 284 virtual void Generate();
374 UNIMPLEMENTED_MIPS(); 285 // This stub makes explicit calls to SaveRegisters(), RestoreRegisters() and
375 } 286 // Exit(). Currently on MIPS SaveRegisters() and RestoreRegisters() are empty
376 ASSERT(!force_cc || !has_valid_frame() || has_cc()); 287 // methods, it is the responsibility of the deferred code to save and restore
377 ASSERT(!has_valid_frame() || 288 // registers.
378 (has_cc() && frame_->height() == original_height) || 289 virtual bool AutoSaveAndRestore() { return false; }
379 (!has_cc() && frame_->height() == original_height + 1)); 290
380 } 291 void JumpToNonSmiInput(Condition cond, Register cmp1, const Operand& cmp2);
381 292 void JumpToAnswerOutOfRange(Condition cond,
382 293 Register cmp1,
383 void CodeGenerator::Load(Expression* x) { 294 const Operand& cmp2);
384 #ifdef DEBUG 295
385 int original_height = frame_->height(); 296 private:
386 #endif 297 void GenerateNonSmiInput();
387 JumpTarget true_target; 298 void GenerateAnswerOutOfRange();
388 JumpTarget false_target; 299 void WriteNonSmiAnswer(Register answer,
389 LoadCondition(x, &true_target, &false_target, false); 300 Register heap_number,
390 301 Register scratch);
391 if (has_cc()) { 302
392 UNIMPLEMENTED_MIPS(); 303 Token::Value op_;
393 } 304 int value_;
394 305 bool reversed_;
395 if (true_target.is_linked() || false_target.is_linked()) { 306 OverwriteMode overwrite_mode_;
396 UNIMPLEMENTED_MIPS(); 307 Register tos_register_;
397 } 308 Label non_smi_input_;
398 ASSERT(has_valid_frame()); 309 Label answer_out_of_range_;
399 ASSERT(!has_cc()); 310 };
400 ASSERT(frame_->height() == original_height + 1); 311
401 } 312
402 313 // For bit operations we try harder and handle the case where the input is not
403 314 // a Smi but a 32bits integer without calling the generic stub.
404 void CodeGenerator::LoadGlobal() { 315 void DeferredInlineSmiOperation::JumpToNonSmiInput(Condition cond,
405 VirtualFrame::SpilledScope spilled_scope; 316 Register cmp1,
406 __ lw(a0, GlobalObject()); 317 const Operand& cmp2) {
407 frame_->EmitPush(a0); 318 UNIMPLEMENTED_MIPS();
408 } 319 }
409 320
410 321
411 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { 322 // For bit operations the result is always 32bits so we handle the case where
412 VirtualFrame::SpilledScope spilled_scope; 323 // the result does not fit in a Smi without calling the generic stub.
413 if (slot->type() == Slot::LOOKUP) { 324 void DeferredInlineSmiOperation::JumpToAnswerOutOfRange(Condition cond,
414 UNIMPLEMENTED_MIPS(); 325 Register cmp1,
415 } else { 326 const Operand& cmp2) {
416 __ lw(a0, SlotOperand(slot, a2)); 327 UNIMPLEMENTED_MIPS();
417 frame_->EmitPush(a0); 328 }
418 if (slot->var()->mode() == Variable::CONST) { 329
419 UNIMPLEMENTED_MIPS(); 330
420 } 331 // On entry the non-constant side of the binary operation is in tos_register_
421 } 332 // and the constant smi side is nowhere. The tos_register_ is not used by the
422 } 333 // virtual frame. On exit the answer is in the tos_register_ and the virtual
423 334 // frame is unchanged.
424 335 void DeferredInlineSmiOperation::Generate() {
425 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { 336 UNIMPLEMENTED_MIPS();
426 ASSERT(slot != NULL); 337 }
427 if (slot->type() == Slot::LOOKUP) { 338
428 UNIMPLEMENTED_MIPS(); 339
429 } else { 340 // Convert and write the integer answer into heap_number.
430 ASSERT(!slot->var()->is_dynamic()); 341 void DeferredInlineSmiOperation::WriteNonSmiAnswer(Register answer,
431 342 Register heap_number,
432 JumpTarget exit; 343 Register scratch) {
433 if (init_state == CONST_INIT) { 344 UNIMPLEMENTED_MIPS();
434 UNIMPLEMENTED_MIPS(); 345 }
435 } 346
436 347
437 // We must execute the store. Storing a variable must keep the 348 void DeferredInlineSmiOperation::GenerateNonSmiInput() {
438 // (new) value on the stack. This is necessary for compiling 349 UNIMPLEMENTED_MIPS();
439 // assignment expressions. 350 }
440 // 351
441 // Note: We will reach here even with slot->var()->mode() == 352
442 // Variable::CONST because of const declarations which will 353 void DeferredInlineSmiOperation::GenerateAnswerOutOfRange() {
443 // initialize consts to 'the hole' value and by doing so, end up 354 UNIMPLEMENTED_MIPS();
444 // calling this code. a2 may be loaded with context; used below in 355 }
445 // RecordWrite. 356
446 frame_->EmitPop(a0); 357
447 __ sw(a0, SlotOperand(slot, a2)); 358 void CodeGenerator::SmiOperation(Token::Value op,
448 frame_->EmitPush(a0); 359 Handle<Object> value,
449 if (slot->type() == Slot::CONTEXT) { 360 bool reversed,
450 UNIMPLEMENTED_MIPS(); 361 OverwriteMode mode) {
451 } 362 UNIMPLEMENTED_MIPS();
452 // If we definitely did not jump over the assignment, we do not need 363 }
453 // to bind the exit label. Doing so can defeat peephole 364
454 // optimization. 365
455 if (init_state == CONST_INIT || slot->type() == Slot::CONTEXT) { 366 // On MIPS we load registers condReg1 and condReg2 with the values which should
456 exit.Bind(); 367 // be compared. With the CodeGenerator::cc_reg_ condition, functions will be
457 } 368 // able to evaluate correctly the condition. (eg CodeGenerator::Branch)
458 } 369 void CodeGenerator::Comparison(Condition cc,
370 Expression* left,
371 Expression* right,
372 bool strict) {
373 UNIMPLEMENTED_MIPS();
374 }
375
376
377 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
378 CallFunctionFlags flags,
379 int position) {
380 UNIMPLEMENTED_MIPS();
381 }
382
383
384 void CodeGenerator::CallApplyLazy(Expression* applicand,
385 Expression* receiver,
386 VariableProxy* arguments,
387 int position) {
388 UNIMPLEMENTED_MIPS();
389 }
390
391
392 void CodeGenerator::Branch(bool if_true, JumpTarget* target) {
393 UNIMPLEMENTED_MIPS();
394 }
395
396
397 void CodeGenerator::CheckStack() {
398 UNIMPLEMENTED_MIPS();
459 } 399 }
460 400
461 401
462 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 402 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
463 VirtualFrame::SpilledScope spilled_scope; 403 UNIMPLEMENTED_MIPS();
464 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { 404 }
465 VisitAndSpill(statements->at(i)); 405
466 } 406
467 }
468
469
470 void CodeGenerator::VisitBlock(Block* node) { 407 void CodeGenerator::VisitBlock(Block* node) {
471 UNIMPLEMENTED_MIPS(); 408 UNIMPLEMENTED_MIPS();
472 } 409 }
473 410
474 411
475 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 412 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
476 VirtualFrame::SpilledScope spilled_scope; 413 UNIMPLEMENTED_MIPS();
477 frame_->EmitPush(cp);
478 __ li(t0, Operand(pairs));
479 frame_->EmitPush(t0);
480 __ li(t0, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
481 frame_->EmitPush(t0);
482 frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
483 // The result is discarded.
484 } 414 }
485 415
486 416
487 void CodeGenerator::VisitDeclaration(Declaration* node) { 417 void CodeGenerator::VisitDeclaration(Declaration* node) {
488 UNIMPLEMENTED_MIPS(); 418 UNIMPLEMENTED_MIPS();
489 } 419 }
490 420
491 421
492 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { 422 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
493 #ifdef DEBUG 423 UNIMPLEMENTED_MIPS();
494 int original_height = frame_->height();
495 #endif
496 VirtualFrame::SpilledScope spilled_scope;
497 Comment cmnt(masm_, "[ ExpressionStatement");
498 CodeForStatementPosition(node);
499 Expression* expression = node->expression();
500 expression->MarkAsStatement();
501 LoadAndSpill(expression);
502 frame_->Drop();
503 ASSERT(frame_->height() == original_height);
504 } 424 }
505 425
506 426
507 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { 427 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
508 UNIMPLEMENTED_MIPS(); 428 UNIMPLEMENTED_MIPS();
509 } 429 }
510 430
511 431
512 void CodeGenerator::VisitIfStatement(IfStatement* node) { 432 void CodeGenerator::VisitIfStatement(IfStatement* node) {
513 UNIMPLEMENTED_MIPS(); 433 UNIMPLEMENTED_MIPS();
514 } 434 }
515 435
516 436
517 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { 437 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
518 UNIMPLEMENTED_MIPS(); 438 UNIMPLEMENTED_MIPS();
519 } 439 }
520 440
521 441
522 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { 442 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
523 UNIMPLEMENTED_MIPS(); 443 UNIMPLEMENTED_MIPS();
524 } 444 }
525 445
526 446
527 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { 447 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
528 VirtualFrame::SpilledScope spilled_scope; 448 UNIMPLEMENTED_MIPS();
529 Comment cmnt(masm_, "[ ReturnStatement");
530
531 CodeForStatementPosition(node);
532 LoadAndSpill(node->expression());
533 if (function_return_is_shadowed_) {
534 frame_->EmitPop(v0);
535 function_return_.Jump();
536 } else {
537 // Pop the result from the frame and prepare the frame for
538 // returning thus making it easier to merge.
539 frame_->EmitPop(v0);
540 frame_->PrepareForReturn();
541
542 function_return_.Jump();
543 }
544 } 449 }
545 450
546 451
452 void CodeGenerator::GenerateReturnSequence() {
453 UNIMPLEMENTED_MIPS();
454 }
455
456
547 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { 457 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
548 UNIMPLEMENTED_MIPS(); 458 UNIMPLEMENTED_MIPS();
549 } 459 }
550 460
551 461
552 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { 462 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
553 UNIMPLEMENTED_MIPS(); 463 UNIMPLEMENTED_MIPS();
554 } 464 }
555 465
556 466
(...skipping 30 matching lines...) Expand all
587 void CodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* node) { 497 void CodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* node) {
588 UNIMPLEMENTED_MIPS(); 498 UNIMPLEMENTED_MIPS();
589 } 499 }
590 500
591 501
592 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { 502 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
593 UNIMPLEMENTED_MIPS(); 503 UNIMPLEMENTED_MIPS();
594 } 504 }
595 505
596 506
507 void CodeGenerator::InstantiateFunction(
508 Handle<SharedFunctionInfo> function_info,
509 bool pretenure) {
510 UNIMPLEMENTED_MIPS();
511 }
512
513
597 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { 514 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
598 UNIMPLEMENTED_MIPS(); 515 UNIMPLEMENTED_MIPS();
599 } 516 }
600 517
601 518
602 void CodeGenerator::VisitSharedFunctionInfoLiteral( 519 void CodeGenerator::VisitSharedFunctionInfoLiteral(
603 SharedFunctionInfoLiteral* node) { 520 SharedFunctionInfoLiteral* node) {
604 UNIMPLEMENTED_MIPS(); 521 UNIMPLEMENTED_MIPS();
605 } 522 }
606 523
607 524
608 void CodeGenerator::VisitConditional(Conditional* node) { 525 void CodeGenerator::VisitConditional(Conditional* node) {
609 UNIMPLEMENTED_MIPS(); 526 UNIMPLEMENTED_MIPS();
610 } 527 }
611 528
612 529
530 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
531 UNIMPLEMENTED_MIPS();
532 }
533
534
535 void CodeGenerator::LoadFromSlotCheckForArguments(Slot* slot,
536 TypeofState state) {
537 UNIMPLEMENTED_MIPS();
538 }
539
540
541 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) {
542 UNIMPLEMENTED_MIPS();
543 }
544
545
546 void CodeGenerator::LoadFromGlobalSlotCheckExtensions(Slot* slot,
547 TypeofState typeof_state,
548 JumpTarget* slow) {
549 UNIMPLEMENTED_MIPS();
550 }
551
552
553 void CodeGenerator::EmitDynamicLoadFromSlotFastCase(Slot* slot,
554 TypeofState typeof_state,
555 JumpTarget* slow,
556 JumpTarget* done) {
557 UNIMPLEMENTED_MIPS();
558 }
559
560
613 void CodeGenerator::VisitSlot(Slot* node) { 561 void CodeGenerator::VisitSlot(Slot* node) {
614 #ifdef DEBUG 562 UNIMPLEMENTED_MIPS();
615 int original_height = frame_->height();
616 #endif
617 VirtualFrame::SpilledScope spilled_scope;
618 Comment cmnt(masm_, "[ Slot");
619 LoadFromSlot(node, typeof_state());
620 ASSERT(frame_->height() == original_height + 1);
621 } 563 }
622 564
623 565
624 void CodeGenerator::VisitVariableProxy(VariableProxy* node) { 566 void CodeGenerator::VisitVariableProxy(VariableProxy* node) {
625 #ifdef DEBUG 567 UNIMPLEMENTED_MIPS();
626 int original_height = frame_->height();
627 #endif
628 VirtualFrame::SpilledScope spilled_scope;
629 Comment cmnt(masm_, "[ VariableProxy");
630
631 Variable* var = node->var();
632 Expression* expr = var->rewrite();
633 if (expr != NULL) {
634 Visit(expr);
635 } else {
636 ASSERT(var->is_global());
637 Reference ref(this, node);
638 ref.GetValueAndSpill();
639 }
640 ASSERT(frame_->height() == original_height + 1);
641 } 568 }
642 569
643 570
644 void CodeGenerator::VisitLiteral(Literal* node) { 571 void CodeGenerator::VisitLiteral(Literal* node) {
645 #ifdef DEBUG 572 UNIMPLEMENTED_MIPS();
646 int original_height = frame_->height();
647 #endif
648 VirtualFrame::SpilledScope spilled_scope;
649 Comment cmnt(masm_, "[ Literal");
650 __ li(t0, Operand(node->handle()));
651 frame_->EmitPush(t0);
652 ASSERT(frame_->height() == original_height + 1);
653 } 573 }
654 574
655 575
656 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { 576 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
657 UNIMPLEMENTED_MIPS(); 577 UNIMPLEMENTED_MIPS();
658 } 578 }
659 579
660 580
661 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { 581 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
662 UNIMPLEMENTED_MIPS(); 582 UNIMPLEMENTED_MIPS();
663 } 583 }
664 584
665 585
666 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { 586 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
667 UNIMPLEMENTED_MIPS(); 587 UNIMPLEMENTED_MIPS();
668 } 588 }
669 589
670 590
671 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { 591 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
672 UNIMPLEMENTED_MIPS(); 592 UNIMPLEMENTED_MIPS();
673 } 593 }
674 594
675 595
596 void CodeGenerator::EmitSlotAssignment(Assignment* node) {
597 UNIMPLEMENTED_MIPS();
598 }
599
600
601 void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
602 UNIMPLEMENTED_MIPS();
603 }
604
605
606 void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) {
607 UNIMPLEMENTED_MIPS();
608 }
609
610
676 void CodeGenerator::VisitAssignment(Assignment* node) { 611 void CodeGenerator::VisitAssignment(Assignment* node) {
677 #ifdef DEBUG 612 UNIMPLEMENTED_MIPS();
678 int original_height = frame_->height();
679 #endif
680 VirtualFrame::SpilledScope spilled_scope;
681 Comment cmnt(masm_, "[ Assignment");
682
683 { Reference target(this, node->target());
684 if (target.is_illegal()) {
685 // Fool the virtual frame into thinking that we left the assignment's
686 // value on the frame.
687 frame_->EmitPush(zero_reg);
688 ASSERT(frame_->height() == original_height + 1);
689 return;
690 }
691
692 if (node->op() == Token::ASSIGN ||
693 node->op() == Token::INIT_VAR ||
694 node->op() == Token::INIT_CONST) {
695 LoadAndSpill(node->value());
696 } else {
697 UNIMPLEMENTED_MIPS();
698 }
699
700 Variable* var = node->target()->AsVariableProxy()->AsVariable();
701 if (var != NULL &&
702 (var->mode() == Variable::CONST) &&
703 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
704 // Assignment ignored - leave the value on the stack.
705 } else {
706 CodeForSourcePosition(node->position());
707 if (node->op() == Token::INIT_CONST) {
708 // Dynamic constant initializations must use the function context
709 // and initialize the actual constant declared. Dynamic variable
710 // initializations are simply assignments and use SetValue.
711 target.SetValue(CONST_INIT);
712 } else {
713 target.SetValue(NOT_CONST_INIT);
714 }
715 }
716 }
717 ASSERT(frame_->height() == original_height + 1);
718 } 613 }
719 614
720 615
721 void CodeGenerator::VisitThrow(Throw* node) { 616 void CodeGenerator::VisitThrow(Throw* node) {
722 UNIMPLEMENTED_MIPS(); 617 UNIMPLEMENTED_MIPS();
723 } 618 }
724 619
725 620
726 void CodeGenerator::VisitProperty(Property* node) { 621 void CodeGenerator::VisitProperty(Property* node) {
727 UNIMPLEMENTED_MIPS(); 622 UNIMPLEMENTED_MIPS();
728 } 623 }
729 624
730 625
731 void CodeGenerator::VisitCall(Call* node) { 626 void CodeGenerator::VisitCall(Call* node) {
732 #ifdef DEBUG 627 UNIMPLEMENTED_MIPS();
733 int original_height = frame_->height();
734 #endif
735 VirtualFrame::SpilledScope spilled_scope;
736 Comment cmnt(masm_, "[ Call");
737
738 Expression* function = node->expression();
739 ZoneList<Expression*>* args = node->arguments();
740
741 // Standard function call.
742 // Check if the function is a variable or a property.
743 Variable* var = function->AsVariableProxy()->AsVariable();
744 Property* property = function->AsProperty();
745
746 // ------------------------------------------------------------------------
747 // Fast-case: Use inline caching.
748 // ---
749 // According to ECMA-262, section 11.2.3, page 44, the function to call
750 // must be resolved after the arguments have been evaluated. The IC code
751 // automatically handles this by loading the arguments before the function
752 // is resolved in cache misses (this also holds for megamorphic calls).
753 // ------------------------------------------------------------------------
754
755 if (var != NULL && var->is_possibly_eval()) {
756 UNIMPLEMENTED_MIPS();
757 } else if (var != NULL && !var->is_this() && var->is_global()) {
758 // ----------------------------------
759 // JavaScript example: 'foo(1, 2, 3)' // foo is global
760 // ----------------------------------
761
762 int arg_count = args->length();
763
764 // We need sp to be 8 bytes aligned when calling the stub.
765 __ SetupAlignedCall(t0, arg_count);
766
767 // Pass the global object as the receiver and let the IC stub
768 // patch the stack to use the global proxy as 'this' in the
769 // invoked function.
770 LoadGlobal();
771
772 // Load the arguments.
773 for (int i = 0; i < arg_count; i++) {
774 LoadAndSpill(args->at(i));
775 }
776
777 // Setup the receiver register and call the IC initialization code.
778 __ li(a2, Operand(var->name()));
779 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
780 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
781 CodeForSourcePosition(node->position());
782 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
783 arg_count + 1);
784 __ ReturnFromAlignedCall();
785 __ lw(cp, frame_->Context());
786 // Remove the function from the stack.
787 frame_->EmitPush(v0);
788
789 } else if (var != NULL && var->slot() != NULL &&
790 var->slot()->type() == Slot::LOOKUP) {
791 UNIMPLEMENTED_MIPS();
792 } else if (property != NULL) {
793 UNIMPLEMENTED_MIPS();
794 } else {
795 UNIMPLEMENTED_MIPS();
796 }
797
798 ASSERT(frame_->height() == original_height + 1);
799 } 628 }
800 629
801 630
802 void CodeGenerator::VisitCallNew(CallNew* node) { 631 void CodeGenerator::VisitCallNew(CallNew* node) {
803 UNIMPLEMENTED_MIPS(); 632 UNIMPLEMENTED_MIPS();
804 } 633 }
805 634
806 635
807 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { 636 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
808 UNIMPLEMENTED_MIPS(); 637 UNIMPLEMENTED_MIPS();
(...skipping 23 matching lines...) Expand all
832 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { 661 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
833 UNIMPLEMENTED_MIPS(); 662 UNIMPLEMENTED_MIPS();
834 } 663 }
835 664
836 665
837 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) { 666 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
838 UNIMPLEMENTED_MIPS(); 667 UNIMPLEMENTED_MIPS();
839 } 668 }
840 669
841 670
842 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
843 UNIMPLEMENTED_MIPS();
844 }
845
846
847 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
848 UNIMPLEMENTED_MIPS();
849 }
850
851
852 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { 671 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
853 UNIMPLEMENTED_MIPS(); 672 UNIMPLEMENTED_MIPS();
854 } 673 }
855 674
856 675
857 // This should generate code that performs a charCodeAt() call or returns 676 class DeferredStringCharCodeAt : public DeferredCode {
858 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt. 677 public:
859 // It is not yet implemented on ARM, so it always goes to the slow case. 678 DeferredStringCharCodeAt(Register object,
860 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) { 679 Register index,
680 Register scratch,
681 Register result)
682 : result_(result),
683 char_code_at_generator_(object,
684 index,
685 scratch,
686 result,
687 &need_conversion_,
688 &need_conversion_,
689 &index_out_of_range_,
690 STRING_INDEX_IS_NUMBER) {}
691
692 StringCharCodeAtGenerator* fast_case_generator() {
693 return &char_code_at_generator_;
694 }
695
696 virtual void Generate() {
697 UNIMPLEMENTED_MIPS();
698 }
699
700 private:
701 Register result_;
702
703 Label need_conversion_;
704 Label index_out_of_range_;
705
706 StringCharCodeAtGenerator char_code_at_generator_;
707 };
708
709
710 void CodeGenerator::GenerateStringCharCodeAt(ZoneList<Expression*>* args) {
861 UNIMPLEMENTED_MIPS(); 711 UNIMPLEMENTED_MIPS();
862 } 712 }
863 713
864 714
865 void CodeGenerator::GenerateCharFromCode(ZoneList<Expression*>* args) { 715 class DeferredStringCharFromCode : public DeferredCode {
716 public:
717 DeferredStringCharFromCode(Register code,
718 Register result)
719 : char_from_code_generator_(code, result) {}
720
721 StringCharFromCodeGenerator* fast_case_generator() {
722 return &char_from_code_generator_;
723 }
724
725 virtual void Generate() {
726 VirtualFrameRuntimeCallHelper call_helper(frame_state());
727 char_from_code_generator_.GenerateSlow(masm(), call_helper);
728 }
729
730 private:
731 StringCharFromCodeGenerator char_from_code_generator_;
732 };
733
734
735 void CodeGenerator::GenerateStringCharFromCode(ZoneList<Expression*>* args) {
866 UNIMPLEMENTED_MIPS(); 736 UNIMPLEMENTED_MIPS();
867 } 737 }
868 738
739
740 class DeferredStringCharAt : public DeferredCode {
741 public:
742 DeferredStringCharAt(Register object,
743 Register index,
744 Register scratch1,
745 Register scratch2,
746 Register result)
747 : result_(result),
748 char_at_generator_(object,
749 index,
750 scratch1,
751 scratch2,
752 result,
753 &need_conversion_,
754 &need_conversion_,
755 &index_out_of_range_,
756 STRING_INDEX_IS_NUMBER) {}
757
758 StringCharAtGenerator* fast_case_generator() {
759 return &char_at_generator_;
760 }
761
762 virtual void Generate() {
763 UNIMPLEMENTED_MIPS();
764 }
765
766 private:
767 Register result_;
768
769 Label need_conversion_;
770 Label index_out_of_range_;
771
772 StringCharAtGenerator char_at_generator_;
773 };
774
775
776 void CodeGenerator::GenerateStringCharAt(ZoneList<Expression*>* args) {
777 UNIMPLEMENTED_MIPS();
778 }
779
869 780
870 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { 781 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
871 UNIMPLEMENTED_MIPS(); 782 UNIMPLEMENTED_MIPS();
872 } 783 }
873 784
874 785
875 void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) { 786 void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
876 UNIMPLEMENTED_MIPS(); 787 UNIMPLEMENTED_MIPS();
877 } 788 }
878 789
879 790
791 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
792 UNIMPLEMENTED_MIPS();
793 }
794
795
796 void CodeGenerator::GenerateIsSpecObject(ZoneList<Expression*>* args) {
797 UNIMPLEMENTED_MIPS();
798 }
799
800
801 class DeferredIsStringWrapperSafeForDefaultValueOf : public DeferredCode {
802 public:
803 DeferredIsStringWrapperSafeForDefaultValueOf(Register object,
804 Register map_result,
805 Register scratch1,
806 Register scratch2)
807 : object_(object),
808 map_result_(map_result),
809 scratch1_(scratch1),
810 scratch2_(scratch2) { }
811
812 virtual void Generate() {
813 UNIMPLEMENTED_MIPS();
814 }
815
816 private:
817 Register object_;
818 Register map_result_;
819 Register scratch1_;
820 Register scratch2_;
821 };
822
823
824 void CodeGenerator::GenerateIsStringWrapperSafeForDefaultValueOf(
825 ZoneList<Expression*>* args) {
826 UNIMPLEMENTED_MIPS();
827 }
828
829
830 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) {
831 UNIMPLEMENTED_MIPS();
832 }
833
834
835 void CodeGenerator::GenerateIsUndetectableObject(ZoneList<Expression*>* args) {
836 UNIMPLEMENTED_MIPS();
837 }
838
839
880 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) { 840 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
881 UNIMPLEMENTED_MIPS(); 841 UNIMPLEMENTED_MIPS();
882 } 842 }
883 843
884 844
885 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { 845 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
886 UNIMPLEMENTED_MIPS(); 846 UNIMPLEMENTED_MIPS();
887 } 847 }
888 848
889 849
890 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) { 850 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) {
891 UNIMPLEMENTED_MIPS(); 851 UNIMPLEMENTED_MIPS();
892 } 852 }
893 853
894 854
895 void CodeGenerator::GenerateRandomHeapNumber(ZoneList<Expression*>* args) { 855 void CodeGenerator::GenerateRandomHeapNumber(
856 ZoneList<Expression*>* args) {
896 UNIMPLEMENTED_MIPS(); 857 UNIMPLEMENTED_MIPS();
897 } 858 }
898 859
899
900 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
901 UNIMPLEMENTED_MIPS();
902 }
903
904
905 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
906 UNIMPLEMENTED_MIPS();
907 }
908
909
910 void CodeGenerator::GenerateIsSpecObject(ZoneList<Expression*>* args) {
911 UNIMPLEMENTED_MIPS();
912 }
913
914
915 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) {
916 UNIMPLEMENTED_MIPS();
917 }
918
919
920 void CodeGenerator::GenerateIsUndetectableObject(ZoneList<Expression*>* args) {
921 UNIMPLEMENTED_MIPS();
922 }
923
924 860
925 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) { 861 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) {
926 UNIMPLEMENTED_MIPS(); 862 UNIMPLEMENTED_MIPS();
927 } 863 }
928 864
929 865
930 void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) { 866 void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) {
931 UNIMPLEMENTED_MIPS(); 867 UNIMPLEMENTED_MIPS();
932 } 868 }
933 869
934 870
935 void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) { 871 void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) {
936 UNIMPLEMENTED_MIPS(); 872 UNIMPLEMENTED_MIPS();
937 } 873 }
938 874
939 875
940 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) { 876 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
941 UNIMPLEMENTED_MIPS(); 877 UNIMPLEMENTED_MIPS();
942 } 878 }
943 879
944 880
881 void CodeGenerator::GenerateRegExpConstructResult(ZoneList<Expression*>* args) {
882 UNIMPLEMENTED_MIPS();
883 }
884
885
886 class DeferredSearchCache: public DeferredCode {
887 public:
888 DeferredSearchCache(Register dst, Register cache, Register key)
889 : dst_(dst), cache_(cache), key_(key) {
890 set_comment("[ DeferredSearchCache");
891 }
892
893 virtual void Generate();
894
895 private:
896 Register dst_, cache_, key_;
897 };
898
899
900 void DeferredSearchCache::Generate() {
901 UNIMPLEMENTED_MIPS();
902 }
903
904
905 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) {
906 UNIMPLEMENTED_MIPS();
907 }
908
909
945 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) { 910 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
946 UNIMPLEMENTED_MIPS(); 911 UNIMPLEMENTED_MIPS();
947 } 912 }
948 913
949 914
915 class DeferredSwapElements: public DeferredCode {
916 public:
917 DeferredSwapElements(Register object, Register index1, Register index2)
918 : object_(object), index1_(index1), index2_(index2) {
919 set_comment("[ DeferredSwapElements");
920 }
921
922 virtual void Generate();
923
924 private:
925 Register object_, index1_, index2_;
926 };
927
928
929 void DeferredSwapElements::Generate() {
930 UNIMPLEMENTED_MIPS();
931 }
932
933
934 void CodeGenerator::GenerateSwapElements(ZoneList<Expression*>* args) {
935 UNIMPLEMENTED_MIPS();
936 }
937
938
939 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) {
940 UNIMPLEMENTED_MIPS();
941 }
942
943
944 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
945 UNIMPLEMENTED_MIPS();
946 }
947
948
949 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
950 UNIMPLEMENTED_MIPS();
951 }
952
953
954 void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) {
955 UNIMPLEMENTED_MIPS();
956 }
957
958
959 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
960 UNIMPLEMENTED_MIPS();
961 }
962
963
964 void CodeGenerator::GenerateIsRegExpEquivalent(ZoneList<Expression*>* args) {
965 UNIMPLEMENTED_MIPS();
966 }
967
968
969 void CodeGenerator::GenerateHasCachedArrayIndex(ZoneList<Expression*>* args) {
970 UNIMPLEMENTED_MIPS();
971 }
972
973
974 void CodeGenerator::GenerateGetCachedArrayIndex(ZoneList<Expression*>* args) {
975 UNIMPLEMENTED_MIPS();
976 }
977
978
979 void CodeGenerator::GenerateFastAsciiArrayJoin(ZoneList<Expression*>* args) {
980 UNIMPLEMENTED_MIPS();
981 }
982
983
950 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { 984 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
951 UNIMPLEMENTED_MIPS(); 985 UNIMPLEMENTED_MIPS();
952 } 986 }
953 987
954 988
955 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { 989 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
956 UNIMPLEMENTED_MIPS(); 990 UNIMPLEMENTED_MIPS();
957 } 991 }
958 992
959 993
994 class DeferredCountOperation: public DeferredCode {
995 public:
996 DeferredCountOperation(Register value,
997 bool is_increment,
998 bool is_postfix,
999 int target_size)
1000 : value_(value),
1001 is_increment_(is_increment),
1002 is_postfix_(is_postfix),
1003 target_size_(target_size) {}
1004
1005 virtual void Generate() {
1006 UNIMPLEMENTED_MIPS();
1007 }
1008
1009 private:
1010 Register value_;
1011 bool is_increment_;
1012 bool is_postfix_;
1013 int target_size_;
1014 };
1015
1016
960 void CodeGenerator::VisitCountOperation(CountOperation* node) { 1017 void CodeGenerator::VisitCountOperation(CountOperation* node) {
961 UNIMPLEMENTED_MIPS(); 1018 UNIMPLEMENTED_MIPS();
962 } 1019 }
963 1020
964 1021
1022 void CodeGenerator::GenerateLogicalBooleanOperation(BinaryOperation* node) {
1023 UNIMPLEMENTED_MIPS();
1024 }
1025
1026
965 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { 1027 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
966 UNIMPLEMENTED_MIPS(); 1028 UNIMPLEMENTED_MIPS();
967 } 1029 }
968 1030
969 1031
970 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 1032 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
971 UNIMPLEMENTED_MIPS(); 1033 UNIMPLEMENTED_MIPS();
972 } 1034 }
973 1035
974 1036
975 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { 1037 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
976 UNIMPLEMENTED_MIPS(); 1038 UNIMPLEMENTED_MIPS();
977 } 1039 }
978 1040
979 1041
1042 void CodeGenerator::VisitCompareToNull(CompareToNull* node) {
1043 UNIMPLEMENTED_MIPS();
1044 }
1045
1046
1047 class DeferredReferenceGetNamedValue: public DeferredCode {
1048 public:
1049 explicit DeferredReferenceGetNamedValue(Register receiver,
1050 Handle<String> name,
1051 bool is_contextual)
1052 : receiver_(receiver),
1053 name_(name),
1054 is_contextual_(is_contextual),
1055 is_dont_delete_(false) {
1056 set_comment(is_contextual
1057 ? "[ DeferredReferenceGetNamedValue (contextual)"
1058 : "[ DeferredReferenceGetNamedValue");
1059 }
1060
1061 virtual void Generate();
1062
1063 void set_is_dont_delete(bool value) {
1064 ASSERT(is_contextual_);
1065 is_dont_delete_ = value;
1066 }
1067
1068 private:
1069 Register receiver_;
1070 Handle<String> name_;
1071 bool is_contextual_;
1072 bool is_dont_delete_;
1073 };
1074
1075
1076
1077 void DeferredReferenceGetNamedValue::Generate() {
1078 UNIMPLEMENTED_MIPS();
1079 }
1080
1081
1082 class DeferredReferenceGetKeyedValue: public DeferredCode {
1083 public:
1084 DeferredReferenceGetKeyedValue(Register key, Register receiver)
1085 : key_(key), receiver_(receiver) {
1086 set_comment("[ DeferredReferenceGetKeyedValue");
1087 }
1088
1089 virtual void Generate();
1090
1091 private:
1092 Register key_;
1093 Register receiver_;
1094 };
1095
1096
1097 void DeferredReferenceGetKeyedValue::Generate() {
1098 UNIMPLEMENTED_MIPS();
1099 }
1100
1101
1102 class DeferredReferenceSetKeyedValue: public DeferredCode {
1103 public:
1104 DeferredReferenceSetKeyedValue(Register value,
1105 Register key,
1106 Register receiver)
1107 : value_(value), key_(key), receiver_(receiver) {
1108 set_comment("[ DeferredReferenceSetKeyedValue");
1109 }
1110
1111 virtual void Generate();
1112
1113 private:
1114 Register value_;
1115 Register key_;
1116 Register receiver_;
1117 };
1118
1119
1120 void DeferredReferenceSetKeyedValue::Generate() {
1121 UNIMPLEMENTED_MIPS();
1122 }
1123
1124
1125 class DeferredReferenceSetNamedValue: public DeferredCode {
1126 public:
1127 DeferredReferenceSetNamedValue(Register value,
1128 Register receiver,
1129 Handle<String> name)
1130 : value_(value), receiver_(receiver), name_(name) {
1131 set_comment("[ DeferredReferenceSetNamedValue");
1132 }
1133
1134 virtual void Generate();
1135
1136 private:
1137 Register value_;
1138 Register receiver_;
1139 Handle<String> name_;
1140 };
1141
1142
1143 void DeferredReferenceSetNamedValue::Generate() {
1144 UNIMPLEMENTED_MIPS();
1145 }
1146
1147
1148 void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
1149 UNIMPLEMENTED_MIPS();
1150 }
1151
1152
1153 void CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
1154 UNIMPLEMENTED_MIPS();
1155 }
1156
1157
1158 void CodeGenerator::EmitKeyedLoad() {
1159 UNIMPLEMENTED_MIPS();
1160 }
1161
1162
1163 void CodeGenerator::EmitKeyedStore(StaticType* key_type,
1164 WriteBarrierCharacter wb_info) {
1165 UNIMPLEMENTED_MIPS();
1166 }
1167
1168
980 #ifdef DEBUG 1169 #ifdef DEBUG
981 bool CodeGenerator::HasValidEntryRegisters() { return true; } 1170 bool CodeGenerator::HasValidEntryRegisters() {
1171 UNIMPLEMENTED_MIPS();
1172 return false;
1173 }
982 #endif 1174 #endif
983 1175
984 1176
985 #undef __ 1177 #undef __
986 #define __ ACCESS_MASM(masm) 1178 #define __ ACCESS_MASM(masm)
987 1179
988 // ----------------------------------------------------------------------------- 1180 // -----------------------------------------------------------------------------
989 // Reference support 1181 // Reference support.
990
991 Reference::Reference(CodeGenerator* cgen,
992 Expression* expression,
993 bool persist_after_get)
994 : cgen_(cgen),
995 expression_(expression),
996 type_(ILLEGAL),
997 persist_after_get_(persist_after_get) {
998 cgen->LoadReference(this);
999 }
1000
1001
1002 Reference::~Reference() {
1003 ASSERT(is_unloaded() || is_illegal());
1004 }
1005 1182
1006 1183
1007 Handle<String> Reference::GetName() { 1184 Handle<String> Reference::GetName() {
1008 ASSERT(type_ == NAMED); 1185 UNIMPLEMENTED_MIPS();
1009 Property* property = expression_->AsProperty(); 1186 return Handle<String>();
1010 if (property == NULL) { 1187 }
1011 // Global variable reference treated as a named property reference. 1188
1012 VariableProxy* proxy = expression_->AsVariableProxy(); 1189
1013 ASSERT(proxy->AsVariable() != NULL); 1190 void Reference::DupIfPersist() {
1014 ASSERT(proxy->AsVariable()->is_global()); 1191 UNIMPLEMENTED_MIPS();
1015 return proxy->name();
1016 } else {
1017 Literal* raw_name = property->key()->AsLiteral();
1018 ASSERT(raw_name != NULL);
1019 return Handle<String>(String::cast(*raw_name->handle()));
1020 }
1021 } 1192 }
1022 1193
1023 1194
1024 void Reference::GetValue() { 1195 void Reference::GetValue() {
1025 ASSERT(cgen_->HasValidEntryRegisters()); 1196 UNIMPLEMENTED_MIPS();
1026 ASSERT(!is_illegal()); 1197 }
1027 ASSERT(!cgen_->has_cc()); 1198
1028 Property* property = expression_->AsProperty(); 1199
1029 if (property != NULL) { 1200 void Reference::SetValue(InitState init_state, WriteBarrierCharacter wb_info) {
1030 cgen_->CodeForSourcePosition(property->position()); 1201 UNIMPLEMENTED_MIPS();
1031 } 1202 }
1032 1203
1033 switch (type_) { 1204
1034 case SLOT: { 1205 const char* GenericBinaryOpStub::GetName() {
1035 UNIMPLEMENTED_MIPS(); 1206 UNIMPLEMENTED_MIPS();
1036 break; 1207 return name_;
1037 } 1208 }
1038 1209
1039 case NAMED: { 1210
1040 UNIMPLEMENTED_MIPS();
1041 break;
1042 }
1043
1044 case KEYED: {
1045 UNIMPLEMENTED_MIPS();
1046 break;
1047 }
1048
1049 default:
1050 UNREACHABLE();
1051 }
1052 }
1053
1054
1055 void Reference::SetValue(InitState init_state) {
1056 ASSERT(!is_illegal());
1057 ASSERT(!cgen_->has_cc());
1058 MacroAssembler* masm = cgen_->masm();
1059 Property* property = expression_->AsProperty();
1060 if (property != NULL) {
1061 cgen_->CodeForSourcePosition(property->position());
1062 }
1063
1064 switch (type_) {
1065 case SLOT: {
1066 Comment cmnt(masm, "[ Store to Slot");
1067 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
1068 cgen_->StoreToSlot(slot, init_state);
1069 cgen_->UnloadReference(this);
1070 break;
1071 }
1072
1073 case NAMED: {
1074 UNIMPLEMENTED_MIPS();
1075 break;
1076 }
1077
1078 case KEYED: {
1079 UNIMPLEMENTED_MIPS();
1080 break;
1081 }
1082
1083 default:
1084 UNREACHABLE();
1085 }
1086 }
1087
1088
1089 // On entry a0 and a1 are the things to be compared. On exit v0 is 0,
1090 // positive or negative to indicate the result of the comparison.
1091 void CompareStub::Generate(MacroAssembler* masm) {
1092 UNIMPLEMENTED_MIPS();
1093 __ break_(0x765);
1094 }
1095
1096
1097 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) {
1098 UNIMPLEMENTED_MIPS();
1099 return Handle<Code>::null();
1100 }
1101
1102
1103 void StackCheckStub::Generate(MacroAssembler* masm) {
1104 UNIMPLEMENTED_MIPS();
1105 __ break_(0x790);
1106 }
1107
1108
1109 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
1110 UNIMPLEMENTED_MIPS();
1111 __ break_(0x808);
1112 }
1113
1114
1115 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
1116 UncatchableExceptionType type) {
1117 UNIMPLEMENTED_MIPS();
1118 __ break_(0x815);
1119 }
1120
1121 void CEntryStub::GenerateCore(MacroAssembler* masm,
1122 Label* throw_normal_exception,
1123 Label* throw_termination_exception,
1124 Label* throw_out_of_memory_exception,
1125 bool do_gc,
1126 bool always_allocate) {
1127 // s0: number of arguments including receiver (C callee-saved)
1128 // s1: pointer to the first argument (C callee-saved)
1129 // s2: pointer to builtin function (C callee-saved)
1130
1131 if (do_gc) {
1132 UNIMPLEMENTED_MIPS();
1133 }
1134
1135 ExternalReference scope_depth =
1136 ExternalReference::heap_always_allocate_scope_depth();
1137 if (always_allocate) {
1138 UNIMPLEMENTED_MIPS();
1139 }
1140
1141 // Call C built-in.
1142 // a0 = argc, a1 = argv
1143 __ mov(a0, s0);
1144 __ mov(a1, s1);
1145
1146 __ CallBuiltin(s2);
1147
1148 if (always_allocate) {
1149 UNIMPLEMENTED_MIPS();
1150 }
1151
1152 // Check for failure result.
1153 Label failure_returned;
1154 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
1155 __ addiu(a2, v0, 1);
1156 __ andi(t0, a2, kFailureTagMask);
1157 __ Branch(eq, &failure_returned, t0, Operand(zero_reg));
1158
1159 // Exit C frame and return.
1160 // v0:v1: result
1161 // sp: stack pointer
1162 // fp: frame pointer
1163 __ LeaveExitFrame(mode_);
1164
1165 // Check if we should retry or throw exception.
1166 Label retry;
1167 __ bind(&failure_returned);
1168 ASSERT(Failure::RETRY_AFTER_GC == 0);
1169 __ andi(t0, v0, ((1 << kFailureTypeTagSize) - 1) << kFailureTagSize);
1170 __ Branch(eq, &retry, t0, Operand(zero_reg));
1171
1172 // Special handling of out of memory exceptions.
1173 Failure* out_of_memory = Failure::OutOfMemoryException();
1174 __ Branch(eq, throw_out_of_memory_exception,
1175 v0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
1176
1177 // Retrieve the pending exception and clear the variable.
1178 __ LoadExternalReference(t0, ExternalReference::the_hole_value_location());
1179 __ lw(a3, MemOperand(t0));
1180 __ LoadExternalReference(t0,
1181 ExternalReference(Top::k_pending_exception_address));
1182 __ lw(v0, MemOperand(t0));
1183 __ sw(a3, MemOperand(t0));
1184
1185 // Special handling of termination exceptions which are uncatchable
1186 // by javascript code.
1187 __ Branch(eq, throw_termination_exception,
1188 v0, Operand(Factory::termination_exception()));
1189
1190 // Handle normal exception.
1191 __ b(throw_normal_exception);
1192 __ nop(); // Branch delay slot nop.
1193
1194 __ bind(&retry); // pass last failure (r0) as parameter (r0) when retrying
1195 }
1196
1197 void CEntryStub::Generate(MacroAssembler* masm) {
1198 // Called from JavaScript; parameters are on stack as if calling JS function
1199 // a0: number of arguments including receiver
1200 // a1: pointer to builtin function
1201 // fp: frame pointer (restored after C call)
1202 // sp: stack pointer (restored as callee's sp after C call)
1203 // cp: current context (C callee-saved)
1204
1205 // NOTE: Invocations of builtins may return failure objects
1206 // instead of a proper result. The builtin entry handles
1207 // this by performing a garbage collection and retrying the
1208 // builtin once.
1209
1210 // Enter the exit frame that transitions from JavaScript to C++.
1211 __ EnterExitFrame(mode_, s0, s1, s2);
1212
1213 // s0: number of arguments (C callee-saved)
1214 // s1: pointer to first argument (C callee-saved)
1215 // s2: pointer to builtin function (C callee-saved)
1216
1217 Label throw_normal_exception;
1218 Label throw_termination_exception;
1219 Label throw_out_of_memory_exception;
1220
1221 // Call into the runtime system.
1222 GenerateCore(masm,
1223 &throw_normal_exception,
1224 &throw_termination_exception,
1225 &throw_out_of_memory_exception,
1226 false,
1227 false);
1228
1229 // Do space-specific GC and retry runtime call.
1230 GenerateCore(masm,
1231 &throw_normal_exception,
1232 &throw_termination_exception,
1233 &throw_out_of_memory_exception,
1234 true,
1235 false);
1236
1237 // Do full GC and retry runtime call one final time.
1238 Failure* failure = Failure::InternalError();
1239 __ li(v0, Operand(reinterpret_cast<int32_t>(failure)));
1240 GenerateCore(masm,
1241 &throw_normal_exception,
1242 &throw_termination_exception,
1243 &throw_out_of_memory_exception,
1244 true,
1245 true);
1246
1247 __ bind(&throw_out_of_memory_exception);
1248 GenerateThrowUncatchable(masm, OUT_OF_MEMORY);
1249
1250 __ bind(&throw_termination_exception);
1251 GenerateThrowUncatchable(masm, TERMINATION);
1252
1253 __ bind(&throw_normal_exception);
1254 GenerateThrowTOS(masm);
1255 }
1256
1257 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
1258 Label invoke, exit;
1259
1260 // Registers:
1261 // a0: entry address
1262 // a1: function
1263 // a2: reveiver
1264 // a3: argc
1265 //
1266 // Stack:
1267 // 4 args slots
1268 // args
1269
1270 // Save callee saved registers on the stack.
1271 __ MultiPush((kCalleeSaved | ra.bit()) & ~sp.bit());
1272
1273 // We build an EntryFrame.
1274 __ li(t3, Operand(-1)); // Push a bad frame pointer to fail if it is used.
1275 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
1276 __ li(t2, Operand(Smi::FromInt(marker)));
1277 __ li(t1, Operand(Smi::FromInt(marker)));
1278 __ LoadExternalReference(t0, ExternalReference(Top::k_c_entry_fp_address));
1279 __ lw(t0, MemOperand(t0));
1280 __ MultiPush(t0.bit() | t1.bit() | t2.bit() | t3.bit());
1281
1282 // Setup frame pointer for the frame to be pushed.
1283 __ addiu(fp, sp, -EntryFrameConstants::kCallerFPOffset);
1284
1285 // Load argv in s0 register.
1286 __ lw(s0, MemOperand(sp, (kNumCalleeSaved + 1) * kPointerSize +
1287 StandardFrameConstants::kCArgsSlotsSize));
1288
1289 // Registers:
1290 // a0: entry_address
1291 // a1: function
1292 // a2: reveiver_pointer
1293 // a3: argc
1294 // s0: argv
1295 //
1296 // Stack:
1297 // caller fp |
1298 // function slot | entry frame
1299 // context slot |
1300 // bad fp (0xff...f) |
1301 // callee saved registers + ra
1302 // 4 args slots
1303 // args
1304
1305 // Call a faked try-block that does the invoke.
1306 __ bal(&invoke);
1307 __ nop(); // Branch delay slot nop.
1308
1309 // Caught exception: Store result (exception) in the pending
1310 // exception field in the JSEnv and return a failure sentinel.
1311 // Coming in here the fp will be invalid because the PushTryHandler below
1312 // sets it to 0 to signal the existence of the JSEntry frame.
1313 __ LoadExternalReference(t0,
1314 ExternalReference(Top::k_pending_exception_address));
1315 __ sw(v0, MemOperand(t0)); // We come back from 'invoke'. result is in v0.
1316 __ li(v0, Operand(reinterpret_cast<int32_t>(Failure::Exception())));
1317 __ b(&exit);
1318 __ nop(); // Branch delay slot nop.
1319
1320 // Invoke: Link this frame into the handler chain.
1321 __ bind(&invoke);
1322 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER);
1323 // If an exception not caught by another handler occurs, this handler
1324 // returns control to the code after the bal(&invoke) above, which
1325 // restores all kCalleeSaved registers (including cp and fp) to their
1326 // saved values before returning a failure to C.
1327
1328 // Clear any pending exceptions.
1329 __ LoadExternalReference(t0, ExternalReference::the_hole_value_location());
1330 __ lw(t1, MemOperand(t0));
1331 __ LoadExternalReference(t0,
1332 ExternalReference(Top::k_pending_exception_address));
1333 __ sw(t1, MemOperand(t0));
1334
1335 // Invoke the function by calling through JS entry trampoline builtin.
1336 // Notice that we cannot store a reference to the trampoline code directly in
1337 // this stub, because runtime stubs are not traversed when doing GC.
1338
1339 // Registers:
1340 // a0: entry_address
1341 // a1: function
1342 // a2: reveiver_pointer
1343 // a3: argc
1344 // s0: argv
1345 //
1346 // Stack:
1347 // handler frame
1348 // entry frame
1349 // callee saved registers + ra
1350 // 4 args slots
1351 // args
1352
1353 if (is_construct) {
1354 ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline);
1355 __ LoadExternalReference(t0, construct_entry);
1356 } else {
1357 ExternalReference entry(Builtins::JSEntryTrampoline);
1358 __ LoadExternalReference(t0, entry);
1359 }
1360 __ lw(t9, MemOperand(t0)); // deref address
1361
1362 // Call JSEntryTrampoline.
1363 __ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag);
1364 __ CallBuiltin(t9);
1365
1366 // Unlink this frame from the handler chain. When reading the
1367 // address of the next handler, there is no need to use the address
1368 // displacement since the current stack pointer (sp) points directly
1369 // to the stack handler.
1370 __ lw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset));
1371 __ LoadExternalReference(t0, ExternalReference(Top::k_handler_address));
1372 __ sw(t1, MemOperand(t0));
1373
1374 // This restores sp to its position before PushTryHandler.
1375 __ addiu(sp, sp, StackHandlerConstants::kSize);
1376
1377 __ bind(&exit); // v0 holds result
1378 // Restore the top frame descriptors from the stack.
1379 __ Pop(t1);
1380 __ LoadExternalReference(t0, ExternalReference(Top::k_c_entry_fp_address));
1381 __ sw(t1, MemOperand(t0));
1382
1383 // Reset the stack to the callee saved registers.
1384 __ addiu(sp, sp, -EntryFrameConstants::kCallerFPOffset);
1385
1386 // Restore callee saved registers from the stack.
1387 __ MultiPop((kCalleeSaved | ra.bit()) & ~sp.bit());
1388 // Return.
1389 __ Jump(ra);
1390 }
1391
1392
1393 // This stub performs an instanceof, calling the builtin function if
1394 // necessary. Uses a1 for the object, a0 for the function that it may
1395 // be an instance of (these are fetched from the stack).
1396 void InstanceofStub::Generate(MacroAssembler* masm) {
1397 UNIMPLEMENTED_MIPS();
1398 __ break_(0x845);
1399 }
1400
1401
1402 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
1403 UNIMPLEMENTED_MIPS();
1404 __ break_(0x851);
1405 }
1406
1407
1408 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
1409 UNIMPLEMENTED_MIPS();
1410 __ break_(0x857);
1411 }
1412
1413
1414 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
1415 UNIMPLEMENTED_MIPS();
1416 __ break_(0x863);
1417 }
1418
1419
1420 const char* CompareStub::GetName() {
1421 UNIMPLEMENTED_MIPS();
1422 return NULL; // UNIMPLEMENTED RETURN
1423 }
1424
1425
1426 int CompareStub::MinorKey() {
1427 // Encode the two parameters in a unique 16 bit value.
1428 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15));
1429 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0);
1430 }
1431
1432
1433 #undef __ 1211 #undef __
1434 1212
1435 } } // namespace v8::internal 1213 } } // namespace v8::internal
1436 1214
1437 #endif // V8_TARGET_ARCH_MIPS 1215 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698