OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 } | 352 } |
353 ASSERT(has_cc() || !force_cc); | 353 ASSERT(has_cc() || !force_cc); |
354 } | 354 } |
355 | 355 |
356 | 356 |
357 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { | 357 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { |
358 Label true_target; | 358 Label true_target; |
359 Label false_target; | 359 Label false_target; |
360 LoadCondition(x, typeof_state, &true_target, &false_target, false); | 360 LoadCondition(x, typeof_state, &true_target, &false_target, false); |
361 | 361 |
| 362 // Materialize boolean values on the stack frame if necessary. |
362 if (has_cc()) { | 363 if (has_cc()) { |
363 // convert cc_reg_ into a bool | 364 // The value we want is in the cc register. Since complicated |
364 Label loaded, materialize_true; | 365 // conditions can require more than one test, there may also be branches |
365 __ b(cc_reg_, &materialize_true); | 366 // to true_target and false_target. |
| 367 Label loaded; |
| 368 __ bind(&false_target); |
| 369 __ b(cc_reg_, &true_target); |
366 __ mov(r0, Operand(Factory::false_value())); | 370 __ mov(r0, Operand(Factory::false_value())); |
367 __ push(r0); | 371 __ push(r0); |
368 __ b(&loaded); | 372 __ b(&loaded); |
369 __ bind(&materialize_true); | 373 __ bind(&true_target); |
370 __ mov(r0, Operand(Factory::true_value())); | 374 __ mov(r0, Operand(Factory::true_value())); |
371 __ push(r0); | 375 __ push(r0); |
372 __ bind(&loaded); | 376 __ bind(&loaded); |
373 cc_reg_ = al; | 377 cc_reg_ = al; |
374 } | 378 } else { |
| 379 // Optimization of boolean-valued expressions whose value is statically |
| 380 // known may have generated an unconditional jump to either of the |
| 381 // targets (but not both) and failed to leave a value in either the cc |
| 382 // register or on top of the frame. |
| 383 ASSERT(!(true_target.is_linked() && false_target.is_linked())); |
375 | 384 |
376 if (true_target.is_linked() || false_target.is_linked()) { | |
377 // we have at least one condition value | |
378 // that has been "translated" into a branch, | |
379 // thus it needs to be loaded explicitly again | |
380 Label loaded; | |
381 __ b(&loaded); // don't lose current TOS | |
382 bool both = true_target.is_linked() && false_target.is_linked(); | |
383 // reincarnate "true", if necessary | |
384 if (true_target.is_linked()) { | 385 if (true_target.is_linked()) { |
385 __ bind(&true_target); | 386 __ bind(&true_target); |
386 __ mov(r0, Operand(Factory::true_value())); | 387 __ mov(r0, Operand(Factory::true_value())); |
387 __ push(r0); | 388 __ push(r0); |
388 } | 389 } |
389 // if both "true" and "false" need to be reincarnated, | 390 |
390 // jump across code for "false" | |
391 if (both) | |
392 __ b(&loaded); | |
393 // reincarnate "false", if necessary | |
394 if (false_target.is_linked()) { | 391 if (false_target.is_linked()) { |
395 __ bind(&false_target); | 392 __ bind(&false_target); |
396 __ mov(r0, Operand(Factory::false_value())); | 393 __ mov(r0, Operand(Factory::false_value())); |
397 __ push(r0); | 394 __ push(r0); |
398 } | 395 } |
399 // everything is loaded at this point | |
400 __ bind(&loaded); | |
401 } | 396 } |
402 ASSERT(!has_cc()); | |
403 } | 397 } |
404 | 398 |
405 | 399 |
406 void CodeGenerator::LoadGlobal() { | 400 void CodeGenerator::LoadGlobal() { |
407 __ ldr(r0, GlobalObject()); | 401 __ ldr(r0, GlobalObject()); |
408 __ push(r0); | 402 __ push(r0); |
409 } | 403 } |
410 | 404 |
411 | 405 |
412 void CodeGenerator::LoadGlobalReceiver(Register s) { | 406 void CodeGenerator::LoadGlobalReceiver(Register s) { |
(...skipping 3797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4210 // Slow-case: Non-function called. | 4204 // Slow-case: Non-function called. |
4211 __ bind(&slow); | 4205 __ bind(&slow); |
4212 __ mov(r0, Operand(argc_)); // Setup the number of arguments. | 4206 __ mov(r0, Operand(argc_)); // Setup the number of arguments. |
4213 __ InvokeBuiltin(Builtins::CALL_NON_FUNCTION, JUMP_JS); | 4207 __ InvokeBuiltin(Builtins::CALL_NON_FUNCTION, JUMP_JS); |
4214 } | 4208 } |
4215 | 4209 |
4216 | 4210 |
4217 #undef __ | 4211 #undef __ |
4218 | 4212 |
4219 } } // namespace v8::internal | 4213 } } // namespace v8::internal |
OLD | NEW |