OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2985 Register src, | 2985 Register src, |
2986 XMMRegister scratch) { | 2986 XMMRegister scratch) { |
2987 if (FLAG_debug_code) { | 2987 if (FLAG_debug_code) { |
2988 cmpq(src, Immediate(0xffffffff)); | 2988 cmpq(src, Immediate(0xffffffff)); |
2989 Assert(below_equal, kInputGPRIsExpectedToHaveUpper32Cleared); | 2989 Assert(below_equal, kInputGPRIsExpectedToHaveUpper32Cleared); |
2990 } | 2990 } |
2991 cvtqsi2sd(dst, src); | 2991 cvtqsi2sd(dst, src); |
2992 } | 2992 } |
2993 | 2993 |
2994 | 2994 |
| 2995 void MacroAssembler::SlowTruncateToI(Register result_reg, |
| 2996 Register input_reg, |
| 2997 int offset) { |
| 2998 DoubleToIStub stub(input_reg, result_reg, offset, true); |
| 2999 call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); |
| 3000 } |
| 3001 |
| 3002 |
| 3003 void MacroAssembler::TruncateHeapNumberToI(Register result_reg, |
| 3004 Register input_reg) { |
| 3005 Label done; |
| 3006 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 3007 cvttsd2siq(result_reg, xmm0); |
| 3008 Set(kScratchRegister, V8_UINT64_C(0x8000000000000000)); |
| 3009 cmpq(result_reg, kScratchRegister); |
| 3010 j(not_equal, &done, Label::kNear); |
| 3011 |
| 3012 // Slow case. |
| 3013 if (input_reg.is(result_reg)) { |
| 3014 subq(rsp, Immediate(kDoubleSize)); |
| 3015 movsd(MemOperand(rsp, 0), xmm0); |
| 3016 SlowTruncateToI(result_reg, rsp, 0); |
| 3017 addq(rsp, Immediate(kDoubleSize)); |
| 3018 } else { |
| 3019 SlowTruncateToI(result_reg, input_reg); |
| 3020 } |
| 3021 |
| 3022 bind(&done); |
| 3023 } |
| 3024 |
| 3025 |
| 3026 void MacroAssembler::TruncateDoubleToI(Register result_reg, |
| 3027 XMMRegister input_reg) { |
| 3028 Label done; |
| 3029 cvttsd2siq(result_reg, input_reg); |
| 3030 movq(kScratchRegister, |
| 3031 V8_INT64_C(0x8000000000000000), |
| 3032 RelocInfo::NONE64); |
| 3033 cmpq(result_reg, kScratchRegister); |
| 3034 j(not_equal, &done, Label::kNear); |
| 3035 |
| 3036 subq(rsp, Immediate(kDoubleSize)); |
| 3037 movsd(MemOperand(rsp, 0), input_reg); |
| 3038 SlowTruncateToI(result_reg, rsp, 0); |
| 3039 addq(rsp, Immediate(kDoubleSize)); |
| 3040 |
| 3041 bind(&done); |
| 3042 } |
| 3043 |
| 3044 |
| 3045 void MacroAssembler::DoubleToI(Register result_reg, |
| 3046 XMMRegister input_reg, |
| 3047 XMMRegister scratch, |
| 3048 MinusZeroMode minus_zero_mode, |
| 3049 Label* conversion_failed, |
| 3050 Label::Distance dst) { |
| 3051 cvttsd2si(result_reg, input_reg); |
| 3052 cvtlsi2sd(xmm0, result_reg); |
| 3053 ucomisd(xmm0, input_reg); |
| 3054 j(not_equal, conversion_failed, dst); |
| 3055 j(parity_even, conversion_failed, dst); // NaN. |
| 3056 if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { |
| 3057 Label done; |
| 3058 // The integer converted back is equal to the original. We |
| 3059 // only have to test if we got -0 as an input. |
| 3060 testl(result_reg, result_reg); |
| 3061 j(not_zero, &done, Label::kNear); |
| 3062 movmskpd(result_reg, input_reg); |
| 3063 // Bit 0 contains the sign of the double in input_reg. |
| 3064 // If input was positive, we are ok and return 0, otherwise |
| 3065 // jump to conversion_failed. |
| 3066 andl(result_reg, Immediate(1)); |
| 3067 j(not_zero, conversion_failed, dst); |
| 3068 bind(&done); |
| 3069 } |
| 3070 } |
| 3071 |
| 3072 |
| 3073 void MacroAssembler::TaggedToI(Register result_reg, |
| 3074 Register input_reg, |
| 3075 XMMRegister temp, |
| 3076 MinusZeroMode minus_zero_mode, |
| 3077 Label* lost_precision, |
| 3078 Label::Distance dst) { |
| 3079 Label done; |
| 3080 ASSERT(!temp.is(xmm0)); |
| 3081 |
| 3082 // Heap number map check. |
| 3083 CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 3084 Heap::kHeapNumberMapRootIndex); |
| 3085 j(not_equal, lost_precision, dst); |
| 3086 |
| 3087 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 3088 cvttsd2si(result_reg, xmm0); |
| 3089 cvtlsi2sd(temp, result_reg); |
| 3090 ucomisd(xmm0, temp); |
| 3091 RecordComment("Deferred TaggedToI: lost precision"); |
| 3092 j(not_equal, lost_precision, dst); |
| 3093 RecordComment("Deferred TaggedToI: NaN"); |
| 3094 j(parity_even, lost_precision, dst); // NaN. |
| 3095 if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { |
| 3096 testl(result_reg, result_reg); |
| 3097 j(not_zero, &done, Label::kNear); |
| 3098 movmskpd(result_reg, xmm0); |
| 3099 andl(result_reg, Immediate(1)); |
| 3100 j(not_zero, lost_precision, dst); |
| 3101 } |
| 3102 bind(&done); |
| 3103 } |
| 3104 |
| 3105 |
2995 void MacroAssembler::LoadInstanceDescriptors(Register map, | 3106 void MacroAssembler::LoadInstanceDescriptors(Register map, |
2996 Register descriptors) { | 3107 Register descriptors) { |
2997 movq(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); | 3108 movq(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); |
2998 } | 3109 } |
2999 | 3110 |
3000 | 3111 |
3001 void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { | 3112 void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { |
3002 movq(dst, FieldOperand(map, Map::kBitField3Offset)); | 3113 movq(dst, FieldOperand(map, Map::kBitField3Offset)); |
3003 DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); | 3114 DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); |
3004 } | 3115 } |
(...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4695 j(greater, &no_memento_available); | 4806 j(greater, &no_memento_available); |
4696 CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), | 4807 CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), |
4697 Heap::kAllocationMementoMapRootIndex); | 4808 Heap::kAllocationMementoMapRootIndex); |
4698 bind(&no_memento_available); | 4809 bind(&no_memento_available); |
4699 } | 4810 } |
4700 | 4811 |
4701 | 4812 |
4702 } } // namespace v8::internal | 4813 } } // namespace v8::internal |
4703 | 4814 |
4704 #endif // V8_TARGET_ARCH_X64 | 4815 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |