OLD | NEW |
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_S390 | 8 #if V8_TARGET_ARCH_S390 |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1949 STATIC_ASSERT(Map::kInstanceTypeOffset < 4096); | 1949 STATIC_ASSERT(Map::kInstanceTypeOffset < 4096); |
1950 STATIC_ASSERT(LAST_TYPE < 256); | 1950 STATIC_ASSERT(LAST_TYPE < 256); |
1951 LoadlB(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 1951 LoadlB(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
1952 CmpP(type_reg, Operand(type)); | 1952 CmpP(type_reg, Operand(type)); |
1953 } | 1953 } |
1954 | 1954 |
1955 void MacroAssembler::CompareRoot(Register obj, Heap::RootListIndex index) { | 1955 void MacroAssembler::CompareRoot(Register obj, Heap::RootListIndex index) { |
1956 CmpP(obj, MemOperand(kRootRegister, index << kPointerSizeLog2)); | 1956 CmpP(obj, MemOperand(kRootRegister, index << kPointerSizeLog2)); |
1957 } | 1957 } |
1958 | 1958 |
1959 void MacroAssembler::CheckFastObjectElements(Register map, Register scratch, | |
1960 Label* fail) { | |
1961 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
1962 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
1963 STATIC_ASSERT(FAST_ELEMENTS == 2); | |
1964 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | |
1965 CmpLogicalByte(FieldMemOperand(map, Map::kBitField2Offset), | |
1966 Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); | |
1967 ble(fail); | |
1968 CmpLogicalByte(FieldMemOperand(map, Map::kBitField2Offset), | |
1969 Operand(Map::kMaximumBitField2FastHoleyElementValue)); | |
1970 bgt(fail); | |
1971 } | |
1972 | |
1973 void MacroAssembler::CheckFastSmiElements(Register map, Register scratch, | |
1974 Label* fail) { | |
1975 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
1976 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
1977 CmpLogicalByte(FieldMemOperand(map, Map::kBitField2Offset), | |
1978 Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); | |
1979 bgt(fail); | |
1980 } | |
1981 | |
1982 void MacroAssembler::SmiToDouble(DoubleRegister value, Register smi) { | 1959 void MacroAssembler::SmiToDouble(DoubleRegister value, Register smi) { |
1983 SmiUntag(ip, smi); | 1960 SmiUntag(ip, smi); |
1984 ConvertIntToDouble(ip, value); | 1961 ConvertIntToDouble(ip, value); |
1985 } | 1962 } |
1986 void MacroAssembler::StoreNumberToDoubleElements( | |
1987 Register value_reg, Register key_reg, Register elements_reg, | |
1988 Register scratch1, DoubleRegister double_scratch, Label* fail, | |
1989 int elements_offset) { | |
1990 DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1)); | |
1991 Label smi_value, store; | |
1992 | |
1993 // Handle smi values specially. | |
1994 JumpIfSmi(value_reg, &smi_value); | |
1995 | |
1996 // Ensure that the object is a heap number | |
1997 CheckMap(value_reg, scratch1, isolate()->factory()->heap_number_map(), fail, | |
1998 DONT_DO_SMI_CHECK); | |
1999 | |
2000 LoadDouble(double_scratch, | |
2001 FieldMemOperand(value_reg, HeapNumber::kValueOffset)); | |
2002 // Force a canonical NaN. | |
2003 CanonicalizeNaN(double_scratch); | |
2004 b(&store); | |
2005 | |
2006 bind(&smi_value); | |
2007 SmiToDouble(double_scratch, value_reg); | |
2008 | |
2009 bind(&store); | |
2010 SmiToDoubleArrayOffset(scratch1, key_reg); | |
2011 StoreDouble(double_scratch, | |
2012 FieldMemOperand(elements_reg, scratch1, | |
2013 FixedDoubleArray::kHeaderSize - elements_offset)); | |
2014 } | |
2015 | 1963 |
2016 void MacroAssembler::CompareMap(Register obj, Register scratch, Handle<Map> map, | 1964 void MacroAssembler::CompareMap(Register obj, Register scratch, Handle<Map> map, |
2017 Label* early_success) { | 1965 Label* early_success) { |
2018 LoadP(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); | 1966 LoadP(scratch, FieldMemOperand(obj, HeapObject::kMapOffset)); |
2019 CompareMap(obj, map, early_success); | 1967 CompareMap(obj, map, early_success); |
2020 } | 1968 } |
2021 | 1969 |
2022 void MacroAssembler::CompareMap(Register obj_map, Handle<Map> map, | 1970 void MacroAssembler::CompareMap(Register obj_map, Handle<Map> map, |
2023 Label* early_success) { | 1971 Label* early_success) { |
2024 mov(r0, Operand(map)); | 1972 mov(r0, Operand(map)); |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2484 LoadP(dst, MemOperand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); | 2432 LoadP(dst, MemOperand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); |
2485 } | 2433 } |
2486 } else { | 2434 } else { |
2487 // Slot is in the current function context. Move it into the | 2435 // Slot is in the current function context. Move it into the |
2488 // destination register in case we store into it (the write barrier | 2436 // destination register in case we store into it (the write barrier |
2489 // cannot be allowed to destroy the context in esi). | 2437 // cannot be allowed to destroy the context in esi). |
2490 LoadRR(dst, cp); | 2438 LoadRR(dst, cp); |
2491 } | 2439 } |
2492 } | 2440 } |
2493 | 2441 |
2494 void MacroAssembler::LoadTransitionedArrayMapConditional( | |
2495 ElementsKind expected_kind, ElementsKind transitioned_kind, | |
2496 Register map_in_out, Register scratch, Label* no_map_match) { | |
2497 DCHECK(IsFastElementsKind(expected_kind)); | |
2498 DCHECK(IsFastElementsKind(transitioned_kind)); | |
2499 | |
2500 // Check that the function's map is the same as the expected cached map. | |
2501 LoadP(scratch, NativeContextMemOperand()); | |
2502 LoadP(ip, ContextMemOperand(scratch, Context::ArrayMapIndex(expected_kind))); | |
2503 CmpP(map_in_out, ip); | |
2504 bne(no_map_match); | |
2505 | |
2506 // Use the transitioned cached map. | |
2507 LoadP(map_in_out, | |
2508 ContextMemOperand(scratch, Context::ArrayMapIndex(transitioned_kind))); | |
2509 } | |
2510 | |
2511 void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { | 2442 void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { |
2512 LoadP(dst, NativeContextMemOperand()); | 2443 LoadP(dst, NativeContextMemOperand()); |
2513 LoadP(dst, ContextMemOperand(dst, index)); | 2444 LoadP(dst, ContextMemOperand(dst, index)); |
2514 } | 2445 } |
2515 | 2446 |
2516 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, | 2447 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, |
2517 Register map, | 2448 Register map, |
2518 Register scratch) { | 2449 Register scratch) { |
2519 // Load the initial map. The global functions all have initial maps. | 2450 // Load the initial map. The global functions all have initial maps. |
2520 LoadP(map, | 2451 LoadP(map, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2585 Label* smi_case) { | 2516 Label* smi_case) { |
2586 STATIC_ASSERT(kSmiTag == 0); | 2517 STATIC_ASSERT(kSmiTag == 0); |
2587 STATIC_ASSERT(kSmiTagSize == 1); | 2518 STATIC_ASSERT(kSmiTagSize == 1); |
2588 // this won't work if src == dst | 2519 // this won't work if src == dst |
2589 DCHECK(src.code() != dst.code()); | 2520 DCHECK(src.code() != dst.code()); |
2590 SmiUntag(dst, src); | 2521 SmiUntag(dst, src); |
2591 TestIfSmi(src); | 2522 TestIfSmi(src); |
2592 beq(smi_case); | 2523 beq(smi_case); |
2593 } | 2524 } |
2594 | 2525 |
2595 void MacroAssembler::UntagAndJumpIfNotSmi(Register dst, Register src, | |
2596 Label* non_smi_case) { | |
2597 STATIC_ASSERT(kSmiTag == 0); | |
2598 STATIC_ASSERT(kSmiTagSize == 1); | |
2599 | |
2600 // We can more optimally use TestIfSmi if dst != src | |
2601 // otherwise, the UnTag operation will kill the CC and we cannot | |
2602 // test the Tag bit. | |
2603 if (src.code() != dst.code()) { | |
2604 SmiUntag(dst, src); | |
2605 TestIfSmi(src); | |
2606 } else { | |
2607 TestBit(src, 0, r0); | |
2608 SmiUntag(dst, src); | |
2609 LoadAndTestRR(r0, r0); | |
2610 } | |
2611 bne(non_smi_case); | |
2612 } | |
2613 | |
2614 void MacroAssembler::JumpIfEitherSmi(Register reg1, Register reg2, | 2526 void MacroAssembler::JumpIfEitherSmi(Register reg1, Register reg2, |
2615 Label* on_either_smi) { | 2527 Label* on_either_smi) { |
2616 STATIC_ASSERT(kSmiTag == 0); | 2528 STATIC_ASSERT(kSmiTag == 0); |
2617 JumpIfSmi(reg1, on_either_smi); | 2529 JumpIfSmi(reg1, on_either_smi); |
2618 JumpIfSmi(reg2, on_either_smi); | 2530 JumpIfSmi(reg2, on_either_smi); |
2619 } | 2531 } |
2620 | 2532 |
2621 void MacroAssembler::AssertNotNumber(Register object) { | 2533 void MacroAssembler::AssertNotNumber(Register object) { |
2622 if (emit_debug_code()) { | 2534 if (emit_debug_code()) { |
2623 STATIC_ASSERT(kSmiTag == 0); | 2535 STATIC_ASSERT(kSmiTag == 0); |
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3406 for (int i = 0; i < config->num_allocatable_general_registers(); ++i) { | 3318 for (int i = 0; i < config->num_allocatable_general_registers(); ++i) { |
3407 int code = config->GetAllocatableGeneralCode(i); | 3319 int code = config->GetAllocatableGeneralCode(i); |
3408 Register candidate = Register::from_code(code); | 3320 Register candidate = Register::from_code(code); |
3409 if (regs & candidate.bit()) continue; | 3321 if (regs & candidate.bit()) continue; |
3410 return candidate; | 3322 return candidate; |
3411 } | 3323 } |
3412 UNREACHABLE(); | 3324 UNREACHABLE(); |
3413 return no_reg; | 3325 return no_reg; |
3414 } | 3326 } |
3415 | 3327 |
3416 void MacroAssembler::JumpIfDictionaryInPrototypeChain(Register object, | |
3417 Register scratch0, | |
3418 Register scratch1, | |
3419 Label* found) { | |
3420 DCHECK(!scratch1.is(scratch0)); | |
3421 Register current = scratch0; | |
3422 Label loop_again, end; | |
3423 | |
3424 // scratch contained elements pointer. | |
3425 LoadRR(current, object); | |
3426 LoadP(current, FieldMemOperand(current, HeapObject::kMapOffset)); | |
3427 LoadP(current, FieldMemOperand(current, Map::kPrototypeOffset)); | |
3428 CompareRoot(current, Heap::kNullValueRootIndex); | |
3429 beq(&end); | |
3430 | |
3431 // Loop based on the map going up the prototype chain. | |
3432 bind(&loop_again); | |
3433 LoadP(current, FieldMemOperand(current, HeapObject::kMapOffset)); | |
3434 | |
3435 STATIC_ASSERT(JS_PROXY_TYPE < JS_OBJECT_TYPE); | |
3436 STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE); | |
3437 LoadlB(scratch1, FieldMemOperand(current, Map::kInstanceTypeOffset)); | |
3438 CmpP(scratch1, Operand(JS_OBJECT_TYPE)); | |
3439 blt(found); | |
3440 | |
3441 LoadlB(scratch1, FieldMemOperand(current, Map::kBitField2Offset)); | |
3442 DecodeField<Map::ElementsKindBits>(scratch1); | |
3443 CmpP(scratch1, Operand(DICTIONARY_ELEMENTS)); | |
3444 beq(found); | |
3445 LoadP(current, FieldMemOperand(current, Map::kPrototypeOffset)); | |
3446 CompareRoot(current, Heap::kNullValueRootIndex); | |
3447 bne(&loop_again); | |
3448 | |
3449 bind(&end); | |
3450 } | |
3451 | |
3452 void MacroAssembler::mov(Register dst, const Operand& src) { | 3328 void MacroAssembler::mov(Register dst, const Operand& src) { |
3453 if (src.rmode_ != kRelocInfo_NONEPTR) { | 3329 if (src.rmode_ != kRelocInfo_NONEPTR) { |
3454 // some form of relocation needed | 3330 // some form of relocation needed |
3455 RecordRelocInfo(src.rmode_, src.imm_); | 3331 RecordRelocInfo(src.rmode_, src.imm_); |
3456 } | 3332 } |
3457 | 3333 |
3458 #if V8_TARGET_ARCH_S390X | 3334 #if V8_TARGET_ARCH_S390X |
3459 int64_t value = src.immediate(); | 3335 int64_t value = src.immediate(); |
3460 int32_t hi_32 = static_cast<int64_t>(value) >> 32; | 3336 int32_t hi_32 = static_cast<int64_t>(value) >> 32; |
3461 int32_t lo_32 = static_cast<int32_t>(value); | 3337 int32_t lo_32 = static_cast<int32_t>(value); |
(...skipping 1845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5307 } | 5183 } |
5308 if (mag.shift > 0) ShiftRightArith(result, result, Operand(mag.shift)); | 5184 if (mag.shift > 0) ShiftRightArith(result, result, Operand(mag.shift)); |
5309 ExtractBit(r0, dividend, 31); | 5185 ExtractBit(r0, dividend, 31); |
5310 AddP(result, r0); | 5186 AddP(result, r0); |
5311 } | 5187 } |
5312 | 5188 |
5313 } // namespace internal | 5189 } // namespace internal |
5314 } // namespace v8 | 5190 } // namespace v8 |
5315 | 5191 |
5316 #endif // V8_TARGET_ARCH_S390 | 5192 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |