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

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

Issue 119036: * Modify simulator and ARM code generator to avoid swi... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/arm/constants-arm.h » ('j') | src/arm/constants-arm.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 4365 matching lines...) Expand 10 before | Expand all | Expand 10 after
4376 } 4376 }
4377 4377
4378 4378
4379 // We fall into this code if the operands were Smis, but the result was 4379 // We fall into this code if the operands were Smis, but the result was
4380 // not (eg. overflow). We branch into this code (to the not_smi label) if 4380 // not (eg. overflow). We branch into this code (to the not_smi label) if
4381 // the operands were not both Smi. 4381 // the operands were not both Smi.
4382 static void HandleBinaryOpSlowCases(MacroAssembler* masm, 4382 static void HandleBinaryOpSlowCases(MacroAssembler* masm,
4383 Label* not_smi, 4383 Label* not_smi,
4384 const Builtins::JavaScript& builtin, 4384 const Builtins::JavaScript& builtin,
4385 Token::Value operation, 4385 Token::Value operation,
4386 int swi_number,
4387 OverwriteMode mode) { 4386 OverwriteMode mode) {
4388 Label slow; 4387 Label slow;
4389 __ bind(&slow); 4388 __ bind(&slow);
4390 __ push(r1); 4389 __ push(r1);
4391 __ push(r0); 4390 __ push(r0);
4392 __ mov(r0, Operand(1)); // Set number of arguments. 4391 __ mov(r0, Operand(1)); // Set number of arguments.
4393 __ InvokeBuiltin(builtin, JUMP_JS); // Tail call. 4392 __ InvokeBuiltin(builtin, JUMP_JS); // Tail call.
4394 4393
4395 __ bind(not_smi); 4394 __ bind(not_smi);
4396 __ tst(r0, Operand(kSmiTagMask)); 4395 __ tst(r0, Operand(kSmiTagMask));
(...skipping 27 matching lines...) Expand all
4424 } else { 4423 } else {
4425 ASSERT(mode == OVERWRITE_RIGHT); 4424 ASSERT(mode == OVERWRITE_RIGHT);
4426 __ push(lr); 4425 __ push(lr);
4427 __ push(r0); 4426 __ push(r0);
4428 } 4427 }
4429 // Calling convention says that first double is in r0 and r1. 4428 // Calling convention says that first double is in r0 and r1.
4430 __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset)); 4429 __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset));
4431 __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize)); 4430 __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize));
4432 // Call C routine that may not cause GC or other trouble. 4431 // Call C routine that may not cause GC or other trouble.
4433 __ mov(r5, Operand(ExternalReference::double_fp_operation(operation))); 4432 __ mov(r5, Operand(ExternalReference::double_fp_operation(operation)));
4434 #if !defined(__arm__)
4435 // Notify the simulator that we are calling an add routine in C.
4436 __ swi(swi_number);
4437 #else
4438 // Actually call the add routine written in C.
4439 __ Call(r5); 4433 __ Call(r5);
4440 #endif
4441 // Store answer in the overwritable heap number. 4434 // Store answer in the overwritable heap number.
4442 __ pop(r4); 4435 __ pop(r4);
4443 #if !defined(__ARM_EABI__) && defined(__arm__) 4436 #if !defined(__ARM_EABI__)
4444 // Double returned in fp coprocessor register 0 and 1, encoded as register 4437 // Double returned in fp coprocessor register 0 and 1, encoded as register
4445 // cr8. Offsets must be divisible by 4 for coprocessor so we need to 4438 // cr8. Offsets must be divisible by 4 for coprocessor so we need to
4446 // substract the tag from r4. 4439 // substract the tag from r4.
4447 __ sub(r5, r4, Operand(kHeapObjectTag)); 4440 __ sub(r5, r4, Operand(kHeapObjectTag));
4448 __ stc(p1, cr8, MemOperand(r5, HeapNumber::kValueOffset)); 4441 __ stc(p1, cr8, MemOperand(r5, HeapNumber::kValueOffset));
4449 #else 4442 #else
4450 // Double returned in fp coprocessor register 0 and 1. 4443 // Double returned in registers 0 and 1.
4451 __ str(r0, FieldMemOperand(r4, HeapNumber::kValueOffset)); 4444 __ str(r0, FieldMemOperand(r4, HeapNumber::kValueOffset));
4452 __ str(r1, FieldMemOperand(r4, HeapNumber::kValueOffset + kPointerSize)); 4445 __ str(r1, FieldMemOperand(r4, HeapNumber::kValueOffset + kPointerSize));
4453 #endif 4446 #endif
4454 __ mov(r0, Operand(r4)); 4447 __ mov(r0, Operand(r4));
4455 // And we are done. 4448 // And we are done.
4456 __ pop(pc); 4449 __ pop(pc);
4457 } 4450 }
4458 4451
4459 4452
4460 void GenericBinaryOpStub::Generate(MacroAssembler* masm) { 4453 void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
(...skipping 14 matching lines...) Expand all
4475 __ b(ne, &not_smi); 4468 __ b(ne, &not_smi);
4476 __ add(r0, r1, Operand(r0), SetCC); // Add y optimistically. 4469 __ add(r0, r1, Operand(r0), SetCC); // Add y optimistically.
4477 // Return if no overflow. 4470 // Return if no overflow.
4478 __ Ret(vc); 4471 __ Ret(vc);
4479 __ sub(r0, r0, Operand(r1)); // Revert optimistic add. 4472 __ sub(r0, r0, Operand(r1)); // Revert optimistic add.
4480 4473
4481 HandleBinaryOpSlowCases(masm, 4474 HandleBinaryOpSlowCases(masm,
4482 &not_smi, 4475 &not_smi,
4483 Builtins::ADD, 4476 Builtins::ADD,
4484 Token::ADD, 4477 Token::ADD,
4485 assembler::arm::simulator_fp_add,
4486 mode_); 4478 mode_);
4487 break; 4479 break;
4488 } 4480 }
4489 4481
4490 case Token::SUB: { 4482 case Token::SUB: {
4491 Label not_smi; 4483 Label not_smi;
4492 // Fast path. 4484 // Fast path.
4493 ASSERT(kSmiTag == 0); // Adjust code below. 4485 ASSERT(kSmiTag == 0); // Adjust code below.
4494 __ tst(r2, Operand(kSmiTagMask)); 4486 __ tst(r2, Operand(kSmiTagMask));
4495 __ b(ne, &not_smi); 4487 __ b(ne, &not_smi);
4496 __ sub(r0, r1, Operand(r0), SetCC); // Subtract y optimistically. 4488 __ sub(r0, r1, Operand(r0), SetCC); // Subtract y optimistically.
4497 // Return if no overflow. 4489 // Return if no overflow.
4498 __ Ret(vc); 4490 __ Ret(vc);
4499 __ sub(r0, r1, Operand(r0)); // Revert optimistic subtract. 4491 __ sub(r0, r1, Operand(r0)); // Revert optimistic subtract.
4500 4492
4501 HandleBinaryOpSlowCases(masm, 4493 HandleBinaryOpSlowCases(masm,
4502 &not_smi, 4494 &not_smi,
4503 Builtins::SUB, 4495 Builtins::SUB,
4504 Token::SUB, 4496 Token::SUB,
4505 assembler::arm::simulator_fp_sub,
4506 mode_); 4497 mode_);
4507 break; 4498 break;
4508 } 4499 }
4509 4500
4510 case Token::MUL: { 4501 case Token::MUL: {
4511 Label not_smi, slow; 4502 Label not_smi, slow;
4512 ASSERT(kSmiTag == 0); // adjust code below 4503 ASSERT(kSmiTag == 0); // adjust code below
4513 __ tst(r2, Operand(kSmiTagMask)); 4504 __ tst(r2, Operand(kSmiTagMask));
4514 __ b(ne, &not_smi); 4505 __ b(ne, &not_smi);
4515 // Remove tag from one operand (but keep sign), so that result is Smi. 4506 // Remove tag from one operand (but keep sign), so that result is Smi.
4516 __ mov(ip, Operand(r0, ASR, kSmiTagSize)); 4507 __ mov(ip, Operand(r0, ASR, kSmiTagSize));
4517 // Do multiplication 4508 // Do multiplication
4518 __ smull(r3, r2, r1, ip); // r3 = lower 32 bits of ip*r1. 4509 __ smull(r3, r2, r1, ip); // r3 = lower 32 bits of ip*r1.
4519 // Go slow on overflows (overflow bit is not set). 4510 // Go slow on overflows (overflow bit is not set).
4520 __ mov(ip, Operand(r3, ASR, 31)); 4511 __ mov(ip, Operand(r3, ASR, 31));
4521 __ cmp(ip, Operand(r2)); // no overflow if higher 33 bits are identical 4512 __ cmp(ip, Operand(r2)); // no overflow if higher 33 bits are identical
4522 __ b(ne, &slow); 4513 __ b(ne, &slow);
4523 // Go slow on zero result to handle -0. 4514 // Go slow on zero result to handle -0.
4524 __ tst(r3, Operand(r3)); 4515 __ tst(r3, Operand(r3));
4525 __ mov(r0, Operand(r3), LeaveCC, ne); 4516 __ mov(r0, Operand(r3), LeaveCC, ne);
4526 __ Ret(ne); 4517 __ Ret(ne);
4527 // Slow case. 4518 // Slow case.
4528 __ bind(&slow); 4519 __ bind(&slow);
4529 4520
4530 HandleBinaryOpSlowCases(masm, 4521 HandleBinaryOpSlowCases(masm,
4531 &not_smi, 4522 &not_smi,
4532 Builtins::MUL, 4523 Builtins::MUL,
4533 Token::MUL, 4524 Token::MUL,
4534 assembler::arm::simulator_fp_mul,
4535 mode_); 4525 mode_);
4536 break; 4526 break;
4537 } 4527 }
4538 4528
4539 case Token::BIT_OR: 4529 case Token::BIT_OR:
4540 case Token::BIT_AND: 4530 case Token::BIT_AND:
4541 case Token::BIT_XOR: { 4531 case Token::BIT_XOR: {
4542 Label slow; 4532 Label slow;
4543 ASSERT(kSmiTag == 0); // adjust code below 4533 ASSERT(kSmiTag == 0); // adjust code below
4544 __ tst(r2, Operand(kSmiTagMask)); 4534 __ tst(r2, Operand(kSmiTagMask));
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
4785 StackFrame::Type frame_type, 4775 StackFrame::Type frame_type,
4786 bool do_gc, 4776 bool do_gc,
4787 bool always_allocate) { 4777 bool always_allocate) {
4788 // r0: result parameter for PerformGC, if any 4778 // r0: result parameter for PerformGC, if any
4789 // r4: number of arguments including receiver (C callee-saved) 4779 // r4: number of arguments including receiver (C callee-saved)
4790 // r5: pointer to builtin function (C callee-saved) 4780 // r5: pointer to builtin function (C callee-saved)
4791 // r6: pointer to the first argument (C callee-saved) 4781 // r6: pointer to the first argument (C callee-saved)
4792 4782
4793 if (do_gc) { 4783 if (do_gc) {
4794 // Passing r0. 4784 // Passing r0.
4795 __ Call(FUNCTION_ADDR(Runtime::PerformGC), RelocInfo::RUNTIME_ENTRY); 4785 ExternalReference gc_reference = ExternalReference::perform_gc_function();
4786 __ Call(gc_reference.address(), RelocInfo::RUNTIME_ENTRY);
4796 } 4787 }
4797 4788
4798 ExternalReference scope_depth = 4789 ExternalReference scope_depth =
4799 ExternalReference::heap_always_allocate_scope_depth(); 4790 ExternalReference::heap_always_allocate_scope_depth();
4800 if (always_allocate) { 4791 if (always_allocate) {
4801 __ mov(r0, Operand(scope_depth)); 4792 __ mov(r0, Operand(scope_depth));
4802 __ ldr(r1, MemOperand(r0)); 4793 __ ldr(r1, MemOperand(r0));
4803 __ add(r1, r1, Operand(1)); 4794 __ add(r1, r1, Operand(1));
4804 __ str(r1, MemOperand(r0)); 4795 __ str(r1, MemOperand(r0));
4805 } 4796 }
4806 4797
4807 // Call C built-in. 4798 // Call C built-in.
4808 // r0 = argc, r1 = argv 4799 // r0 = argc, r1 = argv
4809 __ mov(r0, Operand(r4)); 4800 __ mov(r0, Operand(r4));
4810 __ mov(r1, Operand(r6)); 4801 __ mov(r1, Operand(r6));
4811 4802
4812 // TODO(1242173): To let the GC traverse the return address of the exit 4803 // TODO(1242173): To let the GC traverse the return address of the exit
4813 // frames, we need to know where the return address is. Right now, 4804 // frames, we need to know where the return address is. Right now,
4814 // we push it on the stack to be able to find it again, but we never 4805 // we push it on the stack to be able to find it again, but we never
4815 // restore from it in case of changes, which makes it impossible to 4806 // restore from it in case of changes, which makes it impossible to
4816 // support moving the C entry code stub. This should be fixed, but currently 4807 // support moving the C entry code stub. This should be fixed, but currently
4817 // this is OK because the CEntryStub gets generated so early in the V8 boot 4808 // this is OK because the CEntryStub gets generated so early in the V8 boot
4818 // sequence that it is not moving ever. 4809 // sequence that it is not moving ever.
4819 __ add(lr, pc, Operand(4)); // compute return address: (pc + 8) + 4 4810 __ add(lr, pc, Operand(4)); // compute return address: (pc + 8) + 4
4820 __ push(lr); 4811 __ push(lr);
4821 #if !defined(__arm__)
4822 // Notify the simulator of the transition to C code.
4823 __ swi(assembler::arm::call_rt_r5);
4824 #else /* !defined(__arm__) */
4825 __ Jump(r5); 4812 __ Jump(r5);
4826 #endif /* !defined(__arm__) */
4827 4813
4828 if (always_allocate) { 4814 if (always_allocate) {
4829 // It's okay to clobber r2 and r3 here. Don't mess with r0 and r1 4815 // It's okay to clobber r2 and r3 here. Don't mess with r0 and r1
4830 // though (contain the result). 4816 // though (contain the result).
4831 __ mov(r2, Operand(scope_depth)); 4817 __ mov(r2, Operand(scope_depth));
4832 __ ldr(r3, MemOperand(r2)); 4818 __ ldr(r3, MemOperand(r2));
4833 __ sub(r3, r3, Operand(1)); 4819 __ sub(r3, r3, Operand(1));
4834 __ str(r3, MemOperand(r2)); 4820 __ str(r3, MemOperand(r2));
4835 } 4821 }
4836 4822
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
5189 __ mov(r2, Operand(0)); 5175 __ mov(r2, Operand(0));
5190 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 5176 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
5191 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 5177 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
5192 RelocInfo::CODE_TARGET); 5178 RelocInfo::CODE_TARGET);
5193 } 5179 }
5194 5180
5195 5181
5196 #undef __ 5182 #undef __
5197 5183
5198 } } // namespace v8::internal 5184 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/constants-arm.h » ('j') | src/arm/constants-arm.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698