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

Side by Side Diff: src/ppc/macro-assembler-ppc.cc

Issue 1314263002: PPC: Correctify instanceof and make it optimizable. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years, 3 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/ppc/macro-assembler-ppc.h ('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 #include <assert.h> // For assert 5 #include <assert.h> // For assert
6 #include <limits.h> // For LONG_MIN, LONG_MAX. 6 #include <limits.h> // For LONG_MIN, LONG_MAX.
7 7
8 #if V8_TARGET_ARCH_PPC 8 #if V8_TARGET_ARCH_PPC
9 9
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 1961 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 JumpIfSmi(result, &done); 1972 JumpIfSmi(result, &done);
1973 CompareObjectType(result, temp, temp2, MAP_TYPE); 1973 CompareObjectType(result, temp, temp2, MAP_TYPE);
1974 bne(&done); 1974 bne(&done);
1975 LoadP(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset)); 1975 LoadP(result, FieldMemOperand(result, Map::kConstructorOrBackPointerOffset));
1976 b(&loop); 1976 b(&loop);
1977 bind(&done); 1977 bind(&done);
1978 } 1978 }
1979 1979
1980 1980
1981 void MacroAssembler::TryGetFunctionPrototype(Register function, Register result, 1981 void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
1982 Register scratch, Label* miss, 1982 Register scratch, Label* miss) {
1983 bool miss_on_bound_function) {
1984 Label non_instance;
1985 if (miss_on_bound_function) {
1986 // Check that the receiver isn't a smi.
1987 JumpIfSmi(function, miss);
1988
1989 // Check that the function really is a function. Load map into result reg.
1990 CompareObjectType(function, result, scratch, JS_FUNCTION_TYPE);
1991 bne(miss);
1992
1993 LoadP(scratch,
1994 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
1995 lwz(scratch,
1996 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset));
1997 TestBit(scratch,
1998 #if V8_TARGET_ARCH_PPC64
1999 SharedFunctionInfo::kBoundFunction,
2000 #else
2001 SharedFunctionInfo::kBoundFunction + kSmiTagSize,
2002 #endif
2003 r0);
2004 bne(miss, cr0);
2005
2006 // Make sure that the function has an instance prototype.
2007 lbz(scratch, FieldMemOperand(result, Map::kBitFieldOffset));
2008 andi(r0, scratch, Operand(1 << Map::kHasNonInstancePrototype));
2009 bne(&non_instance, cr0);
2010 }
2011
2012 // Get the prototype or initial map from the function. 1983 // Get the prototype or initial map from the function.
2013 LoadP(result, 1984 LoadP(result,
2014 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 1985 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
2015 1986
2016 // If the prototype or initial map is the hole, don't return it and 1987 // If the prototype or initial map is the hole, don't return it and
2017 // simply miss the cache instead. This will allow us to allocate a 1988 // simply miss the cache instead. This will allow us to allocate a
2018 // prototype object on-demand in the runtime system. 1989 // prototype object on-demand in the runtime system.
2019 LoadRoot(r0, Heap::kTheHoleValueRootIndex); 1990 LoadRoot(r0, Heap::kTheHoleValueRootIndex);
2020 cmp(result, r0); 1991 cmp(result, r0);
2021 beq(miss); 1992 beq(miss);
2022 1993
2023 // If the function does not have an initial map, we're done. 1994 // If the function does not have an initial map, we're done.
2024 Label done; 1995 Label done;
2025 CompareObjectType(result, scratch, scratch, MAP_TYPE); 1996 CompareObjectType(result, scratch, scratch, MAP_TYPE);
2026 bne(&done); 1997 bne(&done);
2027 1998
2028 // Get the prototype from the initial map. 1999 // Get the prototype from the initial map.
2029 LoadP(result, FieldMemOperand(result, Map::kPrototypeOffset)); 2000 LoadP(result, FieldMemOperand(result, Map::kPrototypeOffset));
2030 2001
2031 if (miss_on_bound_function) {
2032 b(&done);
2033
2034 // Non-instance prototype: Fetch prototype from constructor field
2035 // in initial map.
2036 bind(&non_instance);
2037 GetMapConstructor(result, result, scratch, ip);
2038 }
2039
2040 // All done. 2002 // All done.
2041 bind(&done); 2003 bind(&done);
2042 } 2004 }
2043 2005
2044 2006
2045 void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id, 2007 void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id,
2046 Condition cond) { 2008 Condition cond) {
2047 DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs. 2009 DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
2048 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond); 2010 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond);
2049 } 2011 }
(...skipping 1186 matching lines...) Expand 10 before | Expand all | Expand 10 after
3236 slwi(r0, result, Operand(16)); 3198 slwi(r0, result, Operand(16));
3237 // sign-extend and add the load offset 3199 // sign-extend and add the load offset
3238 lwz(result, MemOperand(location, kInstrSize)); 3200 lwz(result, MemOperand(location, kInstrSize));
3239 extsh(result, result); 3201 extsh(result, result);
3240 add(result, r0, result); 3202 add(result, r0, result);
3241 3203
3242 bind(&done); 3204 bind(&done);
3243 } 3205 }
3244 3206
3245 3207
3246 void MacroAssembler::SetRelocatedValue(Register location, Register scratch,
3247 Register new_value) {
3248 lwz(scratch, MemOperand(location));
3249
3250 if (FLAG_enable_embedded_constant_pool) {
3251 if (emit_debug_code()) {
3252 // Check that the instruction sequence is a load from the constant pool
3253 ExtractBitMask(scratch, scratch, 0x1f * B16);
3254 cmpi(scratch, Operand(kConstantPoolRegister.code()));
3255 Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool);
3256 // Scratch was clobbered. Restore it.
3257 lwz(scratch, MemOperand(location));
3258 }
3259 DecodeConstantPoolOffset(scratch, location);
3260 StorePX(new_value, MemOperand(kConstantPoolRegister, scratch));
3261 return;
3262 }
3263
3264 // This code assumes a FIXED_SEQUENCE for lis/ori
3265
3266 // At this point scratch is a lis instruction.
3267 if (emit_debug_code()) {
3268 And(scratch, scratch, Operand(kOpcodeMask | (0x1f * B16)));
3269 Cmpi(scratch, Operand(ADDIS), r0);
3270 Check(eq, kTheInstructionToPatchShouldBeALis);
3271 lwz(scratch, MemOperand(location));
3272 }
3273
3274 // insert new high word into lis instruction
3275 #if V8_TARGET_ARCH_PPC64
3276 srdi(ip, new_value, Operand(32));
3277 rlwimi(scratch, ip, 16, 16, 31);
3278 #else
3279 rlwimi(scratch, new_value, 16, 16, 31);
3280 #endif
3281
3282 stw(scratch, MemOperand(location));
3283
3284 lwz(scratch, MemOperand(location, kInstrSize));
3285 // scratch is now ori.
3286 if (emit_debug_code()) {
3287 And(scratch, scratch, Operand(kOpcodeMask));
3288 Cmpi(scratch, Operand(ORI), r0);
3289 Check(eq, kTheInstructionShouldBeAnOri);
3290 lwz(scratch, MemOperand(location, kInstrSize));
3291 }
3292
3293 // insert new low word into ori instruction
3294 #if V8_TARGET_ARCH_PPC64
3295 rlwimi(scratch, ip, 0, 16, 31);
3296 #else
3297 rlwimi(scratch, new_value, 0, 16, 31);
3298 #endif
3299 stw(scratch, MemOperand(location, kInstrSize));
3300
3301 #if V8_TARGET_ARCH_PPC64
3302 if (emit_debug_code()) {
3303 lwz(scratch, MemOperand(location, 2 * kInstrSize));
3304 // scratch is now sldi.
3305 And(scratch, scratch, Operand(kOpcodeMask | kExt5OpcodeMask));
3306 Cmpi(scratch, Operand(EXT5 | RLDICR), r0);
3307 Check(eq, kTheInstructionShouldBeASldi);
3308 }
3309
3310 lwz(scratch, MemOperand(location, 3 * kInstrSize));
3311 // scratch is now ori.
3312 if (emit_debug_code()) {
3313 And(scratch, scratch, Operand(kOpcodeMask));
3314 Cmpi(scratch, Operand(ORIS), r0);
3315 Check(eq, kTheInstructionShouldBeAnOris);
3316 lwz(scratch, MemOperand(location, 3 * kInstrSize));
3317 }
3318
3319 rlwimi(scratch, new_value, 16, 16, 31);
3320 stw(scratch, MemOperand(location, 3 * kInstrSize));
3321
3322 lwz(scratch, MemOperand(location, 4 * kInstrSize));
3323 // scratch is now ori.
3324 if (emit_debug_code()) {
3325 And(scratch, scratch, Operand(kOpcodeMask));
3326 Cmpi(scratch, Operand(ORI), r0);
3327 Check(eq, kTheInstructionShouldBeAnOri);
3328 lwz(scratch, MemOperand(location, 4 * kInstrSize));
3329 }
3330 rlwimi(scratch, new_value, 0, 16, 31);
3331 stw(scratch, MemOperand(location, 4 * kInstrSize));
3332 #endif
3333
3334 // Update the I-cache so the new lis and addic can be executed.
3335 #if V8_TARGET_ARCH_PPC64
3336 FlushICache(location, 5 * kInstrSize, scratch);
3337 #else
3338 FlushICache(location, 2 * kInstrSize, scratch);
3339 #endif
3340 }
3341
3342
3343 void MacroAssembler::GetRelocatedValue(Register location, Register result,
3344 Register scratch) {
3345 lwz(result, MemOperand(location));
3346
3347 if (FLAG_enable_embedded_constant_pool) {
3348 if (emit_debug_code()) {
3349 // Check that the instruction sequence is a load from the constant pool
3350 ExtractBitMask(result, result, 0x1f * B16);
3351 cmpi(result, Operand(kConstantPoolRegister.code()));
3352 Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool);
3353 lwz(result, MemOperand(location));
3354 }
3355 DecodeConstantPoolOffset(result, location);
3356 LoadPX(result, MemOperand(kConstantPoolRegister, result));
3357 return;
3358 }
3359
3360 // This code assumes a FIXED_SEQUENCE for lis/ori
3361 if (emit_debug_code()) {
3362 And(result, result, Operand(kOpcodeMask | (0x1f * B16)));
3363 Cmpi(result, Operand(ADDIS), r0);
3364 Check(eq, kTheInstructionShouldBeALis);
3365 lwz(result, MemOperand(location));
3366 }
3367
3368 // result now holds a lis instruction. Extract the immediate.
3369 slwi(result, result, Operand(16));
3370
3371 lwz(scratch, MemOperand(location, kInstrSize));
3372 if (emit_debug_code()) {
3373 And(scratch, scratch, Operand(kOpcodeMask));
3374 Cmpi(scratch, Operand(ORI), r0);
3375 Check(eq, kTheInstructionShouldBeAnOri);
3376 lwz(scratch, MemOperand(location, kInstrSize));
3377 }
3378 // Copy the low 16bits from ori instruction into result
3379 rlwimi(result, scratch, 0, 16, 31);
3380
3381 #if V8_TARGET_ARCH_PPC64
3382 if (emit_debug_code()) {
3383 lwz(scratch, MemOperand(location, 2 * kInstrSize));
3384 // scratch is now sldi.
3385 And(scratch, scratch, Operand(kOpcodeMask | kExt5OpcodeMask));
3386 Cmpi(scratch, Operand(EXT5 | RLDICR), r0);
3387 Check(eq, kTheInstructionShouldBeASldi);
3388 }
3389
3390 lwz(scratch, MemOperand(location, 3 * kInstrSize));
3391 // scratch is now ori.
3392 if (emit_debug_code()) {
3393 And(scratch, scratch, Operand(kOpcodeMask));
3394 Cmpi(scratch, Operand(ORIS), r0);
3395 Check(eq, kTheInstructionShouldBeAnOris);
3396 lwz(scratch, MemOperand(location, 3 * kInstrSize));
3397 }
3398 sldi(result, result, Operand(16));
3399 rldimi(result, scratch, 0, 48);
3400
3401 lwz(scratch, MemOperand(location, 4 * kInstrSize));
3402 // scratch is now ori.
3403 if (emit_debug_code()) {
3404 And(scratch, scratch, Operand(kOpcodeMask));
3405 Cmpi(scratch, Operand(ORI), r0);
3406 Check(eq, kTheInstructionShouldBeAnOri);
3407 lwz(scratch, MemOperand(location, 4 * kInstrSize));
3408 }
3409 sldi(result, result, Operand(16));
3410 rldimi(result, scratch, 0, 48);
3411 #endif
3412 }
3413
3414
3415 void MacroAssembler::CheckPageFlag( 3208 void MacroAssembler::CheckPageFlag(
3416 Register object, 3209 Register object,
3417 Register scratch, // scratch may be same register as object 3210 Register scratch, // scratch may be same register as object
3418 int mask, Condition cc, Label* condition_met) { 3211 int mask, Condition cc, Label* condition_met) {
3419 DCHECK(cc == ne || cc == eq); 3212 DCHECK(cc == ne || cc == eq);
3420 ClearRightImm(scratch, object, Operand(kPageSizeBits)); 3213 ClearRightImm(scratch, object, Operand(kPageSizeBits));
3421 LoadP(scratch, MemOperand(scratch, MemoryChunk::kFlagsOffset)); 3214 LoadP(scratch, MemOperand(scratch, MemoryChunk::kFlagsOffset));
3422 3215
3423 And(r0, scratch, Operand(mask), SetRC); 3216 And(r0, scratch, Operand(mask), SetRC);
3424 3217
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after
4646 } 4439 }
4647 if (mag.shift > 0) srawi(result, result, mag.shift); 4440 if (mag.shift > 0) srawi(result, result, mag.shift);
4648 ExtractBit(r0, dividend, 31); 4441 ExtractBit(r0, dividend, 31);
4649 add(result, result, r0); 4442 add(result, result, r0);
4650 } 4443 }
4651 4444
4652 } // namespace internal 4445 } // namespace internal
4653 } // namespace v8 4446 } // namespace v8
4654 4447
4655 #endif // V8_TARGET_ARCH_PPC 4448 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/ppc/macro-assembler-ppc.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698