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

Side by Side Diff: src/builtins/s390/builtins-s390.cc

Issue 2875073003: PPC/s390: [turbofan] [builtins] Unify construct builtins for JS functions and classes and add inlin… (Closed)
Patch Set: added s390 port Created 3 years, 7 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
« no previous file with comments | « src/builtins/ppc/builtins-ppc.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_S390 5 #if V8_TARGET_ARCH_S390
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/debug/debug.h" 8 #include "src/debug/debug.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 __ bge(&ok, Label::kNear); 435 __ bge(&ok, Label::kNear);
436 436
437 GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode); 437 GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode);
438 438
439 __ bind(&ok); 439 __ bind(&ok);
440 GenerateTailCallToSharedCode(masm); 440 GenerateTailCallToSharedCode(masm);
441 } 441 }
442 442
443 namespace { 443 namespace {
444 444
445 void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, 445 void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
446 bool create_implicit_receiver,
447 bool disallow_non_object_return) {
448 Label post_instantiation_deopt_entry; 446 Label post_instantiation_deopt_entry;
449 // ----------- S t a t e ------------- 447 // ----------- S t a t e -------------
450 // -- r2 : number of arguments 448 // -- r2 : number of arguments
451 // -- r3 : constructor function 449 // -- r3 : constructor function
452 // -- r5 : new target 450 // -- r5 : new target
453 // -- cp : context 451 // -- cp : context
454 // -- lr : return address 452 // -- lr : return address
455 // -- sp[...]: constructor arguments 453 // -- sp[...]: constructor arguments
456 // ----------------------------------- 454 // -----------------------------------
457 455
458 Isolate* isolate = masm->isolate();
459
460 // Enter a construct frame. 456 // Enter a construct frame.
461 { 457 {
462 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); 458 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
463 459
464 // Preserve the incoming parameters on the stack. 460 // Preserve the incoming parameters on the stack.
465 461 __ SmiTag(r2);
466 if (!create_implicit_receiver) { 462 __ Push(cp, r2);
467 __ SmiTag(r6, r2); 463 __ SmiUntag(r2);
468 __ LoadAndTestP(r6, r6); 464 // The receiver for the builtin/api call.
469 __ Push(cp, r6); 465 __ PushRoot(Heap::kTheHoleValueRootIndex);
470 __ PushRoot(Heap::kTheHoleValueRootIndex);
471 } else {
472 __ SmiTag(r2);
473 __ Push(cp, r2);
474
475 // Allocate the new receiver object.
476 __ Push(r3, r5);
477 __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
478 RelocInfo::CODE_TARGET);
479 __ LoadRR(r6, r2);
480 __ Pop(r3, r5);
481
482 // ----------- S t a t e -------------
483 // -- r3: constructor function
484 // -- r5: new target
485 // -- r6: newly allocated object
486 // -----------------------------------
487
488 // Retrieve smi-tagged arguments count from the stack.
489 __ LoadP(r2, MemOperand(sp));
490 __ SmiUntag(r2);
491 __ LoadAndTestP(r2, r2);
492
493 // Push the allocated receiver to the stack. We need two copies
494 // because we may have to return the original one and the calling
495 // conventions dictate that the called function pops the receiver.
496 __ Push(r6, r6);
497 }
498
499 // Deoptimizer re-enters stub code here.
500 __ bind(&post_instantiation_deopt_entry);
501
502 // Set up pointer to last argument. 466 // Set up pointer to last argument.
503 __ la(r4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset)); 467 __ la(r6, MemOperand(fp, StandardFrameConstants::kCallerSPOffset));
504 468
505 // Copy arguments and receiver to the expression stack. 469 // Copy arguments and receiver to the expression stack.
506 // r2: number of arguments 470 // r2: number of arguments
507 // r3: constructor function 471 // r3: constructor function
508 // r4: address of last argument (caller sp) 472 // r4: address of last argument (caller sp)
509 // r5: new target 473 // r5: new target
510 // cr0: condition indicating whether r2 is zero 474 // cr0: condition indicating whether r2 is zero
511 // sp[0]: receiver 475 // sp[0]: receiver
512 // sp[1]: receiver 476 // sp[1]: receiver
513 // sp[2]: number of arguments (smi-tagged) 477 // sp[2]: number of arguments (smi-tagged)
514 Label loop, no_args; 478 Label loop, no_args;
515 __ beq(&no_args); 479 __ beq(&no_args);
516 __ ShiftLeftP(ip, r2, Operand(kPointerSizeLog2)); 480 __ ShiftLeftP(ip, r2, Operand(kPointerSizeLog2));
517 __ SubP(sp, sp, ip); 481 __ SubP(sp, sp, ip);
518 __ LoadRR(r1, r2); 482 __ LoadRR(r1, r2);
519 __ bind(&loop); 483 __ bind(&loop);
520 __ lay(ip, MemOperand(ip, -kPointerSize)); 484 __ lay(ip, MemOperand(ip, -kPointerSize));
521 __ LoadP(r0, MemOperand(ip, r4)); 485 __ LoadP(r0, MemOperand(ip, r6));
522 __ StoreP(r0, MemOperand(ip, sp)); 486 __ StoreP(r0, MemOperand(ip, sp));
523 __ BranchOnCount(r1, &loop); 487 __ BranchOnCount(r1, &loop);
524 __ bind(&no_args); 488 __ bind(&no_args);
525 489
526 // Call the function. 490 // Call the function.
527 // r2: number of arguments 491 // r2: number of arguments
528 // r3: constructor function 492 // r3: constructor function
529 // r5: new target 493 // r5: new target
530 494
531 ParameterCount actual(r2); 495 ParameterCount actual(r2);
532 __ InvokeFunction(r3, r5, actual, CALL_FUNCTION, 496 __ InvokeFunction(r3, r5, actual, CALL_FUNCTION,
533 CheckDebugStepCallWrapper()); 497 CheckDebugStepCallWrapper());
534 498
535 // Store offset of return address for deoptimizer.
536 if (create_implicit_receiver && !disallow_non_object_return &&
537 !is_api_function) {
538 masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset(
539 masm->pc_offset());
540 }
541
542 // Restore context from the frame. 499 // Restore context from the frame.
543 // r2: result
544 // sp[0]: receiver
545 // sp[1]: number of arguments (smi-tagged)
546 __ LoadP(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); 500 __ LoadP(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
547 501 // Restore smi-tagged arguments count from the frame.
548 if (create_implicit_receiver) { 502 __ LoadP(r3, MemOperand(fp, ConstructFrameConstants::kLengthOffset));
549 // If the result is an object (in the ECMA sense), we should get rid
550 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
551 // on page 74.
552 Label use_receiver, return_value, do_throw;
553
554 // If the result is a smi, it is *not* an object in the ECMA sense.
555 // r2: result
556 // sp[0]: receiver
557 // sp[1]: new.target
558 // sp[2]: number of arguments (smi-tagged)
559 // If the result is undefined, we jump out to using the implicit
560 // receiver, otherwise we do a smi check and fall through to
561 // check if the return value is a valid receiver.
562 if (disallow_non_object_return) {
563 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
564 __ beq(&use_receiver);
565 __ JumpIfSmi(r2, &do_throw);
566 } else {
567 __ JumpIfSmi(r2, &use_receiver);
568 }
569
570 // If the type of the result (stored in its map) is less than
571 // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
572 __ CompareObjectType(r2, r3, r5, FIRST_JS_RECEIVER_TYPE);
573 __ bge(&return_value);
574
575 if (disallow_non_object_return) {
576 __ bind(&do_throw);
577 __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
578 }
579
580 // Throw away the result of the constructor invocation and use the
581 // on-stack receiver as the result.
582 __ bind(&use_receiver);
583 __ LoadP(r2, MemOperand(sp));
584
585 // Remove receiver from the stack, remove caller arguments, and
586 // return.
587 __ bind(&return_value);
588 // r2: result
589 // sp[0]: receiver (newly allocated object)
590 // sp[1]: number of arguments (smi-tagged)
591 __ LoadP(r3, MemOperand(sp, 1 * kPointerSize));
592 } else {
593 __ LoadP(r3, MemOperand(sp));
594 }
595 503
596 // Leave construct frame. 504 // Leave construct frame.
597 } 505 }
598 506 // Remove caller arguments from the stack and return.
599 // ES6 9.2.2. Step 13+ 507 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
600 // For derived class constructors, throw a TypeError here if the result 508
601 // is not a JSReceiver. For the base constructor, we've already checked 509 __ SmiToPtrArrayOffset(r3, r3);
602 // the result, so we omit the check. 510 __ AddP(sp, sp, r3);
603 if (disallow_non_object_return && !create_implicit_receiver) { 511 __ AddP(sp, sp, Operand(kPointerSize));
604 Label do_throw, dont_throw; 512 __ Ret();
605 __ JumpIfSmi(r2, &do_throw); 513 }
514
515 // The construct stub for ES5 constructor functions and ES6 class constructors.
516 void Generate_JSConstructStubGeneric(MacroAssembler* masm,
517 bool restrict_constructor_return) {
518 // ----------- S t a t e -------------
519 // -- r2: number of arguments (untagged)
520 // -- r3: constructor function
521 // -- r5: new target
522 // -- cp: context
523 // -- lr: return address
524 // -- sp[...]: constructor arguments
525 // -----------------------------------
526
527 // Enter a construct frame.
528 {
529 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
530 Label post_instantiation_deopt_entry, not_create_implicit_receiver;
531
532 // Preserve the incoming parameters on the stack.
533 __ SmiTag(r2);
534 __ Push(cp, r2, r3, r5);
535
536 // ----------- S t a t e -------------
537 // -- sp[0*kPointerSize]: new target
538 // -- r3 and sp[1*kPointerSize]: constructor function
539 // -- sp[2*kPointerSize]: number of arguments (tagged)
540 // -- sp[3*kPointerSize]: context
541 // -----------------------------------
542
543 __ LoadP(r6, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
544 __ LoadlW(r6,
545 FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset));
546 __ TestBitMask(r6,
547 FunctionKind::kDerivedConstructor
548 << SharedFunctionInfo::kFunctionKindShift,
549 r0);
550 __ bne(&not_create_implicit_receiver);
551
552 // If not derived class constructor: Allocate the new receiver object.
553 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1,
554 r6, r7);
555 __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
556 RelocInfo::CODE_TARGET);
557 __ b(&post_instantiation_deopt_entry);
558
559 // Else: use TheHoleValue as receiver for constructor call
560 __ bind(&not_create_implicit_receiver);
561 __ LoadRoot(r2, Heap::kTheHoleValueRootIndex);
562
563 // ----------- S t a t e -------------
564 // -- r2: receiver
565 // -- Slot 3 / sp[0*kPointerSize]: new target
566 // -- Slot 2 / sp[1*kPointerSize]: constructor function
567 // -- Slot 1 / sp[2*kPointerSize]: number of arguments (tagged)
568 // -- Slot 0 / sp[3*kPointerSize]: context
569 // -----------------------------------
570 // Deoptimizer enters here.
571 masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset(
572 masm->pc_offset());
573 __ bind(&post_instantiation_deopt_entry);
574
575 // Restore new target.
576 __ Pop(r5);
577 // Push the allocated receiver to the stack. We need two copies
578 // because we may have to return the original one and the calling
579 // conventions dictate that the called function pops the receiver.
580 __ Push(r2, r2);
581
582 // ----------- S t a t e -------------
583 // -- r5: new target
584 // -- sp[0*kPointerSize]: implicit receiver
585 // -- sp[1*kPointerSize]: implicit receiver
586 // -- sp[2*kPointerSize]: constructor function
587 // -- sp[3*kPointerSize]: number of arguments (tagged)
588 // -- sp[4*kPointerSize]: context
589 // -----------------------------------
590
591 // Restore constructor function and argument count.
592 __ LoadP(r3, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
593 __ LoadP(r2, MemOperand(fp, ConstructFrameConstants::kLengthOffset));
594 __ SmiUntag(r2);
595
596 // Set up pointer to last argument.
597 __ la(r6, MemOperand(fp, StandardFrameConstants::kCallerSPOffset));
598
599 // Copy arguments and receiver to the expression stack.
600 Label loop, no_args;
601 // ----------- S t a t e -------------
602 // -- r2: number of arguments (untagged)
603 // -- r5: new target
604 // -- r6: pointer to last argument
605 // -- cr0: condition indicating whether r2 is zero
606 // -- sp[0*kPointerSize]: implicit receiver
607 // -- sp[1*kPointerSize]: implicit receiver
608 // -- r3 and sp[2*kPointerSize]: constructor function
609 // -- sp[3*kPointerSize]: number of arguments (tagged)
610 // -- sp[4*kPointerSize]: context
611 // -----------------------------------
612
613 __ beq(&no_args);
614 __ ShiftLeftP(ip, r2, Operand(kPointerSizeLog2));
615 __ SubP(sp, sp, ip);
616 __ LoadRR(r1, r2);
617 __ bind(&loop);
618 __ lay(ip, MemOperand(ip, -kPointerSize));
619 __ LoadP(r0, MemOperand(ip, r6));
620 __ StoreP(r0, MemOperand(ip, sp));
621 __ BranchOnCount(r1, &loop);
622 __ bind(&no_args);
623
624 // Call the function.
625 ParameterCount actual(r2);
626 __ InvokeFunction(r3, r5, actual, CALL_FUNCTION,
627 CheckDebugStepCallWrapper());
628
629 // ----------- S t a t e -------------
630 // -- r0: constructor result
631 // -- sp[0*kPointerSize]: implicit receiver
632 // -- sp[1*kPointerSize]: constructor function
633 // -- sp[2*kPointerSize]: number of arguments
634 // -- sp[3*kPointerSize]: context
635 // -----------------------------------
636
637 // Store offset of return address for deoptimizer.
638 masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset(
639 masm->pc_offset());
640
641 // Restore the context from the frame.
642 __ LoadP(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
643
644 // If the result is an object (in the ECMA sense), we should get rid
645 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
646 // on page 74.
647 Label use_receiver, do_throw, other_result, leave_frame;
648
649 // If the result is undefined, we jump out to using the implicit receiver.
650 __ JumpIfRoot(r2, Heap::kUndefinedValueRootIndex, &use_receiver);
651
652 // Otherwise we do a smi check and fall through to check if the return value
653 // is a valid receiver.
654
655 // If the result is a smi, it is *not* an object in the ECMA sense.
656 __ JumpIfSmi(r2, &other_result);
657
658 // If the type of the result (stored in its map) is less than
659 // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
606 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); 660 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
607 __ CompareObjectType(r2, r5, r5, FIRST_JS_RECEIVER_TYPE); 661 __ CompareObjectType(r2, r6, r6, FIRST_JS_RECEIVER_TYPE);
608 __ bge(&dont_throw); 662 __ bge(&leave_frame);
663
664 __ bind(&other_result);
665 // The result is now neither undefined nor an object.
666 if (restrict_constructor_return) {
667 // Throw if constructor function is a class constructor
668 __ LoadP(r6, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
669 __ LoadP(r6, FieldMemOperand(r6, JSFunction::kSharedFunctionInfoOffset));
670 __ LoadlW(r6,
671 FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset));
672 __ TestBitMask(r6,
673 FunctionKind::kClassConstructor
674 << SharedFunctionInfo::kFunctionKindShift,
675 r0);
676 __ beq(&use_receiver);
677 } else {
678 __ b(&use_receiver);
679 }
609 __ bind(&do_throw); 680 __ bind(&do_throw);
610 { 681 {
611 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 682 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
612 __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject); 683 __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
613 } 684 }
614 __ bind(&dont_throw); 685
686 // Throw away the result of the constructor invocation and use the
687 // on-stack receiver as the result.
688 __ bind(&use_receiver);
689 __ LoadP(r2, MemOperand(sp));
690 __ JumpIfRoot(r2, Heap::kTheHoleValueRootIndex, &do_throw);
691
692 __ bind(&leave_frame);
693 // Restore smi-tagged arguments count from the frame.
694 __ LoadP(r3, MemOperand(fp, ConstructFrameConstants::kLengthOffset));
695 // Leave construct frame.
615 } 696 }
616 697
698 // Remove caller arguments from the stack and return.
699 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
700
617 __ SmiToPtrArrayOffset(r3, r3); 701 __ SmiToPtrArrayOffset(r3, r3);
618 __ AddP(sp, sp, r3); 702 __ AddP(sp, sp, r3);
619 __ AddP(sp, sp, Operand(kPointerSize)); 703 __ AddP(sp, sp, Operand(kPointerSize));
620 if (create_implicit_receiver) {
621 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r3, r4);
622 }
623 __ Ret(); 704 __ Ret();
624 705 }
625 // Store offset of trampoline address for deoptimizer. This is the bailout
626 // point after the receiver instantiation but before the function invocation.
627 // We need to restore some registers in order to continue the above code.
628 if (create_implicit_receiver && !disallow_non_object_return &&
629 !is_api_function) {
630 masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset(
631 masm->pc_offset());
632
633 // ----------- S t a t e -------------
634 // -- r2 : newly allocated object
635 // -- sp[0] : constructor function
636 // -----------------------------------
637
638 __ pop(r3);
639 __ Push(r2, r2);
640
641 // Retrieve smi-tagged arguments count from the stack.
642 __ LoadP(r2, MemOperand(fp, ConstructFrameConstants::kLengthOffset));
643 __ SmiUntag(r2);
644
645 // Retrieve the new target value from the stack. This was placed into the
646 // frame description in place of the receiver by the optimizing compiler.
647 __ la(r5, MemOperand(fp, StandardFrameConstants::kCallerSPOffset));
648 __ ShiftLeftP(ip, r2, Operand(kPointerSizeLog2));
649 __ LoadP(r5, MemOperand(r5, ip));
650
651 // Continue with constructor function invocation.
652 __ b(&post_instantiation_deopt_entry);
653 }
654 }
655
656 } // namespace 706 } // namespace
657 707
658 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 708 void Builtins::Generate_JSConstructStubGenericRestrictedReturn(
659 Generate_JSConstructStubHelper(masm, false, true, false); 709 MacroAssembler* masm) {
660 } 710 Generate_JSConstructStubGeneric(masm, true);
661 711 }
712 void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
713 MacroAssembler* masm) {
714 Generate_JSConstructStubGeneric(masm, false);
715 }
662 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 716 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
663 Generate_JSConstructStubHelper(masm, true, false, false); 717 Generate_JSBuiltinsConstructStubHelper(masm);
664 } 718 }
665
666 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { 719 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
667 Generate_JSConstructStubHelper(masm, false, false, false); 720 Generate_JSBuiltinsConstructStubHelper(masm);
668 }
669
670 void Builtins::Generate_JSBuiltinsConstructStubForBase(MacroAssembler* masm) {
671 Generate_JSConstructStubHelper(masm, false, true, true);
672 }
673
674 void Builtins::Generate_JSBuiltinsConstructStubForDerived(
675 MacroAssembler* masm) {
676 Generate_JSConstructStubHelper(masm, false, false, true);
677 } 721 }
678 722
679 // static 723 // static
680 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { 724 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
681 // ----------- S t a t e ------------- 725 // ----------- S t a t e -------------
682 // -- r2 : the value to pass to the generator 726 // -- r2 : the value to pass to the generator
683 // -- r3 : the JSGeneratorObject to resume 727 // -- r3 : the JSGeneratorObject to resume
684 // -- r4 : the resume mode (tagged) 728 // -- r4 : the resume mode (tagged)
685 // -- r5 : the SuspendFlags of the earlier suspend call (tagged) 729 // -- r5 : the SuspendFlags of the earlier suspend call (tagged)
686 // -- lr : return address 730 // -- lr : return address
(...skipping 2440 matching lines...) Expand 10 before | Expand all | Expand 10 after
3127 // Now jump to the instructions of the returned code object. 3171 // Now jump to the instructions of the returned code object.
3128 __ Jump(ip); 3172 __ Jump(ip);
3129 } 3173 }
3130 3174
3131 #undef __ 3175 #undef __
3132 3176
3133 } // namespace internal 3177 } // namespace internal
3134 } // namespace v8 3178 } // namespace v8
3135 3179
3136 #endif // V8_TARGET_ARCH_S390 3180 #endif // V8_TARGET_ARCH_S390
OLDNEW
« no previous file with comments | « src/builtins/ppc/builtins-ppc.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698