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

Side by Side Diff: src/ppc/code-stubs-ppc.cc

Issue 1693833002: Remove strong mode support from binary operations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments. Created 4 years, 10 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 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_PPC 5 #if V8_TARGET_ARCH_PPC
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 84
85 85
86 void InternalArrayNArgumentsConstructorStub::InitializeDescriptor( 86 void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
87 CodeStubDescriptor* descriptor) { 87 CodeStubDescriptor* descriptor) {
88 InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1); 88 InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
89 } 89 }
90 90
91 91
92 #define __ ACCESS_MASM(masm) 92 #define __ ACCESS_MASM(masm)
93 93
94
95 static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow, 94 static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
96 Condition cond, Strength strength); 95 Condition cond);
97 static void EmitSmiNonsmiComparison(MacroAssembler* masm, Register lhs, 96 static void EmitSmiNonsmiComparison(MacroAssembler* masm, Register lhs,
98 Register rhs, Label* lhs_not_nan, 97 Register rhs, Label* lhs_not_nan,
99 Label* slow, bool strict); 98 Label* slow, bool strict);
100 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, Register lhs, 99 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, Register lhs,
101 Register rhs); 100 Register rhs);
102 101
103 102
104 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm, 103 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm,
105 ExternalReference miss) { 104 ExternalReference miss) {
106 // Update the static counter each time a new code stub is generated. 105 // Update the static counter each time a new code stub is generated.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 __ pop(scratch); 240 __ pop(scratch);
242 241
243 __ Ret(); 242 __ Ret();
244 } 243 }
245 244
246 245
247 // Handle the case where the lhs and rhs are the same object. 246 // Handle the case where the lhs and rhs are the same object.
248 // Equality is almost reflexive (everything but NaN), so this is a test 247 // Equality is almost reflexive (everything but NaN), so this is a test
249 // for "identity and not NaN". 248 // for "identity and not NaN".
250 static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow, 249 static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
251 Condition cond, Strength strength) { 250 Condition cond) {
252 Label not_identical; 251 Label not_identical;
253 Label heap_number, return_equal; 252 Label heap_number, return_equal;
254 __ cmp(r3, r4); 253 __ cmp(r3, r4);
255 __ bne(&not_identical); 254 __ bne(&not_identical);
256 255
257 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), 256 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
258 // so we do the second best thing - test it ourselves. 257 // so we do the second best thing - test it ourselves.
259 // They are both equal and they are not both Smis so both of them are not 258 // They are both equal and they are not both Smis so both of them are not
260 // Smis. If it's not a heap number, then return equal. 259 // Smis. If it's not a heap number, then return equal.
261 if (cond == lt || cond == gt) { 260 if (cond == lt || cond == gt) {
262 // Call runtime on identical JSObjects. 261 // Call runtime on identical JSObjects.
263 __ CompareObjectType(r3, r7, r7, FIRST_JS_RECEIVER_TYPE); 262 __ CompareObjectType(r3, r7, r7, FIRST_JS_RECEIVER_TYPE);
264 __ bge(slow); 263 __ bge(slow);
265 // Call runtime on identical symbols since we need to throw a TypeError. 264 // Call runtime on identical symbols since we need to throw a TypeError.
266 __ cmpi(r7, Operand(SYMBOL_TYPE)); 265 __ cmpi(r7, Operand(SYMBOL_TYPE));
267 __ beq(slow); 266 __ beq(slow);
268 // Call runtime on identical SIMD values since we must throw a TypeError. 267 // Call runtime on identical SIMD values since we must throw a TypeError.
269 __ cmpi(r7, Operand(SIMD128_VALUE_TYPE)); 268 __ cmpi(r7, Operand(SIMD128_VALUE_TYPE));
270 __ beq(slow); 269 __ beq(slow);
271 if (is_strong(strength)) {
272 // Call the runtime on anything that is converted in the semantics, since
273 // we need to throw a TypeError. Smis have already been ruled out.
274 __ cmpi(r7, Operand(HEAP_NUMBER_TYPE));
275 __ beq(&return_equal);
276 __ andi(r0, r7, Operand(kIsNotStringMask));
277 __ bne(slow, cr0);
278 }
279 } else { 270 } else {
280 __ CompareObjectType(r3, r7, r7, HEAP_NUMBER_TYPE); 271 __ CompareObjectType(r3, r7, r7, HEAP_NUMBER_TYPE);
281 __ beq(&heap_number); 272 __ beq(&heap_number);
282 // Comparing JS objects with <=, >= is complicated. 273 // Comparing JS objects with <=, >= is complicated.
283 if (cond != eq) { 274 if (cond != eq) {
284 __ cmpi(r7, Operand(FIRST_JS_RECEIVER_TYPE)); 275 __ cmpi(r7, Operand(FIRST_JS_RECEIVER_TYPE));
285 __ bge(slow); 276 __ bge(slow);
286 // Call runtime on identical symbols since we need to throw a TypeError. 277 // Call runtime on identical symbols since we need to throw a TypeError.
287 __ cmpi(r7, Operand(SYMBOL_TYPE)); 278 __ cmpi(r7, Operand(SYMBOL_TYPE));
288 __ beq(slow); 279 __ beq(slow);
289 // Call runtime on identical SIMD values since we must throw a TypeError. 280 // Call runtime on identical SIMD values since we must throw a TypeError.
290 __ cmpi(r7, Operand(SIMD128_VALUE_TYPE)); 281 __ cmpi(r7, Operand(SIMD128_VALUE_TYPE));
291 __ beq(slow); 282 __ beq(slow);
292 if (is_strong(strength)) {
293 // Call the runtime on anything that is converted in the semantics,
294 // since we need to throw a TypeError. Smis and heap numbers have
295 // already been ruled out.
296 __ andi(r0, r7, Operand(kIsNotStringMask));
297 __ bne(slow, cr0);
298 }
299 // Normally here we fall through to return_equal, but undefined is 283 // Normally here we fall through to return_equal, but undefined is
300 // special: (undefined == undefined) == true, but 284 // special: (undefined == undefined) == true, but
301 // (undefined <= undefined) == false! See ECMAScript 11.8.5. 285 // (undefined <= undefined) == false! See ECMAScript 11.8.5.
302 if (cond == le || cond == ge) { 286 if (cond == le || cond == ge) {
303 __ cmpi(r7, Operand(ODDBALL_TYPE)); 287 __ cmpi(r7, Operand(ODDBALL_TYPE));
304 __ bne(&return_equal); 288 __ bne(&return_equal);
305 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); 289 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
306 __ cmp(r3, r5); 290 __ cmp(r3, r5);
307 __ bne(&return_equal); 291 __ bne(&return_equal);
308 if (cond == le) { 292 if (cond == le) {
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 __ SmiUntag(r3); 586 __ SmiUntag(r3);
603 __ sub(r3, r4, r3); 587 __ sub(r3, r4, r3);
604 __ Ret(); 588 __ Ret();
605 __ bind(&not_two_smis); 589 __ bind(&not_two_smis);
606 590
607 // NOTICE! This code is only reached after a smi-fast-case check, so 591 // NOTICE! This code is only reached after a smi-fast-case check, so
608 // it is certain that at least one operand isn't a smi. 592 // it is certain that at least one operand isn't a smi.
609 593
610 // Handle the case where the objects are identical. Either returns the answer 594 // Handle the case where the objects are identical. Either returns the answer
611 // or goes to slow. Only falls through if the objects were not identical. 595 // or goes to slow. Only falls through if the objects were not identical.
612 EmitIdenticalObjectComparison(masm, &slow, cc, strength()); 596 EmitIdenticalObjectComparison(masm, &slow, cc);
613 597
614 // If either is a Smi (we know that not both are), then they can only 598 // If either is a Smi (we know that not both are), then they can only
615 // be strictly equal if the other is a HeapNumber. 599 // be strictly equal if the other is a HeapNumber.
616 STATIC_ASSERT(kSmiTag == 0); 600 STATIC_ASSERT(kSmiTag == 0);
617 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); 601 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0));
618 __ and_(r5, lhs, rhs); 602 __ and_(r5, lhs, rhs);
619 __ JumpIfNotSmi(r5, &not_smis); 603 __ JumpIfNotSmi(r5, &not_smis);
620 // One operand is a smi. EmitSmiNonsmiComparison generates code that can: 604 // One operand is a smi. EmitSmiNonsmiComparison generates code that can:
621 // 1) Return the answer. 605 // 1) Return the answer.
622 // 2) Go to slow. 606 // 2) Go to slow.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 ncr = GREATER; 708 ncr = GREATER;
725 } else { 709 } else {
726 DCHECK(cc == gt || cc == ge); // remaining cases 710 DCHECK(cc == gt || cc == ge); // remaining cases
727 ncr = LESS; 711 ncr = LESS;
728 } 712 }
729 __ LoadSmiLiteral(r3, Smi::FromInt(ncr)); 713 __ LoadSmiLiteral(r3, Smi::FromInt(ncr));
730 __ push(r3); 714 __ push(r3);
731 715
732 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) 716 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
733 // tagged as a small integer. 717 // tagged as a small integer.
734 __ TailCallRuntime(is_strong(strength()) ? Runtime::kCompare_Strong 718 __ TailCallRuntime(Runtime::kCompare);
735 : Runtime::kCompare);
736 } 719 }
737 720
738 __ bind(&miss); 721 __ bind(&miss);
739 GenerateMiss(masm); 722 GenerateMiss(masm);
740 } 723 }
741 724
742 725
743 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { 726 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
744 // We don't allow a GC during a store buffer overflow so there is no need to 727 // We don't allow a GC during a store buffer overflow so there is no need to
745 // store the registers in any particular way, but we do have to store and 728 // store the registers in any particular way, but we do have to store and
(...skipping 2272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3018 __ TailCallStub(&stub); 3001 __ TailCallStub(&stub);
3019 } 3002 }
3020 3003
3021 3004
3022 void CompareICStub::GenerateBooleans(MacroAssembler* masm) { 3005 void CompareICStub::GenerateBooleans(MacroAssembler* masm) {
3023 DCHECK_EQ(CompareICState::BOOLEAN, state()); 3006 DCHECK_EQ(CompareICState::BOOLEAN, state());
3024 Label miss; 3007 Label miss;
3025 3008
3026 __ CheckMap(r4, r5, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK); 3009 __ CheckMap(r4, r5, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK);
3027 __ CheckMap(r3, r6, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK); 3010 __ CheckMap(r3, r6, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK);
3028 if (op() != Token::EQ_STRICT && is_strong(strength())) { 3011 if (!Token::IsEqualityOp(op())) {
3029 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion); 3012 __ LoadP(r4, FieldMemOperand(r4, Oddball::kToNumberOffset));
3030 } else { 3013 __ AssertSmi(r4);
3031 if (!Token::IsEqualityOp(op())) { 3014 __ LoadP(r3, FieldMemOperand(r3, Oddball::kToNumberOffset));
3032 __ LoadP(r4, FieldMemOperand(r4, Oddball::kToNumberOffset)); 3015 __ AssertSmi(r3);
3033 __ AssertSmi(r4);
3034 __ LoadP(r3, FieldMemOperand(r3, Oddball::kToNumberOffset));
3035 __ AssertSmi(r3);
3036 }
3037 __ sub(r3, r4, r3);
3038 __ Ret();
3039 } 3016 }
3017 __ sub(r3, r4, r3);
3018 __ Ret();
3040 3019
3041 __ bind(&miss); 3020 __ bind(&miss);
3042 GenerateMiss(masm); 3021 GenerateMiss(masm);
3043 } 3022 }
3044 3023
3045 3024
3046 void CompareICStub::GenerateSmis(MacroAssembler* masm) { 3025 void CompareICStub::GenerateSmis(MacroAssembler* masm) {
3047 DCHECK(state() == CompareICState::SMI); 3026 DCHECK(state() == CompareICState::SMI);
3048 Label miss; 3027 Label miss;
3049 __ orx(r5, r4, r3); 3028 __ orx(r5, r4, r3);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3127 __ bind(&equal); 3106 __ bind(&equal);
3128 __ li(r3, Operand(EQUAL)); 3107 __ li(r3, Operand(EQUAL));
3129 __ Ret(); 3108 __ Ret();
3130 __ bind(&less_than); 3109 __ bind(&less_than);
3131 __ li(r3, Operand(LESS)); 3110 __ li(r3, Operand(LESS));
3132 __ Ret(); 3111 __ Ret();
3133 } 3112 }
3134 3113
3135 __ bind(&unordered); 3114 __ bind(&unordered);
3136 __ bind(&generic_stub); 3115 __ bind(&generic_stub);
3137 CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC, 3116 CompareICStub stub(isolate(), op(), CompareICState::GENERIC,
3138 CompareICState::GENERIC, CompareICState::GENERIC); 3117 CompareICState::GENERIC, CompareICState::GENERIC);
3139 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 3118 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
3140 3119
3141 __ bind(&maybe_undefined1); 3120 __ bind(&maybe_undefined1);
3142 if (Token::IsOrderedRelationalCompareOp(op())) { 3121 if (Token::IsOrderedRelationalCompareOp(op())) {
3143 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); 3122 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
3144 __ bne(&miss); 3123 __ bne(&miss);
3145 __ JumpIfSmi(r4, &unordered); 3124 __ JumpIfSmi(r4, &unordered);
3146 __ CompareObjectType(r4, r5, r5, HEAP_NUMBER_TYPE); 3125 __ CompareObjectType(r4, r5, r5, HEAP_NUMBER_TYPE);
3147 __ bne(&maybe_undefined2); 3126 __ bne(&maybe_undefined2);
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
3350 __ LoadP(r5, FieldMemOperand(r3, HeapObject::kMapOffset)); 3329 __ LoadP(r5, FieldMemOperand(r3, HeapObject::kMapOffset));
3351 __ LoadP(r6, FieldMemOperand(r4, HeapObject::kMapOffset)); 3330 __ LoadP(r6, FieldMemOperand(r4, HeapObject::kMapOffset));
3352 __ cmp(r5, r7); 3331 __ cmp(r5, r7);
3353 __ bne(&miss); 3332 __ bne(&miss);
3354 __ cmp(r6, r7); 3333 __ cmp(r6, r7);
3355 __ bne(&miss); 3334 __ bne(&miss);
3356 3335
3357 if (Token::IsEqualityOp(op())) { 3336 if (Token::IsEqualityOp(op())) {
3358 __ sub(r3, r3, r4); 3337 __ sub(r3, r3, r4);
3359 __ Ret(); 3338 __ Ret();
3360 } else if (is_strong(strength())) {
3361 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion);
3362 } else { 3339 } else {
3363 if (op() == Token::LT || op() == Token::LTE) { 3340 if (op() == Token::LT || op() == Token::LTE) {
3364 __ LoadSmiLiteral(r5, Smi::FromInt(GREATER)); 3341 __ LoadSmiLiteral(r5, Smi::FromInt(GREATER));
3365 } else { 3342 } else {
3366 __ LoadSmiLiteral(r5, Smi::FromInt(LESS)); 3343 __ LoadSmiLiteral(r5, Smi::FromInt(LESS));
3367 } 3344 }
3368 __ Push(r4, r3, r5); 3345 __ Push(r4, r3, r5);
3369 __ TailCallRuntime(Runtime::kCompare); 3346 __ TailCallRuntime(Runtime::kCompare);
3370 } 3347 }
3371 3348
(...skipping 2384 matching lines...) Expand 10 before | Expand all | Expand 10 after
5756 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, 5733 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
5757 kStackUnwindSpace, NULL, return_value_operand, NULL); 5734 kStackUnwindSpace, NULL, return_value_operand, NULL);
5758 } 5735 }
5759 5736
5760 5737
5761 #undef __ 5738 #undef __
5762 } // namespace internal 5739 } // namespace internal
5763 } // namespace v8 5740 } // namespace v8
5764 5741
5765 #endif // V8_TARGET_ARCH_PPC 5742 #endif // V8_TARGET_ARCH_PPC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698